#if !BESTHTTP_DISABLE_SOCKETIO
using System;
using System.Collections.Generic;
namespace BestHTTP.SocketIO.Events
{
public delegate void SocketIOCallback(Socket socket, Packet packet, params object[] args);
public delegate void SocketIOAckCallback(Socket socket, Packet packet, params object[] args);
///
/// A class to describe an event, and its metadatas.
///
internal sealed class EventDescriptor
{
#region Public Properties
///
/// List of callback delegates.
///
public List Callbacks { get; private set; }
///
/// If this property is true, callbacks are removed automatically after the event dispatch.
///
public bool OnlyOnce { get; private set; }
///
/// If this property is true, the dispatching packet's Payload will be decoded using the Manager's Encoder.
///
public bool AutoDecodePayload { get; private set; }
#endregion
///
/// Cache an array on a hot-path.
///
private SocketIOCallback[] CallbackArray;
///
/// Constructor to create an EventDescriptor instance and set the meta-datas.
///
public EventDescriptor(bool onlyOnce, bool autoDecodePayload, SocketIOCallback callback)
{
this.OnlyOnce = onlyOnce;
this.AutoDecodePayload = autoDecodePayload;
this.Callbacks = new List(1);
if (callback != null)
Callbacks.Add(callback);
}
///
/// Will call the callback delegates with the given parameters and remove the callbacks if this descriptor marked with a true OnlyOnce property.
///
public void Call(Socket socket, Packet packet, params object[] args)
{
int callbackCount = Callbacks.Count;
if (CallbackArray == null || CallbackArray.Length < callbackCount)
Array.Resize(ref CallbackArray, callbackCount);
// Copy the callback delegates to an array, because in one of the callbacks we can modify the list(by calling On/Once/Off in an event handler)
// This way we can prevent some strange bug
Callbacks.CopyTo(CallbackArray);
// Go through the delegates and call them
for (int i = 0; i < callbackCount; ++i)
{
try
{
// Call the delegate.
SocketIOCallback callback = CallbackArray[i];
if (callback!= null)
callback(socket, packet, args);
}
catch (Exception ex)
{
// Do not try to emit a new Error when we already tried to deliver an Error, possible causing a
// stack overflow
if (args == null || args.Length == 0 || !(args[0] is Error))
(socket as ISocket).EmitError(SocketIOErrors.User, ex.Message + " " + ex.StackTrace);
HTTPManager.Logger.Exception("EventDescriptor", "Call", ex);
}
// If these callbacks has to be called only once, remove them from the main list
if (this.OnlyOnce)
Callbacks.Remove(CallbackArray[i]);
// Don't keep any reference avoiding memory leaks
CallbackArray[i] = null;
}
}
}
}
#endif