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 createdIds; protected readonly List queuedMessages = new List (); protected readonly System.Threading.SemaphoreSlim slimSema=new System.Threading.SemaphoreSlim(0,1); protected void LockQueue() { slimSema.Wait(); } protected void UnlockQueue() { slimSema.Release(); } protected readonly bool disposeElementAfterSession; readonly Action errorLogger; public Session (Element element, bool disposeElementAfterSession, double initialWidth, double initialHeight, Action errorLogger) { this.errorLogger = errorLogger; this.element = element; this.disposeElementAfterSession = disposeElementAfterSession; this.initialWidth = initialWidth; this.initialHeight = initialHeight; // // Keep a list of all the elements for which we've transmitted the initial state // createdIds = new HashSet { "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); } } } protected void QueueMessageLocked (Message message) { // // 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) { lock (queuedMessages) { QueueMessageLocked (message); } } protected void Error (string message, Exception ex) { errorLogger?.Invoke (message, ex); } } }