package instance import ( "common/discover" "common/log" "common/proto/gen/grpc_pb" "common/utils" "context" "google.golang.org/protobuf/proto" "runtime/debug" "sync" "time" ) // Instance 场景类 type Instance struct { wg sync.WaitGroup players map[int]*PlayerNode // 存储所有玩家节点 [uid] ctx context.Context // 停止指令 cancel context.CancelFunc // 停止函数 SID int64 // 服务ID InstanceID int // 副本ID UniqueNo int64 // 唯一编号 EventIn chan proto.Message // 消息入口 EventOut chan *Msg2Client // 消息出口 } // NewScene 初始化场景 func NewScene(sid int64, instanceID int) *Instance { s := &Instance{ players: make(map[int]*PlayerNode), SID: sid, InstanceID: instanceID, UniqueNo: utils.SnowflakeInstance().Generate().Int64(), EventIn: make(chan proto.Message), EventOut: make(chan *Msg2Client), } s.ctx, s.cancel = context.WithCancel(context.Background()) return s } func (i *Instance) Start(ttl int64) { i.wg.Add(1) go func() { defer i.wg.Done() defer func() { if err := recover(); err != nil { log.Infof("instance err: %v, uniqueNo: %v", err, i.UniqueNo) debug.PrintStack() } }() Mgr.Add(i.UniqueNo, i) defer func() { log.Infof("instance destroy: %v, %v", i.InstanceID, i.UniqueNo) discover.UnRegisterInstance(i.UniqueNo) close(i.EventIn) Mgr.Delete(i.UniqueNo) }() if err := discover.RegisterInstance(i.SID, i.InstanceID, i.UniqueNo, ttl); err != nil { log.Errorf("register discover error") return } // 场景心跳 tick := time.NewTicker(50 * time.Millisecond) for { select { case <-i.ctx.Done(): return case <-tick.C: i.onLogic() case e := <-i.EventIn: i.onEvent(e) } } }() log.Infof("new scene start: %v, %v", i.InstanceID, i.UniqueNo) } // 网络帧 func (i *Instance) onEvent(e proto.Message) { switch v := e.(type) { case *grpc_pb.ActionReq: if node, ok := i.players[int(v.UID)]; ok { node.addAction(v) } } } // 逻辑帧 func (i *Instance) onLogic() { // 优先处理移动指令 for _, node := range i.players { node.logicMove() } }