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;
|
||||
}
|
||||
else if (v is Node n) {
|
||||
return "\u2999" + n.Id;
|
||||
else if (v is EventTarget t) {
|
||||
return "\u2999" + t.Id;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
|
93
Ooui/Node.cs
93
Ooui/Node.cs
|
@ -4,21 +4,13 @@ using System.Linq;
|
|||
|
||||
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<Message> messages = new List<Message> ();
|
||||
readonly List<Message> stateMessages = new List<Message> ();
|
||||
|
||||
public event Action<Message> MessageLogged;
|
||||
|
||||
public IEnumerable<Message> AllMessages =>
|
||||
messages
|
||||
.Concat (from c in children from m in c.AllMessages select m)
|
||||
public IEnumerable<Message> AllStateMessages =>
|
||||
StateMessages
|
||||
.Concat (from c in children from m in c.AllStateMessages select m)
|
||||
.OrderBy (x => x.Id);
|
||||
|
||||
public virtual string Text {
|
||||
|
@ -30,8 +22,7 @@ namespace Ooui
|
|||
|
||||
public Node ()
|
||||
{
|
||||
Mapping = Mapping.Get (GetType ());
|
||||
LogCreate ();
|
||||
SendCreate ();
|
||||
}
|
||||
|
||||
public Node AppendChild (Node newChild)
|
||||
|
@ -54,7 +45,7 @@ namespace Ooui
|
|||
children.Insert (index, newChild);
|
||||
}
|
||||
newChild.ParentNode = this;
|
||||
LogCall ("insertBefore", newChild, referenceChild);
|
||||
SendCall ("insertBefore", newChild, referenceChild);
|
||||
return newChild;
|
||||
}
|
||||
|
||||
|
@ -64,7 +55,7 @@ namespace Ooui
|
|||
throw new ArgumentException ("Child not contained in this element", nameof(child));
|
||||
}
|
||||
child.ParentNode = null;
|
||||
LogCall ("removeChild", child);
|
||||
SendCall ("removeChild", child);
|
||||
return child;
|
||||
}
|
||||
|
||||
|
@ -75,75 +66,5 @@ namespace Ooui
|
|||
RemoveChild (c);
|
||||
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
|
||||
//
|
||||
foreach (var m in element.AllMessages) {
|
||||
foreach (var m in element.AllStateMessages) {
|
||||
if (webSocket.State == WebSocketState.Open) {
|
||||
await SendMessageAsync (webSocket, m, token);
|
||||
}
|
||||
}
|
||||
element.MessageLogged += onElementMessage;
|
||||
element.MessageSent += onElementMessage;
|
||||
await SendMessageAsync (webSocket, new Message {
|
||||
TargetId = "document.body",
|
||||
MessageType = MessageType.Call,
|
||||
|
@ -243,7 +243,7 @@ namespace Ooui
|
|||
Error ("Failed to process web socket", ex);
|
||||
}
|
||||
finally {
|
||||
element.MessageLogged -= onElementMessage;
|
||||
element.MessageSent -= onElementMessage;
|
||||
webSocket?.Dispose ();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue