2017-06-15 01:24:59 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
namespace Ooui
|
|
|
|
{
|
|
|
|
public abstract class EventTarget
|
|
|
|
{
|
2017-06-15 06:10:58 +00:00
|
|
|
readonly List<Message> stateMessages = new List<Message> ();
|
|
|
|
|
|
|
|
readonly Dictionary<string, List<EventHandler>> eventListeners =
|
|
|
|
new Dictionary<string, List<EventHandler>> ();
|
|
|
|
|
2017-06-15 01:24:59 +00:00
|
|
|
public string Id { get; private set; } = GenerateId ();
|
|
|
|
|
2017-06-15 06:20:51 +00:00
|
|
|
public string TagName { get; private set; }
|
2017-06-15 01:24:59 +00:00
|
|
|
|
|
|
|
public event Action<Message> MessageSent;
|
|
|
|
|
|
|
|
public IEnumerable<Message> StateMessages => stateMessages;
|
|
|
|
|
2017-06-15 06:20:51 +00:00
|
|
|
protected EventTarget (string tagName)
|
2017-06-15 01:24:59 +00:00
|
|
|
{
|
2017-06-15 06:20:51 +00:00
|
|
|
TagName = tagName;
|
2017-06-15 06:27:28 +00:00
|
|
|
|
|
|
|
Send (new Message {
|
|
|
|
MessageType = MessageType.Create,
|
|
|
|
TargetId = Id,
|
|
|
|
Key = TagName,
|
|
|
|
});
|
2017-06-15 01:24:59 +00:00
|
|
|
}
|
|
|
|
|
2017-06-15 06:10:58 +00:00
|
|
|
public void AddEventListener (string eventType, EventHandler handler)
|
|
|
|
{
|
|
|
|
if (eventType == null) return;
|
|
|
|
if (handler == null) return;
|
|
|
|
|
|
|
|
var sendListen = false;
|
|
|
|
|
|
|
|
List<EventHandler> handlers;
|
|
|
|
if (!eventListeners.TryGetValue (eventType, out handlers)) {
|
|
|
|
handlers = new List<EventHandler> ();
|
|
|
|
eventListeners[eventType] = handlers;
|
|
|
|
sendListen = true;
|
|
|
|
}
|
|
|
|
handlers.Add (handler);
|
|
|
|
|
|
|
|
if (sendListen)
|
2017-06-15 06:27:28 +00:00
|
|
|
Send (Message.Listen (Id, eventType));
|
2017-06-15 06:10:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void RemoveEventListener (string eventType, EventHandler handler)
|
|
|
|
{
|
|
|
|
if (eventType == null) return;
|
|
|
|
if (handler == null) return;
|
|
|
|
|
|
|
|
List<EventHandler> handlers;
|
|
|
|
if (eventListeners.TryGetValue (eventType, out handlers)) {
|
|
|
|
handlers.Remove (handler);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-15 01:24:59 +00:00
|
|
|
protected bool SetProperty<T> (ref T backingStore, T newValue, string attributeName, [System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
|
|
|
|
{
|
|
|
|
if (!backingStore.Equals (newValue)) {
|
|
|
|
backingStore = newValue;
|
|
|
|
SendSet (attributeName, newValue);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static long idCounter = 0;
|
|
|
|
static string GenerateId ()
|
|
|
|
{
|
|
|
|
var id = System.Threading.Interlocked.Increment (ref idCounter);
|
|
|
|
return "n" + id;
|
|
|
|
}
|
|
|
|
|
|
|
|
public virtual void Send (Message message)
|
|
|
|
{
|
2017-06-15 06:27:28 +00:00
|
|
|
SaveStateMessageIfNeeded (message);
|
2017-06-15 01:24:59 +00:00
|
|
|
MessageSent?.Invoke (message);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void SendCall (string methodName, params object[] args)
|
|
|
|
{
|
|
|
|
Send (new Message {
|
|
|
|
MessageType = MessageType.Call,
|
|
|
|
TargetId = Id,
|
|
|
|
Key = methodName,
|
|
|
|
Value = args,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void SendSet (string attributeName, object value)
|
|
|
|
{
|
|
|
|
Send (new Message {
|
|
|
|
MessageType = MessageType.Set,
|
|
|
|
TargetId = Id,
|
|
|
|
Key = attributeName,
|
|
|
|
Value = value,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public virtual void Receive (Message message)
|
|
|
|
{
|
|
|
|
if (message == null)
|
|
|
|
return;
|
|
|
|
if (message.TargetId != Id)
|
|
|
|
return;
|
|
|
|
SaveStateMessageIfNeeded (message);
|
|
|
|
TriggerEventFromMessage (message);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void SaveStateMessage (Message message)
|
|
|
|
{
|
|
|
|
stateMessages.Add (message);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void ReplaceStateMessage (Message old, Message message)
|
|
|
|
{
|
|
|
|
if (old != null) {
|
|
|
|
stateMessages.Remove (old);
|
|
|
|
}
|
|
|
|
stateMessages.Add (message);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual void SaveStateMessageIfNeeded (Message message)
|
|
|
|
{
|
|
|
|
switch (message.MessageType) {
|
|
|
|
case MessageType.Create:
|
|
|
|
SaveStateMessage (message);
|
|
|
|
break;
|
|
|
|
case MessageType.Set:
|
|
|
|
{
|
|
|
|
var old = stateMessages.FirstOrDefault (
|
|
|
|
x => x.MessageType == MessageType.Set &&
|
|
|
|
x.Key == message.Key);
|
|
|
|
ReplaceStateMessage (old, message);
|
|
|
|
}
|
|
|
|
break;
|
2017-06-15 06:10:58 +00:00
|
|
|
case MessageType.Listen:
|
|
|
|
SaveStateMessage (message);
|
|
|
|
break;
|
2017-06-15 01:24:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual void TriggerEventFromMessage (Message message)
|
|
|
|
{
|
2017-06-15 06:10:58 +00:00
|
|
|
List<EventHandler> handlers;
|
|
|
|
if (eventListeners.TryGetValue (message.Key, out handlers)) {
|
|
|
|
var args = EventArgs.Empty;
|
|
|
|
foreach (var h in handlers) {
|
|
|
|
h.Invoke (this, args);
|
|
|
|
}
|
|
|
|
}
|
2017-06-15 01:24:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|