2018-03-09 23:14:51 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
namespace Ooui
|
|
|
|
|
{
|
|
|
|
|
public abstract class Session
|
|
|
|
|
{
|
|
|
|
|
protected readonly Element element;
|
|
|
|
|
protected readonly double initialWidth;
|
|
|
|
|
protected readonly double initialHeight;
|
|
|
|
|
|
|
|
|
|
protected readonly HashSet<string> createdIds;
|
|
|
|
|
|
|
|
|
|
protected readonly List<Message> queuedMessages = new List<Message> ();
|
|
|
|
|
|
2023-03-17 13:05:48 +00:00
|
|
|
|
protected readonly System.Threading.SemaphoreSlim slimSema=new System.Threading.SemaphoreSlim(0,1);
|
|
|
|
|
|
|
|
|
|
protected void LockQueue()
|
|
|
|
|
{
|
|
|
|
|
slimSema.Wait();
|
|
|
|
|
}
|
|
|
|
|
protected void UnlockQueue()
|
|
|
|
|
{
|
|
|
|
|
slimSema.Release();
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-16 00:54:30 +00:00
|
|
|
|
protected readonly bool disposeElementAfterSession;
|
2018-04-16 01:05:19 +00:00
|
|
|
|
readonly Action<string, Exception> errorLogger;
|
2018-04-16 00:54:30 +00:00
|
|
|
|
|
2018-04-16 01:05:19 +00:00
|
|
|
|
public Session (Element element, bool disposeElementAfterSession, double initialWidth, double initialHeight, Action<string, Exception> errorLogger)
|
2018-03-09 23:14:51 +00:00
|
|
|
|
{
|
2018-04-16 01:05:19 +00:00
|
|
|
|
this.errorLogger = errorLogger;
|
2018-03-09 23:14:51 +00:00
|
|
|
|
this.element = element;
|
2018-04-16 00:54:30 +00:00
|
|
|
|
this.disposeElementAfterSession = disposeElementAfterSession;
|
2018-03-09 23:14:51 +00:00
|
|
|
|
this.initialWidth = initialWidth;
|
|
|
|
|
this.initialHeight = initialHeight;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Keep a list of all the elements for which we've transmitted the initial state
|
|
|
|
|
//
|
|
|
|
|
createdIds = new HashSet<string> {
|
|
|
|
|
"window",
|
|
|
|
|
"document",
|
|
|
|
|
"document.body",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QueueStateMessagesLocked (EventTarget target)
|
|
|
|
|
{
|
|
|
|
|
if (target == null) return;
|
|
|
|
|
var created = false;
|
|
|
|
|
foreach (var m in target.StateMessages) {
|
|
|
|
|
if (m.MessageType == MessageType.Create) {
|
|
|
|
|
createdIds.Add (m.TargetId);
|
|
|
|
|
created = true;
|
|
|
|
|
}
|
|
|
|
|
if (created) {
|
|
|
|
|
QueueMessageLocked (m);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-10 07:12:07 +00:00
|
|
|
|
protected void QueueMessageLocked (Message message)
|
2018-03-09 23:14:51 +00:00
|
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
// Make sure all the referenced objects have been created
|
|
|
|
|
//
|
|
|
|
|
if (!createdIds.Contains (message.TargetId)) {
|
|
|
|
|
QueueStateMessagesLocked (element.GetElementById (message.TargetId));
|
|
|
|
|
}
|
|
|
|
|
if (message.Value is EventTarget ve) {
|
|
|
|
|
if (!createdIds.Contains (ve.Id)) {
|
|
|
|
|
QueueStateMessagesLocked (ve);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (message.Value is Array a) {
|
|
|
|
|
for (var i = 0; i < a.Length; i++) {
|
|
|
|
|
// Console.WriteLine ($"A{i} = {a.GetValue(i)}");
|
|
|
|
|
if (a.GetValue (i) is EventTarget e && !createdIds.Contains (e.Id)) {
|
|
|
|
|
QueueStateMessagesLocked (e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Add it to the queue
|
|
|
|
|
//
|
|
|
|
|
//Console.WriteLine ($"QM {message.MessageType} {message.TargetId} {message.Key} {message.Value}");
|
|
|
|
|
queuedMessages.Add (message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual void QueueMessage (Message message)
|
|
|
|
|
{
|
2023-03-17 13:07:52 +00:00
|
|
|
|
LockQueue();
|
2018-03-09 23:14:51 +00:00
|
|
|
|
QueueMessageLocked (message);
|
2023-03-17 13:07:52 +00:00
|
|
|
|
UnlockQueue();
|
2018-03-09 23:14:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void Error (string message, Exception ex)
|
|
|
|
|
{
|
2018-04-16 01:05:19 +00:00
|
|
|
|
errorLogger?.Invoke (message, ex);
|
2018-03-09 23:14:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|