multiple subscribers, and unsubscribe

This commit is contained in:
2023-10-07 20:20:02 +03:00
parent c892c2b67a
commit 64842886d7
2 changed files with 82 additions and 28 deletions
+41 -12
View File
@@ -50,7 +50,8 @@ namespace Ragon.Client
private RagonPayload _destroyPayload; private RagonPayload _destroyPayload;
private readonly Dictionary<int, OnEventDelegate> _events = new Dictionary<int, OnEventDelegate>(); private readonly Dictionary<int, OnEventDelegate> _events = new Dictionary<int, OnEventDelegate>();
private readonly Dictionary<int, Action<RagonPlayer, IRagonEvent>> _localEvents = new Dictionary<int, Action<RagonPlayer, IRagonEvent>>(); private readonly Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>> _localListeners = new Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>>();
private readonly Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>> _listeners = new Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>>();
public RagonEntity(ushort type = 0, ushort sceneId = 0) public RagonEntity(ushort type = 0, ushort sceneId = 0)
{ {
@@ -155,12 +156,16 @@ namespace Ragon.Client
{ {
if (replicationMode == RagonReplicationMode.Local) if (replicationMode == RagonReplicationMode.Local)
{ {
_localEvents[eventCode].Invoke(_client.Room.Local, evnt); var localListeners = _localListeners[eventCode];
foreach (var listener in localListeners)
listener.Invoke(_client.Room.Local, evnt);
return; return;
} }
if (replicationMode == RagonReplicationMode.LocalAndServer) if (replicationMode == RagonReplicationMode.LocalAndServer)
{ {
_localEvents[eventCode].Invoke(_client.Room.Local, evnt); var localListeners = _localListeners[eventCode];
foreach (var listener in localListeners)
listener.Invoke(_client.Room.Local, evnt);
} }
} }
@@ -179,25 +184,49 @@ namespace Ragon.Client
_client.Reliable.Send(sendData); _client.Reliable.Send(sendData);
} }
public void OnEvent<TEvent>(Action<RagonPlayer, TEvent> callback) where TEvent : IRagonEvent, new() public Action<RagonPlayer, IRagonEvent> OnEvent<TEvent>(Action<RagonPlayer, TEvent> callback) where TEvent : IRagonEvent, new()
{ {
var t = new TEvent(); var t = new TEvent();
var eventCode = _client.Event.GetEventCode(t); var eventCode = _client.Event.GetEventCode(t);
var callbacks = _listeners[eventCode];
if (_events.ContainsKey(eventCode)) var action = (RagonPlayer player, IRagonEvent eventData) => callback.Invoke(player, (TEvent)eventData);
if (callbacks == null)
{ {
_events.Remove(eventCode); callbacks = new List<Action<RagonPlayer, IRagonEvent>>();
_localEvents.Remove(eventCode); _listeners.Add(eventCode, callbacks);
RagonLog.Warn($"Event already {eventCode} subscribed, removed old one!");
} }
_localEvents.Add(eventCode, (player, eventData) => { callback.Invoke(player, (TEvent)eventData); }); var localCallbacks = _localListeners[eventCode];
if (localCallbacks == null)
{
localCallbacks = new List<Action<RagonPlayer, IRagonEvent>>();
_localListeners.Add(eventCode, callbacks);
}
callbacks.Add(action);
localCallbacks.Add(action);
_events.Add(eventCode, (player, serializer) => _events.Add(eventCode, (player, serializer) =>
{ {
t.Deserialize(serializer); t.Deserialize(serializer);
callback.Invoke(player, t);
foreach (var callbackListener in callbacks)
callbackListener.Invoke(player, t);
}); });
return action;
}
public void OffEvent<TEvent>(Action<RagonPlayer, IRagonEvent> callback) where TEvent : IRagonEvent, new()
{
var t = new TEvent();
var eventCode = _client.Event.GetEventCode(t);
var callbacks = _listeners[eventCode];
var localCallbacks = _localListeners[eventCode];
callbacks?.Remove(callback);
localCallbacks?.Remove(callback);
} }
internal void Write(RagonBuffer buffer) internal void Write(RagonBuffer buffer)
+41 -16
View File
@@ -21,13 +21,13 @@ namespace Ragon.Client
public class RagonRoom public class RagonRoom
{ {
private delegate void OnEventDelegate(RagonPlayer player, RagonBuffer serializer); private delegate void OnEventDelegate(RagonPlayer player, RagonBuffer serializer);
private RagonClient _client; private RagonClient _client;
private RagonScene _scene; private RagonScene _scene;
private RagonEntityCache _entityCache; private RagonEntityCache _entityCache;
private RagonPlayerCache _playerCache; private RagonPlayerCache _playerCache;
private RagonRoomInformation _information; private RagonRoomInformation _information;
public string Id => _information.RoomId; public string Id => _information.RoomId;
public int MinPlayers => _information.Min; public int MinPlayers => _information.Min;
public int MaxPlayers => _information.Max; public int MaxPlayers => _information.Max;
@@ -36,10 +36,11 @@ namespace Ragon.Client
public IReadOnlyList<RagonPlayer> Players => _playerCache.Players; public IReadOnlyList<RagonPlayer> Players => _playerCache.Players;
public RagonPlayer Local => _playerCache.Local; public RagonPlayer Local => _playerCache.Local;
public RagonPlayer Owner => _playerCache.Owner; public RagonPlayer Owner => _playerCache.Owner;
private readonly Dictionary<int, OnEventDelegate> _events = new Dictionary<int, OnEventDelegate>(); private readonly Dictionary<int, OnEventDelegate> _events = new Dictionary<int, OnEventDelegate>();
private readonly Dictionary<int, Action<RagonPlayer, IRagonEvent>> _localEvents = new Dictionary<int, Action<RagonPlayer, IRagonEvent>>(); private readonly Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>> _localListeners = new Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>>();
private readonly Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>> _listeners = new Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>>();
public RagonRoom(RagonClient client, public RagonRoom(RagonClient client,
RagonEntityCache entityCache, RagonEntityCache entityCache,
RagonPlayerCache playerCache, RagonPlayerCache playerCache,
@@ -71,31 +72,55 @@ namespace Ragon.Client
else else
RagonLog.Warn($"Handler event on entity {Id} with eventCode {eventCode} not defined"); RagonLog.Warn($"Handler event on entity {Id} with eventCode {eventCode} not defined");
} }
public void OnEvent<TEvent>(Action<RagonPlayer, TEvent> callback) where TEvent : IRagonEvent, new() public Action<RagonPlayer, IRagonEvent> OnEvent<TEvent>(Action<RagonPlayer, TEvent> callback) where TEvent : IRagonEvent, new()
{ {
var t = new TEvent(); var t = new TEvent();
var eventCode = _client.Event.GetEventCode(t); var eventCode = _client.Event.GetEventCode(t);
var callbacks = _listeners[eventCode];
if (_events.ContainsKey(eventCode)) var action = (RagonPlayer player, IRagonEvent eventData) => callback.Invoke(player, (TEvent)eventData);
if (callbacks == null)
{ {
_events.Remove(eventCode); callbacks = new List<Action<RagonPlayer, IRagonEvent>>();
_localEvents.Remove(eventCode); _listeners.Add(eventCode, callbacks);
RagonLog.Warn($"Event already {eventCode} subscribed, removed old one!");
} }
_localEvents.Add(eventCode, (player, eventData) => { callback.Invoke(player, (TEvent)eventData); }); var localCallbacks = _localListeners[eventCode];
if (localCallbacks == null)
{
localCallbacks = new List<Action<RagonPlayer, IRagonEvent>>();
_localListeners.Add(eventCode, callbacks);
}
callbacks.Add(action);
localCallbacks.Add(action);
_events.Add(eventCode, (player, serializer) => _events.Add(eventCode, (player, serializer) =>
{ {
t.Deserialize(serializer); t.Deserialize(serializer);
callback.Invoke(player, t);
foreach (var callbackListener in callbacks)
callbackListener.Invoke(player, t);
}); });
return action;
}
public void OffEvent<TEvent>(Action<RagonPlayer, IRagonEvent> callback) where TEvent : IRagonEvent, new()
{
var t = new TEvent();
var eventCode = _client.Event.GetEventCode(t);
var callbacks = _listeners[eventCode];
var localCallbacks = _localListeners[eventCode];
callbacks?.Remove(callback);
localCallbacks?.Remove(callback);
} }
public void LoadScene(string sceneName) => _scene.Load(sceneName); public void LoadScene(string sceneName) => _scene.Load(sceneName);
public void SceneLoaded() => _scene.SceneLoaded(); public void SceneLoaded() => _scene.SceneLoaded();
public void ReplicateEvent<TEvent>(TEvent evnt, RagonTarget target, RagonReplicationMode mode) where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode); public void ReplicateEvent<TEvent>(TEvent evnt, RagonTarget target, RagonReplicationMode mode) where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode);
public void ReplicateEvent<TEvent>(TEvent evnt, RagonPlayer target, RagonReplicationMode mode) where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode); public void ReplicateEvent<TEvent>(TEvent evnt, RagonPlayer target, RagonReplicationMode mode) where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode);