diff --git a/events.go b/events.go index a6186b1..1539e68 100644 --- a/events.go +++ b/events.go @@ -21,8 +21,6 @@ type ( } // 事件订阅者定义 Subscriber[T any] func(w World, event T) - // 事件管理回调定义 - ManageEventFunc func() ) // 开启底层事件处理调试 @@ -48,40 +46,39 @@ func processAllEvents(w World) { // 发布该类型的事件 // 在world协程外执行 func (me *EventType[T]) Publish(wd World, event *T) { - wd.(*world).chanManageEvent <- func() { + wd.Execute(func() { me.et.Publish(wd.(*world).world, *event) - } + }) } /////////////////////////////////////////////////////////////////////////////////// // 订阅该类型的事件 -// 在world启动前执行 func (me *EventType[T]) Subscribe(wd World, subscriber Subscriber[T]) { me.subscriberMapLock.Lock() defer me.subscriberMapLock.Unlock() - // subscriberKey := subscriberKey[T](wd, subscriber) if _, exist := me.subscriberMap[subscriberKey]; !exist { - me.subscriberMap[subscriberKey] = func(w donburi.World, event T) { + fn := func(w donburi.World, event T) { subscriber(wd, event) } - me.et.Subscribe(wd.(*world).world, me.subscriberMap[subscriberKey]) - } else { - panic("重复注册事件订阅者") + me.subscriberMap[subscriberKey] = fn + wd.Execute(func() { + me.et.Subscribe(wd.(*world).world, fn) + }) } } // 取消订阅该类型的事件 -// 在world启动前执行 func (me *EventType[T]) Unsubscribe(wd World, subscriber Subscriber[T]) { me.subscriberMapLock.Lock() defer me.subscriberMapLock.Unlock() - // subscriberKey := subscriberKey[T](wd, subscriber) if sub, ok := me.subscriberMap[subscriberKey]; ok { - me.et.Unsubscribe(wd.(*world).world, sub) - delete(me.subscriberMap, subscriberKey) + wd.Execute(func() { + me.et.Unsubscribe(wd.(*world).world, sub) + delete(me.subscriberMap, subscriberKey) + }) } } diff --git a/examples/rtss-event/main.go b/examples/rtss-event/main.go index 2ea821d..507c890 100644 --- a/examples/rtss-event/main.go +++ b/examples/rtss-event/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "runtime" "time" "joylink.club/ecs" @@ -35,31 +34,17 @@ func NewSwitchSystem() *SwitchSystem { } var ( - wd1 = ecs.NewWorld(1) - wd2 = ecs.NewWorld(20) + wd1 = ecs.NewWorld(500) + wd2 = ecs.NewWorld(500) ) // //////////////////////////////////////// func main() { - // go world1() - // go world2() - // time.Sleep(4 * time.Second) - // fireSwitchDcEventType.Publish(wd1, &FireSwitchDcEvent{Dc: true}) - // fireSwitchDcEventType.Publish(wd2, &FireSwitchDcEvent{Dc: false}) - - fmt.Println("当前运行系统为:", runtime.GOOS) - - wd1.AddSystem(NewSwitchSystem()) - wd1.StartUp() - - // - wd2.AddSystem(NewSwitchSystem()) - wd2.StartUp() - fmt.Println("开始", time.Now()) - - time.Sleep(5 * time.Second) - fmt.Println("结束", time.Now()) - + go world1() + go world2() + time.Sleep(4 * time.Second) + fireSwitchDcEventType.Publish(wd1, &FireSwitchDcEvent{Dc: true}) + fireSwitchDcEventType.Publish(wd2, &FireSwitchDcEvent{Dc: false}) } func world1() { world := wd1 diff --git a/examples/rtss/main.go b/examples/rtss/main.go index 74dfa98..0c20e5e 100644 --- a/examples/rtss/main.go +++ b/examples/rtss/main.go @@ -1,17 +1,18 @@ package main import ( - "time" - - "joylink.club/ecs" - system "joylink.club/ecs/examples/rtss/sys" + "fmt" + "math" + "strconv" ) func main() { - w := ecs.NewWorld(1) - turnoutSys := system.NewTurnoutSys() - w.AddSystem(turnoutSys) - w.StartUp() + // w := ecs.NewWorld(20) + // turnoutSys := system.NewTurnoutSys() + // w.AddSystem(turnoutSys) + // w.StartUp() + // w.SetSpeed(10) + // for i := 0; i < 5; i++ { // w := ecs.NewWorld(1) @@ -40,5 +41,12 @@ func main() { // // } // // }() // } - time.Sleep(5 * time.Second) + // time.Sleep(5 * time.Second) + + f := 2.1 + i := math.Floor(f) + d := f - i + fmt.Println(f, i, d) + f1, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", d), 64) + fmt.Println(f1) } diff --git a/world.go b/world.go index 89a5382..f7b841a 100644 --- a/world.go +++ b/world.go @@ -3,6 +3,7 @@ package ecs import ( "fmt" "log" + "math" "time" "github.com/yohamta/donburi" @@ -21,45 +22,54 @@ const ( Closed ) -type World interface { +type ( + World interface { - // Id returns the unique identifier for the world. - Id() WorldId - // Create creates a new entity with the specified components. - Create(components ...donburi.IComponentType) *Entry - // CreateMany creates a new entity with the specified components. - CreateMany(n int, components ...donburi.IComponentType) []*Entry - // Entry returns an entry for the specified entity. - Entry(entity Entity) *Entry - // Remove removes the specified entity. - Remove(entity Entity) - // Valid returns true if the specified entity is valid. - Valid(e Entity) bool - // Len returns the number of entities in the world. - Len() int + // Id returns the unique identifier for the world. + Id() WorldId + // Create creates a new entity with the specified components. + Create(components ...donburi.IComponentType) *Entry + // CreateMany creates a new entity with the specified components. + CreateMany(n int, components ...donburi.IComponentType) []*Entry + // Entry returns an entry for the specified entity. + Entry(entity Entity) *Entry + // Remove removes the specified entity. + Remove(entity Entity) + // Valid returns true if the specified entity is valid. + Valid(e Entity) bool + // Len returns the number of entities in the world. + Len() int - StartUp() - Pause() - Resume() - SetSpeed(speed float64) error - AddSystem(sys ...ISystem) - Close() - // 世界时间间隔 - Tick() int - Running() bool -} + StartUp() + Pause() + Resume() + SetSpeed(speed float64) error + AddSystem(sys ...ISystem) + // 在世界线程执行 + Execute(fn ExecuteFunc) + Close() + // 世界时间间隔 + Tick() int + Running() bool + } + // 世界执行函数 + ExecuteFunc func() +) type world struct { - world donburi.World - systems []ISystem - state WorldState - tick int - lastTick time.Time - ticker *time.Ticker - speed float64 + world donburi.World + systems []ISystem + state WorldState + tick int + ticker *time.Ticker + speed float64 + // 下一帧需要执行的次数 + times float64 - quit chan struct{} - chanManageEvent chan ManageEventFunc + // 退出信号 + quit chan struct{} + // 待执行函数 + toBeExecuteds chan ExecuteFunc } func NewComponentType[T any](opts ...interface{}) *ComponentType[T] { @@ -71,15 +81,15 @@ func NewComponentType[T any](opts ...interface{}) *ComponentType[T] { // tick 单位为ms,且必须大于0 func NewWorld(tick int) World { return &world{ - world: donburi.NewWorld(), - systems: make([]ISystem, 0), - state: Init, - tick: tick, - lastTick: time.Now(), - ticker: time.NewTicker(time.Duration(tick) * time.Millisecond), - speed: 1, - quit: make(chan struct{}), - chanManageEvent: make(chan ManageEventFunc, 1024), + world: donburi.NewWorld(), + systems: make([]ISystem, 0), + state: Init, + tick: tick, + ticker: time.NewTicker(time.Duration(tick) * time.Millisecond), + speed: 1, + times: 1, + quit: make(chan struct{}), + toBeExecuteds: make(chan ExecuteFunc, 1024), } } func (w *world) Running() bool { @@ -157,20 +167,9 @@ func (w *world) SetSpeed(speed float64) error { return fmt.Errorf("速度必须在[%f, %d]之间", SpeedMin, SpeedMax) } w.speed = speed - fmt.Println("更新速度,实际tick=", w.ActualTick()) - w.ticker.Reset(time.Duration(w.ActualTick()) * time.Millisecond) return nil } -// 世界实际运行频率 -func (w *world) ActualTick() int64 { - tick := int64(float64(w.tick) / (w.speed)) - if tick <= 0 { - return 1 - } - return tick -} - // 启动世界,世界逻辑开始执行且世界为运行状态 func (w *world) StartUp() { if w.state == Init { // 避免重复运行 @@ -179,19 +178,19 @@ func (w *world) StartUp() { } } +// 在世界线程执行逻辑 +func (w *world) Execute(fn ExecuteFunc) { + w.toBeExecuteds <- fn +} + // 关闭世界 func (w *world) Close() { w.quit <- struct{}{} } -// 获取world与事件系统间的管道的只读引用 -func (w *world) eventChanReader() <-chan ManageEventFunc { - return w.chanManageEvent -} - // 事件管理相关处理 func (w *world) processManageEventFuncs() { - manageEventChan := w.eventChanReader() + manageEventChan := w.toBeExecuteds for { select { case callBack := <-manageEventChan: @@ -224,30 +223,22 @@ func (w *world) run() { } <-w.ticker.C if w.state == Pause { // 暂停不更新 - // time.Sleep(1 * time.Millisecond) continue } - // dt := time.Since(w.lastTick).Milliseconds() - // if dt >= w.ActualTick() { - // // fmt.Println("仿真更新,id:", info.id) - // w.lastTick = time.Now() - - // for _, sys := range w.systems { - // sys.Update(w) - // } - // // 处理事件管理相关 - // w.processManageEventFuncs() - // // 处理所有事件 - // processAllEvents(w) - // } - // time.Sleep(15 * time.Millisecond) - - for _, sys := range w.systems { - sys.Update(w) + if w.times > 1 { + times := int(math.Floor(w.times)) + for i := 0; i < times; i++ { + for _, sys := range w.systems { + sys.Update(w) + } + // 处理事件管理相关 + w.processManageEventFuncs() + // 处理所有事件 + processAllEvents(w) + } + w.times = w.times - float64(times) + w.speed + } else { + w.times += w.speed } - // 处理事件管理相关 - w.processManageEventFuncs() - // 处理所有事件 - processAllEvents(w) } }