-
Notifications
You must be signed in to change notification settings - Fork 0
/
room.go
108 lines (88 loc) · 2.15 KB
/
room.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package netgate
import (
"sync"
"time"
)
// RoomInterface is the interface that must be implemented by a room
type RoomInterface interface {
Init()
Destroy()
Update(int64)
ClientJoin(*Client)
ClientLeave(*Client)
ClientData(*Client, []byte)
}
// RoomController is the controller for a room
type RoomController struct {
id string // room id
tickRate int // room tick rate
room RoomInterface // room
clients map[string]*Client // clients in room
stopChan chan bool // stop channel
lock *sync.RWMutex // lock
}
func newRoomController(id string, room RoomInterface) *RoomController {
return &RoomController{
id: id,
tickRate: DEFAULT_ROOM_TICK_RATE,
room: room,
clients: make(map[string]*Client),
stopChan: make(chan bool),
lock: &sync.RWMutex{},
}
}
func (rc *RoomController) GetID() string {
return rc.id
}
func (rc *RoomController) GetRoom() RoomInterface {
return rc.room
}
func (rc *RoomController) GetClients() map[string]*Client {
return rc.clients
}
func (rc *RoomController) SetTickRate(rate int) {
rc.tickRate = rate
}
// join client
func (rc *RoomController) clientJoin(client *Client) {
rc.lock.Lock()
defer rc.lock.Unlock()
rc.clients[client.GetID()] = client
client.room = &rc.room
rc.room.ClientJoin(client)
}
// leave client
func (rc *RoomController) clientLeave(client *Client) {
rc.lock.Lock()
defer rc.lock.Unlock()
client.room = nil
rc.room.ClientLeave(client)
delete(rc.clients, client.GetID())
}
func (rc *RoomController) clientData(client *Client, data []byte) {
rc.lock.Lock()
defer rc.lock.Unlock()
rc.room.ClientData(client, data)
}
func (rc *RoomController) run() {
// start ticker to execute room update at tickRate
ticker := time.NewTicker(time.Second / time.Duration(rc.tickRate))
for {
select {
case tick := <-ticker.C:
rc.lock.Lock()
rc.room.Update(tick.UnixNano())
rc.lock.Unlock()
case <-rc.stopChan:
ticker.Stop()
rc.room.Destroy()
rc.lock.Lock()
defer rc.lock.Unlock()
for _, client := range rc.clients {
client.Disconnect()
}
rc.clients = make(map[string]*Client)
return
}
}
}