Skip to content

Commit 2af0cb6

Browse files
committed
refactor: update Client and Player interfaces for improved type safety and consistency
1 parent d73fdd0 commit 2af0cb6

File tree

15 files changed

+446
-489
lines changed

15 files changed

+446
-489
lines changed

disgolink/client.go

Lines changed: 70 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package disgolink
22

33
import (
44
"context"
5+
"iter"
56
"log/slog"
67
"net/http"
78
"runtime/debug"
@@ -12,62 +13,31 @@ import (
1213
"github.com/disgoorg/disgolink/v4/lavalink"
1314
)
1415

15-
type Client interface {
16-
AddNode(ctx context.Context, config NodeConfig) (Node, error)
17-
ForNodes(nodeFunc func(node Node))
18-
Node(name string) Node
19-
BestNode() Node
20-
RemoveNode(name string)
16+
func New(userID snowflake.ID, opts ...ConfigOpt) *Client {
17+
cfg := defaultConfig()
18+
cfg.apply(opts)
2119

22-
Player(guildID snowflake.ID) Player
23-
PlayerOnNode(node Node, guildID snowflake.ID) Player
24-
ExistingPlayer(guildID snowflake.ID) Player
25-
RemovePlayer(guildID snowflake.ID)
26-
ForPlayers(playerFunc func(player Player))
27-
28-
EmitEvent(player Player, event lavalink.Message)
29-
AddListeners(listeners ...EventListener)
30-
RemoveListeners(listeners ...EventListener)
31-
32-
AddPlugins(plugins ...Plugin)
33-
ForPlugins(pluginFunc func(plugin Plugin))
34-
RemovePlugins(plugins ...Plugin)
35-
36-
UserID() snowflake.ID
37-
Close()
38-
39-
OnVoiceServerUpdate(ctx context.Context, guildID snowflake.ID, token string, endpoint string)
40-
OnVoiceStateUpdate(ctx context.Context, guildID snowflake.ID, channelID *snowflake.ID, sessionID string)
41-
}
42-
43-
func New(userID snowflake.ID, opts ...ConfigOpt) Client {
44-
cfg := DefaultConfig()
45-
cfg.Apply(opts)
46-
cfg.Logger = cfg.Logger.With(slog.String("name", "disgolink_client"))
47-
48-
return &clientImpl{
20+
return &Client{
4921
logger: cfg.Logger,
5022
httpClient: cfg.HTTPClient,
5123
userID: userID,
52-
nodes: map[string]Node{},
53-
players: map[snowflake.ID]Player{},
24+
nodes: make(map[string]*Node),
25+
players: make(map[snowflake.ID]*Player),
5426
listeners: cfg.Listeners,
5527
plugins: cfg.Plugins,
5628
}
5729
}
5830

59-
var _ Client = (*clientImpl)(nil)
60-
61-
type clientImpl struct {
31+
type Client struct {
6232
logger *slog.Logger
6333
httpClient *http.Client
6434
userID snowflake.ID
6535

6636
nodesMu sync.Mutex
67-
nodes map[string]Node
37+
nodes map[string]*Node
6838

6939
playersMu sync.Mutex
70-
players map[snowflake.ID]Player
40+
players map[snowflake.ID]*Player
7141

7242
listenersMu sync.Mutex
7343
listeners []EventListener
@@ -76,7 +46,7 @@ type clientImpl struct {
7646
plugins []Plugin
7747
}
7848

79-
func (c *clientImpl) AddNode(ctx context.Context, config NodeConfig) (Node, error) {
49+
func (c *Client) AddNode(ctx context.Context, config NodeConfig) (*Node, error) {
8050
node := newNode(c.logger, config, c, c.httpClient)
8151
if err := node.Open(ctx); err != nil {
8252
return nil, err
@@ -88,83 +58,99 @@ func (c *clientImpl) AddNode(ctx context.Context, config NodeConfig) (Node, erro
8858
return node, nil
8959
}
9060

91-
func (c *clientImpl) ForNodes(nodeFunc func(node Node)) {
92-
c.nodesMu.Lock()
93-
defer c.nodesMu.Unlock()
94-
for i := range c.nodes {
95-
nodeFunc(c.nodes[i])
61+
func (c *Client) Nodes() iter.Seq[*Node] {
62+
return func(yield func(*Node) bool) {
63+
c.nodesMu.Lock()
64+
defer c.nodesMu.Unlock()
65+
66+
for _, node := range c.nodes {
67+
yield(node)
68+
}
9669
}
9770
}
9871

99-
func (c *clientImpl) Node(name string) Node {
72+
func (c *Client) Node(name string) *Node {
10073
c.nodesMu.Lock()
10174
defer c.nodesMu.Unlock()
75+
10276
return c.nodes[name]
10377
}
10478

105-
func (c *clientImpl) BestNode() Node {
79+
func (c *Client) BestNode() *Node {
10680
c.nodesMu.Lock()
10781
defer c.nodesMu.Unlock()
108-
var bestNode Node
82+
83+
var bestNode *Node
10984
for _, node := range c.nodes {
11085
if bestNode == nil || node.Stats().Better(bestNode.Stats()) {
11186
bestNode = node
11287
}
11388
}
89+
11490
return bestNode
11591
}
11692

117-
func (c *clientImpl) RemoveNode(name string) {
93+
func (c *Client) RemoveNode(name string) {
11894
c.nodesMu.Lock()
11995
defer c.nodesMu.Unlock()
96+
12097
if node, ok := c.nodes[name]; ok {
12198
node.Close()
12299
delete(c.nodes, name)
123100
}
124101
}
125102

126-
func (c *clientImpl) Player(guildID snowflake.ID) Player {
103+
func (c *Client) Player(guildID snowflake.ID) *Player {
127104
return c.PlayerOnNode(c.BestNode(), guildID)
128105
}
129106

130-
func (c *clientImpl) PlayerOnNode(node Node, guildID snowflake.ID) Player {
107+
func (c *Client) PlayerOnNode(node *Node, guildID snowflake.ID) *Player {
131108
c.playersMu.Lock()
132109
defer c.playersMu.Unlock()
110+
133111
if player, ok := c.players[guildID]; ok {
134112
return player
135113
}
136114

137-
player := NewPlayer(c.logger, c, node, guildID)
138-
c.ForPlugins(func(plugin Plugin) {
115+
player := newPlayer(c.logger, c, node, guildID)
116+
for plugin := range c.Plugins() {
139117
if pl, ok := plugin.(PluginEventHandler); ok {
140118
pl.OnNewPlayer(player)
141119
}
142-
})
120+
121+
}
122+
143123
c.players[guildID] = player
124+
144125
return player
145126
}
146127

147-
func (c *clientImpl) ExistingPlayer(guildID snowflake.ID) Player {
128+
func (c *Client) ExistingPlayer(guildID snowflake.ID) *Player {
148129
c.playersMu.Lock()
149130
defer c.playersMu.Unlock()
131+
150132
return c.players[guildID]
151133
}
152134

153-
func (c *clientImpl) RemovePlayer(guildID snowflake.ID) {
135+
func (c *Client) RemovePlayer(guildID snowflake.ID) {
154136
c.playersMu.Lock()
155137
defer c.playersMu.Unlock()
138+
156139
delete(c.players, guildID)
157140
}
158141

159-
func (c *clientImpl) ForPlayers(playerFunc func(player Player)) {
160-
c.playersMu.Lock()
161-
defer c.playersMu.Unlock()
162-
for _, player := range c.players {
163-
playerFunc(player)
142+
func (c *Client) Players() iter.Seq[*Player] {
143+
return func(yield func(*Player) bool) {
144+
c.playersMu.Lock()
145+
defer c.playersMu.Unlock()
146+
147+
for _, player := range c.players {
148+
yield(player)
149+
}
164150
}
165151
}
166152

167-
func (c *clientImpl) EmitEvent(player Player, event lavalink.Message) {
153+
func (c *Client) EmitEvent(player *Player, event lavalink.Message) {
168154
c.listenersMu.Lock()
169155
defer c.listenersMu.Unlock()
170156

@@ -179,15 +165,17 @@ func (c *clientImpl) EmitEvent(player Player, event lavalink.Message) {
179165
}
180166
}
181167

182-
func (c *clientImpl) AddListeners(listeners ...EventListener) {
168+
func (c *Client) AddListeners(listeners ...EventListener) {
183169
c.listenersMu.Lock()
184170
defer c.listenersMu.Unlock()
171+
185172
c.listeners = append(c.listeners, listeners...)
186173
}
187174

188-
func (c *clientImpl) RemoveListeners(listeners ...EventListener) {
175+
func (c *Client) RemoveListeners(listeners ...EventListener) {
189176
c.listenersMu.Lock()
190177
defer c.listenersMu.Unlock()
178+
191179
for _, listener := range listeners {
192180
for i, ln := range c.listeners {
193181
if ln == listener {
@@ -197,23 +185,28 @@ func (c *clientImpl) RemoveListeners(listeners ...EventListener) {
197185
}
198186
}
199187

200-
func (c *clientImpl) AddPlugins(plugins ...Plugin) {
188+
func (c *Client) AddPlugins(plugins ...Plugin) {
201189
c.pluginsMu.Lock()
202190
defer c.pluginsMu.Unlock()
191+
203192
c.plugins = append(c.plugins, plugins...)
204193
}
205194

206-
func (c *clientImpl) ForPlugins(pluginFunc func(plugin Plugin)) {
207-
c.pluginsMu.Lock()
208-
defer c.pluginsMu.Unlock()
209-
for _, plugin := range c.plugins {
210-
pluginFunc(plugin)
195+
func (c *Client) Plugins() iter.Seq[Plugin] {
196+
return func(yield func(Plugin) bool) {
197+
c.pluginsMu.Lock()
198+
defer c.pluginsMu.Unlock()
199+
200+
for _, plugin := range c.plugins {
201+
yield(plugin)
202+
}
211203
}
212204
}
213205

214-
func (c *clientImpl) RemovePlugins(plugins ...Plugin) {
206+
func (c *Client) RemovePlugins(plugins ...Plugin) {
215207
c.pluginsMu.Lock()
216208
defer c.pluginsMu.Unlock()
209+
217210
for _, plugin := range plugins {
218211
for i, pl := range c.plugins {
219212
if pl == plugin {
@@ -223,22 +216,23 @@ func (c *clientImpl) RemovePlugins(plugins ...Plugin) {
223216
}
224217
}
225218

226-
func (c *clientImpl) UserID() snowflake.ID {
219+
func (c *Client) UserID() snowflake.ID {
227220
return c.userID
228221
}
229222

230-
func (c *clientImpl) Close() {
223+
func (c *Client) Close() {
231224
c.nodesMu.Lock()
232225
defer c.nodesMu.Unlock()
226+
233227
for _, node := range c.nodes {
234228
node.Close()
235229
}
236230
}
237231

238-
func (c *clientImpl) OnVoiceServerUpdate(ctx context.Context, guildID snowflake.ID, token string, endpoint string) {
232+
func (c *Client) OnVoiceServerUpdate(ctx context.Context, guildID snowflake.ID, token string, endpoint string) {
239233
c.Player(guildID).OnVoiceServerUpdate(ctx, token, endpoint)
240234
}
241235

242-
func (c *clientImpl) OnVoiceStateUpdate(ctx context.Context, guildID snowflake.ID, channelID *snowflake.ID, sessionID string) {
236+
func (c *Client) OnVoiceStateUpdate(ctx context.Context, guildID snowflake.ID, channelID *snowflake.ID, sessionID string) {
243237
c.Player(guildID).OnVoiceStateUpdate(ctx, channelID, sessionID)
244238
}
Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,43 +8,46 @@ import (
88
"github.com/disgoorg/disgolink/v4/lavalink"
99
)
1010

11-
func DefaultConfig() *Config {
12-
return &Config{
13-
Logger: slog.Default(),
14-
HTTPClient: &http.Client{Timeout: 10 * time.Second},
11+
func defaultConfig() *config {
12+
return &config{
13+
Logger: slog.Default(),
14+
HTTPClient: &http.Client{
15+
Timeout: 10 * time.Second,
16+
},
1517
}
1618
}
1719

18-
type Config struct {
20+
type config struct {
1921
Logger *slog.Logger
2022
HTTPClient *http.Client
2123
Listeners []EventListener
2224
Plugins []Plugin
2325
}
2426

25-
type ConfigOpt func(config *Config)
27+
type ConfigOpt func(config *config)
2628

27-
func (c *Config) Apply(opts []ConfigOpt) {
29+
func (c *config) apply(opts []ConfigOpt) {
2830
for _, opt := range opts {
2931
opt(c)
3032
}
33+
c.Logger = c.Logger.With(slog.String("name", "disgolink_client"))
3134
}
3235

3336
// WithLogger lets you inject your own logger implementing log.Logger
3437
func WithLogger(logger *slog.Logger) ConfigOpt {
35-
return func(config *Config) {
38+
return func(config *config) {
3639
config.Logger = logger
3740
}
3841
}
3942

4043
func WithHTTPClient(httpClient *http.Client) ConfigOpt {
41-
return func(config *Config) {
44+
return func(config *config) {
4245
config.HTTPClient = httpClient
4346
}
4447
}
4548

4649
func WithListeners(listeners ...EventListener) ConfigOpt {
47-
return func(config *Config) {
50+
return func(config *config) {
4851
config.Listeners = append(config.Listeners, listeners...)
4952
}
5053
}
@@ -54,7 +57,7 @@ func WithListenerFunc[E lavalink.Message](listenerFunc func(p Player, e E)) Conf
5457
}
5558

5659
func WithPlugins(plugins ...Plugin) ConfigOpt {
57-
return func(config *Config) {
60+
return func(config *config) {
5861
config.Plugins = append(config.Plugins, plugins...)
5962
}
6063
}

disgolink/event.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@ package disgolink
33
import "github.com/disgoorg/disgolink/v4/lavalink"
44

55
type EventListener interface {
6-
OnEvent(player Player, event lavalink.Message)
6+
OnEvent(player *Player, event lavalink.Message)
77
}
88

9-
func NewListenerFunc[E lavalink.Message](f func(p Player, e E)) EventListener {
9+
func NewListenerFunc[E lavalink.Message](f func(p *Player, e E)) EventListener {
1010
return &listenerFunc[E]{f: f}
1111
}
1212

1313
type listenerFunc[E lavalink.Message] struct {
14-
f func(p Player, e E)
14+
f func(p *Player, e E)
1515
}
1616

17-
func (l *listenerFunc[E]) OnEvent(p Player, e lavalink.Message) {
17+
func (l *listenerFunc[E]) OnEvent(p *Player, e lavalink.Message) {
1818
if event, ok := e.(E); ok {
1919
l.f(p, event)
2020
}

disgolink/info.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ import (
77
const (
88
Name = "disgolink"
99
Module = "github.com/disgoorg/disgolink/v4"
10-
GitHub = "https://github.com/disgoorg/disgo"
10+
GitHub = "https://github.com/disgoorg/disgolink"
1111
)
1212

1313
var (
1414
Version = getVersion()
15+
16+
SemVersion = "semver:" + Version
1517
)
1618

1719
func getVersion() string {

0 commit comments

Comments
 (0)