调整世界运行倍速实现方式
调整事件订阅发布接口 调整事件回调函数为待执行函数,世界添加执行接口(待考虑是否需要处理结果返回)
This commit is contained in:
parent
5744018095
commit
03669cd1b3
21
events.go
21
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 {
|
||||
wd.Execute(func() {
|
||||
me.et.Unsubscribe(wd.(*world).world, sub)
|
||||
delete(me.subscriberMap, subscriberKey)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
67
world.go
67
world.go
@ -3,6 +3,7 @@ package ecs
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/yohamta/donburi"
|
||||
@ -21,7 +22,8 @@ const (
|
||||
Closed
|
||||
)
|
||||
|
||||
type World interface {
|
||||
type (
|
||||
World interface {
|
||||
|
||||
// Id returns the unique identifier for the world.
|
||||
Id() WorldId
|
||||
@ -43,23 +45,31 @@ type World interface {
|
||||
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
|
||||
// 下一帧需要执行的次数
|
||||
times float64
|
||||
|
||||
// 退出信号
|
||||
quit chan struct{}
|
||||
chanManageEvent chan ManageEventFunc
|
||||
// 待执行函数
|
||||
toBeExecuteds chan ExecuteFunc
|
||||
}
|
||||
|
||||
func NewComponentType[T any](opts ...interface{}) *ComponentType[T] {
|
||||
@ -75,11 +85,11 @@ func NewWorld(tick int) World {
|
||||
systems: make([]ISystem, 0),
|
||||
state: Init,
|
||||
tick: tick,
|
||||
lastTick: time.Now(),
|
||||
ticker: time.NewTicker(time.Duration(tick) * time.Millisecond),
|
||||
speed: 1,
|
||||
times: 1,
|
||||
quit: make(chan struct{}),
|
||||
chanManageEvent: make(chan ManageEventFunc, 1024),
|
||||
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,24 +223,11 @@ 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)
|
||||
|
||||
if w.times > 1 {
|
||||
times := int(math.Floor(w.times))
|
||||
for i := 0; i < times; i++ {
|
||||
for _, sys := range w.systems {
|
||||
sys.Update(w)
|
||||
}
|
||||
@ -250,4 +236,9 @@ func (w *world) run() {
|
||||
// 处理所有事件
|
||||
processAllEvents(w)
|
||||
}
|
||||
w.times = w.times - float64(times) + w.speed
|
||||
} else {
|
||||
w.times += w.speed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user