]>
Commit | Line | Data |
---|---|---|
d9bc63a1 JH |
1 | package hotline |
2 | ||
3 | import ( | |
4 | "crypto/rand" | |
5 | "github.com/stretchr/testify/mock" | |
6 | "slices" | |
7 | "sync" | |
8 | ) | |
9 | ||
10 | type PrivateChat struct { | |
11 | Subject string | |
12 | ClientConn map[[2]byte]*ClientConn | |
13 | } | |
14 | ||
15 | type ChatID [4]byte | |
16 | ||
17 | type ChatManager interface { | |
18 | New(cc *ClientConn) ChatID | |
19 | GetSubject(id ChatID) string | |
20 | Join(id ChatID, cc *ClientConn) | |
21 | Leave(id ChatID, clientID [2]byte) | |
22 | SetSubject(id ChatID, subject string) | |
23 | Members(id ChatID) []*ClientConn | |
24 | } | |
25 | ||
26 | type MockChatManager struct { | |
27 | mock.Mock | |
28 | } | |
29 | ||
30 | func (m *MockChatManager) New(cc *ClientConn) ChatID { | |
31 | args := m.Called(cc) | |
32 | ||
33 | return args.Get(0).(ChatID) | |
34 | } | |
35 | ||
36 | func (m *MockChatManager) GetSubject(id ChatID) string { | |
37 | args := m.Called(id) | |
38 | ||
39 | return args.String(0) | |
40 | } | |
41 | ||
42 | func (m *MockChatManager) Join(id ChatID, cc *ClientConn) { | |
43 | m.Called(id, cc) | |
44 | } | |
45 | ||
46 | func (m *MockChatManager) Leave(id ChatID, clientID [2]byte) { | |
47 | m.Called(id, clientID) | |
48 | } | |
49 | ||
50 | func (m *MockChatManager) SetSubject(id ChatID, subject string) { | |
51 | m.Called(id, subject) | |
52 | ||
53 | } | |
54 | ||
55 | func (m *MockChatManager) Members(id ChatID) []*ClientConn { | |
56 | args := m.Called(id) | |
57 | ||
58 | return args.Get(0).([]*ClientConn) | |
59 | } | |
60 | ||
61 | type MemChatManager struct { | |
62 | chats map[ChatID]*PrivateChat | |
63 | ||
64 | mu sync.Mutex | |
65 | } | |
66 | ||
67 | func NewMemChatManager() *MemChatManager { | |
68 | return &MemChatManager{ | |
69 | chats: make(map[ChatID]*PrivateChat), | |
70 | } | |
71 | } | |
72 | ||
73 | func (cm *MemChatManager) New(cc *ClientConn) ChatID { | |
74 | cm.mu.Lock() | |
75 | defer cm.mu.Unlock() | |
76 | ||
77 | var randID [4]byte | |
78 | _, _ = rand.Read(randID[:]) | |
79 | ||
80 | cm.chats[randID] = &PrivateChat{ClientConn: make(map[[2]byte]*ClientConn)} | |
81 | ||
82 | cm.chats[randID].ClientConn[cc.ID] = cc | |
83 | ||
84 | return randID | |
85 | } | |
86 | ||
87 | func (cm *MemChatManager) Join(id ChatID, cc *ClientConn) { | |
88 | cm.mu.Lock() | |
89 | defer cm.mu.Unlock() | |
90 | ||
91 | chat := cm.chats[id] | |
92 | chat.ClientConn[cc.ID] = cc | |
93 | } | |
94 | ||
95 | func (cm *MemChatManager) Leave(id ChatID, clientID [2]byte) { | |
96 | cm.mu.Lock() | |
97 | defer cm.mu.Unlock() | |
98 | ||
99 | privChat, ok := cm.chats[id] | |
100 | if !ok { | |
101 | return | |
102 | } | |
103 | ||
104 | delete(privChat.ClientConn, clientID) | |
105 | } | |
106 | ||
107 | func (cm *MemChatManager) GetSubject(id ChatID) string { | |
108 | cm.mu.Lock() | |
109 | defer cm.mu.Unlock() | |
110 | ||
111 | return cm.chats[id].Subject | |
112 | } | |
113 | ||
114 | func (cm *MemChatManager) Members(id ChatID) []*ClientConn { | |
115 | cm.mu.Lock() | |
116 | defer cm.mu.Unlock() | |
117 | ||
118 | chat := cm.chats[id] | |
119 | ||
120 | var members []*ClientConn | |
121 | for _, cc := range chat.ClientConn { | |
122 | members = append(members, cc) | |
123 | } | |
124 | ||
125 | slices.SortFunc(members, clientConnSortFunc) | |
126 | ||
127 | return members | |
128 | } | |
129 | ||
130 | func (cm *MemChatManager) SetSubject(id ChatID, subject string) { | |
131 | cm.mu.Lock() | |
132 | defer cm.mu.Unlock() | |
133 | ||
134 | chat := cm.chats[id] | |
135 | ||
136 | chat.Subject = subject | |
137 | } |