Commit 6f0d72bd0a4b53e74afe665f5fe4034ac689dfd3
1 parent
0cc58315
定时器功能完善优化
Showing
9 changed files
with
273 additions
and
283 deletions
 
Show diff stats
Makefile
src/components/net/server.go
| ... | ... | @@ -102,7 +102,7 @@ func (s *Server) handleTimeOut() { | 
| 102 | 102 | return true | 
| 103 | 103 | }) | 
| 104 | 104 | |
| 105 | - TimeWheel.AfterFunc(1*time.Second, s.handleTimeOut) | |
| 105 | + timewheel.TimeOut(1*time.Second, s.handleTimeOut) | |
| 106 | 106 | } | 
| 107 | 107 | |
| 108 | 108 | func (s *Server)Start() error { | 
| ... | ... | @@ -134,8 +134,6 @@ func (s *Server)Start() error { | 
| 134 | 134 | s.StartWorkerPool() | 
| 135 | 135 | |
| 136 | 136 | //启动定时器 | 
| 137 | - TimeWheel = timewheel.NewTimeWheel(common.TickMS * time.Millisecond, common.WheelSize) | |
| 138 | - TimeWheel.Start() | |
| 139 | 137 | s.handleTimeOut() | 
| 140 | 138 | |
| 141 | 139 | //监听端口 | ... | ... | 
src/components/timewheel/bucket.go deleted
| ... | ... | @@ -1,85 +0,0 @@ | 
| 1 | -package timewheel | |
| 2 | - | |
| 3 | -import ( | |
| 4 | - "container/list" | |
| 5 | - "sync" | |
| 6 | - "sync/atomic" | |
| 7 | - "unsafe" | |
| 8 | -) | |
| 9 | -type bucket struct { | |
| 10 | - //过期时间 | |
| 11 | - expiration int64 | |
| 12 | - | |
| 13 | - mu sync.Mutex | |
| 14 | - //相同过期时间的任务队列 | |
| 15 | - timers *list.List | |
| 16 | -} | |
| 17 | - | |
| 18 | -func newBucket() *bucket { | |
| 19 | - return &bucket{ | |
| 20 | - expiration: -1, | |
| 21 | - mu: sync.Mutex{}, | |
| 22 | - timers: list.New(), | |
| 23 | - } | |
| 24 | -} | |
| 25 | - | |
| 26 | -func (b *bucket) SetExpiration(expiration int64) { | |
| 27 | - atomic.AddInt64(&b.expiration, expiration) | |
| 28 | -} | |
| 29 | - | |
| 30 | -func (b *bucket) Add(t *Timer) { | |
| 31 | - b.mu.Lock() | |
| 32 | - defer b.mu.Unlock() | |
| 33 | - | |
| 34 | - e := b.timers.PushBack(t) | |
| 35 | - t.setBucket(b) | |
| 36 | - t.element = e | |
| 37 | -} | |
| 38 | - | |
| 39 | -func (b *bucket) Flush(reinsert func(*Timer)) { | |
| 40 | - b.mu.Lock() | |
| 41 | - defer b.mu.Unlock() | |
| 42 | - | |
| 43 | - for e := b.timers.Front(); e != nil; { | |
| 44 | - next := e.Next() | |
| 45 | - t := e.Value.(*Timer) | |
| 46 | - b.remove(t) | |
| 47 | - | |
| 48 | - reinsert(t) | |
| 49 | - e = next | |
| 50 | - } | |
| 51 | -} | |
| 52 | - | |
| 53 | -func (b *bucket) remove(t *Timer) bool { | |
| 54 | - if t.getBucket() != b { | |
| 55 | - return false | |
| 56 | - } | |
| 57 | - b.timers.Remove(t.element) | |
| 58 | - t.setBucket(nil) | |
| 59 | - t.element = nil | |
| 60 | - return true | |
| 61 | -} | |
| 62 | - | |
| 63 | -func (b *bucket) Remove(t *Timer) bool { | |
| 64 | - b.mu.Lock() | |
| 65 | - defer b.mu.Unlock() | |
| 66 | - | |
| 67 | - return b.remove(t) | |
| 68 | -} | |
| 69 | - | |
| 70 | -type Timer struct { | |
| 71 | - expiration int64 | |
| 72 | - //要被执行的任务 | |
| 73 | - task func() | |
| 74 | - | |
| 75 | - b unsafe.Pointer | |
| 76 | - element *list.Element | |
| 77 | -} | |
| 78 | - | |
| 79 | -func (t *Timer) setBucket(b *bucket) { | |
| 80 | - atomic.StorePointer(&t.b, unsafe.Pointer(b)) | |
| 81 | -} | |
| 82 | - | |
| 83 | -func (t *Timer) getBucket() *bucket { | |
| 84 | - return (*bucket)(atomic.LoadPointer(&t.b)) | |
| 85 | -} | |
| 86 | 0 | \ No newline at end of file | 
| ... | ... | @@ -0,0 +1,202 @@ | 
| 1 | +package timewheel | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "container/list" | |
| 5 | + "pro2d/src/common" | |
| 6 | + "pro2d/src/components/workpool" | |
| 7 | + "sync" | |
| 8 | + "sync/atomic" | |
| 9 | + "time" | |
| 10 | +) | |
| 11 | + | |
| 12 | +//skynet的时间轮 + 协程池 | |
| 13 | +const ( | |
| 14 | + TimeNearShift = 8 | |
| 15 | + TimeNear = 1 << TimeNearShift | |
| 16 | + TimeLevelShift = 6 | |
| 17 | + TimeLevel = 1 << TimeLevelShift | |
| 18 | + TimeNearMask = TimeNear - 1 | |
| 19 | + TimeLevelMask = TimeLevel - 1 | |
| 20 | +) | |
| 21 | + | |
| 22 | +type bucket struct { | |
| 23 | + expiration int32 | |
| 24 | + timers *list.List | |
| 25 | + | |
| 26 | + mu sync.Mutex | |
| 27 | +} | |
| 28 | + | |
| 29 | +func newBucket() *bucket { | |
| 30 | + return &bucket{ | |
| 31 | + expiration: -1, | |
| 32 | + timers: list.New(), | |
| 33 | + mu: sync.Mutex{}, | |
| 34 | + } | |
| 35 | +} | |
| 36 | + | |
| 37 | +func (b*bucket) Add(t *timer) { | |
| 38 | + b.mu.Lock() | |
| 39 | + defer b.mu.Unlock() | |
| 40 | + | |
| 41 | + b.timers.PushBack(t) | |
| 42 | + //t.setBucket(b) | |
| 43 | + //t.element = e | |
| 44 | +} | |
| 45 | + | |
| 46 | +func (b*bucket) Flush(reinsert func(t *timer)) { | |
| 47 | + b.mu.Lock() | |
| 48 | + defer b.mu.Unlock() | |
| 49 | + | |
| 50 | + for e := b.timers.Front(); e != nil; { | |
| 51 | + next := e.Next() | |
| 52 | + reinsert(e.Value.(*timer)) | |
| 53 | + | |
| 54 | + b.timers.Remove(e) | |
| 55 | + e = next | |
| 56 | + } | |
| 57 | +} | |
| 58 | + | |
| 59 | +type timer struct { | |
| 60 | + expiration uint32 | |
| 61 | + f func() | |
| 62 | +} | |
| 63 | + | |
| 64 | +var TimingWheel *TimeWheel | |
| 65 | + | |
| 66 | +func init() { | |
| 67 | + TimingWheel = NewTimeWheel() | |
| 68 | + TimingWheel.Start() | |
| 69 | +} | |
| 70 | +type TimeWheel struct { | |
| 71 | + tick time.Duration | |
| 72 | + ticker *time.Ticker | |
| 73 | + near [TimeNear]*bucket | |
| 74 | + t [4][TimeLevel]*bucket | |
| 75 | + time uint32 | |
| 76 | + | |
| 77 | + WorkPool *workpool.WorkPool | |
| 78 | + exit chan struct{} | |
| 79 | +} | |
| 80 | + | |
| 81 | +func NewTimeWheel() *TimeWheel { | |
| 82 | + tw := &TimeWheel{ | |
| 83 | + tick: 10*time.Millisecond, | |
| 84 | + time: 0, | |
| 85 | + WorkPool: workpool.NewWorkPool(common.WorkerPoolSize, common.MaxTaskPerWorker), | |
| 86 | + exit: nil, | |
| 87 | + } | |
| 88 | + for i :=0; i < TimeNear; i++ { | |
| 89 | + tw.near[i] = newBucket() | |
| 90 | + } | |
| 91 | + | |
| 92 | + for i :=0; i < 4; i++ { | |
| 93 | + for j :=0; j < TimeLevel; j++ { | |
| 94 | + tw.t[i][j] = newBucket() | |
| 95 | + } | |
| 96 | + } | |
| 97 | + return tw | |
| 98 | +} | |
| 99 | + | |
| 100 | +func (tw *TimeWheel) add(t *timer) bool { | |
| 101 | + time := t.expiration | |
| 102 | + currentTime := tw.time | |
| 103 | + if time <= currentTime { | |
| 104 | + return false | |
| 105 | + } | |
| 106 | + | |
| 107 | + if (time | TimeNearMask) == (currentTime | TimeNearMask) { | |
| 108 | + tw.near[time&TimeNearMask].Add(t) | |
| 109 | + }else { | |
| 110 | + i := 0 | |
| 111 | + mask := TimeNear << TimeNearShift | |
| 112 | + for i=0; i < 3; i ++ { | |
| 113 | + if (time | uint32(mask - 1)) == (currentTime | uint32(mask - 1)) { | |
| 114 | + break | |
| 115 | + } | |
| 116 | + mask <<= TimeLevelShift | |
| 117 | + } | |
| 118 | + | |
| 119 | + tw.t[i][((time>>(TimeNearShift + i*TimeLevelShift)) & TimeLevelMask)].Add(t) | |
| 120 | + } | |
| 121 | + return true | |
| 122 | +} | |
| 123 | + | |
| 124 | +func (tw *TimeWheel) addOrRun(t *timer) { | |
| 125 | + if !tw.add(t) { | |
| 126 | + workerID := int64(t.expiration) % tw.WorkPool.WorkerPoolSize | |
| 127 | + //将请求消息发送给任务队列 | |
| 128 | + tw.WorkPool.TaskQueue[workerID] <- t.f | |
| 129 | + } | |
| 130 | +} | |
| 131 | + | |
| 132 | +func (tw *TimeWheel) moveList(level, idx int) { | |
| 133 | + current := tw.t[level][idx] | |
| 134 | + current.Flush(tw.addOrRun) | |
| 135 | +} | |
| 136 | + | |
| 137 | +func (tw *TimeWheel) shift() { | |
| 138 | + mask := TimeNear | |
| 139 | + tw.time++ | |
| 140 | + ct := tw.time | |
| 141 | + if ct == 0 { | |
| 142 | + tw.moveList(3, 0) | |
| 143 | + }else { | |
| 144 | + time := ct >> TimeNearShift | |
| 145 | + | |
| 146 | + i := 0 | |
| 147 | + for (ct & uint32(mask-1)) == 0{ | |
| 148 | + idx := time & TimeLevelMask | |
| 149 | + if idx != 0 { | |
| 150 | + tw.moveList(i, int(idx)) | |
| 151 | + break | |
| 152 | + } | |
| 153 | + | |
| 154 | + mask <<= TimeLevelShift | |
| 155 | + time >>= TimeLevelShift | |
| 156 | + i++ | |
| 157 | + } | |
| 158 | + } | |
| 159 | +} | |
| 160 | + | |
| 161 | +func (tw *TimeWheel) execute() { | |
| 162 | + idx := tw.time & TimeNearMask | |
| 163 | + tw.near[idx].Flush(tw.addOrRun) | |
| 164 | +} | |
| 165 | + | |
| 166 | +func (tw *TimeWheel) update() { | |
| 167 | + tw.execute() | |
| 168 | + tw.shift() | |
| 169 | + tw.execute() | |
| 170 | +} | |
| 171 | + | |
| 172 | +func (tw *TimeWheel) Start() { | |
| 173 | + tw.ticker = time.NewTicker(tw.tick) | |
| 174 | + tw.WorkPool.StartWorkerPool() | |
| 175 | + | |
| 176 | + go func() { | |
| 177 | + for { | |
| 178 | + select { | |
| 179 | + case <- tw.ticker.C: | |
| 180 | + tw.update() | |
| 181 | + case <- tw.exit: | |
| 182 | + return | |
| 183 | + } | |
| 184 | + } | |
| 185 | + }() | |
| 186 | +} | |
| 187 | + | |
| 188 | +func (tw *TimeWheel) Stop() { | |
| 189 | + close(tw.exit) | |
| 190 | +} | |
| 191 | + | |
| 192 | +func (tw *TimeWheel) afterFunc(expiration time.Duration, f func()) { | |
| 193 | + time := atomic.LoadUint32(&tw.time) | |
| 194 | + tw.addOrRun(&timer{ | |
| 195 | + expiration: uint32(expiration / tw.tick) + time, | |
| 196 | + f: f, | |
| 197 | + }) | |
| 198 | +} | |
| 199 | + | |
| 200 | +func TimeOut(expire time.Duration, f func()) { | |
| 201 | + TimingWheel.afterFunc(expire, f) | |
| 202 | +} | |
| 0 | 203 | \ No newline at end of file | ... | ... | 
src/components/timewheel/timewheel.go deleted
| ... | ... | @@ -1,165 +0,0 @@ | 
| 1 | -package timewheel | |
| 2 | - | |
| 3 | -import ( | |
| 4 | - "pro2d/src/common" | |
| 5 | - "pro2d/src/components/workpool" | |
| 6 | - "sync/atomic" | |
| 7 | - "time" | |
| 8 | - "unsafe" | |
| 9 | -) | |
| 10 | - | |
| 11 | -type TimeWheel struct { | |
| 12 | - ticker *time.Ticker | |
| 13 | - tickMs int64 //一滴答的时间 1ms 可以自定义 我们这里选择使用1ms | |
| 14 | - wheelSize int64 | |
| 15 | - startMs int64 //开始时间 in millisecond | |
| 16 | - endMs int64 | |
| 17 | - wheelTime int64 //跑完一圈所需时间 | |
| 18 | - level int64 //层级 | |
| 19 | - | |
| 20 | - //时间刻度 列表 | |
| 21 | - bucket []*bucket | |
| 22 | - currentTime int64 //当前时间 in millisecond | |
| 23 | - prevflowWheel unsafe.Pointer // type: *TimingWheel | |
| 24 | - overflowWheel unsafe.Pointer // type: *TimingWheel | |
| 25 | - exitC chan struct{} | |
| 26 | - | |
| 27 | - WorkPool *workpool.WorkPool | |
| 28 | -} | |
| 29 | - | |
| 30 | -func NewTimeWheel(tick time.Duration, wheelSize int64) *TimeWheel { | |
| 31 | - //转化为毫秒 | |
| 32 | - tickMs := int64(tick / time.Millisecond) | |
| 33 | - //如果小于零 | |
| 34 | - if tickMs <=0 { | |
| 35 | - panic("tick must be greater than or equal to 1 ms") | |
| 36 | - } | |
| 37 | - | |
| 38 | - startMs := time.Now().UnixMilli() //ms | |
| 39 | - | |
| 40 | - workpool := workpool.NewWorkPool(common.WorkerPoolSize, common.MaxTaskPerWorker) | |
| 41 | - return newTimingWheel(tickMs, wheelSize, startMs, 0, nil, workpool) | |
| 42 | -} | |
| 43 | - | |
| 44 | -func newTimingWheel(tick, wheelSize int64, start, level int64, prev *TimeWheel, pool *workpool.WorkPool) *TimeWheel { | |
| 45 | - buckets := make([]*bucket, wheelSize) | |
| 46 | - for i := range buckets { | |
| 47 | - buckets[i] = newBucket() | |
| 48 | - } | |
| 49 | - | |
| 50 | - return &TimeWheel{ | |
| 51 | - tickMs: tick, | |
| 52 | - wheelSize: wheelSize, | |
| 53 | - startMs: start, | |
| 54 | - endMs: wheelSize * tick + start, | |
| 55 | - wheelTime: wheelSize * tick, | |
| 56 | - bucket: buckets, | |
| 57 | - currentTime: truncate(start, tick), | |
| 58 | - exitC: make(chan struct{}), | |
| 59 | - WorkPool: pool, | |
| 60 | - | |
| 61 | - prevflowWheel: unsafe.Pointer(prev), | |
| 62 | - level: level, | |
| 63 | - } | |
| 64 | -} | |
| 65 | - | |
| 66 | -func truncate(dst, m int64) int64 { | |
| 67 | - return dst - dst%m | |
| 68 | -} | |
| 69 | - | |
| 70 | -func (tw *TimeWheel) add(t *Timer) bool { | |
| 71 | - currentTime := atomic.LoadInt64(&tw.currentTime) | |
| 72 | - if t.expiration < currentTime + tw.tickMs { | |
| 73 | - return false | |
| 74 | - }else if t.expiration < currentTime + tw.wheelTime { | |
| 75 | - virtualID := t.expiration / tw.tickMs //需要多少滴答数 | |
| 76 | - b := tw.bucket[virtualID%tw.wheelSize] //pos = 所需滴答数 % wheelSize | |
| 77 | - b.Add(t) | |
| 78 | - | |
| 79 | - b.SetExpiration(virtualID * tw.tickMs) | |
| 80 | - }else { | |
| 81 | - overflowWheel := atomic.LoadPointer(&tw.overflowWheel) | |
| 82 | - if overflowWheel == nil { | |
| 83 | - level := atomic.LoadInt64(&tw.level) + 1 | |
| 84 | - atomic.CompareAndSwapPointer( | |
| 85 | - &tw.overflowWheel, | |
| 86 | - nil, | |
| 87 | - unsafe.Pointer(newTimingWheel(tw.wheelTime, tw.wheelSize, currentTime, level, tw , tw.WorkPool)), | |
| 88 | - ) | |
| 89 | - overflowWheel = atomic.LoadPointer(&tw.overflowWheel) | |
| 90 | - } | |
| 91 | - //递归添加到下一级定时器中 | |
| 92 | - (*TimeWheel)(overflowWheel).add(t) | |
| 93 | - } | |
| 94 | - | |
| 95 | - return true | |
| 96 | -} | |
| 97 | - | |
| 98 | -func (tw *TimeWheel) addOrRun(t *Timer) { | |
| 99 | - if !tw.add(t) { | |
| 100 | - workerID := t.expiration % tw.WorkPool.WorkerPoolSize | |
| 101 | - //将请求消息发送给任务队列 | |
| 102 | - tw.WorkPool.TaskQueue[workerID] <- t.task | |
| 103 | - } | |
| 104 | -} | |
| 105 | - | |
| 106 | -//拨动时钟 | |
| 107 | -func (tw *TimeWheel) advanceClock(expiration int64) { | |
| 108 | - level := atomic.LoadInt64(&tw.level) | |
| 109 | - currentTime := truncate(expiration, tw.tickMs) | |
| 110 | - atomic.StoreInt64(&tw.currentTime, currentTime) | |
| 111 | - | |
| 112 | - if level == 0 { | |
| 113 | - virtualID := expiration / tw.tickMs //需要多少滴答数 | |
| 114 | - b := tw.bucket[virtualID%tw.wheelSize] //pos = 所需滴答数 % wheelSize | |
| 115 | - b.Flush(tw.addOrRun) | |
| 116 | - } else { | |
| 117 | - prevflowWheel := atomic.LoadPointer(&tw.prevflowWheel) | |
| 118 | - if prevflowWheel != nil { | |
| 119 | - virtualID := expiration / tw.tickMs //需要多少滴答数 | |
| 120 | - b := tw.bucket[virtualID%tw.wheelSize] //pos = 所需滴答数 % wheelSize | |
| 121 | - b.Flush((*TimeWheel)(prevflowWheel).addOrRun) | |
| 122 | - } | |
| 123 | - } | |
| 124 | - | |
| 125 | - //如果基础的时钟指针转完了一圈,则递归拨动下一级时钟 | |
| 126 | - if currentTime >= tw.endMs { | |
| 127 | - atomic.StoreInt64(&tw.startMs, currentTime) | |
| 128 | - atomic.StoreInt64(&tw.endMs, currentTime + tw.wheelTime) | |
| 129 | - | |
| 130 | - overflowWheel := atomic.LoadPointer(&tw.overflowWheel) | |
| 131 | - if overflowWheel != nil { | |
| 132 | - (*TimeWheel)(overflowWheel).advanceClock(currentTime) | |
| 133 | - } | |
| 134 | - } | |
| 135 | -} | |
| 136 | - | |
| 137 | - | |
| 138 | -func (tw *TimeWheel) AfterFunc(d time.Duration, f func()) *Timer { | |
| 139 | - t := &Timer{ | |
| 140 | - expiration: time.Now().UTC().Add(d).UnixMilli(), | |
| 141 | - task: f, | |
| 142 | - } | |
| 143 | - tw.addOrRun(t) | |
| 144 | - return t | |
| 145 | -} | |
| 146 | - | |
| 147 | -func (tw *TimeWheel) Start() { | |
| 148 | - tw.ticker = time.NewTicker(time.Duration(tw.tickMs) * time.Millisecond) | |
| 149 | - tw.WorkPool.StartWorkerPool() | |
| 150 | - | |
| 151 | - go func() { | |
| 152 | - for { | |
| 153 | - select { | |
| 154 | - case t := <- tw.ticker.C: | |
| 155 | - tw.advanceClock(t.UnixMilli()) | |
| 156 | - case <- tw.exitC: | |
| 157 | - return | |
| 158 | - } | |
| 159 | - } | |
| 160 | - }() | |
| 161 | -} | |
| 162 | - | |
| 163 | -func (tw *TimeWheel) Stop() { | |
| 164 | - tw.exitC <- struct{}{} | |
| 165 | -} | |
| 166 | 0 | \ No newline at end of file | 
src/components/timewheel/timewheel_test.go
| ... | ... | @@ -5,26 +5,14 @@ import ( | 
| 5 | 5 | "testing" | 
| 6 | 6 | "time" | 
| 7 | 7 | ) | 
| 8 | -var tw *TimeWheel | |
| 9 | 8 | |
| 10 | -func Add() { | |
| 11 | - fmt.Println("ADD : 123456") | |
| 12 | - tw.AfterFunc(6*time.Second, Add) | |
| 9 | +func PRINT() { | |
| 10 | + fmt.Println("12312312312") | |
| 13 | 11 | } | 
| 14 | 12 | |
| 15 | -func Add1() { | |
| 16 | - fmt.Println("GET : 78901112") | |
| 17 | - tw.AfterFunc(9*time.Second, Add1) | |
| 18 | -} | |
| 19 | - | |
| 20 | -func TestTimeWheel_AfterFunc(t *testing.T) { | |
| 21 | - | |
| 22 | - tw = NewTimeWheel(time.Second, 5) | |
| 23 | - tw.Start() | |
| 24 | - defer tw.Stop() | |
| 25 | - | |
| 26 | - | |
| 27 | - Add() | |
| 28 | - Add1() | |
| 29 | - time.Sleep(time.Second * 200) | |
| 13 | +func TestTimeWheel_Start(t *testing.T) { | |
| 14 | + TimeOut(1 * time.Second, func() { | |
| 15 | + fmt.Println("12312313123") | |
| 16 | + }) | |
| 17 | + select{} | |
| 30 | 18 | } | ... | ... | 
src/models/role.go
| ... | ... | @@ -13,8 +13,8 @@ type RoleModel struct { | 
| 13 | 13 | Role *pb.Role | 
| 14 | 14 | Heros HeroMap | 
| 15 | 15 | Teams *TeamModel | 
| 16 | - Equip *pb.Equipment | |
| 17 | - Prop *pb.Prop | |
| 16 | + Equip *EquipModels | |
| 17 | + Prop *PropModels | |
| 18 | 18 | } | 
| 19 | 19 | |
| 20 | 20 | func RoleExistByUid(uid string) *RoleModel { | 
| ... | ... | @@ -25,10 +25,17 @@ func RoleExistByUid(uid string) *RoleModel { | 
| 25 | 25 | return nil | 
| 26 | 26 | } | 
| 27 | 27 | |
| 28 | - return &RoleModel{ | |
| 28 | + | |
| 29 | + r := &RoleModel{ | |
| 29 | 30 | MgoColl: db.NewMongoColl(strconv.Itoa(int(data.Id)), data), | 
| 30 | 31 | Role: data, | 
| 32 | + Heros: make(HeroMap), | |
| 33 | + Teams: new(TeamModel), | |
| 34 | + Equip: new(EquipModels), | |
| 35 | + Prop: new(PropModels), | |
| 31 | 36 | } | 
| 37 | + r.LoadAll() | |
| 38 | + return r | |
| 32 | 39 | } | 
| 33 | 40 | |
| 34 | 41 | func NewRole(id int64) *RoleModel { | 
| ... | ... | @@ -37,14 +44,49 @@ func NewRole(id int64) *RoleModel { | 
| 37 | 44 | MgoColl: db.NewMongoColl(strconv.Itoa(int(id)), data), | 
| 38 | 45 | Role: data, | 
| 39 | 46 | Heros: make(HeroMap), | 
| 47 | + Teams: new(TeamModel), | |
| 48 | + Equip: new(EquipModels), | |
| 49 | + Prop: new(PropModels), | |
| 40 | 50 | } | 
| 41 | 51 | return m | 
| 42 | 52 | } | 
| 43 | 53 | |
| 44 | -func (m *RoleModel) LoadAll() { | |
| 54 | +func (m *RoleModel) LoadHero() { | |
| 55 | + m.Heros["test"] = NewHero(0) | |
| 56 | + m.Heros["test"].Hero = &pb.Hero{ | |
| 57 | + Id: 1, | |
| 58 | + RoleId: m.Role.Id, | |
| 59 | + Type: 1, | |
| 60 | + Level: 1, | |
| 61 | + ReinCount: 0, | |
| 62 | + ReinPoint: 0, | |
| 63 | + Equipments: "123123", | |
| 64 | + } | |
| 45 | 65 | } | 
| 46 | 66 | |
| 47 | -func (m *RoleModel) LoadHero() { | |
| 67 | +func (m *RoleModel) LoadTeams() { | |
| 68 | + m.Teams = NewTeam(0) | |
| 69 | + m.Teams.Team = &pb.Team{ | |
| 70 | + Id: 1, | |
| 71 | + HeroIds: "1", | |
| 72 | + } | |
| 73 | +} | |
| 74 | + | |
| 75 | +func (m *RoleModel) LoadEquips() { | |
| 76 | + m.Equip = NewEquip(0) | |
| 77 | + m.Equip.Equip = &pb.Equipment{ | |
| 78 | + Id: 0, | |
| 79 | + RoleId: m.Role.Id, | |
| 80 | + Type: 0, | |
| 81 | + Equip: false, | |
| 82 | + EnhanceLevel: false, | |
| 83 | + } | |
| 84 | +} | |
| 85 | + | |
| 86 | +func (m *RoleModel) LoadAll() { | |
| 87 | + m.LoadHero() | |
| 88 | + m.LoadTeams() | |
| 89 | + m.LoadEquips() | |
| 48 | 90 | } | 
| 49 | 91 | |
| 50 | 92 | func (m *RoleModel) AddHero(hero *pb.Hero) { | 
| ... | ... | @@ -52,4 +94,12 @@ func (m *RoleModel) AddHero(hero *pb.Hero) { | 
| 52 | 94 | h.Hero = hero | 
| 53 | 95 | h.Create() | 
| 54 | 96 | m.Heros[fmt.Sprintf("%d%d", m.Role.Id, h.Hero.Id)] = h | 
| 55 | -} | |
| 56 | 97 | \ No newline at end of file | 
| 98 | +} | |
| 99 | + | |
| 100 | +func (m *RoleModel) GetAllHero() map[string]*pb.Hero { | |
| 101 | + h := make(map[string]*pb.Hero) | |
| 102 | + for k, hero := range m.Heros { | |
| 103 | + h[k] = hero.Hero | |
| 104 | + } | |
| 105 | + return h | |
| 106 | +} | ... | ... | 
src/plugin/RolePlugin.go
| ... | ... | @@ -54,8 +54,10 @@ func LoginRpc(msg *net.MsgPkg) (int32, proto.Message) { | 
| 54 | 54 | // Team: nil, | 
| 55 | 55 | // Equips: nil, | 
| 56 | 56 | //} | 
| 57 | - return 0, &pb.LoginResponse{ | |
| 58 | - Uid: role.Role.Uid, | |
| 59 | - Device: role.Role.Device, | |
| 57 | + return 0, &pb.RoleRsp{ | |
| 58 | + Role: role.Role, | |
| 59 | + Hero: role.GetAllHero(), | |
| 60 | + Team: role.Teams.Team, | |
| 61 | + Equips: []*pb.Equipment{role.Equip.Equip}, | |
| 60 | 62 | } | 
| 61 | 63 | } | 
| 62 | 64 | \ No newline at end of file | ... | ... |