Add EventTarget
This commit is contained in:
parent
4c8c4e2b03
commit
44ae8c96f3
|
@ -0,0 +1,120 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Ooui
|
||||||
|
{
|
||||||
|
public abstract class EventTarget
|
||||||
|
{
|
||||||
|
public string Id { get; private set; } = GenerateId ();
|
||||||
|
|
||||||
|
public Mapping Mapping { get; private set; }
|
||||||
|
|
||||||
|
readonly List<Message> stateMessages = new List<Message> ();
|
||||||
|
|
||||||
|
public event Action<Message> MessageSent;
|
||||||
|
|
||||||
|
public IEnumerable<Message> StateMessages => stateMessages;
|
||||||
|
|
||||||
|
public EventTarget ()
|
||||||
|
{
|
||||||
|
Mapping = Mapping.Get (GetType ());
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
SaveStateMessage (message);
|
||||||
|
MessageSent?.Invoke (message);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void SendCreate ()
|
||||||
|
{
|
||||||
|
Send (new Message {
|
||||||
|
MessageType = MessageType.Create,
|
||||||
|
TargetId = Id,
|
||||||
|
Key = Mapping.TagName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void TriggerEventFromMessage (Message message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,8 +35,8 @@ namespace Ooui
|
||||||
}
|
}
|
||||||
return na;
|
return na;
|
||||||
}
|
}
|
||||||
else if (v is Node n) {
|
else if (v is EventTarget t) {
|
||||||
return "\u2999" + n.Id;
|
return "\u2999" + t.Id;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
93
Ooui/Node.cs
93
Ooui/Node.cs
|
@ -4,21 +4,13 @@ using System.Linq;
|
||||||
|
|
||||||
namespace Ooui
|
namespace Ooui
|
||||||
{
|
{
|
||||||
public abstract class Node
|
public abstract class Node : EventTarget
|
||||||
{
|
{
|
||||||
public string Id { get; private set; } = GenerateId ();
|
|
||||||
|
|
||||||
public Mapping Mapping { get; private set; }
|
|
||||||
|
|
||||||
readonly List<Node> children = new List<Node> ();
|
readonly List<Node> children = new List<Node> ();
|
||||||
readonly List<Message> messages = new List<Message> ();
|
|
||||||
readonly List<Message> stateMessages = new List<Message> ();
|
|
||||||
|
|
||||||
public event Action<Message> MessageLogged;
|
public IEnumerable<Message> AllStateMessages =>
|
||||||
|
StateMessages
|
||||||
public IEnumerable<Message> AllMessages =>
|
.Concat (from c in children from m in c.AllStateMessages select m)
|
||||||
messages
|
|
||||||
.Concat (from c in children from m in c.AllMessages select m)
|
|
||||||
.OrderBy (x => x.Id);
|
.OrderBy (x => x.Id);
|
||||||
|
|
||||||
public virtual string Text {
|
public virtual string Text {
|
||||||
|
@ -30,8 +22,7 @@ namespace Ooui
|
||||||
|
|
||||||
public Node ()
|
public Node ()
|
||||||
{
|
{
|
||||||
Mapping = Mapping.Get (GetType ());
|
SendCreate ();
|
||||||
LogCreate ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node AppendChild (Node newChild)
|
public Node AppendChild (Node newChild)
|
||||||
|
@ -54,7 +45,7 @@ namespace Ooui
|
||||||
children.Insert (index, newChild);
|
children.Insert (index, newChild);
|
||||||
}
|
}
|
||||||
newChild.ParentNode = this;
|
newChild.ParentNode = this;
|
||||||
LogCall ("insertBefore", newChild, referenceChild);
|
SendCall ("insertBefore", newChild, referenceChild);
|
||||||
return newChild;
|
return newChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +55,7 @@ namespace Ooui
|
||||||
throw new ArgumentException ("Child not contained in this element", nameof(child));
|
throw new ArgumentException ("Child not contained in this element", nameof(child));
|
||||||
}
|
}
|
||||||
child.ParentNode = null;
|
child.ParentNode = null;
|
||||||
LogCall ("removeChild", child);
|
SendCall ("removeChild", child);
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,75 +66,5 @@ namespace Ooui
|
||||||
RemoveChild (c);
|
RemoveChild (c);
|
||||||
InsertBefore (newNode, null);
|
InsertBefore (newNode, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Log (Message message)
|
|
||||||
{
|
|
||||||
messages.Add (message);
|
|
||||||
|
|
||||||
switch (message.MessageType) {
|
|
||||||
case MessageType.Create:
|
|
||||||
stateMessages.Add (message);
|
|
||||||
break;
|
|
||||||
case MessageType.Set:
|
|
||||||
{
|
|
||||||
var old = stateMessages.FirstOrDefault (
|
|
||||||
x => x.MessageType == MessageType.Set &&
|
|
||||||
x.Key == message.Key);
|
|
||||||
if (old != null) {
|
|
||||||
stateMessages.Remove (old);
|
|
||||||
}
|
|
||||||
stateMessages.Add (message);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageLogged?.Invoke (message);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void LogCreate ()
|
|
||||||
{
|
|
||||||
Log (new Message {
|
|
||||||
MessageType = MessageType.Create,
|
|
||||||
TargetId = Id,
|
|
||||||
Key = Mapping.TagName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void LogCall (string methodName, params object[] args)
|
|
||||||
{
|
|
||||||
Log (new Message {
|
|
||||||
MessageType = MessageType.Call,
|
|
||||||
TargetId = Id,
|
|
||||||
Key = methodName,
|
|
||||||
Value = args,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void LogSet (string attributeName, object value)
|
|
||||||
{
|
|
||||||
Log (new Message {
|
|
||||||
MessageType = MessageType.Set,
|
|
||||||
TargetId = Id,
|
|
||||||
Key = attributeName,
|
|
||||||
Value = value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected bool SetProperty<T> (ref T backingStore, T newValue, string attributeName, [System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
|
|
||||||
{
|
|
||||||
if (!backingStore.Equals (newValue)) {
|
|
||||||
backingStore = newValue;
|
|
||||||
LogSet (attributeName, newValue);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static long idCounter = 0;
|
|
||||||
static string GenerateId ()
|
|
||||||
{
|
|
||||||
var id = System.Threading.Interlocked.Increment (ref idCounter);
|
|
||||||
return "n" + id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,12 +191,12 @@ namespace Ooui
|
||||||
//
|
//
|
||||||
// Send message history, start sending updates, and add it to the body
|
// Send message history, start sending updates, and add it to the body
|
||||||
//
|
//
|
||||||
foreach (var m in element.AllMessages) {
|
foreach (var m in element.AllStateMessages) {
|
||||||
if (webSocket.State == WebSocketState.Open) {
|
if (webSocket.State == WebSocketState.Open) {
|
||||||
await SendMessageAsync (webSocket, m, token);
|
await SendMessageAsync (webSocket, m, token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
element.MessageLogged += onElementMessage;
|
element.MessageSent += onElementMessage;
|
||||||
await SendMessageAsync (webSocket, new Message {
|
await SendMessageAsync (webSocket, new Message {
|
||||||
TargetId = "document.body",
|
TargetId = "document.body",
|
||||||
MessageType = MessageType.Call,
|
MessageType = MessageType.Call,
|
||||||
|
@ -243,7 +243,7 @@ namespace Ooui
|
||||||
Error ("Failed to process web socket", ex);
|
Error ("Failed to process web socket", ex);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
element.MessageLogged -= onElementMessage;
|
element.MessageSent -= onElementMessage;
|
||||||
webSocket?.Dispose ();
|
webSocket?.Dispose ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue