From 637bc98a5fe055314bc373a4e70c4b59b9d823e4 Mon Sep 17 00:00:00 2001 From: Almir Kadric Date: Wed, 19 Oct 2016 15:11:38 +0900 Subject: [PATCH] added namespaces for all mage sdk files --- Async/Async.cs | 119 +-- EventEmitter/EventEmitter.cs | 94 ++- HTTPRequest/HTTPRequest.DotNet.cs | 270 +++---- HTTPRequest/HTTPRequest.Unity.cs | 250 +++--- HTTPRequest/HTTPRequestException.cs | 14 +- HTTPRequest/HTTPRequestManager.cs | 38 +- JSONRPC/JSONRPC.cs | 180 ++--- JSONRPC/JSONRPCBatch.cs | 46 +- Mage/Archivist/Archivist.cs | 742 +++++++++--------- Mage/Archivist/VaultValue.cs | 131 ++-- Mage/CommandCenter/CommandBatch.cs | 23 +- Mage/CommandCenter/CommandBatchItem.cs | 23 +- Mage/CommandCenter/CommandCenter.cs | 235 +++--- .../TransportClient/CommandHTTPClient.cs | 241 +++--- .../TransportClient/CommandJSONRPCClient.cs | 132 ++-- .../TransportClient/CommandTransportClient.cs | 24 +- Mage/EventManager.cs | 57 +- Mage/Logger/LogEntry.cs | 141 ++-- Mage/Logger/Logger.cs | 158 ++-- Mage/Logger/Writers/ConsoleWriter.cs | 255 +++--- Mage/Logger/Writers/LogWriter.cs | 8 +- Mage/Logger/Writers/ServerWriter.cs | 58 +- Mage/Mage.cs | 282 +++---- Mage/MessageStream/MessageStream.cs | 355 +++++---- .../TransportClient/LongPolling.cs | 195 ++--- .../TransportClient/ShortPolling.cs | 179 +++-- .../TransportClient/TransportClient.cs | 22 +- Mage/Module.cs | 172 ++-- Mage/Session.cs | 78 +- Singleton/MonoSingleton.cs | 58 +- Singleton/SceneInstance.cs | 26 +- Singleton/Singleton.cs | 30 +- Tomes/Tome.cs | 209 ++--- Tomes/TomeArray.cs | 729 ++++++++--------- Tomes/TomeObject.cs | 509 ++++++------ Tomes/TomeValue.cs | 226 +++--- Unity/UnityApplicationState.cs | 2 + Unity/UnityEditorPlayMode.cs | 99 ++- 38 files changed, 3243 insertions(+), 3167 deletions(-) diff --git a/Async/Async.cs b/Async/Async.cs index df2676d..7946f62 100644 --- a/Async/Async.cs +++ b/Async/Async.cs @@ -1,80 +1,81 @@ -using System; +using System; using System.Collections.Generic; - -/// -/// Async is a utility class which provides straight-forward, powerful functions for working with asynchronous C#. -/// -/// Async provides around 20 functions that include the usual 'functional' suspects (map, reduce, filter, each…) as well as -/// some common patterns for asynchronous control flow (parallel, series, waterfall…). All these functions assume you follow -/// the convention of providing a single callback as the last argument of your async function. -/// -public class Async { - public static void each (List items, Action> fn, Action cb) { - if (items == null || items.Count == 0) { - cb(null); - return; - } - - int currentItemI = 0; - Action iterate = null; - iterate = () => { - if (currentItemI >= items.Count) { +namespace Wizcorp.MageSDK.Utils { + /// + /// Async is a utility class which provides straight-forward, powerful functions for working with asynchronous C#. + /// + /// Async provides around 20 functions that include the usual 'functional' suspects (map, reduce, filter, each…) as well as + /// some common patterns for asynchronous control flow (parallel, series, waterfall…). All these functions assume you follow + /// the convention of providing a single callback as the last argument of your async function. + /// + public class Async { + public static void each(List items, Action> fn, Action cb) { + if (items == null || items.Count == 0) { cb(null); return; } - // Execute the given function on this item - fn(items[currentItemI], (Exception error) => { - // Stop iteration if there was an error - if (error != null) { - cb(error); + int currentItemI = 0; + Action iterate = null; + iterate = () => { + if (currentItemI >= items.Count) { + cb(null); return; } - // Continue to next item - currentItemI++; - iterate(); - }); - }; + // Execute the given function on this item + fn(items[currentItemI], (Exception error) => { + // Stop iteration if there was an error + if (error != null) { + cb(error); + return; + } - // Begin the iteration - iterate (); - } + // Continue to next item + currentItemI++; + iterate(); + }); + }; - public static void series (List>> actionItems, Action cb) { - bool isEmpty = actionItems == null || actionItems.Count == 0; - if (isEmpty) { - cb(null); - return; + // Begin the iteration + iterate(); } - int currentItemI = 0; - Action iterate = null; - iterate = () => { - if (currentItemI >= actionItems.Count) { + public static void series(List>> actionItems, Action cb) { + bool isEmpty = actionItems == null || actionItems.Count == 0; + if (isEmpty) { cb(null); return; } - - // Shift an element from the list - Action> actionItem = actionItems[currentItemI]; - - // Execute the given function on this item - actionItem((Exception error) => { - // Stop iteration if there was an error - if (error != null) { - cb(error); + + int currentItemI = 0; + Action iterate = null; + iterate = () => { + if (currentItemI >= actionItems.Count) { + cb(null); return; } - - // Continue to next item - currentItemI++; - iterate(); - }); - }; - // Begin the iteration - iterate (); + // Shift an element from the list + Action> actionItem = actionItems[currentItemI]; + + // Execute the given function on this item + actionItem((Exception error) => { + // Stop iteration if there was an error + if (error != null) { + cb(error); + return; + } + + // Continue to next item + currentItemI++; + iterate(); + }); + }; + + // Begin the iteration + iterate(); + } } } diff --git a/EventEmitter/EventEmitter.cs b/EventEmitter/EventEmitter.cs index 45b36fb..dacbc57 100644 --- a/EventEmitter/EventEmitter.cs +++ b/EventEmitter/EventEmitter.cs @@ -1,64 +1,60 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel; -public class EventEmitter { - // - private Dictionary eventTags = new Dictionary(); - private EventHandlerList eventsList = new EventHandlerList(); +namespace Wizcorp.MageSDK.Event { + public class EventEmitter { + // + private Dictionary eventTags = new Dictionary(); + private EventHandlerList eventsList = new EventHandlerList(); - // - public void on(string eventTag, Action handler) - { - if (!eventTags.ContainsKey(eventTag)) { - eventTags.Add(eventTag, new object()); + // + public void on(string eventTag, Action handler) { + if (!eventTags.ContainsKey(eventTag)) { + eventTags.Add(eventTag, new object()); + } + + eventsList.AddHandler(eventTags[eventTag], handler); } - eventsList.AddHandler(eventTags[eventTag], handler); - } + // + public void once(string eventTag, Action handler) { + Action handlerWrapper = null; + handlerWrapper = (object obj, T arguments) => { + eventsList.RemoveHandler(eventTags[eventTag], handlerWrapper); + handler(obj, arguments); + }; - // - public void once(string eventTag, Action handler) - { - Action handlerWrapper = null; - handlerWrapper = (object obj, T arguments) => { - eventsList.RemoveHandler(eventTags[eventTag], handlerWrapper); - handler(obj, arguments); - }; + on(eventTag, handlerWrapper); + } - on(eventTag, handlerWrapper); - } + // + public void emit(string eventTag, object sender, T arguments) { + if (!eventTags.ContainsKey(eventTag)) { + return; + } - // - public void emit(string eventTag, object sender, T arguments) - { - if (!eventTags.ContainsKey(eventTag)) { - return; + Action execEventList = (Action)eventsList[eventTags[eventTag]]; + execEventList(sender, arguments); } - Action execEventList = (Action)eventsList[eventTags[eventTag]]; - execEventList(sender, arguments); - } - - public void emit(string eventTag, T arguments) - { - emit(eventTag, null, arguments); - } + public void emit(string eventTag, T arguments) { + emit(eventTag, null, arguments); + } - // - public void off(string eventTag, Action handler) - { - eventsList.RemoveHandler(eventTags[eventTag], handler); - } + // + public void off(string eventTag, Action handler) { + eventsList.RemoveHandler(eventTags[eventTag], handler); + } - // - public void removeAllListeners() - { - // Destroy all event handlers - eventsList.Dispose(); - eventsList = new EventHandlerList(); + // + public void removeAllListeners() { + // Destroy all event handlers + eventsList.Dispose(); + eventsList = new EventHandlerList(); - // Destroy all event tags - eventTags = new Dictionary(); + // Destroy all event tags + eventTags = new Dictionary(); + } } -} \ No newline at end of file +} diff --git a/HTTPRequest/HTTPRequest.DotNet.cs b/HTTPRequest/HTTPRequest.DotNet.cs index c243d90..085f3a2 100644 --- a/HTTPRequest/HTTPRequest.DotNet.cs +++ b/HTTPRequest/HTTPRequest.DotNet.cs @@ -10,183 +10,159 @@ using System.Text; using System.Threading; - -public class HTTPRequest { - private HttpWebRequest request; - private CookieContainer cookies; - private Action cb; - private Timer timeoutTimer; - - // Timeout setting for request - private long _timeout = 100 * 1000; - public long timeout - { - get - { - return _timeout; +namespace Wizcorp.MageSDK.Network.Http { + public class HTTPRequest { + private HttpWebRequest request; + private CookieContainer cookies; + private Action cb; + private Timer timeoutTimer; + + // Timeout setting for request + private long _timeout = 100 * 1000; + public long timeout { + get { + return _timeout; + } + set { + _timeout = value; + + timeoutTimer.Dispose(); + timeoutTimer = new Timer((object state) => { + this.Abort(); + cb(new Exception("Request timed out"), null); + }, null, timeout, Timeout.Infinite); + } } - set - { - _timeout = value; - timeoutTimer.Dispose(); + + // Constructor + public HTTPRequest(string url, string contentType, byte[] postData, Dictionary headers, CookieContainer cookies, Action cb) { + // Start timeout timer timeoutTimer = new Timer((object state) => { this.Abort(); cb(new Exception("Request timed out"), null); }, null, timeout, Timeout.Infinite); - } - } + // Initialize request instance + HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url); + httpRequest.Method = (postData != null) ? WebRequestMethods.Http.Post : WebRequestMethods.Http.Get; - // Constructor - public HTTPRequest(string url, string contentType, byte[] postData, Dictionary headers, CookieContainer cookies, Action cb) - { - // Start timeout timer - timeoutTimer = new Timer((object state) => { - this.Abort(); - cb(new Exception("Request timed out"), null); - }, null, timeout, Timeout.Infinite); - - // Initialize request instance - HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url); - httpRequest.Method = (postData != null) ? WebRequestMethods.Http.Post : WebRequestMethods.Http.Get; - - // Set request headers - if (headers != null) - { - foreach (KeyValuePair entry in headers) - { - httpRequest.Headers.Add(entry.Key, entry.Value); + // Set request headers + if (headers != null) { + foreach (KeyValuePair entry in headers) { + httpRequest.Headers.Add(entry.Key, entry.Value); + } } - } - // Set content type if provided - if (contentType != null) - { - httpRequest.ContentType = contentType; - } + // Set content type if provided + if (contentType != null) { + httpRequest.ContentType = contentType; + } - // Set cookies if provided - if (cookies != null) - { - httpRequest.CookieContainer = cookies; - } + // Set cookies if provided + if (cookies != null) { + httpRequest.CookieContainer = cookies; + } - // Setup private properties and fire off the request - this.cb = cb; - this.cookies = cookies; - this.request = httpRequest; - - // Initiate response - if (postData == null) - { - ReadResponseData(cb); - return; - } else - { - WritePostData(postData, (Exception requestError) => { - if (requestError != null) - { - cb(requestError, null); - return; - } + // Setup private properties and fire off the request + this.cb = cb; + this.cookies = cookies; + this.request = httpRequest; - // Process the response + // Initiate response + if (postData == null) { ReadResponseData(cb); - }); - return; - } - } - - - // Write post data to request buffer - private void WritePostData(byte[] postData, Action cb) - { - request.BeginGetRequestStream((IAsyncResult callbackResult) => { - try - { - Stream postStream = request.EndGetRequestStream(callbackResult); - postStream.Write(postData, 0, postData.Length); - postStream.Close(); - } - catch (Exception error) - { - cb(error); + return; + } else { + WritePostData(postData, (Exception requestError) => { + if (requestError != null) { + cb(requestError, null); + return; + } + + // Process the response + ReadResponseData(cb); + }); return; } - cb(null); - }, null); - } + } - // Read response data from request buffer - private void ReadResponseData(Action cb) - { - // Begin waiting for a response - request.BeginGetResponse(new AsyncCallback((IAsyncResult callbackResult) => { - // Cleanup timeout - timeoutTimer.Dispose(); - timeoutTimer = null; - // Process response - string responseString = null; - try - { - HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult); + // Write post data to request buffer + private void WritePostData(byte[] postData, Action cb) { + request.BeginGetRequestStream((IAsyncResult callbackResult) => { + try { + Stream postStream = request.EndGetRequestStream(callbackResult); + postStream.Write(postData, 0, postData.Length); + postStream.Close(); + } catch (Exception error) { + cb(error); + return; + } + cb(null); + }, null); + } - using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream())) - { - responseString = httpWebStreamReader.ReadToEnd(); + // Read response data from request buffer + private void ReadResponseData(Action cb) { + // Begin waiting for a response + request.BeginGetResponse(new AsyncCallback((IAsyncResult callbackResult) => { + // Cleanup timeout + timeoutTimer.Dispose(); + timeoutTimer = null; + + // Process response + string responseString = null; + try { + HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult); + + using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream())) { + responseString = httpWebStreamReader.ReadToEnd(); + } + + response.Close(); + } catch (Exception error) { + cb(error, null); + return; } - response.Close(); - } - catch (Exception error) - { - cb(error, null); + cb(null, responseString); + }), null); + } + + + // Abort request + public void Abort() { + if (request == null) { return; } - cb(null, responseString); - }), null); - } - + HttpWebRequest _request = request; + request = null; - // Abort request - public void Abort() - { - if (request == null) - { - return; + _request.Abort(); + timeoutTimer.Dispose(); + timeoutTimer = null; } - HttpWebRequest _request = request; - request = null; - - _request.Abort(); - timeoutTimer.Dispose(); - timeoutTimer = null; - } - - // Create GET request and return it - public static HTTPRequest Get(string url, Dictionary headers, CookieContainer cookies, Action cb) - { - // Create request and return it - // The callback will be called when the request is complete - return new HTTPRequest(url, null, null, headers, cookies, cb); - } + // Create GET request and return it + public static HTTPRequest Get(string url, Dictionary headers, CookieContainer cookies, Action cb) { + // Create request and return it + // The callback will be called when the request is complete + return new HTTPRequest(url, null, null, headers, cookies, cb); + } - // Create POST request and return it - public static HTTPRequest Post(string url, string contentType, string postData, Dictionary headers, CookieContainer cookies, Action cb) - { - byte[] binaryPostData = Encoding.UTF8.GetBytes(postData); - return Post(url, contentType, binaryPostData, headers, cookies, cb); - } + // Create POST request and return it + public static HTTPRequest Post(string url, string contentType, string postData, Dictionary headers, CookieContainer cookies, Action cb) { + byte[] binaryPostData = Encoding.UTF8.GetBytes(postData); + return Post(url, contentType, binaryPostData, headers, cookies, cb); + } - // Create POST request and return it - public static HTTPRequest Post(string url, string contentType, byte[] postData, Dictionary headers, CookieContainer cookies, Action cb) - { - return new HTTPRequest(url, contentType, postData, headers, cookies, cb); + // Create POST request and return it + public static HTTPRequest Post(string url, string contentType, byte[] postData, Dictionary headers, CookieContainer cookies, Action cb) { + return new HTTPRequest(url, contentType, postData, headers, cookies, cb); + } } } #endif diff --git a/HTTPRequest/HTTPRequest.Unity.cs b/HTTPRequest/HTTPRequest.Unity.cs index d0c25ea..b9293f7 100644 --- a/HTTPRequest/HTTPRequest.Unity.cs +++ b/HTTPRequest/HTTPRequest.Unity.cs @@ -1,4 +1,4 @@ -// IF WE ARE USING UNITY AND WE HAVE NOT DEFINED THE +// IF WE ARE USING UNITY AND WE HAVE NOT DEFINED THE // MAGE_USE_WEBREQUEST MACROS, USE THIS VERSION #if UNITY_5 && !MAGE_USE_WEBREQUEST @@ -12,164 +12,160 @@ using UnityEngine; - -public class HTTPRequest { - private WWW request; - private CookieContainer cookies; - private Action cb; - private Stopwatch timeoutTimer; - - // Timeout setting for request - private long _timeout = 100 * 1000; - public long timeout - { - get - { - return _timeout; - } - set - { - _timeout = value; +namespace Wizcorp.MageSDK.Network.Http { + public class HTTPRequest { + private WWW request; + private CookieContainer cookies; + private Action cb; + private Stopwatch timeoutTimer; + + // Timeout setting for request + private long _timeout = 100 * 1000; + public long timeout { + get { + return _timeout; + } + set { + _timeout = value; + } } - } - // Constructor - public HTTPRequest(string url, string contentType, byte[] postData, Dictionary headers, CookieContainer cookies, Action cb) { - // Start timeout timer - timeoutTimer = new Stopwatch(); - timeoutTimer.Start(); + // Constructor + public HTTPRequest(string url, string contentType, byte[] postData, Dictionary headers, CookieContainer cookies, Action cb) { + // Start timeout timer + timeoutTimer = new Stopwatch(); + timeoutTimer.Start(); - // Queue constructor for main thread execution - HTTPRequestManager.Queue(Constructor(url, contentType, postData, headers, cookies, cb)); - } + // Queue constructor for main thread execution + HTTPRequestManager.Queue(Constructor(url, contentType, postData, headers, cookies, cb)); + } - // Main thread constructor - private IEnumerator Constructor(string url, string contentType, byte[] postData, Dictionary headers, CookieContainer cookies, Action cb) { - Dictionary headersCopy = new Dictionary(headers); + // Main thread constructor + private IEnumerator Constructor(string url, string contentType, byte[] postData, Dictionary headers, CookieContainer cookies, Action cb) { + Dictionary headersCopy = new Dictionary(headers); - // Set content type if provided - if (contentType != null) { - headersCopy.Add("ContentType", contentType); - } + // Set content type if provided + if (contentType != null) { + headersCopy.Add("ContentType", contentType); + } - // Set cookies if provided - if (cookies != null) { - Uri requestUri = new Uri(url); - string cookieString = cookies.GetCookieHeader(requestUri); - if (!string.IsNullOrEmpty(cookieString)) { - headersCopy.Add("Cookie", cookieString); + // Set cookies if provided + if (cookies != null) { + Uri requestUri = new Uri(url); + string cookieString = cookies.GetCookieHeader(requestUri); + if (!string.IsNullOrEmpty(cookieString)) { + headersCopy.Add("Cookie", cookieString); + } } + + // Setup private properties and fire off the request + this.cb = cb; + this.cookies = cookies; + this.request = new WWW(url, postData, headersCopy); + + // Initiate response + HTTPRequestManager.Queue(WaitLoop()); + yield break; } - // Setup private properties and fire off the request - this.cb = cb; - this.cookies = cookies; - this.request = new WWW(url, postData, headersCopy); - // Initiate response - HTTPRequestManager.Queue(WaitLoop()); - yield break; - } + // Wait for www request to complete with timeout checks + private IEnumerator WaitLoop() { + while (request != null && !request.isDone) { + if (timeoutTimer.ElapsedMilliseconds >= timeout) { + // Timed out abort the request with timeout error + this.Abort(); + cb(new Exception("Request timed out"), null); + yield break; + } + // Otherwise continue to wait + yield return null; + } - // Wait for www request to complete with timeout checks - private IEnumerator WaitLoop() { - while (request != null && !request.isDone) { - if (timeoutTimer.ElapsedMilliseconds >= timeout) { - // Timed out abort the request with timeout error - this.Abort(); - cb(new Exception("Request timed out"), null); + // Check if we destroyed the request due to an abort + if (request == null) { yield break; } - // Otherwise continue to wait - yield return null; - } - - // Check if we destroyed the request due to an abort - if (request == null) { - yield break; - } + // Cleanup timeout + timeoutTimer.Stop(); + timeoutTimer = null; - // Cleanup timeout - timeoutTimer.Stop(); - timeoutTimer = null; + // Check if there is a callback + if (cb == null) { + yield break; + } - // Check if there is a callback - if (cb == null) { - yield break; - } + // Check if there was an error with the request + if (request.error != null) { + int statusCode = 0; + if (request.responseHeaders.ContainsKey("STATUS")) { + statusCode = int.Parse(request.responseHeaders["STATUS"].Split(' ')[1]); + } - // Check if there was an error with the request - if (request.error != null) { - int statusCode = 0; - if (request.responseHeaders.ContainsKey("STATUS")) { - statusCode = int.Parse(request.responseHeaders["STATUS"].Split(' ')[1]); + cb(new HTTPRequestException(request.error, statusCode), null); + yield break; } - cb(new HTTPRequestException(request.error, statusCode), null); - yield break; - } - - // Otherwise check for cookies and return the response - // HACK: we need to use reflection as cookieContainer - // junks same key cookies as it uses a dictionary. To - // work around this we use reflection to get the original - // cookie response text, which isn't exposed, and parse - // it ourselves - Uri requestUri = new Uri(request.url); - PropertyInfo pinfoHeadersString = typeof(WWW).GetProperty("responseHeadersString", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - - if (pinfoHeadersString != null) { - string headersString = pinfoHeadersString.GetValue(request, null) as string; - string[] headerLines = headersString.Split('\n'); - - foreach (string headerStr in headerLines) { - if (headerStr.StartsWith("set-cookie:", true, null)) { - cookies.SetCookies(requestUri, headerStr.Remove(0, 11)); + // Otherwise check for cookies and return the response + // HACK: we need to use reflection as cookieContainer + // junks same key cookies as it uses a dictionary. To + // work around this we use reflection to get the original + // cookie response text, which isn't exposed, and parse + // it ourselves + Uri requestUri = new Uri(request.url); + PropertyInfo pinfoHeadersString = typeof(WWW).GetProperty("responseHeadersString", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + + if (pinfoHeadersString != null) { + string headersString = pinfoHeadersString.GetValue(request, null) as string; + string[] headerLines = headersString.Split('\n'); + + foreach (string headerStr in headerLines) { + if (headerStr.StartsWith("set-cookie:", true, null)) { + cookies.SetCookies(requestUri, headerStr.Remove(0, 11)); + } } } + + cb(null, request.text); } - cb(null, request.text); - } + // Abort request + public void Abort() { + if (this.request == null) { + return; + } - // Abort request - public void Abort() - { - if (this.request == null) - { - return; + WWW request = this.request; + this.request = null; + + request.Dispose(); + timeoutTimer.Stop(); + timeoutTimer = null; } - WWW request = this.request; - this.request = null; - request.Dispose(); - timeoutTimer.Stop(); - timeoutTimer = null; - } + // Create GET request and return it + public static HTTPRequest Get(string url, Dictionary headers, CookieContainer cookies, Action cb) { + // Create request and return it + // The callback will be called when the request is complete + return new HTTPRequest(url, null, null, headers, cookies, cb); + } + // Create POST request and return it + public static HTTPRequest Post(string url, string contentType, string postData, Dictionary headers, CookieContainer cookies, Action cb) { + byte[] binaryPostData = Encoding.UTF8.GetBytes(postData); + return Post(url, contentType, binaryPostData, headers, cookies, cb); + } - // Create GET request and return it - public static HTTPRequest Get(string url, Dictionary headers, CookieContainer cookies, Action cb) { - // Create request and return it - // The callback will be called when the request is complete - return new HTTPRequest(url, null, null, headers, cookies, cb); - } - - // Create POST request and return it - public static HTTPRequest Post(string url, string contentType, string postData, Dictionary headers, CookieContainer cookies, Action cb) { - byte[] binaryPostData = Encoding.UTF8.GetBytes(postData); - return Post(url, contentType, binaryPostData, headers, cookies, cb); - } - - // Create POST request and return it - public static HTTPRequest Post(string url, string contentType, byte[] postData, Dictionary headers, CookieContainer cookies, Action cb) { - return new HTTPRequest(url, contentType, postData, headers, cookies, cb); + // Create POST request and return it + public static HTTPRequest Post(string url, string contentType, byte[] postData, Dictionary headers, CookieContainer cookies, Action cb) { + return new HTTPRequest(url, contentType, postData, headers, cookies, cb); + } } } -#endif \ No newline at end of file +#endif diff --git a/HTTPRequest/HTTPRequestException.cs b/HTTPRequest/HTTPRequestException.cs index 6864e74..dda517e 100644 --- a/HTTPRequest/HTTPRequestException.cs +++ b/HTTPRequest/HTTPRequestException.cs @@ -1,9 +1,11 @@ -using System; +using System; -public class HTTPRequestException : Exception { - public int Status = 0; +namespace Wizcorp.MageSDK.Network.Http { + public class HTTPRequestException : Exception { + public int Status = 0; - public HTTPRequestException(string Message, int Status) : base(Message) { - this.Status = Status; + public HTTPRequestException(string Message, int Status) : base(Message) { + this.Status = Status; + } } -} \ No newline at end of file +} diff --git a/HTTPRequest/HTTPRequestManager.cs b/HTTPRequest/HTTPRequestManager.cs index eee9c65..4ad2c4d 100644 --- a/HTTPRequest/HTTPRequestManager.cs +++ b/HTTPRequest/HTTPRequestManager.cs @@ -1,27 +1,29 @@ -using System.Collections; +using System.Collections; using System.Collections.Generic; -using UnityEngine; +using Wizcorp.MageSDK.Utils; -public class HTTPRequestManager : MonoSingleton { - // - private static List queued = new List(); +namespace Wizcorp.MageSDK.Network.Http { + public class HTTPRequestManager : MonoSingleton { + // + private static List queued = new List(); - // - public static void Queue(IEnumerator coroutine) { - lock ((object)queued) { - queued.Add(coroutine); + // + public static void Queue(IEnumerator coroutine) { + lock ((object)queued) { + queued.Add(coroutine); + } } - } - // - void Update () { - lock ((object)queued) { - for (int i = 0; i < queued.Count; i += 1) { - StartCoroutine(queued[i]); - } + // + void Update() { + lock ((object)queued) { + for (int i = 0; i < queued.Count; i += 1) { + StartCoroutine(queued[i]); + } - queued.Clear(); + queued.Clear(); + } } } -} \ No newline at end of file +} diff --git a/JSONRPC/JSONRPC.cs b/JSONRPC/JSONRPC.cs index dd0eff9..f6497a4 100644 --- a/JSONRPC/JSONRPC.cs +++ b/JSONRPC/JSONRPC.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Net; using System.IO; @@ -6,114 +6,118 @@ using Newtonsoft.Json.Linq; -public class JSONRPC { - // Endpoint and Basic Authentication - private string endpoint; - Dictionary headers; +using Wizcorp.MageSDK.Network.Http; - public void SetEndpoint(string endpoint, Dictionary headers = null) { - this.endpoint = endpoint; - this.headers = new Dictionary(headers); - } +namespace Wizcorp.MageSDK.Network.JsonRpc { + public class JSONRPC { + // Endpoint and Basic Authentication + private string endpoint; + Dictionary headers; - public void Call(string methodName, JObject parameters, Dictionary headers, CookieContainer cookies, Action cb) { - Call(JValue.CreateNull(), methodName, parameters, headers, cookies, cb); - } + public void SetEndpoint(string endpoint, Dictionary headers = null) { + this.endpoint = endpoint; + this.headers = new Dictionary(headers); + } - public void Call(string id, string methodName, JObject parameters, Dictionary headers, CookieContainer cookies, Action cb) { - Call(new JValue(id), methodName, parameters, headers, cookies, cb); - } + public void Call(string methodName, JObject parameters, Dictionary headers, CookieContainer cookies, Action cb) { + Call(JValue.CreateNull(), methodName, parameters, headers, cookies, cb); + } - public void Call(int id, string methodName, JObject parameters, Dictionary headers, CookieContainer cookies, Action cb) { - Call(new JValue(id), methodName, parameters, headers, cookies, cb); - } + public void Call(string id, string methodName, JObject parameters, Dictionary headers, CookieContainer cookies, Action cb) { + Call(new JValue(id), methodName, parameters, headers, cookies, cb); + } - public void Call(JValue id, string methodName, JObject parameters, Dictionary headers, CookieContainer cookies, Action cb) { - // Setup JSON request object - JObject requestObject = new JObject (); - requestObject.Add("jsonrpc", new JValue("2.0")); - - requestObject.Add("id", id); - requestObject.Add("method", new JValue(methodName)); - requestObject.Add("params", parameters); - - // Serialize JSON request object into string - string postData; - try { - postData = requestObject.ToString (); - } catch (Exception serializeError) { - cb(serializeError, null); - return; + public void Call(int id, string methodName, JObject parameters, Dictionary headers, CookieContainer cookies, Action cb) { + Call(new JValue(id), methodName, parameters, headers, cookies, cb); } - // Send request - SendRequest(postData, headers, cookies, (Exception requestError, string responseString) => { - if (requestError != null) { - cb(requestError, null); - return; - } - - // Deserialize the JSON response - JObject responseObject; + public void Call(JValue id, string methodName, JObject parameters, Dictionary headers, CookieContainer cookies, Action cb) { + // Setup JSON request object + JObject requestObject = new JObject(); + requestObject.Add("jsonrpc", new JValue("2.0")); + + requestObject.Add("id", id); + requestObject.Add("method", new JValue(methodName)); + requestObject.Add("params", parameters); + + // Serialize JSON request object into string + string postData; try { - responseObject = JObject.Parse(responseString); - } catch (Exception parseError) { - cb(parseError, null); + postData = requestObject.ToString(); + } catch (Exception serializeError) { + cb(serializeError, null); return; } - - cb(null, responseObject); - }); - } - public void CallBatch(JSONRPCBatch rpcBatch, Dictionary headers, CookieContainer cookies, Action cb) { - // Serialize JSON request object into string - string postData; - try { - postData = rpcBatch.batch.ToString(); - } catch (Exception serializeError) { - cb(serializeError, null); - return; + // Send request + SendRequest(postData, headers, cookies, (Exception requestError, string responseString) => { + if (requestError != null) { + cb(requestError, null); + return; + } + + // Deserialize the JSON response + JObject responseObject; + try { + responseObject = JObject.Parse(responseString); + } catch (Exception parseError) { + cb(parseError, null); + return; + } + + cb(null, responseObject); + }); } - // Send request - SendRequest(postData, headers, cookies, (Exception requestError, string responseString) => { - if (requestError != null) { - cb(requestError, null); - return; - } - - // Deserialize the JSON response - JArray responseArray; + public void CallBatch(JSONRPCBatch rpcBatch, Dictionary headers, CookieContainer cookies, Action cb) { + // Serialize JSON request object into string + string postData; try { - responseArray = JArray.Parse(responseString); - } catch (Exception parseError) { - cb(parseError, null); + postData = rpcBatch.batch.ToString(); + } catch (Exception serializeError) { + cb(serializeError, null); return; } - - cb(null, responseArray); - }); - } - private void SendRequest(string postData, Dictionary headers, CookieContainer cookies, Action cb) { - // Make sure the endpoint is set - if (string.IsNullOrEmpty(this.endpoint)) { - cb(new Exception("Endpoint has not been set"), null); - return; + // Send request + SendRequest(postData, headers, cookies, (Exception requestError, string responseString) => { + if (requestError != null) { + cb(requestError, null); + return; + } + + // Deserialize the JSON response + JArray responseArray; + try { + responseArray = JArray.Parse(responseString); + } catch (Exception parseError) { + cb(parseError, null); + return; + } + + cb(null, responseArray); + }); } - // Make a copy of the provided headers and add additional required headers - Dictionary finalHeaders = new Dictionary(this.headers); - foreach (var header in headers) { - if (finalHeaders.ContainsKey(header.Key)) { - continue; + private void SendRequest(string postData, Dictionary headers, CookieContainer cookies, Action cb) { + // Make sure the endpoint is set + if (string.IsNullOrEmpty(this.endpoint)) { + cb(new Exception("Endpoint has not been set"), null); + return; } - finalHeaders.Add(header.Key, header.Value); - } + // Make a copy of the provided headers and add additional required headers + Dictionary finalHeaders = new Dictionary(this.headers); + foreach (var header in headers) { + if (finalHeaders.ContainsKey(header.Key)) { + continue; + } - // Send HTTP post to JSON rpc endpoint - HTTPRequest.Post(this.endpoint, "application/json", postData, finalHeaders, cookies, cb); + finalHeaders.Add(header.Key, header.Value); + } + + // Send HTTP post to JSON rpc endpoint + HTTPRequest.Post(this.endpoint, "application/json", postData, finalHeaders, cookies, cb); + } } } diff --git a/JSONRPC/JSONRPCBatch.cs b/JSONRPC/JSONRPCBatch.cs index 25d8007..1b74c17 100644 --- a/JSONRPC/JSONRPCBatch.cs +++ b/JSONRPC/JSONRPCBatch.cs @@ -1,28 +1,30 @@ -using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Linq; -public class JSONRPCBatch { - public JArray batch = new JArray(); - - public void Add(string methodName, JObject parameters) { - Add(JValue.CreateNull(), methodName, parameters); - } +namespace Wizcorp.MageSDK.Network.JsonRpc { + public class JSONRPCBatch { + public JArray batch = new JArray(); - public void Add(string id, string methodName, JObject parameters) { - Add(new JValue(id), methodName, parameters); - } + public void Add(string methodName, JObject parameters) { + Add(JValue.CreateNull(), methodName, parameters); + } - public void Add(int id, string methodName, JObject parameters) { - Add(new JValue(id), methodName, parameters); - } + public void Add(string id, string methodName, JObject parameters) { + Add(new JValue(id), methodName, parameters); + } + + public void Add(int id, string methodName, JObject parameters) { + Add(new JValue(id), methodName, parameters); + } + + public void Add(JValue id, string methodName, JObject parameters) { + JObject requestObject = new JObject(); + requestObject.Add("jsonrpc", new JValue("2.0")); - public void Add(JValue id, string methodName, JObject parameters) { - JObject requestObject = new JObject(); - requestObject.Add("jsonrpc", new JValue("2.0")); - - requestObject.Add("id", id); - requestObject.Add("method", new JValue(methodName)); - requestObject.Add("params", parameters); + requestObject.Add("id", id); + requestObject.Add("method", new JValue(methodName)); + requestObject.Add("params", parameters); - batch.Add(requestObject); + batch.Add(requestObject); + } } -} \ No newline at end of file +} diff --git a/Mage/Archivist/Archivist.cs b/Mage/Archivist/Archivist.cs index 526c067..8f13ba1 100644 --- a/Mage/Archivist/Archivist.cs +++ b/Mage/Archivist/Archivist.cs @@ -1,473 +1,477 @@ -using System; -using System.Collections; +using System; using System.Collections.Generic; using Newtonsoft.Json.Linq; -public class Archivist : EventEmitter { - private Mage mage { get { return Mage.Instance; } } - private Logger logger { get { return mage.logger("archivist"); } } +using Wizcorp.MageSDK.Event; +using Wizcorp.MageSDK.Log; + +namespace Wizcorp.MageSDK.MageClient { + public class Archivist : EventEmitter { + private Mage mage { get { return Mage.Instance; } } + private Logger logger { get { return mage.logger("archivist"); } } + + // Local cache of all retrieved vault values + private Dictionary _cache = new Dictionary(); + + + // Constructor + public Archivist() { + // Set data to vault value when set event received + mage.eventManager.on("archivist:set", (object sender, JToken info) => { + string topic = (string)info["key"]["topic"]; + JObject index = (JObject)info["key"]["index"]; + JToken data = info["value"]["data"]; + string mediaType = (string)info["value"]["mediaType"]; + int? expirationTime = (int?)info["expirationTime"]; + ValueSet(topic, index, data, mediaType, expirationTime); + }); + + // Del data inside vault value when del event received + mage.eventManager.on("archivist:del", (object sender, JToken info) => { + string topic = (string)info["key"]["topic"]; + JObject index = (JObject)info["key"]["index"]; + ValueDel(topic, index); + }); + + // Touch vault value expiry when touch event received + mage.eventManager.on("archivist:touch", (object sender, JToken info) => { + string topic = (string)info["key"]["topic"]; + JObject index = (JObject)info["key"]["index"]; + int? expirationTime = (int?)info["expirationTime"]; + ValueTouch(topic, index, expirationTime); + }); + + // Apply changes to vault value when applyDiff event is received + mage.eventManager.on("archivist:applyDiff", (object sender, JToken info) => { + string topic = (string)info["key"]["topic"]; + JObject index = (JObject)info["key"]["index"]; + JArray diff = (JArray)info["diff"]; + int? expirationTime = (int?)info["expirationTime"]; + ValueApplyDiff(topic, index, diff, expirationTime); + }); + } - // Local cache of all retrieved vault values - private Dictionary _cache = new Dictionary(); + //////////////////////////////////////////// + // Cache Manipulation // + //////////////////////////////////////////// - // Constructor - public Archivist () { - // Set data to vault value when set event received - mage.eventManager.on("archivist:set", (object sender, JToken info) => { - string topic = (string)info["key"]["topic"]; - JObject index = (JObject)info["key"]["index"]; - JToken data = info["value"]["data"]; - string mediaType = (string)info["value"]["mediaType"]; - int? expirationTime = (int?)info["expirationTime"]; - ValueSet(topic, index, data, mediaType, expirationTime); - }); - - // Del data inside vault value when del event received - mage.eventManager.on("archivist:del", (object sender, JToken info) => { - string topic = (string)info["key"]["topic"]; - JObject index = (JObject)info["key"]["index"]; - ValueDel(topic, index); - }); + // Returns string id of a vault value for given topic and index + private static string CreateCacheKey(string topic, JObject index) { + // Sort the keys so order of index is always the same + List indexKeys = new List(); + foreach (var property in index) { + indexKeys.Add(property.Key); + } + indexKeys.Sort(); - // Touch vault value expiry when touch event received - mage.eventManager.on("archivist:touch", (object sender, JToken info) => { - string topic = (string)info["key"]["topic"]; - JObject index = (JObject)info["key"]["index"]; - int? expirationTime = (int?)info["expirationTime"]; - ValueTouch(topic, index, expirationTime); - }); + // Construct cache key list with correct ordering + List cacheKeys = new List(); + cacheKeys.Add(topic); - // Apply changes to vault value when applyDiff event is received - mage.eventManager.on("archivist:applyDiff", (object sender, JToken info) => { - string topic = (string)info["key"]["topic"]; - JObject index = (JObject)info["key"]["index"]; - JArray diff = (JArray)info["diff"]; - int? expirationTime = (int?)info["expirationTime"]; - ValueApplyDiff(topic, index, diff, expirationTime); - }); - } + foreach (string indexKey in indexKeys) { + cacheKeys.Add(indexKey + "=" + index[indexKey].ToString()); + } + // Join the cache key list into final key string + return string.Join(":", cacheKeys.ToArray()); + } - //////////////////////////////////////////// - // Cache Manipulation // - //////////////////////////////////////////// - // Returns string id of a vault value for given topic and index - private static string CreateCacheKey (string topic, JObject index) { - // Sort the keys so order of index is always the same - List indexKeys = new List (); - foreach (var property in index) { - indexKeys.Add(property.Key); - } - indexKeys.Sort (); + // Returns cache value if it exists and has not passed max allowed age + private VaultValue GetCacheValue(string cacheKeyName, int? maxAge = null) { + lock ((object)_cache) { + if (!_cache.ContainsKey(cacheKeyName)) { + return null; + } - // Construct cache key list with correct ordering - List cacheKeys = new List (); - cacheKeys.Add (topic); + VaultValue value = _cache[cacheKeyName]; + double timespan = (DateTime.UtcNow - value.writtenAt).TotalMilliseconds; + if (maxAge != null && timespan > maxAge * 1000) { + return null; + } - foreach (string indexKey in indexKeys) { - cacheKeys.Add (indexKey + "=" + index[indexKey].ToString()); + return value; + } } - // Join the cache key list into final key string - return string.Join(":", cacheKeys.ToArray()); - } + // Return cache dictionary + public Dictionary GetCache() { + return _cache; + } - // Returns cache value if it exists and has not passed max allowed age - private VaultValue GetCacheValue(string cacheKeyName, int? maxAge = null) { - lock ((object)_cache) { - if (!_cache.ContainsKey(cacheKeyName)) { - return null; - } - VaultValue value = _cache[cacheKeyName]; - double timespan = (DateTime.UtcNow - value.writtenAt).TotalMilliseconds; - if (maxAge != null && timespan > maxAge * 1000) { - return null; + // Clear out the cache entirely + public void ClearCache() { + lock ((object)_cache) { + _cache.Clear(); } - - return value; } - } - // Return cache dictionary - public Dictionary GetCache() { - return _cache; - } + // Remove a vault value from the cache by it's topic and index + public void DeleteCacheItem(string topic, JObject index) { + DeleteCacheItem(CreateCacheKey(topic, index)); + } - // Clear out the cache entirely - public void ClearCache() { - lock ((object)_cache) { - _cache.Clear(); - } - } + // Remove a vault value from the cache by it's cache key name + public void DeleteCacheItem(string cacheKeyName) { + lock ((object)_cache) { + logger.debug("Deleting cache item: " + cacheKeyName); + if (!_cache.ContainsKey(cacheKeyName)) { + return; + } + _cache.Remove(cacheKeyName); + } + } - // Remove a vault value from the cache by it's topic and index - public void DeleteCacheItem(string topic, JObject index) { - DeleteCacheItem(CreateCacheKey(topic, index)); - } + //////////////////////////////////////////// + // Vault Value Manipulation // + //////////////////////////////////////////// + private void ValueSetOrDelete(JObject info) { + string topic = (string)info["key"]["topic"]; + JObject index = (JObject)info["key"]["index"]; + JObject rawValue = (JObject)info["value"]; - // Remove a vault value from the cache by it's cache key name - public void DeleteCacheItem(string cacheKeyName) { - lock ((object)_cache) { - logger.debug("Deleting cache item: " + cacheKeyName); - if (!_cache.ContainsKey(cacheKeyName)) { - return; + if (rawValue != null) { + ValueSet(topic, index, rawValue["data"], (string)rawValue["mediaType"], (int?)info["expirationTime"]); + } else { + ValueDel(topic, index); } - - _cache.Remove(cacheKeyName); } - } + private void ValueSet(string topic, JObject index, JToken data, string mediaType, int? expirationTime) { + string cacheKeyName = CreateCacheKey(topic, index); + VaultValue cacheValue = null; + + // NOTE: even though some of these operations lock already, we put them inside this + // lock to ensure there is no time inconsistencies if things happen too fast. + lock ((object)_cache) { + cacheValue = GetCacheValue(cacheKeyName); + if (cacheValue == null) { + // If it doesn't exist, create a new vault value + cacheValue = new VaultValue(topic, index); + _cache.Add(cacheKeyName, cacheValue); + } else { + // If it exists delete existing value in preparation for set + cacheValue.Del(); + } - //////////////////////////////////////////// - // Vault Value Manipulation // - //////////////////////////////////////////// - private void ValueSetOrDelete(JObject info) { - string topic = (string)info["key"]["topic"]; - JObject index = (JObject)info["key"]["index"]; - JObject rawValue = (JObject)info["value"]; + // Set data to vault value + cacheValue.SetData(mediaType, data); + cacheValue.Touch(expirationTime); + } - if (rawValue != null) { - ValueSet(topic, index, rawValue["data"], (string)rawValue["mediaType"], (int?)info["expirationTime"]); - } else { - ValueDel(topic, index); + // Emit set event + this.emit(topic + ":set", cacheValue); } - } - private void ValueSet(string topic, JObject index, JToken data, string mediaType, int? expirationTime) { - string cacheKeyName = CreateCacheKey(topic, index); - VaultValue cacheValue = null; + private void ValueAdd(string topic, JObject index, JToken data, string mediaType, int? expirationTime) { + string cacheKeyName = CreateCacheKey(topic, index); + VaultValue cacheValue = null; + + // NOTE: even though some of these operations lock already, we put them inside this + // lock to ensure there is no time inconsistencies if things happen too fast. + lock ((object)_cache) { + // Check if value already exists + cacheValue = GetCacheValue(cacheKeyName); + if (cacheValue != null) { + logger.error("Could not add value (already exists): " + cacheKeyName); + return; + } - // NOTE: even though some of these operations lock already, we put them inside this - // lock to ensure there is no time inconsistencies if things happen too fast. - lock ((object)_cache) { - cacheValue = GetCacheValue(cacheKeyName); - if (cacheValue == null) { - // If it doesn't exist, create a new vault value + // Create new vault value cacheValue = new VaultValue(topic, index); _cache.Add(cacheKeyName, cacheValue); - } else { - // If it exists delete existing value in preparation for set - cacheValue.Del(); + + // Set data to vault value + cacheValue.SetData(mediaType, data); + cacheValue.Touch(expirationTime); } - // Set data to vault value - cacheValue.SetData(mediaType, data); - cacheValue.Touch(expirationTime); + // Emit add event + this.emit(topic + ":add", cacheValue); } - // Emit set event - this.emit(topic + ":set", cacheValue); - } - - private void ValueAdd(string topic, JObject index, JToken data, string mediaType, int? expirationTime) { - string cacheKeyName = CreateCacheKey(topic, index); - VaultValue cacheValue = null; - - // NOTE: even though some of these operations lock already, we put them inside this - // lock to ensure there is no time inconsistencies if things happen too fast. - lock ((object)_cache) { + private void ValueDel(string topic, JObject index) { // Check if value already exists - cacheValue = GetCacheValue(cacheKeyName); - if (cacheValue != null) { - logger.error("Could not add value (already exists): " + cacheKeyName); + string cacheKeyName = CreateCacheKey(topic, index); + VaultValue cacheValue = GetCacheValue(cacheKeyName); + if (cacheValue == null) { + logger.warning("Could not delete value (doesn't exist): " + cacheKeyName); return; } - // Create new vault value - cacheValue = new VaultValue(topic, index); - _cache.Add(cacheKeyName, cacheValue); + // Do delete + cacheValue.Del(); - // Set data to vault value - cacheValue.SetData(mediaType, data); - cacheValue.Touch(expirationTime); + // Emit touch event + this.emit(topic + ":del", cacheValue); } - // Emit add event - this.emit(topic + ":add", cacheValue); - } + private void ValueTouch(string topic, JObject index, int? expirationTime) { + // Check if value already exists + string cacheKeyName = CreateCacheKey(topic, index); + VaultValue cacheValue = GetCacheValue(cacheKeyName); + if (cacheValue == null) { + logger.warning("Could not touch value (doesn't exist): " + cacheKeyName); + return; + } - private void ValueDel(string topic, JObject index) { - // Check if value already exists - string cacheKeyName = CreateCacheKey(topic, index); - VaultValue cacheValue = GetCacheValue(cacheKeyName); - if (cacheValue == null) { - logger.warning("Could not delete value (doesn't exist): " + cacheKeyName); - return; - } - - // Do delete - cacheValue.Del(); - - // Emit touch event - this.emit(topic + ":del", cacheValue); - } + // Do touch + cacheValue.Touch(expirationTime); - private void ValueTouch(string topic, JObject index, int? expirationTime) { - // Check if value already exists - string cacheKeyName = CreateCacheKey(topic, index); - VaultValue cacheValue = GetCacheValue(cacheKeyName); - if (cacheValue == null) { - logger.warning("Could not touch value (doesn't exist): " + cacheKeyName); - return; + // Emit touch event + this.emit(topic + ":touch", cacheValue); } - // Do touch - cacheValue.Touch(expirationTime); - - // Emit touch event - this.emit(topic + ":touch", cacheValue); - } + private void ValueApplyDiff(string topic, JObject index, JArray diff, int? expirationTime) { + // Make sure value exists + string cacheKeyName = CreateCacheKey(topic, index); + VaultValue cacheValue = GetCacheValue(cacheKeyName); + if (cacheValue == null) { + logger.warning("Got a diff for a non-existent value:" + cacheKeyName); + return; + } - private void ValueApplyDiff(string topic, JObject index, JArray diff, int? expirationTime) { - // Make sure value exists - string cacheKeyName = CreateCacheKey(topic, index); - VaultValue cacheValue = GetCacheValue(cacheKeyName); - if (cacheValue == null) { - logger.warning("Got a diff for a non-existent value:" + cacheKeyName); - return; + // Apply diff + cacheValue.ApplyDiff(diff); + cacheValue.Touch(expirationTime); + + // Emit applyDiff event + this.emit(topic + ":applyDiff", cacheValue); } - - // Apply diff - cacheValue.ApplyDiff(diff); - cacheValue.Touch(expirationTime); - - // Emit applyDiff event - this.emit(topic + ":applyDiff", cacheValue); - } - //////////////////////////////////////////// - // Raw Communication // - //////////////////////////////////////////// - private void rawGet(string topic, JObject index, Action cb) { - JObject parameters = new JObject(); - parameters.Add("topic", topic); - parameters.Add("index", index); - - mage.commandCenter.SendCommand("archivist.rawGet", parameters, cb); - } - - private void rawMGet(JToken queries, JObject options, Action cb) { - JObject parameters = new JObject(); - parameters.Add(new JProperty ("queries", queries)); - parameters.Add("options", options); + //////////////////////////////////////////// + // Raw Communication // + //////////////////////////////////////////// + private void rawGet(string topic, JObject index, Action cb) { + JObject parameters = new JObject(); + parameters.Add("topic", topic); + parameters.Add("index", index); - mage.commandCenter.SendCommand("archivist.rawMGet", parameters, cb); - } - - private void rawList(string topic, JObject partialIndex, JObject options, Action cb) { - JObject parameters = new JObject(); - parameters.Add("topic", new JValue(topic)); - parameters.Add("partialIndex", partialIndex); - parameters.Add("options", options); - - mage.commandCenter.SendCommand("archivist.rawList", parameters, cb); - } - - private void rawSet(string topic, JObject index, JToken data, string mediaType, string encoding, string expirationTime, Action cb) { - JObject parameters = new JObject(); - parameters.Add ("topic", new JValue(topic)); - parameters.Add ("index", index); - parameters.Add(new JProperty ("data", data)); - parameters.Add ("mediaType", new JValue(mediaType)); - parameters.Add ("encoding", new JValue(encoding)); - parameters.Add ("expirationTime", new JValue(expirationTime)); - - mage.commandCenter.SendCommand("archivist.rawSet", parameters, cb); - } - - private void rawDel(string topic, JObject index, Action cb) { - JObject parameters = new JObject(); - parameters.Add ("topic", new JValue(topic)); - parameters.Add ("index", index); + mage.commandCenter.SendCommand("archivist.rawGet", parameters, cb); + } - mage.commandCenter.SendCommand("archivist.rawDel", parameters, cb); - } - - - //////////////////////////////////////////// - // Exposed Operations // - //////////////////////////////////////////// - public void get(string topic, JObject index, JObject options, Action cb) { - // Default options - options = (options != null) ? options : new JObject(); - if (options["optional"] == null) { - options.Add("optional", new JValue(false)); + private void rawMGet(JToken queries, JObject options, Action cb) { + JObject parameters = new JObject(); + parameters.Add(new JProperty("queries", queries)); + parameters.Add("options", options); + + mage.commandCenter.SendCommand("archivist.rawMGet", parameters, cb); } + private void rawList(string topic, JObject partialIndex, JObject options, Action cb) { + JObject parameters = new JObject(); + parameters.Add("topic", new JValue(topic)); + parameters.Add("partialIndex", partialIndex); + parameters.Add("options", options); - // Check cache - string cacheKeyName = CreateCacheKey(topic, index); - VaultValue cacheValue = GetCacheValue(cacheKeyName, (int?)options["maxAge"]); - if (cacheValue != null) { - cb(null, cacheValue.data); - return; + mage.commandCenter.SendCommand("archivist.rawList", parameters, cb); } - - // Get data from server - rawGet (topic, index, (Exception error, JToken result) => { - if (error != null) { - cb (error, null); - return; - } + private void rawSet(string topic, JObject index, JToken data, string mediaType, string encoding, string expirationTime, Action cb) { + JObject parameters = new JObject(); + parameters.Add("topic", new JValue(topic)); + parameters.Add("index", index); + parameters.Add(new JProperty("data", data)); + parameters.Add("mediaType", new JValue(mediaType)); + parameters.Add("encoding", new JValue(encoding)); + parameters.Add("expirationTime", new JValue(expirationTime)); - // Parse value - try { - ValueSetOrDelete((JObject)result); - } catch (Exception cacheError) { - cb(cacheError, null); - return; - } + mage.commandCenter.SendCommand("archivist.rawSet", parameters, cb); + } - // Return result - cb (null, GetCacheValue(cacheKeyName).data); - }); - } + private void rawDel(string topic, JObject index, Action cb) { + JObject parameters = new JObject(); + parameters.Add("topic", new JValue(topic)); + parameters.Add("index", index); - public void mget(JArray queries, JObject options, Action cb) { - // Default options - options = (options != null) ? options : new JObject(); - if (options["optional"] == null) { - options.Add("optional", new JValue(false)); + mage.commandCenter.SendCommand("archivist.rawDel", parameters, cb); } - // Keep track of actual data we need from server - JArray realQueries = new JArray(); - Dictionary realQueryKeys = new Dictionary(); - JArray responseArray = new JArray(); + //////////////////////////////////////////// + // Exposed Operations // + //////////////////////////////////////////// + public void get(string topic, JObject index, JObject options, Action cb) { + // Default options + options = (options != null) ? options : new JObject(); + if (options["optional"] == null) { + options.Add("optional", new JValue(false)); + } - // Check cache - foreach (JObject query in queries) { - string topic = (string)query["topic"]; - JObject index = (JObject)query["index"]; + // Check cache string cacheKeyName = CreateCacheKey(topic, index); VaultValue cacheValue = GetCacheValue(cacheKeyName, (int?)options["maxAge"]); if (cacheValue != null) { - responseArray.Add(cacheValue.data); - } else { - realQueryKeys.Add(cacheKeyName, responseArray.Count); - responseArray.Add(null); - realQueries.Add(query); + cb(null, cacheValue.data); + return; } - } - // Check if any real queries exist - if (realQueries.Count == 0) { - cb (null, responseArray); - return; - } + // Get data from server + rawGet(topic, index, (Exception error, JToken result) => { + if (error != null) { + cb(error, null); + return; + } + + // Parse value + try { + ValueSetOrDelete((JObject)result); + } catch (Exception cacheError) { + cb(cacheError, null); + return; + } + // Return result + cb(null, GetCacheValue(cacheKeyName).data); + }); + } - // Get data from server - rawMGet (realQueries, options, (Exception error, JToken results) => { - if (error != null) { - cb (error, null); - return; + public void mget(JArray queries, JObject options, Action cb) { + // Default options + options = (options != null) ? options : new JObject(); + if (options["optional"] == null) { + options.Add("optional", new JValue(false)); } - try { - foreach (JObject topicValue in results as JArray) { - // Determine value cacheKeyName - string topic = (string)topicValue["key"]["topic"]; - JObject index = (JObject)topicValue["key"]["index"]; - string cacheKeyName = CreateCacheKey(topic, index); - - // Set value to cache - ValueSetOrDelete(topicValue); - // Add value to response - int responseKey = realQueryKeys[cacheKeyName]; - responseArray[responseKey].Replace(GetCacheValue(cacheKeyName).data); + // Keep track of actual data we need from server + JArray realQueries = new JArray(); + Dictionary realQueryKeys = new Dictionary(); + JArray responseArray = new JArray(); + + + // Check cache + foreach (JObject query in queries) { + string topic = (string)query["topic"]; + JObject index = (JObject)query["index"]; + string cacheKeyName = CreateCacheKey(topic, index); + VaultValue cacheValue = GetCacheValue(cacheKeyName, (int?)options["maxAge"]); + if (cacheValue != null) { + responseArray.Add(cacheValue.data); + } else { + realQueryKeys.Add(cacheKeyName, responseArray.Count); + responseArray.Add(null); + realQueries.Add(query); } - } catch (Exception cacheError) { - cb(cacheError, null); + } + + + // Check if any real queries exist + if (realQueries.Count == 0) { + cb(null, responseArray); return; } - - // Return result - cb (null, responseArray); - }); - } - - public void mget(JObject queries, JObject options, Action cb) { - // Default options - options = (options != null) ? options : new JObject(); - if (options["optional"] == null) { - options.Add("optional", new JValue(false)); - } - // Keep track of actual data we need from server - JObject realQueries = new JObject(); - Dictionary realQueryKeys = new Dictionary(); - JObject responseObject = new JObject(); + // Get data from server + rawMGet(realQueries, options, (Exception error, JToken results) => { + if (error != null) { + cb(error, null); + return; + } + try { + foreach (JObject topicValue in results as JArray) { + // Determine value cacheKeyName + string topic = (string)topicValue["key"]["topic"]; + JObject index = (JObject)topicValue["key"]["index"]; + string cacheKeyName = CreateCacheKey(topic, index); + + // Set value to cache + ValueSetOrDelete(topicValue); + + // Add value to response + int responseKey = realQueryKeys[cacheKeyName]; + responseArray[responseKey].Replace(GetCacheValue(cacheKeyName).data); + } + } catch (Exception cacheError) { + cb(cacheError, null); + return; + } - // Check cache - foreach (var query in queries) { - string cacheKeyName = CreateCacheKey(query.Value["topic"].ToString(), query.Value["index"] as JObject); - VaultValue cacheValue = GetCacheValue(cacheKeyName, (int?)options["maxAge"]); - if (cacheValue != null) { - responseObject.Add(query.Key, cacheValue.data); - } else { - realQueryKeys.Add(cacheKeyName, query.Key); - realQueries.Add(query.Key, query.Value); - } + // Return result + cb(null, responseArray); + }); } + public void mget(JObject queries, JObject options, Action cb) { + // Default options + options = (options != null) ? options : new JObject(); + if (options["optional"] == null) { + options.Add("optional", new JValue(false)); + } + + + // Keep track of actual data we need from server + JObject realQueries = new JObject(); + Dictionary realQueryKeys = new Dictionary(); + JObject responseObject = new JObject(); - // Check if any real queries exist - if (realQueries.Count == 0) { - cb (null, responseObject); - return; - } + // Check cache + foreach (var query in queries) { + string cacheKeyName = CreateCacheKey(query.Value["topic"].ToString(), query.Value["index"] as JObject); + VaultValue cacheValue = GetCacheValue(cacheKeyName, (int?)options["maxAge"]); + if (cacheValue != null) { + responseObject.Add(query.Key, cacheValue.data); + } else { + realQueryKeys.Add(cacheKeyName, query.Key); + realQueries.Add(query.Key, query.Value); + } + } - // Get data from server - rawMGet (realQueries, options, (Exception error, JToken results) => { - if (error != null) { - cb (error, null); + + // Check if any real queries exist + if (realQueries.Count == 0) { + cb(null, responseObject); return; } - try { - foreach (JObject topicValue in results as JArray) { - // Determine value cacheKeyName - string valueTopic = topicValue["key"]["topic"].ToString(); - JObject valueIndex = (JObject)topicValue["key"]["index"]; - string cacheKeyName = CreateCacheKey(valueTopic, valueIndex); - // Set value to cache - ValueSetOrDelete(topicValue); + // Get data from server + rawMGet(realQueries, options, (Exception error, JToken results) => { + if (error != null) { + cb(error, null); + return; + } - // Add value to response - string responseKey = realQueryKeys[cacheKeyName]; - responseObject.Add(responseKey, GetCacheValue(cacheKeyName).data); + try { + foreach (JObject topicValue in results as JArray) { + // Determine value cacheKeyName + string valueTopic = topicValue["key"]["topic"].ToString(); + JObject valueIndex = (JObject)topicValue["key"]["index"]; + string cacheKeyName = CreateCacheKey(valueTopic, valueIndex); + + // Set value to cache + ValueSetOrDelete(topicValue); + + // Add value to response + string responseKey = realQueryKeys[cacheKeyName]; + responseObject.Add(responseKey, GetCacheValue(cacheKeyName).data); + } + } catch (Exception cacheError) { + cb(cacheError, null); + return; } - } catch (Exception cacheError) { - cb(cacheError, null); - return; - } - - // Return result - cb (null, responseObject); - }); - } - - public void list(string topic, JObject partialIndex, JObject options, Action cb) { - rawList (topic, partialIndex, options, cb); + + // Return result + cb(null, responseObject); + }); + } + + public void list(string topic, JObject partialIndex, JObject options, Action cb) { + rawList(topic, partialIndex, options, cb); + } } } diff --git a/Mage/Archivist/VaultValue.cs b/Mage/Archivist/VaultValue.cs index 2214459..aca67c5 100644 --- a/Mage/Archivist/VaultValue.cs +++ b/Mage/Archivist/VaultValue.cs @@ -1,93 +1,96 @@ -using System; +using System; using Newtonsoft.Json.Linq; -public class VaultValue { - // - private string _topic; - public string topic { get { return _topic; } } +using Wizcorp.MageSDK.Tomes; - private JObject _index; - public JObject index { get { return _index; } } - - private JToken _data; - public JToken data { get { return _data; } } +namespace Wizcorp.MageSDK.MageClient { + public class VaultValue { + // + private string _topic; + public string topic { get { return _topic; } } - private string _mediaType; - public string mediaType { get { return _mediaType; } } + private JObject _index; + public JObject index { get { return _index; } } - private int? _expirationTime; - public int? expirationTime { get { return _expirationTime; } } + private JToken _data; + public JToken data { get { return _data; } } - // - private DateTime _writtenAt; - public DateTime writtenAt { get { return _writtenAt; }} + private string _mediaType; + public string mediaType { get { return _mediaType; } } + private int? _expirationTime; + public int? expirationTime { get { return _expirationTime; } } - // - public VaultValue(string topic, JObject index) { - _topic = topic; - _index = index; - } + // + private DateTime _writtenAt; + public DateTime writtenAt { get { return _writtenAt; } } - // TODO: implement multiple media-types and encoding - public void SetData(string mediaType, JToken data) { - lock ((object)this) { - // Detect media type - _mediaType = mediaType; + // + public VaultValue(string topic, JObject index) { + _topic = topic; + _index = index; + } - // Set data based on media type - _data = Tome.Conjure(JToken.Parse ((string)data)); - // Bump the last written time - _writtenAt = DateTime.UtcNow; - } - } + // TODO: implement multiple media-types and encoding + public void SetData(string mediaType, JToken data) { + lock ((object)this) { + // Detect media type + _mediaType = mediaType; + // Set data based on media type + _data = Tome.Conjure(JToken.Parse((string)data)); - // - public void Del() { - lock ((object)this) { - // Bump the last written time and check if we have data to destroy - _writtenAt = DateTime.UtcNow; - if (_data == null) { - return; + // Bump the last written time + _writtenAt = DateTime.UtcNow; } + } - // Cleanup data - Tome.Destroy(_data); - _data = null; - _mediaType = null; - // Clear expiration time - Touch (null); - } - } + // + public void Del() { + lock ((object)this) { + // Bump the last written time and check if we have data to destroy + _writtenAt = DateTime.UtcNow; + if (_data == null) { + return; + } + // Cleanup data + Tome.Destroy(_data); + _data = null; + _mediaType = null; - // TODO: the actual implementation of this requires the MAGE time module, - // also we have a timer to clear the value once expired. - public void Touch(int? expirationTime) { - lock ((object)this) { - _expirationTime = expirationTime; + // Clear expiration time + Touch(null); + } } - } - // - public void ApplyDiff(JArray diff) { - lock ((object)this) { - if (diff == null || _data == null) { - return; + // TODO: the actual implementation of this requires the MAGE time module, + // also we have a timer to clear the value once expired. + public void Touch(int? expirationTime) { + lock ((object)this) { + _expirationTime = expirationTime; } + } - // Apply diff to data - Tome.ApplyDiff(_data, diff); - // Bump the last written time - _writtenAt = DateTime.UtcNow; + // + public void ApplyDiff(JArray diff) { + lock ((object)this) { + if (diff == null || _data == null) { + return; + } + + // Apply diff to data + Tome.ApplyDiff(_data, diff); + + // Bump the last written time + _writtenAt = DateTime.UtcNow; + } } } } - \ No newline at end of file diff --git a/Mage/CommandCenter/CommandBatch.cs b/Mage/CommandCenter/CommandBatch.cs index 9abbdf4..716a691 100644 --- a/Mage/CommandCenter/CommandBatch.cs +++ b/Mage/CommandCenter/CommandBatch.cs @@ -3,19 +3,20 @@ using Newtonsoft.Json.Linq; +namespace Wizcorp.MageSDK.MageClient.Command { + public class CommandBatch { + public int queryId; + public List> batchHeaders = new List>(); + public List batchItems = new List(); -public class CommandBatch { - public int queryId; - public List> batchHeaders = new List>(); - public List batchItems = new List(); + public object serialisedCache; - public object serialisedCache; + public CommandBatch(int queryId) { + this.queryId = queryId; + } - public CommandBatch(int queryId) { - this.queryId = queryId; - } - - public void Queue(string commandName, JObject parameters, Action cb) { - batchItems.Add(new CommandBatchItem(commandName, parameters, cb)); + public void Queue(string commandName, JObject parameters, Action cb) { + batchItems.Add(new CommandBatchItem(commandName, parameters, cb)); + } } } diff --git a/Mage/CommandCenter/CommandBatchItem.cs b/Mage/CommandCenter/CommandBatchItem.cs index 2e12c17..97ce042 100644 --- a/Mage/CommandCenter/CommandBatchItem.cs +++ b/Mage/CommandCenter/CommandBatchItem.cs @@ -1,16 +1,17 @@ -using System; +using System; using Newtonsoft.Json.Linq; +namespace Wizcorp.MageSDK.MageClient.Command { + public class CommandBatchItem { + public string commandName; + public JObject parameters; + public Action cb; -public class CommandBatchItem { - public string commandName; - public JObject parameters; - public Action cb; - - public CommandBatchItem(string commandName, JObject parameters, Action cb) { - this.commandName = commandName; - this.parameters = parameters; - this.cb = cb; + public CommandBatchItem(string commandName, JObject parameters, Action cb) { + this.commandName = commandName; + this.parameters = parameters; + this.cb = cb; + } } -} \ No newline at end of file +} diff --git a/Mage/CommandCenter/CommandCenter.cs b/Mage/CommandCenter/CommandCenter.cs index c68cea1..609f143 100644 --- a/Mage/CommandCenter/CommandCenter.cs +++ b/Mage/CommandCenter/CommandCenter.cs @@ -3,146 +3,151 @@ using Newtonsoft.Json.Linq; - -public class CommandCenter { - private Mage mage { get { return Mage.Instance; }} - private Logger logger { get { return mage.logger("CommandCenter"); }} - - // Endpoint and credentials - private string baseUrl; - private string appName; - Dictionary headers = new Dictionary(); - - // Message Hooks - public delegate void MessageHook(CommandBatch commandBatch); - public MessageHook preSerialiseHook; - public MessageHook preNetworkHook; - - // Current transport client - private CommandTransportClient transportClient; - - // Command Batches - private int nextQueryId = 1; - private CommandBatch currentBatch; - private CommandBatch sendingBatch; - - // - public CommandCenter(CommandTransportType transportType = CommandTransportType.HTTP) { - currentBatch = new CommandBatch(nextQueryId++); - SetTransport(transportType); - } - - // - public void SetTransport(CommandTransportType transportType) { - // Cleanup existing transport client - if (transportClient != null) { - transportClient = null; +using Wizcorp.MageSDK.Command.Client; +using Wizcorp.MageSDK.CommandCenter.Client; +using Wizcorp.MageSDK.Log; + +namespace Wizcorp.MageSDK.MageClient.Command { + public class CommandCenter { + private Mage mage { get { return Mage.Instance; } } + private Logger logger { get { return mage.logger("CommandCenter"); } } + + // Endpoint and credentials + private string baseUrl; + private string appName; + Dictionary headers = new Dictionary(); + + // Message Hooks + public delegate void MessageHook(CommandBatch commandBatch); + public MessageHook preSerialiseHook; + public MessageHook preNetworkHook; + + // Current transport client + private CommandTransportClient transportClient; + + // Command Batches + private int nextQueryId = 1; + private CommandBatch currentBatch; + private CommandBatch sendingBatch; + + // + public CommandCenter(CommandTransportType transportType = CommandTransportType.HTTP) { + currentBatch = new CommandBatch(nextQueryId++); + SetTransport(transportType); } - // Create new transport client instance - if (transportType == CommandTransportType.HTTP) { - transportClient = new CommandHTTPClient() as CommandTransportClient; - transportClient.SetEndpoint(baseUrl, appName, headers); - } else if (transportType == CommandTransportType.JSONRPC) { - transportClient = new CommandJSONRPCClient() as CommandTransportClient; - transportClient.SetEndpoint(baseUrl, appName, headers); - } else { - throw new Exception("Invalid transport type: " + transportType); - } + // + public void SetTransport(CommandTransportType transportType) { + // Cleanup existing transport client + if (transportClient != null) { + transportClient = null; + } - // Setup event handlers - transportClient.OnSendComplete += BatchComplete; - transportClient.OnTransportError += TransportError; - } + // Create new transport client instance + if (transportType == CommandTransportType.HTTP) { + transportClient = new CommandHTTPClient() as CommandTransportClient; + transportClient.SetEndpoint(baseUrl, appName, headers); + } else if (transportType == CommandTransportType.JSONRPC) { + transportClient = new CommandJSONRPCClient() as CommandTransportClient; + transportClient.SetEndpoint(baseUrl, appName, headers); + } else { + throw new Exception("Invalid transport type: " + transportType); + } - // - public void SetEndpoint(string baseUrl, string appName, Dictionary headers = null) { - this.baseUrl = baseUrl; - this.appName = appName; - this.headers = new Dictionary(headers); + // Setup event handlers + transportClient.OnSendComplete += BatchComplete; + transportClient.OnTransportError += TransportError; + } + + // + public void SetEndpoint(string baseUrl, string appName, Dictionary headers = null) { + this.baseUrl = baseUrl; + this.appName = appName; + this.headers = new Dictionary(headers); - if (transportClient != null) { - transportClient.SetEndpoint(this.baseUrl, this.appName, this.headers); + if (transportClient != null) { + transportClient.SetEndpoint(this.baseUrl, this.appName, this.headers); + } } - } - // - private void SendBatch() { - mage.eventManager.emit("io.send", null); + // + private void SendBatch() { + mage.eventManager.emit("io.send", null); - lock ((object)this) { - // Swap batches around locking the queue - sendingBatch = currentBatch; - currentBatch = new CommandBatch(nextQueryId++); + lock ((object)this) { + // Swap batches around locking the queue + sendingBatch = currentBatch; + currentBatch = new CommandBatch(nextQueryId++); - // Execute pre-serialisation message hooks - if (preSerialiseHook != null) { - preSerialiseHook.Invoke(sendingBatch); - } + // Execute pre-serialisation message hooks + if (preSerialiseHook != null) { + preSerialiseHook.Invoke(sendingBatch); + } + + // Serialise the batch + logger.debug("Serialising batch: " + sendingBatch.queryId); + transportClient.SerialiseBatch(sendingBatch); - // Serialise the batch - logger.debug("Serialising batch: " + sendingBatch.queryId); - transportClient.SerialiseBatch(sendingBatch); + // Execute pre-network message hooks + if (preNetworkHook != null) { + preNetworkHook.Invoke(sendingBatch); + } - // Execute pre-network message hooks - if (preNetworkHook != null) { - preNetworkHook.Invoke(sendingBatch); + // Send the batch + logger.debug("Sending batch: " + sendingBatch.queryId); + transportClient.SendBatch(sendingBatch); } + } + + // Resend batch + public void Resend() { + mage.eventManager.emit("io.resend", null); - // Send the batch - logger.debug("Sending batch: " + sendingBatch.queryId); + logger.debug("Re-sending batch: " + sendingBatch.queryId); transportClient.SendBatch(sendingBatch); } - } - - // Resend batch - public void Resend() { - mage.eventManager.emit("io.resend", null); - logger.debug("Re-sending batch: " + sendingBatch.queryId); - transportClient.SendBatch(sendingBatch); - } + // + private void BatchComplete() { + mage.eventManager.emit("io.response", null); - // - private void BatchComplete() { - mage.eventManager.emit("io.response", null); + lock ((object)this) { + sendingBatch = null; - lock ((object)this) { - sendingBatch = null; - - // Check if next queued batch should be sent as well - if (currentBatch.batchItems.Count > 0) { - SendBatch(); + // Check if next queued batch should be sent as well + if (currentBatch.batchItems.Count > 0) { + SendBatch(); + } } } - } - - // - private void TransportError(string errorType, Exception error) { - logger.data(error).error("Error when sending command batch request '" + errorType + "'"); - mage.eventManager.emit("io.error." + errorType, null); - } - // Try and send a command right away if there is nothing being sent. - public void SendCommand(string commandName, JObject parameters, Action cb) { - lock ((object)this) { - // Add command to queue - currentBatch.Queue(commandName, parameters, cb); + // + private void TransportError(string errorType, Exception error) { + logger.data(error).error("Error when sending command batch request '" + errorType + "'"); + mage.eventManager.emit("io.error." + errorType, null); + } - // Check if we are busy and should only queue - if (sendingBatch != null) { - return; - } + // Try and send a command right away if there is nothing being sent. + public void SendCommand(string commandName, JObject parameters, Action cb) { + lock ((object)this) { + // Add command to queue + currentBatch.Queue(commandName, parameters, cb); - // Otherwise send the batch - SendBatch(); + // Check if we are busy and should only queue + if (sendingBatch != null) { + return; + } + + // Otherwise send the batch + SendBatch(); + } } - } - // Queue command to current batch and wait for it to get processed by another command - public void PiggyBackCommand(string commandName, JObject parameters, Action cb) { - lock ((object)this) { - currentBatch.Queue(commandName, parameters, cb); + // Queue command to current batch and wait for it to get processed by another command + public void PiggyBackCommand(string commandName, JObject parameters, Action cb) { + lock ((object)this) { + currentBatch.Queue(commandName, parameters, cb); + } } } } diff --git a/Mage/CommandCenter/TransportClient/CommandHTTPClient.cs b/Mage/CommandCenter/TransportClient/CommandHTTPClient.cs index bebb5a0..86ff736 100644 --- a/Mage/CommandCenter/TransportClient/CommandHTTPClient.cs +++ b/Mage/CommandCenter/TransportClient/CommandHTTPClient.cs @@ -5,138 +5,145 @@ using Newtonsoft.Json.Linq; -public class CommandHttpClientCache { - public string batchUrl; - public string postData; - public Dictionary headers; - - public CommandHttpClientCache(string batchUrl, string postData, Dictionary headers) { - this.batchUrl = batchUrl; - this.postData = postData; - this.headers = headers; +using Wizcorp.MageSDK.CommandCenter.Client; +using Wizcorp.MageSDK.Log; +using Wizcorp.MageSDK.MageClient; +using Wizcorp.MageSDK.MageClient.Command; +using Wizcorp.MageSDK.Network.Http; + +namespace Wizcorp.MageSDK.Command.Client { + public class CommandHttpClientCache { + public string batchUrl; + public string postData; + public Dictionary headers; + + public CommandHttpClientCache(string batchUrl, string postData, Dictionary headers) { + this.batchUrl = batchUrl; + this.postData = postData; + this.headers = headers; + } } -} -public class CommandHTTPClient : CommandTransportClient { - private Mage mage { get { return Mage.Instance; } } - private Logger logger { get { return mage.logger("CommandHTTPClient"); } } - - // - private string endpoint; - private Dictionary headers; - - // - public override void SetEndpoint(string baseUrl, string appName, Dictionary headers = null) { - this.endpoint = baseUrl + "/" + appName; - this.headers = new Dictionary(headers); - } + public class CommandHTTPClient : CommandTransportClient { + private Mage mage { get { return Mage.Instance; } } + private Logger logger { get { return mage.logger("CommandHTTPClient"); } } - // - public override void SerialiseBatch(CommandBatch commandBatch) { - List commands = new List(); - List data = new List(); + // + private string endpoint; + private Dictionary headers; - // Attach batch headers to post data - JArray batchHeaders = new JArray(); - for (int batchHeaderI = 0; batchHeaderI < commandBatch.batchHeaders.Count; batchHeaderI += 1) { - Dictionary batchHeader = commandBatch.batchHeaders[batchHeaderI]; - batchHeaders.Add(JObject.FromObject(batchHeader)); - } - data.Add(batchHeaders.ToString(Newtonsoft.Json.Formatting.None)); - - // Attach command names to url and parameters to post data - for (int batchItemI = 0; batchItemI < commandBatch.batchItems.Count; batchItemI += 1) { - CommandBatchItem commandItem = commandBatch.batchItems[batchItemI]; - commands.Add(commandItem.commandName); - data.Add(commandItem.parameters.ToString(Newtonsoft.Json.Formatting.None)); - logger.data(commandItem.parameters).verbose("sending command: " + commandItem.commandName); + // + public override void SetEndpoint(string baseUrl, string appName, Dictionary headers = null) { + this.endpoint = baseUrl + "/" + appName; + this.headers = new Dictionary(headers); } - string batchUrl = endpoint + "/" + String.Join(",", commands.ToArray()) + "?queryId=" + commandBatch.queryId.ToString(); - string postData = string.Join("\n", data.ToArray()); + // + public override void SerialiseBatch(CommandBatch commandBatch) { + List commands = new List(); + List data = new List(); - // Cached the serialisation - commandBatch.serialisedCache = (object)new CommandHttpClientCache( - batchUrl, - postData, - new Dictionary(this.headers) - ); - } - - // - public override void SendBatch(CommandBatch commandBatch) { - // Extract serialisation from cache - CommandHttpClientCache serialisedCache = (CommandHttpClientCache)commandBatch.serialisedCache; - string batchUrl = serialisedCache.batchUrl; - string postData = serialisedCache.postData; - Dictionary headers = serialisedCache.headers; - - // Send HTTP request - SendRequest(batchUrl, postData, headers, (JArray responseArray) => { - // Process each command response - try { - for (int batchId = 0; batchId < responseArray.Count; batchId += 1) { - JArray commandResponse = responseArray[batchId] as JArray; - CommandBatchItem commandItem = commandBatch.batchItems[batchId]; - string commandName = commandItem.commandName; - Action commandCb = commandItem.cb; - - // Check if there are any events attached to this request - if (commandResponse.Count >= 3) { - logger.verbose("[" + commandName + "] processing events"); - mage.eventManager.emitEventList((JArray)commandResponse[2]); - } - - // Check if the response was an error - if (commandResponse[0].Type != JTokenType.Null) { - logger.verbose("[" + commandName + "] server error"); - commandCb(new Exception(commandResponse[0].ToString()), null); - return; - } - - // Pull off call result object, if it doesn't exist - logger.verbose("[" + commandName + "] call response"); - commandCb(null, commandResponse[1]); - } - } catch (Exception error) { - logger.data(error).error("Error when processing command batch responses"); + // Attach batch headers to post data + JArray batchHeaders = new JArray(); + for (int batchHeaderI = 0; batchHeaderI < commandBatch.batchHeaders.Count; batchHeaderI += 1) { + Dictionary batchHeader = commandBatch.batchHeaders[batchHeaderI]; + batchHeaders.Add(JObject.FromObject(batchHeader)); + } + data.Add(batchHeaders.ToString(Newtonsoft.Json.Formatting.None)); + + // Attach command names to url and parameters to post data + for (int batchItemI = 0; batchItemI < commandBatch.batchItems.Count; batchItemI += 1) { + CommandBatchItem commandItem = commandBatch.batchItems[batchItemI]; + commands.Add(commandItem.commandName); + data.Add(commandItem.parameters.ToString(Newtonsoft.Json.Formatting.None)); + logger.data(commandItem.parameters).verbose("sending command: " + commandItem.commandName); } - }); - } - private void SendRequest(string batchUrl, string postData, Dictionary headers, Action cb) { - HTTPRequest.Post(batchUrl, "", postData, headers, mage.cookies, (Exception requestError, string responseString) => { - logger.verbose("Recieved response: " + responseString); + string batchUrl = endpoint + "/" + String.Join(",", commands.ToArray()) + "?queryId=" + commandBatch.queryId.ToString(); + string postData = string.Join("\n", data.ToArray()); - // Check if there was a transport error - if (requestError != null) { - string error = "network"; + // Cached the serialisation + commandBatch.serialisedCache = (object)new CommandHttpClientCache( + batchUrl, + postData, + new Dictionary(this.headers) + ); + } - // On error - var httpError = requestError as HTTPRequestException; - if (httpError != null && httpError.Status == 503) - { - error = "maintenance"; + // + public override void SendBatch(CommandBatch commandBatch) { + // Extract serialisation from cache + CommandHttpClientCache serialisedCache = (CommandHttpClientCache)commandBatch.serialisedCache; + string batchUrl = serialisedCache.batchUrl; + string postData = serialisedCache.postData; + Dictionary headers = serialisedCache.headers; + + // Send HTTP request + SendRequest(batchUrl, postData, headers, (JArray responseArray) => { + // Process each command response + try { + for (int batchId = 0; batchId < responseArray.Count; batchId += 1) { + JArray commandResponse = responseArray[batchId] as JArray; + CommandBatchItem commandItem = commandBatch.batchItems[batchId]; + string commandName = commandItem.commandName; + Action commandCb = commandItem.cb; + + // Check if there are any events attached to this request + if (commandResponse.Count >= 3) { + logger.verbose("[" + commandName + "] processing events"); + mage.eventManager.emitEventList((JArray)commandResponse[2]); + } + + // Check if the response was an error + if (commandResponse[0].Type != JTokenType.Null) { + logger.verbose("[" + commandName + "] server error"); + commandCb(new Exception(commandResponse[0].ToString()), null); + return; + } + + // Pull off call result object, if it doesn't exist + logger.verbose("[" + commandName + "] call response"); + commandCb(null, commandResponse[1]); + } + } catch (Exception error) { + logger.data(error).error("Error when processing command batch responses"); } + }); + } - OnTransportError.Invoke(error, requestError); - return; - } + private void SendRequest(string batchUrl, string postData, Dictionary headers, Action cb) { + HTTPRequest.Post(batchUrl, "", postData, headers, mage.cookies, (Exception requestError, string responseString) => { + logger.verbose("Recieved response: " + responseString); - // Parse reponse array - JArray responseArray; - try { - responseArray = JArray.Parse(responseString); - } catch (Exception parseError) { - OnTransportError.Invoke("parse", parseError); - return; - } + // Check if there was a transport error + if (requestError != null) { + string error = "network"; - // Let CommandCenter know this batch was successful - OnSendComplete.Invoke(); + // On error + var httpError = requestError as HTTPRequestException; + if (httpError != null && httpError.Status == 503) { + error = "maintenance"; + } - // Return array for processing - cb(responseArray); - }); + OnTransportError.Invoke(error, requestError); + return; + } + + // Parse reponse array + JArray responseArray; + try { + responseArray = JArray.Parse(responseString); + } catch (Exception parseError) { + OnTransportError.Invoke("parse", parseError); + return; + } + + // Let CommandCenter know this batch was successful + OnSendComplete.Invoke(); + + // Return array for processing + cb(responseArray); + }); + } } } diff --git a/Mage/CommandCenter/TransportClient/CommandJSONRPCClient.cs b/Mage/CommandCenter/TransportClient/CommandJSONRPCClient.cs index ed9cd3f..727d60b 100644 --- a/Mage/CommandCenter/TransportClient/CommandJSONRPCClient.cs +++ b/Mage/CommandCenter/TransportClient/CommandJSONRPCClient.cs @@ -1,83 +1,89 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json.Linq; +using Wizcorp.MageSDK.CommandCenter.Client; +using Wizcorp.MageSDK.Log; +using Wizcorp.MageSDK.MageClient; +using Wizcorp.MageSDK.MageClient.Command; +using Wizcorp.MageSDK.Network.JsonRpc; -public class CommandJSONRPCClient : CommandTransportClient { - private Mage mage { get { return Mage.Instance; } } - private Logger logger { get { return mage.logger("CommandJSONRPCClient"); } } - - private JSONRPC rpcClient = new JSONRPC(); +namespace Wizcorp.MageSDK.Command.Client { + public class CommandJSONRPCClient : CommandTransportClient { + private Mage mage { get { return Mage.Instance; } } + private Logger logger { get { return mage.logger("CommandJSONRPCClient"); } } - // - public override void SetEndpoint(string baseUrl, string appName, Dictionary headers = null) { - rpcClient.SetEndpoint(baseUrl + "/" + appName + "/jsonrpc", headers); - } - - // - public override void SerialiseBatch(CommandBatch commandBatch) { - logger.verbose("THIS TRANSPORT CLIENT IS NOT IMPLEMENTED"); - throw new Exception("THIS TRANSPORT CLIENT IS NOT IMPLEMENTED"); - } - - // - public override void SendBatch(CommandBatch commandBatch) { - // NOTE: This transport client cannot be implemented yet as JSON RPC support is - // terminally broken in MAGE (does not support queryId and response caching). - // Until this is fixed, this transport client cannot be used or completed. - logger.verbose("THIS TRANSPORT CLIENT IS NOT IMPLEMENTED"); - throw new Exception("THIS TRANSPORT CLIENT IS NOT IMPLEMENTED"); + private JSONRPC rpcClient = new JSONRPC(); - /* - JSONRPCBatch rpcBatch = new JSONRPCBatch(); - for (int batchId = 0; batchId < commandBatch.batchItems.Count; batchId += 1) { - CommandBatchItem commandItem = commandBatch.batchItems[batchId]; - rpcBatch.Add(batchId, commandItem.commandName, commandItem.parameters); - logger.data(commandItem.parameters).verbose("[" + commandItem.commandName + "] executing command"); + // + public override void SetEndpoint(string baseUrl, string appName, Dictionary headers = null) { + rpcClient.SetEndpoint(baseUrl + "/" + appName + "/jsonrpc", headers); } - // Attach any required mage headers - Dictionary headers = new Dictionary(); - - string sessionKey = mage.session.GetSessionKey(); - if (!string.IsNullOrEmpty(sessionKey)) { - headers.Add("X-MAGE-SESSION", sessionKey); + // + public override void SerialiseBatch(CommandBatch commandBatch) { + logger.verbose("THIS TRANSPORT CLIENT IS NOT IMPLEMENTED"); + throw new Exception("THIS TRANSPORT CLIENT IS NOT IMPLEMENTED"); } - // Send rpc batch - rpcClient.CallBatch(rpcBatch, headers, mage.cookies, (Exception error, JArray responseArray) => { - logger.data(responseArray).verbose("Recieved response: "); + // + public override void SendBatch(CommandBatch commandBatch) { + // NOTE: This transport client cannot be implemented yet as JSON RPC support is + // terminally broken in MAGE (does not support queryId and response caching). + // Until this is fixed, this transport client cannot be used or completed. + logger.verbose("THIS TRANSPORT CLIENT IS NOT IMPLEMENTED"); + throw new Exception("THIS TRANSPORT CLIENT IS NOT IMPLEMENTED"); - if (error != null) { - //TODO: OnTransportError.Invoke("", error); - return; + /* + JSONRPCBatch rpcBatch = new JSONRPCBatch(); + for (int batchId = 0; batchId < commandBatch.batchItems.Count; batchId += 1) { + CommandBatchItem commandItem = commandBatch.batchItems[batchId]; + rpcBatch.Add(batchId, commandItem.commandName, commandItem.parameters); + logger.data(commandItem.parameters).verbose("[" + commandItem.commandName + "] executing command"); } - // Process each command response - foreach (JObject responseObject in responseArray) { - int batchId = (int)responseObject["id"]; - CommandBatchItem commandItem = commandBatch.batchItems[batchId]; - string commandName = commandItem.commandName; - Action commandCb = commandItem.cb; + // Attach any required mage headers + Dictionary headers = new Dictionary(); - // Check if there are any events attached to this request - if (responseObject["result"]["myEvents"] != null) { - logger.verbose("[" + commandName + "] processing events"); - mage.eventManager.emitEventList((JArray)responseObject["result"]["myEvents"]); - } + string sessionKey = mage.session.GetSessionKey(); + if (!string.IsNullOrEmpty(sessionKey)) { + headers.Add("X-MAGE-SESSION", sessionKey); + } + + // Send rpc batch + rpcClient.CallBatch(rpcBatch, headers, mage.cookies, (Exception error, JArray responseArray) => { + logger.data(responseArray).verbose("Recieved response: "); - // Check if the response was an error - if (responseObject["result"]["errorCode"] != null) { - logger.verbose("[" + commandName + "] server error"); - commandCb(new Exception(responseObject["result"]["errorCode"].ToString()), null); + if (error != null) { + //TODO: OnTransportError.Invoke("", error); return; } - // Pull off call result object, if it doesn't exist - logger.verbose("[" + commandName + "] call response"); - commandCb(null, responseObject["result"]["response"]); - } - }); - */ + // Process each command response + foreach (JObject responseObject in responseArray) { + int batchId = (int)responseObject["id"]; + CommandBatchItem commandItem = commandBatch.batchItems[batchId]; + string commandName = commandItem.commandName; + Action commandCb = commandItem.cb; + + // Check if there are any events attached to this request + if (responseObject["result"]["myEvents"] != null) { + logger.verbose("[" + commandName + "] processing events"); + mage.eventManager.emitEventList((JArray)responseObject["result"]["myEvents"]); + } + + // Check if the response was an error + if (responseObject["result"]["errorCode"] != null) { + logger.verbose("[" + commandName + "] server error"); + commandCb(new Exception(responseObject["result"]["errorCode"].ToString()), null); + return; + } + + // Pull off call result object, if it doesn't exist + logger.verbose("[" + commandName + "] call response"); + commandCb(null, responseObject["result"]["response"]); + } + }); + */ + } } } diff --git a/Mage/CommandCenter/TransportClient/CommandTransportClient.cs b/Mage/CommandCenter/TransportClient/CommandTransportClient.cs index 959d7b4..8363c1e 100644 --- a/Mage/CommandCenter/TransportClient/CommandTransportClient.cs +++ b/Mage/CommandCenter/TransportClient/CommandTransportClient.cs @@ -1,16 +1,20 @@ using System; using System.Collections.Generic; -public enum CommandTransportType { - HTTP, - JSONRPC -} +using Wizcorp.MageSDK.MageClient.Command; + +namespace Wizcorp.MageSDK.CommandCenter.Client { + public enum CommandTransportType { + HTTP, + JSONRPC + } -public abstract class CommandTransportClient { - public Action OnSendComplete; - public Action OnTransportError; + public abstract class CommandTransportClient { + public Action OnSendComplete; + public Action OnTransportError; - public abstract void SetEndpoint(string baseUrl, string appName, Dictionary headers = null); - public abstract void SerialiseBatch(CommandBatch commandBatch); - public abstract void SendBatch(CommandBatch batch); + public abstract void SetEndpoint(string baseUrl, string appName, Dictionary headers = null); + public abstract void SerialiseBatch(CommandBatch commandBatch); + public abstract void SendBatch(CommandBatch batch); + } } diff --git a/Mage/EventManager.cs b/Mage/EventManager.cs index b526d12..6c200e0 100644 --- a/Mage/EventManager.cs +++ b/Mage/EventManager.cs @@ -1,36 +1,41 @@ -using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Linq; -public class EventManager : EventEmitter { - private Mage mage { get { return Mage.Instance; } } - private Logger logger { get { return mage.logger("eventManager"); } } +using Wizcorp.MageSDK.Event; +using Wizcorp.MageSDK.Log; - public void emitEventList(JArray events) { - foreach (JToken responseEvent in events) { - string eventTag = null; - JToken eventData = null; +namespace Wizcorp.MageSDK.MageClient { + public class EventManager : EventEmitter { + private Mage mage { get { return Mage.Instance; } } + private Logger logger { get { return mage.logger("eventManager"); } } - // Copy the eventItem for processing - JArray eventItem = JArray.Parse(responseEvent.ToString()); + public void emitEventList(JArray events) { + foreach (JToken responseEvent in events) { + string eventTag = null; + JToken eventData = null; - // Check that event name is present - if (eventItem.Count >= 1) { - eventTag = eventItem[0].ToString(); - } + // Copy the eventItem for processing + JArray eventItem = JArray.Parse(responseEvent.ToString()); - // Check if any event data is present - if (eventItem.Count == 2) { - eventData = eventItem[1]; - } + // Check that event name is present + if (eventItem.Count >= 1) { + eventTag = eventItem[0].ToString(); + } - // Check if there were any errors, log and skip them - if (eventTag == null || eventItem.Count > 2) { - logger.data(eventItem).error("Invalid event format:"); - continue; - } + // Check if any event data is present + if (eventItem.Count == 2) { + eventData = eventItem[1]; + } - // Emit the event - logger.debug("Emitting '" + eventTag + "'"); - mage.eventManager.emit (eventTag, eventData); + // Check if there were any errors, log and skip them + if (eventTag == null || eventItem.Count > 2) { + logger.data(eventItem).error("Invalid event format:"); + continue; + } + + // Emit the event + logger.debug("Emitting '" + eventTag + "'"); + mage.eventManager.emit(eventTag, eventData); + } } } } diff --git a/Mage/Logger/LogEntry.cs b/Mage/Logger/LogEntry.cs index 85981a3..234b3fe 100644 --- a/Mage/Logger/LogEntry.cs +++ b/Mage/Logger/LogEntry.cs @@ -1,76 +1,77 @@ +namespace Wizcorp.MageSDK.Log { + public class LogEntry { + // + public string channel; + public string context; + public object data; + public string message; -public class LogEntry { - // - public string channel; - public string context; - public object data; - public string message; + public LogEntry(string context, object data = null) { + this.context = context; + this.data = data; + } - public LogEntry(string context, object data = null) { - this.context = context; - this.data = data; - } + // + private void emitLog() { + Logger.logEmitter.emit("log", this); + Logger.logEmitter.emit("log:" + this.channel, this); + } - // - private void emitLog() { - Logger.logEmitter.emit("log", this); - Logger.logEmitter.emit("log:" + this.channel, this); - } - - - // - public void verbose (string message) { - this.channel = "verbose"; - this.message = message; - emitLog(); - } - - public void debug (string message) { - this.channel = "debug"; - this.message = message; - emitLog(); - } - - public void info (string message) { - this.channel = "info"; - this.message = message; - emitLog(); - } - - public void notice (string message) { - this.channel = "notice"; - this.message = message; - emitLog(); - } - - public void warning (string message) { - this.channel = "warning"; - this.message = message; - emitLog(); - } - - public void error (string message) { - this.channel = "error"; - this.message = message; - emitLog(); - } - - public void critical (string message) { - this.channel = "critical"; - this.message = message; - emitLog(); - } - - public void alert (string message) { - this.channel = "alert"; - this.message = message; - emitLog(); - } - - public void emergency (string message) { - this.channel = "emergency"; - this.message = message; - emitLog(); + + // + public void verbose(string message) { + this.channel = "verbose"; + this.message = message; + emitLog(); + } + + public void debug(string message) { + this.channel = "debug"; + this.message = message; + emitLog(); + } + + public void info(string message) { + this.channel = "info"; + this.message = message; + emitLog(); + } + + public void notice(string message) { + this.channel = "notice"; + this.message = message; + emitLog(); + } + + public void warning(string message) { + this.channel = "warning"; + this.message = message; + emitLog(); + } + + public void error(string message) { + this.channel = "error"; + this.message = message; + emitLog(); + } + + public void critical(string message) { + this.channel = "critical"; + this.message = message; + emitLog(); + } + + public void alert(string message) { + this.channel = "alert"; + this.message = message; + emitLog(); + } + + public void emergency(string message) { + this.channel = "emergency"; + this.message = message; + emitLog(); + } } } diff --git a/Mage/Logger/Logger.cs b/Mage/Logger/Logger.cs index db54597..760b30c 100644 --- a/Mage/Logger/Logger.cs +++ b/Mage/Logger/Logger.cs @@ -1,95 +1,99 @@ -using System; +using System; using System.Collections.Generic; +using Wizcorp.MageSDK.Event; +using Wizcorp.MageSDK.Log.Writers; -public class Logger { - // - public static EventEmitter logEmitter = new EventEmitter(); +namespace Wizcorp.MageSDK.Log { + public class Logger { + // + public static EventEmitter logEmitter = new EventEmitter(); - // - public static Dictionary logWriters; - public static void SetConfig(Dictionary> config) { - // Destroy existing log writers - if (logWriters != null) { - foreach (var writer in logWriters.Values) { - writer.Dispose(); + // + public static Dictionary logWriters; + public static void SetConfig(Dictionary> config) { + // Destroy existing log writers + if (logWriters != null) { + foreach (var writer in logWriters.Values) { + writer.Dispose(); + } + logWriters = null; + } + + // Make sure we have configured something + if (config == null) { + return; + } + + // Create each writer with log levels + logWriters = new Dictionary(); + foreach (var property in config) { + string writer = property.Key; + List writerConfig = property.Value; + + switch (writer) { + case "console": + logWriters.Add(writer, new ConsoleWriter(writerConfig) as LogWriter); + break; + case "server": + logWriters.Add(writer, new ServerWriter(writerConfig) as LogWriter); + break; + default: + throw new Exception("Unknown Log Writer: " + writer); + } } - logWriters = null; } - // Make sure we have configured something - if (config == null) { - return; + + // + private string _context; + + public Logger(string context) { + _context = context; } - // Create each writer with log levels - logWriters = new Dictionary(); - foreach (var property in config) { - string writer = property.Key; - List writerConfig = property.Value; - - switch (writer) { - case "console": - logWriters.Add(writer, new ConsoleWriter(writerConfig) as LogWriter); - break; - case "server": - logWriters.Add(writer, new ServerWriter(writerConfig) as LogWriter); - break; - default: - throw new Exception("Unknown Log Writer: " + writer); - } + + // + public LogEntry data(object data) { + return new LogEntry(_context, data); } - } - // - private string _context; + // + public void verbose(string message) { + (new LogEntry(_context)).verbose(message); + } - public Logger(string context) { - _context = context; - } - - - // - public LogEntry data (object data) { - return new LogEntry (_context, data); - } + public void debug(string message) { + (new LogEntry(_context)).debug(message); + } + public void info(string message) { + (new LogEntry(_context)).info(message); + } - // - public void verbose (string message) { - (new LogEntry (_context)).verbose (message); - } - - public void debug (string message) { - (new LogEntry (_context)).debug (message); - } + public void notice(string message) { + (new LogEntry(_context)).notice(message); + } - public void info (string message) { - (new LogEntry (_context)).info (message); - } - - public void notice (string message) { - (new LogEntry (_context)).notice (message); - } - - public void warning (string message) { - (new LogEntry (_context)).warning (message); - } - - public void error (string message) { - (new LogEntry (_context)).error (message); - } - - public void critical (string message) { - (new LogEntry (_context)).critical (message); - } - - public void alert (string message) { - (new LogEntry (_context)).alert (message); - } - - public void emergency (string message) { - (new LogEntry (_context)).emergency (message); + public void warning(string message) { + (new LogEntry(_context)).warning(message); + } + + public void error(string message) { + (new LogEntry(_context)).error(message); + } + + public void critical(string message) { + (new LogEntry(_context)).critical(message); + } + + public void alert(string message) { + (new LogEntry(_context)).alert(message); + } + + public void emergency(string message) { + (new LogEntry(_context)).emergency(message); + } } } diff --git a/Mage/Logger/Writers/ConsoleWriter.cs b/Mage/Logger/Writers/ConsoleWriter.cs index 7407e08..be96b84 100644 --- a/Mage/Logger/Writers/ConsoleWriter.cs +++ b/Mage/Logger/Writers/ConsoleWriter.cs @@ -1,157 +1,158 @@ -using System; +using System; using System.Collections.Generic; +namespace Wizcorp.MageSDK.Log.Writers { + public class ConsoleWriter : LogWriter { + private List config; -public class ConsoleWriter : LogWriter { - private List config; + public ConsoleWriter(List logLevels) { + config = logLevels; - public ConsoleWriter(List logLevels) { - config = logLevels; + if (config.Contains("verbose")) { + Logger.logEmitter.on("log:verbose", Verbose); + } - if (config.Contains("verbose")) { - Logger.logEmitter.on("log:verbose", Verbose); - } + if (config.Contains("debug")) { + Logger.logEmitter.on("log:debug", Debug); + } - if (config.Contains("debug")) { - Logger.logEmitter.on("log:debug", Debug); - } + if (config.Contains("info")) { + Logger.logEmitter.on("log:info", Info); + } - if (config.Contains("info")) { - Logger.logEmitter.on("log:info", Info); - } + if (config.Contains("notice")) { + Logger.logEmitter.on("log:notice", Notice); + } - if (config.Contains("notice")) { - Logger.logEmitter.on("log:notice", Notice); - } + if (config.Contains("warning")) { + Logger.logEmitter.on("log:warning", Warning); + } - if (config.Contains("warning")) { - Logger.logEmitter.on("log:warning", Warning); - } + if (config.Contains("error")) { + Logger.logEmitter.on("log:error", Error); + } - if (config.Contains("error")) { - Logger.logEmitter.on("log:error", Error); - } + if (config.Contains("critical")) { + Logger.logEmitter.on("log:critical", Critical); + } - if (config.Contains("critical")) { - Logger.logEmitter.on("log:critical", Critical); - } + if (config.Contains("alert")) { + Logger.logEmitter.on("log:alert", Alert); + } - if (config.Contains("alert")) { - Logger.logEmitter.on("log:alert", Alert); - } - - if (config.Contains("emergency")) { - Logger.logEmitter.on("log:emergency", Emergency); + if (config.Contains("emergency")) { + Logger.logEmitter.on("log:emergency", Emergency); + } } - } - public override void Dispose() { - if (config.Contains("verbose")) { - Logger.logEmitter.off("log:verbose", Verbose); - } - - if (config.Contains("debug")) { - Logger.logEmitter.off("log:debug", Debug); - } - - if (config.Contains("info")) { - Logger.logEmitter.off("log:info", Info); - } - - if (config.Contains("notice")) { - Logger.logEmitter.off("log:notice", Notice); - } - - if (config.Contains("warning")) { - Logger.logEmitter.off("log:warning", Warning); - } - - if (config.Contains("error")) { - Logger.logEmitter.off("log:error", Error); - } - - if (config.Contains("critical")) { - Logger.logEmitter.off("log:critical", Critical); + public override void Dispose() { + if (config.Contains("verbose")) { + Logger.logEmitter.off("log:verbose", Verbose); + } + + if (config.Contains("debug")) { + Logger.logEmitter.off("log:debug", Debug); + } + + if (config.Contains("info")) { + Logger.logEmitter.off("log:info", Info); + } + + if (config.Contains("notice")) { + Logger.logEmitter.off("log:notice", Notice); + } + + if (config.Contains("warning")) { + Logger.logEmitter.off("log:warning", Warning); + } + + if (config.Contains("error")) { + Logger.logEmitter.off("log:error", Error); + } + + if (config.Contains("critical")) { + Logger.logEmitter.off("log:critical", Critical); + } + + if (config.Contains("alert")) { + Logger.logEmitter.off("log:alert", Alert); + } + + if (config.Contains("emergency")) { + Logger.logEmitter.off("log:emergency", Emergency); + } } - - if (config.Contains("alert")) { - Logger.logEmitter.off("log:alert", Alert); + + private string makeLogString(string channel, string context, string message) { + return String.Format("[{0}] [{1}] {2}", channel, context, message); } - - if (config.Contains("emergency")) { - Logger.logEmitter.off("log:emergency", Emergency); + + private void Verbose(object sender, LogEntry logEntry) { + UnityEngine.Debug.Log(makeLogString("verbose", logEntry.context, logEntry.message)); + if (logEntry.data != null) { + UnityEngine.Debug.Log(logEntry.data); + } } - } - private string makeLogString(string channel, string context, string message) { - return String.Format("[{0}] [{1}] {2}", channel, context, message); - } - - private void Verbose(object sender, LogEntry logEntry) { - UnityEngine.Debug.Log(makeLogString("verbose", logEntry.context, logEntry.message)); - if (logEntry.data != null) { - UnityEngine.Debug.Log(logEntry.data); + private void Debug(object sender, LogEntry logEntry) { + UnityEngine.Debug.Log(makeLogString("debug", logEntry.context, logEntry.message)); + if (logEntry.data != null) { + UnityEngine.Debug.Log(logEntry.data); + } } - } - - private void Debug(object sender, LogEntry logEntry) { - UnityEngine.Debug.Log(makeLogString("debug", logEntry.context, logEntry.message)); - if (logEntry.data != null) { - UnityEngine.Debug.Log(logEntry.data); + + private void Info(object sender, LogEntry logEntry) { + UnityEngine.Debug.Log(makeLogString("info", logEntry.context, logEntry.message)); + if (logEntry.data != null) { + UnityEngine.Debug.Log(logEntry.data); + } } - } - - private void Info(object sender, LogEntry logEntry) { - UnityEngine.Debug.Log(makeLogString("info", logEntry.context, logEntry.message)); - if (logEntry.data != null) { - UnityEngine.Debug.Log(logEntry.data); + + private void Notice(object sender, LogEntry logEntry) { + UnityEngine.Debug.Log(makeLogString("notice", logEntry.context, logEntry.message)); + if (logEntry.data != null) { + UnityEngine.Debug.Log(logEntry.data); + } } - } - - private void Notice(object sender, LogEntry logEntry) { - UnityEngine.Debug.Log(makeLogString("notice", logEntry.context, logEntry.message)); - if (logEntry.data != null) { - UnityEngine.Debug.Log(logEntry.data); + + private void Warning(object sender, LogEntry logEntry) { + UnityEngine.Debug.LogWarning(makeLogString("warning", logEntry.context, logEntry.message)); + if (logEntry.data != null) { + UnityEngine.Debug.LogWarning(logEntry.data); + } } - } - - private void Warning(object sender, LogEntry logEntry) { - UnityEngine.Debug.LogWarning(makeLogString("warning", logEntry.context, logEntry.message)); - if (logEntry.data != null) { - UnityEngine.Debug.LogWarning (logEntry.data); + + private void Error(object sender, LogEntry logEntry) { + UnityEngine.Debug.LogError(makeLogString("error", logEntry.context, logEntry.message)); + if (logEntry.data != null) { + UnityEngine.Debug.LogError(logEntry.data); + } } - } - - private void Error(object sender, LogEntry logEntry) { - UnityEngine.Debug.LogError(makeLogString("error", logEntry.context, logEntry.message)); - if (logEntry.data != null) { - UnityEngine.Debug.LogError(logEntry.data); + + private void Critical(object sender, LogEntry logEntry) { + UnityEngine.Debug.LogError(makeLogString("critical", logEntry.context, logEntry.message)); + if (logEntry.data != null) { + if (logEntry.data is Exception && (logEntry.data as Exception).StackTrace != null) { + Exception excpt = logEntry.data as Exception; + UnityEngine.Debug.LogError(excpt.ToString() + ":\n" + excpt.StackTrace.ToString()); + } else { + UnityEngine.Debug.LogError(logEntry.data); + } + } } - } - - private void Critical(object sender, LogEntry logEntry) { - UnityEngine.Debug.LogError(makeLogString("critical", logEntry.context, logEntry.message)); - if (logEntry.data != null) { - if (logEntry.data is Exception && (logEntry.data as Exception).StackTrace != null) { - Exception excpt = logEntry.data as Exception; - UnityEngine.Debug.LogError(excpt.ToString() + ":\n" + excpt.StackTrace.ToString()); - } else { + + private void Alert(object sender, LogEntry logEntry) { + UnityEngine.Debug.LogError(makeLogString("alert", logEntry.context, logEntry.message)); + if (logEntry.data != null) { UnityEngine.Debug.LogError(logEntry.data); } } - } - - private void Alert(object sender, LogEntry logEntry) { - UnityEngine.Debug.LogError(makeLogString("alert", logEntry.context, logEntry.message)); - if (logEntry.data != null) { - UnityEngine.Debug.LogError(logEntry.data); - } - } - - private void Emergency(object sender, LogEntry logEntry) { - UnityEngine.Debug.LogError(makeLogString("emergency", logEntry.context, logEntry.message)); - if (logEntry.data != null) { - UnityEngine.Debug.LogError(logEntry.data); + + private void Emergency(object sender, LogEntry logEntry) { + UnityEngine.Debug.LogError(makeLogString("emergency", logEntry.context, logEntry.message)); + if (logEntry.data != null) { + UnityEngine.Debug.LogError(logEntry.data); + } } } } diff --git a/Mage/Logger/Writers/LogWriter.cs b/Mage/Logger/Writers/LogWriter.cs index 41c71df..42f3f17 100644 --- a/Mage/Logger/Writers/LogWriter.cs +++ b/Mage/Logger/Writers/LogWriter.cs @@ -1,3 +1,5 @@ -public abstract class LogWriter { - public abstract void Dispose(); -} \ No newline at end of file +namespace Wizcorp.MageSDK.Log.Writers { + public abstract class LogWriter { + public abstract void Dispose(); + } +} diff --git a/Mage/Logger/Writers/ServerWriter.cs b/Mage/Logger/Writers/ServerWriter.cs index 6171102..7c7676f 100644 --- a/Mage/Logger/Writers/ServerWriter.cs +++ b/Mage/Logger/Writers/ServerWriter.cs @@ -3,44 +3,46 @@ using Newtonsoft.Json.Linq; +using Wizcorp.MageSDK.MageClient; -public class ServerWriter : LogWriter { - protected Mage mage { get { return Mage.Instance; } } +namespace Wizcorp.MageSDK.Log.Writers { + public class ServerWriter : LogWriter { + protected Mage mage { get { return Mage.Instance; } } - private List config; + private List config; - public ServerWriter(List logLevels) { - config = logLevels; + public ServerWriter(List logLevels) { + config = logLevels; - Logger.logEmitter.on("log", HandleLog); - } + Logger.logEmitter.on("log", HandleLog); + } - public override void Dispose() { - Logger.logEmitter.off("log", HandleLog); - } + public override void Dispose() { + Logger.logEmitter.off("log", HandleLog); + } - private void HandleLog(object sender, LogEntry logEntry) { - if (config == null || !config.Contains(logEntry.channel)) { - return; - } + private void HandleLog(object sender, LogEntry logEntry) { + if (config == null || !config.Contains(logEntry.channel)) { + return; + } - string contextMessage = "[" + logEntry.context + "] " + logEntry.message; - JObject dataObject = null; - if (logEntry.data != null) - { - dataObject = JObject.FromObject(logEntry.data); - } + string contextMessage = "[" + logEntry.context + "] " + logEntry.message; + JObject dataObject = null; + if (logEntry.data != null) { + dataObject = JObject.FromObject(logEntry.data); + } - JObject arguments = new JObject(); - arguments.Add("channel", new JValue(logEntry.channel)); - arguments.Add("message", new JValue(contextMessage)); - arguments.Add("data", dataObject); + JObject arguments = new JObject(); + arguments.Add("channel", new JValue(logEntry.channel)); + arguments.Add("message", new JValue(contextMessage)); + arguments.Add("data", dataObject); - mage.commandCenter.SendCommand("logger.sendReport", arguments, (Exception error, JToken result) => { - // if (error) - // We honestly can't do anything about this.... - }); + mage.commandCenter.SendCommand("logger.sendReport", arguments, (Exception error, JToken result) => { + // if (error) + // We honestly can't do anything about this.... + }); + } } } diff --git a/Mage/Mage.cs b/Mage/Mage.cs index 085abf7..07ff64c 100644 --- a/Mage/Mage.cs +++ b/Mage/Mage.cs @@ -1,132 +1,135 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Net; -using Newtonsoft.Json.Linq; +using Wizcorp.MageSDK.Log; +using Wizcorp.MageSDK.MageClient.Message; +using Wizcorp.MageSDK.Network.Http; +using Wizcorp.MageSDK.Utils; +namespace Wizcorp.MageSDK.MageClient { + public class MageSetupStatus { + public bool done = false; + public Exception error = null; + } -public class MageSetupStatus { - public bool done = false; - public Exception error = null; -} + public class Mage : Singleton { + // + public EventManager eventManager; + public Session session; + public Command.CommandCenter commandCenter; + public MessageStream messageStream; + public Archivist archivist; -public class Mage : Singleton { - // - public EventManager eventManager; - public Session session; - public CommandCenter commandCenter; - public MessageStream messageStream; - public Archivist archivist; + private Logger _logger; - private Logger _logger; + // + string baseUrl; + string appName; + Dictionary headers; + public CookieContainer cookies; - // - string baseUrl; - string appName; - Dictionary headers; - public CookieContainer cookies; + // + private Dictionary _loggers = new Dictionary(); + public Logger logger(string context = null) { + if (string.IsNullOrEmpty(context)) { + context = "Default"; + } - // - private Dictionary _loggers = new Dictionary(); - public Logger logger (string context = null) { - if (string.IsNullOrEmpty(context)) { - context = "Default"; - } + if (_loggers.ContainsKey(context)) { + return _loggers[context]; + } - if (_loggers.ContainsKey(context)) { - return _loggers[context]; + Logger newLogger = new Logger(context); + _loggers.Add(context, new Logger(context)); + return newLogger; } - Logger newLogger = new Logger (context); - _loggers.Add (context, new Logger(context)); - return newLogger; - } - - // Avoid putting setup logic in the contstuctor. Only things that can be - // carried between game sessions should go here. Otherwise we need to be - // able to re-initialize them inside the setup function. - public Mage() { - // Setup log writters - _logger = logger("mage"); + // Avoid putting setup logic in the contstuctor. Only things that can be + // carried between game sessions should go here. Otherwise we need to be + // able to re-initialize them inside the setup function. + public Mage() { + // Setup log writters + _logger = logger("mage"); - // TODO: properly check the damn certificate, for now ignore invalid ones (fix issue on Android/iOS) - ServicePointManager.ServerCertificateValidationCallback += (o, cert, chain, errors) => true; - } + // TODO: properly check the damn certificate, for now ignore invalid ones (fix issue on Android/iOS) + ServicePointManager.ServerCertificateValidationCallback += (o, cert, chain, errors) => true; + } - // - public void setEndpoints (string baseUrl, string appName, Dictionary headers = null) { - this.baseUrl = baseUrl; - this.appName = appName; - this.headers = new Dictionary(headers); + // + public void setEndpoints(string baseUrl, string appName, Dictionary headers = null) { + this.baseUrl = baseUrl; + this.appName = appName; + this.headers = new Dictionary(headers); - if (commandCenter != null) { - commandCenter.SetEndpoint(baseUrl, appName, this.headers); - } + if (commandCenter != null) { + commandCenter.SetEndpoint(baseUrl, appName, this.headers); + } - if (messageStream != null) { - messageStream.SetEndpoint(baseUrl, this.headers); + if (messageStream != null) { + messageStream.SetEndpoint(baseUrl, this.headers); + } } - } - // - public void Setup(Action cb) { - // Cleanup any existing internal modules - if (messageStream != null) { - messageStream.Dispose(); - } + // + public void Setup(Action cb) { + // Cleanup any existing internal modules + if (messageStream != null) { + messageStream.Dispose(); + } - // Instantiate Singletons - UnityApplicationState.Instantiate(); - HTTPRequestManager.Instantiate(); + // Instantiate Singletons + UnityApplicationState.Instantiate(); + HTTPRequestManager.Instantiate(); - // Create a shared cookie container - cookies = new CookieContainer(); + // Create a shared cookie container + cookies = new CookieContainer(); - // Initialize mage internal modules - eventManager = new EventManager(); - commandCenter = new CommandCenter(); - messageStream = new MessageStream(); + // Initialize mage internal modules + eventManager = new EventManager(); + commandCenter = new CommandCenter(); + messageStream = new MessageStream(); - session = new Session(); - archivist = new Archivist(); + session = new Session(); + archivist = new Archivist(); - // Set endpoints - commandCenter.SetEndpoint(baseUrl, appName, headers); - messageStream.SetEndpoint(baseUrl, headers); + // Set endpoints + commandCenter.SetEndpoint(baseUrl, appName, headers); + messageStream.SetEndpoint(baseUrl, headers); - cb(null); - } + cb(null); + } - // - public void SetupModules(List moduleNames, Action cb) { - // Setup application modules - _logger.info ("Setting up modules"); - Async.each (moduleNames, (string moduleName, Action callback) => { - _logger.info("Setting up module: " + moduleName); - - // Use reflection to find module by name - Assembly assembly = Assembly.GetExecutingAssembly(); - Type[] assemblyTypes = assembly.GetTypes(); - foreach(Type t in assemblyTypes) { - if (moduleName == t.Name) { - BindingFlags staticProperty = BindingFlags.Static | BindingFlags.GetProperty; - BindingFlags publicMethod = BindingFlags.Public | BindingFlags.InvokeMethod; - - // Grab module instance from singleton base - var singletonType = typeof(Singleton<>).MakeGenericType(t); - Object instance = singletonType.InvokeMember("Instance", staticProperty, null, null, null); - - // Setup module - var moduleType = typeof(Module<>).MakeGenericType(t); - Async.series (new List>>() { + // + public void SetupModules(List moduleNames, Action cb) { + // Setup application modules + _logger.info("Setting up modules"); + Async.each(moduleNames, (string moduleName, Action callback) => { + _logger.info("Setting up module: " + moduleName); + + // Use reflection to find module by name + Assembly assembly = Assembly.GetExecutingAssembly(); + Type[] assemblyTypes = assembly.GetTypes(); + foreach (Type t in assemblyTypes) { + if (moduleName == t.Name) { + BindingFlags staticProperty = BindingFlags.Static | BindingFlags.GetProperty; + BindingFlags publicMethod = BindingFlags.Public | BindingFlags.InvokeMethod; + + // Grab module instance from singleton base + var singletonType = typeof(Singleton<>).MakeGenericType(t); + Object instance = singletonType.InvokeMember("Instance", staticProperty, null, null, null); + + // Setup module + var moduleType = typeof(Module<>).MakeGenericType(t); + Async.series(new List>>() { (Action callbackInner) => { // Setup module user commands object[] arguments = new object[]{callbackInner}; @@ -152,62 +155,63 @@ public void SetupModules(List moduleNames, Action cb) { // Invoke the setup method on the module logger(moduleName).info("Executing setup function"); - object[] arguments = new object[]{callback}; + object[] arguments = new object[] { callback }; t.InvokeMember("Setup", publicMethod, null, instance, arguments); }); + return; + } + } + + // If nothing found throw an error + callback(new Exception("Can't find module " + moduleName)); + }, (Exception error) => { + if (error != null) { + _logger.data(error).error("Setup failed!"); + cb(error); return; } - } - // If nothing found throw an error - callback(new Exception("Can't find module " + moduleName)); - }, (Exception error) => { - if (error != null) { - _logger.data(error).error("Setup failed!"); - cb(error); - return; - } + _logger.info("Setup complete"); + cb(null); + }); + } - _logger.info("Setup complete"); - cb(null); - }); - } + // + public IEnumerator SetupTask(Action cb) { + // Execute async setup function + MageSetupStatus setupStatus = new MageSetupStatus(); + Setup((Exception error) => { + setupStatus.error = error; + setupStatus.done = true; + }); - // - public IEnumerator SetupTask(Action cb) { - // Execute async setup function - MageSetupStatus setupStatus = new MageSetupStatus(); - Setup((Exception error) => { - setupStatus.error = error; - setupStatus.done = true; - }); + // Wait for setup to return + while (!setupStatus.done) { + yield return null; + } - // Wait for setup to return - while (!setupStatus.done) { - yield return null; + // Call callback with error if there is one + cb(setupStatus.error); } - // Call callback with error if there is one - cb (setupStatus.error); - } + // + public IEnumerator SetupModulesTask(List moduleNames, Action cb) { + // Execute async setup function + MageSetupStatus setupStatus = new MageSetupStatus(); + SetupModules(moduleNames, (Exception error) => { + setupStatus.error = error; + setupStatus.done = true; + }); + + // Wait for setup to return + while (!setupStatus.done) { + yield return null; + } - // - public IEnumerator SetupModulesTask(List moduleNames, Action cb) { - // Execute async setup function - MageSetupStatus setupStatus = new MageSetupStatus (); - SetupModules(moduleNames, (Exception error) => { - setupStatus.error = error; - setupStatus.done = true; - }); - - // Wait for setup to return - while (!setupStatus.done) { - yield return null; + // Call callback with error if there is one + cb(setupStatus.error); } - - // Call callback with error if there is one - cb (setupStatus.error); } } diff --git a/Mage/MessageStream/MessageStream.cs b/Mage/MessageStream/MessageStream.cs index 9e6c368..0a67a91 100644 --- a/Mage/MessageStream/MessageStream.cs +++ b/Mage/MessageStream/MessageStream.cs @@ -1,227 +1,236 @@ -using System; +using System; using System.Collections.Generic; using System.Text; using Newtonsoft.Json.Linq; -public class MessageStream { - private Mage mage { get { return Mage.Instance; } } - private Logger logger { get { return mage.logger("messagestream"); } } +using Wizcorp.MageSDK.Log; +using Wizcorp.MageSDK.MageClient.Message.Client; - // Endpoint and credentials - private string endpoint; - Dictionary headers; - private string sessionKey; +#if UNITY_EDITOR +using Wizcorp.MageSDK.Editor; +#endif - // Current transport client - private TransportClient transportClient; +namespace Wizcorp.MageSDK.MageClient.Message { + public class MessageStream { + private Mage mage { get { return Mage.Instance; } } + private Logger logger { get { return mage.logger("messagestream"); } } - // Current message stack - private int currentMessageId; - private int largestMessageId; - private Dictionary messageQueue; - private List confirmIds; + // Endpoint and credentials + private string endpoint; + Dictionary headers; + private string sessionKey; + // Current transport client + private TransportClient transportClient; - // - private void initializeMessageList() { - currentMessageId = -1; - largestMessageId = -1; - messageQueue = new Dictionary(); - confirmIds = new List(); - - logger.debug ("Initialized message queue"); - } + // Current message stack + private int currentMessageId; + private int largestMessageId; + private Dictionary messageQueue; + private List confirmIds; - // Constructor - public MessageStream (TransportType transport = TransportType.LONGPOLLING) { // - initializeMessageList (); - - // Start transport client when session is acquired - mage.eventManager.on ("session.set", (object sender, JToken session) => { - sessionKey = UnityEngine.WWW.EscapeURL(session["key"].ToString()); - transportClient.start(); - }); - - // Stop the message client when session is lost - mage.eventManager.on ("session.unset", (object sender, JToken reason) => { - transportClient.stop(); + private void initializeMessageList() { + currentMessageId = -1; + largestMessageId = -1; + messageQueue = new Dictionary(); + confirmIds = new List(); + + logger.debug("Initialized message queue"); + } + + + // Constructor + public MessageStream(TransportType transport = TransportType.LONGPOLLING) { + // initializeMessageList(); - sessionKey = null; - }); - // Also stop the message client when the application is stopped - #if UNITY_EDITOR - UnityEditorPlayMode.onEditorModeChanged += (EditorPlayModeState newState) => { - if (newState == EditorPlayModeState.Stopped) { + // Start transport client when session is acquired + mage.eventManager.on("session.set", (object sender, JToken session) => { + sessionKey = UnityEngine.WWW.EscapeURL(session["key"].ToString()); + transportClient.start(); + }); + + // Stop the message client when session is lost + mage.eventManager.on("session.unset", (object sender, JToken reason) => { transportClient.stop(); initializeMessageList(); sessionKey = null; - } - if (newState == EditorPlayModeState.Paused && transportClient.running) { - transportClient.stop(); - } - if (newState == EditorPlayModeState.Playing && !transportClient.running && sessionKey != null) { - transportClient.start(); - } - }; - #endif - UnityApplicationState.Instance.onAppStateChanged += (bool pauseStatus) => { - if (pauseStatus && transportClient.running) { - transportClient.stop(); - } - if (!pauseStatus && !transportClient.running && sessionKey != null) { - transportClient.start(); - } - }; - - // Set the selected transport client (or the default) - this.SetTransport(transport); - } - + }); + + // Also stop the message client when the application is stopped +#if UNITY_EDITOR + UnityEditorPlayMode.onEditorModeChanged += (EditorPlayModeState newState) => { + if (newState == EditorPlayModeState.Stopped) { + transportClient.stop(); + initializeMessageList(); + sessionKey = null; + } + if (newState == EditorPlayModeState.Paused && transportClient.running) { + transportClient.stop(); + } + if (newState == EditorPlayModeState.Playing && !transportClient.running && sessionKey != null) { + transportClient.start(); + } + }; +#endif + UnityApplicationState.Instance.onAppStateChanged += (bool pauseStatus) => { + if (pauseStatus && transportClient.running) { + transportClient.stop(); + } + if (!pauseStatus && !transportClient.running && sessionKey != null) { + transportClient.start(); + } + }; - // - public void Dispose() { - // Stop the transport client if it exists - if (transportClient != null) { - transportClient.stop (); + // Set the selected transport client (or the default) + this.SetTransport(transport); } - initializeMessageList(); - sessionKey = null; - } + // + public void Dispose() { + // Stop the transport client if it exists + if (transportClient != null) { + transportClient.stop(); + } - // Updates URI and credentials - public void SetEndpoint(string baseURL, Dictionary headers = null) { - this.endpoint = baseURL + "/msgstream"; - this.headers = headers; - } + initializeMessageList(); + sessionKey = null; + } - // Sets up given transport client type - public void SetTransport(TransportType transport) { - // Stop existing transport client if any, when nulled out it will be collected - // by garbage collecter after existing connections have been terminated. - if (transportClient != null) { - transportClient.stop (); - transportClient = null; + // Updates URI and credentials + public void SetEndpoint(string baseURL, Dictionary headers = null) { + this.endpoint = baseURL + "/msgstream"; + this.headers = headers; } - // Create new transport client instance - if (transport == TransportType.SHORTPOLLING) { - Func getShortPollingEndpoint = () => { - return getHttpPollingEndpoint ("shortpolling"); - }; - transportClient = new ShortPolling(getShortPollingEndpoint, getHttpHeaders, processMessagesString, 5000) as TransportClient; - } else if (transport == TransportType.LONGPOLLING) { - Func getLongPollingEndpoint = () => { - return getHttpPollingEndpoint("longpolling"); - }; + // Sets up given transport client type + public void SetTransport(TransportType transport) { + // Stop existing transport client if any, when nulled out it will be collected + // by garbage collecter after existing connections have been terminated. + if (transportClient != null) { + transportClient.stop(); + transportClient = null; + } - transportClient = new LongPolling(getLongPollingEndpoint, getHttpHeaders, processMessagesString) as TransportClient; - } else { - throw new Exception("Invalid transport type: " + transport); + // Create new transport client instance + if (transport == TransportType.SHORTPOLLING) { + Func getShortPollingEndpoint = () => { + return getHttpPollingEndpoint("shortpolling"); + }; + + transportClient = new ShortPolling(getShortPollingEndpoint, getHttpHeaders, processMessagesString, 5000) as TransportClient; + } else if (transport == TransportType.LONGPOLLING) { + Func getLongPollingEndpoint = () => { + return getHttpPollingEndpoint("longpolling"); + }; + + transportClient = new LongPolling(getLongPollingEndpoint, getHttpHeaders, processMessagesString) as TransportClient; + } else { + throw new Exception("Invalid transport type: " + transport); + } } - } - // Returns the endpoint URL for polling transport clients i.e. longpolling and shortpolling - private string getHttpPollingEndpoint(string transport) { - string endpoint = this.endpoint + "?transport=" + transport + "&sessionKey=" + sessionKey; - if (confirmIds.Count > 0) { - endpoint += "&confirmIds=" + string.Join(",", confirmIds.ToArray()); - confirmIds.Clear(); + // Returns the endpoint URL for polling transport clients i.e. longpolling and shortpolling + private string getHttpPollingEndpoint(string transport) { + string endpoint = this.endpoint + "?transport=" + transport + "&sessionKey=" + sessionKey; + if (confirmIds.Count > 0) { + endpoint += "&confirmIds=" + string.Join(",", confirmIds.ToArray()); + confirmIds.Clear(); + } + + return endpoint; } - - return endpoint; - } - - - // Returns the required HTTP headers - private Dictionary getHttpHeaders() { - return headers; - } - // Deserilizes and processes given messagesString - private void processMessagesString(string messagesString) { - if (messagesString == "" || messagesString == null) { - return; + // Returns the required HTTP headers + private Dictionary getHttpHeaders() { + return headers; } - JObject messages = JObject.Parse(messagesString); - addMessages(messages); - processMessages(); - } + // Deserilizes and processes given messagesString + private void processMessagesString(string messagesString) { + if (messagesString == "" || messagesString == null) { + return; + } - // Add list of messages to message queue - private void addMessages(JObject messages) { - if (messages == null) { - return; + JObject messages = JObject.Parse(messagesString); + addMessages(messages); + processMessages(); } - int lowestMessageId = -1; - foreach (var message in messages) { - // Check if the messageId is lower than our current messageId - int messageId = int.Parse(message.Key); - if (messageId == 0) { - messageQueue.Add(messageId, message.Value); - continue; - } - if (messageId < currentMessageId) { - continue; + // Add list of messages to message queue + private void addMessages(JObject messages) { + if (messages == null) { + return; } - - // Keep track of the largest messageId in the list - if (messageId > largestMessageId) { - largestMessageId = messageId; - } - - // Keep track of the lowest messageId in the list - if (lowestMessageId == -1 || messageId < lowestMessageId) { - lowestMessageId = messageId; + + int lowestMessageId = -1; + + foreach (var message in messages) { + // Check if the messageId is lower than our current messageId + int messageId = int.Parse(message.Key); + if (messageId == 0) { + messageQueue.Add(messageId, message.Value); + continue; + } + if (messageId < currentMessageId) { + continue; + } + + // Keep track of the largest messageId in the list + if (messageId > largestMessageId) { + largestMessageId = messageId; + } + + // Keep track of the lowest messageId in the list + if (lowestMessageId == -1 || messageId < lowestMessageId) { + lowestMessageId = messageId; + } + + // Check if the message exists in the queue, if not add it + if (!messageQueue.ContainsKey(messageId)) { + messageQueue.Add(messageId, message.Value); + } } - - // Check if the message exists in the queue, if not add it - if (!messageQueue.ContainsKey(messageId)) { - messageQueue.Add(messageId, message.Value); + + // If the current messageId has never been set, set it to the current lowest + if (currentMessageId == -1) { + currentMessageId = lowestMessageId; } } - - // If the current messageId has never been set, set it to the current lowest - if (currentMessageId == -1) { - currentMessageId = lowestMessageId; - } - } - // Process the message queue till we reach the end or a gap - private void processMessages() { - // Process all ordered messages in the order they appear - while (currentMessageId <= largestMessageId) { - // Check if the next messageId exists - if (!messageQueue.ContainsKey(currentMessageId)) { - break; - } + // Process the message queue till we reach the end or a gap + private void processMessages() { + // Process all ordered messages in the order they appear + while (currentMessageId <= largestMessageId) { + // Check if the next messageId exists + if (!messageQueue.ContainsKey(currentMessageId)) { + break; + } - // Process the message - mage.eventManager.emitEventList((JArray)messageQueue[currentMessageId]); - confirmIds.Add(currentMessageId.ToString()); - messageQueue.Remove(currentMessageId); + // Process the message + mage.eventManager.emitEventList((JArray)messageQueue[currentMessageId]); + confirmIds.Add(currentMessageId.ToString()); + messageQueue.Remove(currentMessageId); - currentMessageId += 1; - } + currentMessageId += 1; + } - // Finally emit any events that don't have an ID and thus don't need confirmation and lack order - if (messageQueue.ContainsKey(0)) { - mage.eventManager.emitEventList((JArray)messageQueue[0]); - messageQueue.Remove(0); + // Finally emit any events that don't have an ID and thus don't need confirmation and lack order + if (messageQueue.ContainsKey(0)) { + mage.eventManager.emitEventList((JArray)messageQueue[0]); + messageQueue.Remove(0); + } } } } diff --git a/Mage/MessageStream/TransportClient/LongPolling.cs b/Mage/MessageStream/TransportClient/LongPolling.cs index b6d014d..51a2b0e 100644 --- a/Mage/MessageStream/TransportClient/LongPolling.cs +++ b/Mage/MessageStream/TransportClient/LongPolling.cs @@ -1,130 +1,133 @@ -using System; -using System.Collections; +using System; using System.Collections.Generic; using System.Threading; -using System.Net; -public class LongPolling : TransportClient { - private Mage mage { get { return Mage.Instance; } } - private Logger logger { get { return mage.logger("longpolling"); } } +using Wizcorp.MageSDK.Log; +using Wizcorp.MageSDK.Network.Http; - // Required functions for poll requests - private Func _getEndpoint; - private Func> _getHeaders; - private Action _processMessages; +namespace Wizcorp.MageSDK.MageClient.Message.Client { + public class LongPolling : TransportClient { + private Mage mage { get { return Mage.Instance; } } + private Logger logger { get { return mage.logger("longpolling"); } } - // - HTTPRequest _currentRequest; + // Required functions for poll requests + private Func _getEndpoint; + private Func> _getHeaders; + private Action _processMessages; - // Required interval timer for polling delay - private int _errorInterval; - private Timer _intervalTimer; + // + HTTPRequest _currentRequest; - - // Constructor - public LongPolling(Func getEndpointFn, Func> getHeadersFn, Action processMessagesFn, int errorInterval = 5000) { - _getEndpoint = getEndpointFn; - _getHeaders = getHeadersFn; - _processMessages = processMessagesFn; - _errorInterval = errorInterval; - } + // Required interval timer for polling delay + private int _errorInterval; + private Timer _intervalTimer; - // Starts the poller - public override void start() { - if (_running == true) { - return; + // Constructor + public LongPolling(Func getEndpointFn, Func> getHeadersFn, Action processMessagesFn, int errorInterval = 5000) { + _getEndpoint = getEndpointFn; + _getHeaders = getHeadersFn; + _processMessages = processMessagesFn; + _errorInterval = errorInterval; } - logger.debug("Starting"); - _running = true; - requestLoop (); - } - - // Stops the poller - public override void stop() { - _running = false; - logger.debug("Stopping..."); - - if (_intervalTimer != null) { - _intervalTimer.Dispose(); - _intervalTimer = null; - } else { - logger.debug("Timer Stopped"); - } + // Starts the poller + public override void start() { + if (_running == true) { + return; + } - if (_currentRequest != null) { - _currentRequest.Abort(); - _currentRequest = null; - } else { - logger.debug("Connections Stopped"); + logger.debug("Starting"); + _running = true; + requestLoop(); } - } - // Queues the next poll request - private void queueNextRequest(int waitFor) { - // Wait _requestInterval milliseconds till next poll - _intervalTimer = new Timer((object state) => { - requestLoop(); - }, null, waitFor, Timeout.Infinite); - } + // Stops the poller + public override void stop() { + _running = false; + logger.debug("Stopping..."); + if (_intervalTimer != null) { + _intervalTimer.Dispose(); + _intervalTimer = null; + } else { + logger.debug("Timer Stopped"); + } - // Poller request function - private void requestLoop() { - // Clear the timer - if (_intervalTimer != null) { - _intervalTimer.Dispose(); - _intervalTimer = null; + if (_currentRequest != null) { + _currentRequest.Abort(); + _currentRequest = null; + } else { + logger.debug("Connections Stopped"); + } } - // Check if the poller should be running - if (_running == false) { - logger.debug("Stopped"); - return; + + // Queues the next poll request + private void queueNextRequest(int waitFor) { + // Wait _requestInterval milliseconds till next poll + _intervalTimer = new Timer((object state) => { + requestLoop(); + }, null, waitFor, Timeout.Infinite); } - // Send poll request and wait for a response - string endpoint = _getEndpoint(); - logger.debug("Sending request: " + endpoint); - _currentRequest = HTTPRequest.Get(endpoint, _getHeaders(), mage.cookies, (Exception requestError, string responseString) => { - _currentRequest = null; - // Ignore errors if we have been stopped - if (requestError != null && !_running) { + // Poller request function + private void requestLoop() { + // Clear the timer + if (_intervalTimer != null) { + _intervalTimer.Dispose(); + _intervalTimer = null; + } + + // Check if the poller should be running + if (_running == false) { logger.debug("Stopped"); return; } - if (requestError != null) { - if (requestError is HTTPRequestException) { - // Only log web exceptions if they aren't an empty response or gateway timeout - HTTPRequestException requestException = requestError as HTTPRequestException; - if (requestException.Status != 0 && requestException.Status != 504) { - logger.error("(" + requestException.Status.ToString() + ") " + requestError.Message); - } - } else { - logger.error(requestError.ToString()); + // Send poll request and wait for a response + string endpoint = _getEndpoint(); + logger.debug("Sending request: " + endpoint); + _currentRequest = HTTPRequest.Get(endpoint, _getHeaders(), mage.cookies, (Exception requestError, string responseString) => { + _currentRequest = null; + + // Ignore errors if we have been stopped + if (requestError != null && !_running) { + logger.debug("Stopped"); + return; } - queueNextRequest(_errorInterval); - return; - } + if (requestError != null) { + if (requestError is HTTPRequestException) { + // Only log web exceptions if they aren't an empty response or gateway timeout + HTTPRequestException requestException = requestError as HTTPRequestException; + if (requestException.Status != 0 && requestException.Status != 504) { + logger.error("(" + requestException.Status.ToString() + ") " + requestError.Message); + } + } else { + logger.error(requestError.ToString()); + } - // Call the message processer hook and re-call request loop function - try { - logger.verbose("Recieved response: " + responseString); - if (responseString != null) { - _processMessages(responseString); + queueNextRequest(_errorInterval); + return; } - requestLoop(); - } catch (Exception error) { - logger.error (error.ToString()); - queueNextRequest(_errorInterval); - } - }); + // Call the message processer hook and re-call request loop function + try { + logger.verbose("Recieved response: " + responseString); + if (responseString != null) { + _processMessages(responseString); + } + + requestLoop(); + } catch (Exception error) { + logger.error(error.ToString()); + queueNextRequest(_errorInterval); + } + }); + } } } diff --git a/Mage/MessageStream/TransportClient/ShortPolling.cs b/Mage/MessageStream/TransportClient/ShortPolling.cs index 826d1a0..346551e 100644 --- a/Mage/MessageStream/TransportClient/ShortPolling.cs +++ b/Mage/MessageStream/TransportClient/ShortPolling.cs @@ -1,102 +1,107 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Threading; -public class ShortPolling : TransportClient { - private Mage mage { get { return Mage.Instance; } } - private Logger logger { get { return mage.logger("shortpolling"); } } - - // Whether or not the poller is working - private bool _running = false; - - // Required functions for poll requests - private Func _getEndpoint; - private Func> _getHeaders; - private Action _processMessages; - - // Required interval timer for polling delay - private int _requestInterval; - private int _errorInterval; - private Timer _intervalTimer; - - - // Constructor - public ShortPolling(Func getEndpointFn, Func> getHeadersFn, Action processMessagesFn, int requestInterval = 5000, int errorInterval = 5000) { - _getEndpoint = getEndpointFn; - _getHeaders = getHeadersFn; - _processMessages = processMessagesFn; - _requestInterval = requestInterval; - _errorInterval = errorInterval; - } - - - // Starts the poller - public override void start() { - if (_running == true) { - return; - } - - logger.debug ("Starting"); - _running = true; - requestLoop (); - } - - - // Stops the poller - public override void stop() { - if (_intervalTimer != null) { - _intervalTimer.Dispose(); - _intervalTimer = null; - logger.debug ("Stopped"); - } else { - logger.debug ("Stopping..."); +using Wizcorp.MageSDK.Log; +using Wizcorp.MageSDK.Network.Http; + +namespace Wizcorp.MageSDK.MageClient.Message.Client { + public class ShortPolling : TransportClient { + private Mage mage { get { return Mage.Instance; } } + private Logger logger { get { return mage.logger("shortpolling"); } } + + // Whether or not the poller is working + private bool _running = false; + + // Required functions for poll requests + private Func _getEndpoint; + private Func> _getHeaders; + private Action _processMessages; + + // Required interval timer for polling delay + private int _requestInterval; + private int _errorInterval; + private Timer _intervalTimer; + + + // Constructor + public ShortPolling(Func getEndpointFn, Func> getHeadersFn, Action processMessagesFn, int requestInterval = 5000, int errorInterval = 5000) { + _getEndpoint = getEndpointFn; + _getHeaders = getHeadersFn; + _processMessages = processMessagesFn; + _requestInterval = requestInterval; + _errorInterval = errorInterval; } - _running = false; - } - // Queues the next poll request - private void queueNextRequest(int waitFor) { - // Wait _requestInterval milliseconds till next poll - _intervalTimer = new Timer((object state) => { + // Starts the poller + public override void start() { + if (_running == true) { + return; + } + + logger.debug("Starting"); + _running = true; requestLoop(); - }, null, waitFor, Timeout.Infinite); - } - - - // Poller request function - private void requestLoop() { - // Clear the timer - if (_intervalTimer != null) { - _intervalTimer.Dispose(); - _intervalTimer = null; } - // Check if the poller should be running - if (_running == false) { - logger.debug ("Stopped"); - return; + + // Stops the poller + public override void stop() { + if (_intervalTimer != null) { + _intervalTimer.Dispose(); + _intervalTimer = null; + logger.debug("Stopped"); + } else { + logger.debug("Stopping..."); + } + _running = false; } - - // Send poll request and wait for a response - string endpoint = _getEndpoint(); - logger.debug ("Sending request: " + endpoint); - HTTPRequest.Get(endpoint, _getHeaders(), mage.cookies, (Exception requestError, string responseString) => { - if (requestError != null) { - logger.error (requestError.ToString()); - queueNextRequest(_errorInterval); - return; + + + // Queues the next poll request + private void queueNextRequest(int waitFor) { + // Wait _requestInterval milliseconds till next poll + _intervalTimer = new Timer((object state) => { + requestLoop(); + }, null, waitFor, Timeout.Infinite); + } + + + // Poller request function + private void requestLoop() { + // Clear the timer + if (_intervalTimer != null) { + _intervalTimer.Dispose(); + _intervalTimer = null; } - - // Call the message processer hook and queue the next request - try { - _processMessages(responseString); - queueNextRequest(_requestInterval); - } catch (Exception error) { - logger.data(responseString).error (error.ToString()); - queueNextRequest(_errorInterval); + + // Check if the poller should be running + if (_running == false) { + logger.debug("Stopped"); + return; } - }); + + // Send poll request and wait for a response + string endpoint = _getEndpoint(); + logger.debug("Sending request: " + endpoint); + HTTPRequest.Get(endpoint, _getHeaders(), mage.cookies, (Exception requestError, string responseString) => { + if (requestError != null) { + logger.error(requestError.ToString()); + queueNextRequest(_errorInterval); + return; + } + + // Call the message processer hook and queue the next request + try { + _processMessages(responseString); + queueNextRequest(_requestInterval); + } catch (Exception error) { + logger.data(responseString).error(error.ToString()); + queueNextRequest(_errorInterval); + } + }); + } } } diff --git a/Mage/MessageStream/TransportClient/TransportClient.cs b/Mage/MessageStream/TransportClient/TransportClient.cs index dc73298..9ba9c96 100644 --- a/Mage/MessageStream/TransportClient/TransportClient.cs +++ b/Mage/MessageStream/TransportClient/TransportClient.cs @@ -1,14 +1,16 @@ -using System; +using System; -public enum TransportType { - SHORTPOLLING, - LONGPOLLING -} +namespace Wizcorp.MageSDK.MageClient.Message.Client { + public enum TransportType { + SHORTPOLLING, + LONGPOLLING + } -public abstract class TransportClient { - protected bool _running; - public bool running { get { return _running; }} + public abstract class TransportClient { + protected bool _running; + public bool running { get { return _running; } } - public abstract void stop (); - public abstract void start(); + public abstract void stop(); + public abstract void start(); + } } diff --git a/Mage/Module.cs b/Mage/Module.cs index d6eacf4..0e29be0 100644 --- a/Mage/Module.cs +++ b/Mage/Module.cs @@ -1,109 +1,113 @@ -using System; +using System; using System.Collections.Generic; using Newtonsoft.Json.Linq; +using Wizcorp.MageSDK.Log; +using Wizcorp.MageSDK.Utils; -public class UsercommandStatus { - public bool done = false; - public Exception error = null; - public JToken result = null; -} +namespace Wizcorp.MageSDK.MageClient { + public class UsercommandStatus { + public bool done = false; + public Exception error = null; + public JToken result = null; + } -public class Module : Singleton where T : class, new() { - // - protected Mage mage { get { return Mage.Instance; } } - protected Logger logger { get { return mage.logger(this.GetType().Name); } } + public class Module : Singleton where T : class, new() { + // + protected Mage mage { get { return Mage.Instance; } } + protected Logger logger { get { return mage.logger(this.GetType().Name); } } - // - protected virtual List staticTopics { get { return null; } } - public JToken staticData; - public void setupStaticData (Action cb) { - logger.info ("Setting up static data"); + // + protected virtual List staticTopics { get { return null; } } + public JToken staticData; + public void setupStaticData(Action cb) { + logger.info("Setting up static data"); - if (staticTopics == null) { - cb(null); - return; - } + if (staticTopics == null) { + cb(null); + return; + } + + JObject queries = new JObject(); + for (int i = 0; i < staticTopics.Count; i++) { + string topic = staticTopics[i]; - JObject queries = new JObject(); - for (int i = 0; i < staticTopics.Count; i++) { - string topic = staticTopics[i]; + JObject query = new JObject(); + query.Add("topic", new JValue(topic)); + query.Add("index", new JObject()); + queries.Add(topic, query); + } - JObject query = new JObject(); - query.Add("topic", new JValue(topic)); - query.Add("index", new JObject()); - queries.Add(topic, query); + staticData = null; + mage.archivist.mget(queries, null, (Exception error, JToken data) => { + if (error != null) { + cb(error); + return; + } + + staticData = data; + cb(null); + }); } - staticData = null; - mage.archivist.mget (queries, null, (Exception error, JToken data)=>{ - if (error != null) { - cb(error); - return; - } - staticData = data; - cb(null); - }); - } + // + protected virtual string commandPrefix { get { return null; } } + protected virtual List commands { get { return null; } } + private Dictionary>> commandHandlerActions; + private Dictionary> commandHandlerFuncs; + public void command(string commandName, JObject arguments, Action cb) { + commandHandlerActions[commandName](arguments, cb); + } - // - protected virtual string commandPrefix { get { return null; } } - protected virtual List commands { get { return null; } } - private Dictionary>> commandHandlerActions; - private Dictionary> commandHandlerFuncs; - - public void command(string commandName, JObject arguments, Action cb) { - commandHandlerActions[commandName](arguments, cb); - } - - public UsercommandStatus command(string commandName, JObject arguments) { - return commandHandlerFuncs[commandName](arguments); - } + public UsercommandStatus command(string commandName, JObject arguments) { + return commandHandlerFuncs[commandName](arguments); + } - private void registerCommand(string command) { - commandHandlerActions.Add(command, (JObject arguments, Action commandCb) => { - mage.commandCenter.SendCommand(commandPrefix + "." + command, arguments, (Exception error, JToken result) => { - try { - commandCb(error, result); - } catch (Exception callbackError) { - logger.data(callbackError).critical("Uncaught exception:"); - } + private void registerCommand(string command) { + commandHandlerActions.Add(command, (JObject arguments, Action commandCb) => { + mage.commandCenter.SendCommand(commandPrefix + "." + command, arguments, (Exception error, JToken result) => { + try { + commandCb(error, result); + } catch (Exception callbackError) { + logger.data(callbackError).critical("Uncaught exception:"); + } + }); }); - }); - - commandHandlerFuncs.Add(command, (JObject arguments) => { - UsercommandStatus commandStatus = new UsercommandStatus(); - - mage.commandCenter.SendCommand(commandPrefix + "." + command, arguments, (Exception error, JToken result) => { - commandStatus.error = error; - commandStatus.result = result; - commandStatus.done = true; + + commandHandlerFuncs.Add(command, (JObject arguments) => { + UsercommandStatus commandStatus = new UsercommandStatus(); + + mage.commandCenter.SendCommand(commandPrefix + "." + command, arguments, (Exception error, JToken result) => { + commandStatus.error = error; + commandStatus.result = result; + commandStatus.done = true; + }); + + return commandStatus; }); - - return commandStatus; - }); - } - - public void setupUsercommands (Action cb) { - logger.info ("Setting up usercommands"); - - commandHandlerActions = new Dictionary>>(); - commandHandlerFuncs = new Dictionary>(); - - if (commands == null) { - cb(null); - return; } - foreach (string command in commands) { - registerCommand(command); + public void setupUsercommands(Action cb) { + logger.info("Setting up usercommands"); + + commandHandlerActions = new Dictionary>>(); + commandHandlerFuncs = new Dictionary>(); + + if (commands == null) { + cb(null); + return; + } + + foreach (string command in commands) { + registerCommand(command); + } + + cb(null); } - - cb(null); } } diff --git a/Mage/Session.cs b/Mage/Session.cs index 2913926..12d3774 100644 --- a/Mage/Session.cs +++ b/Mage/Session.cs @@ -2,43 +2,45 @@ using Newtonsoft.Json.Linq; -public class Session { - private Mage mage { get { return Mage.Instance; }} - - // - private string sessionKey; - private string actorId; - - // - public Session () { - mage.eventManager.on ("session.set", (object sender, JToken session) => { - actorId = session["actorId"].ToString(); - sessionKey = session["key"].ToString(); - }); - - mage.eventManager.on ("session.unset", (object sender, JToken reason) => { - actorId = null; - sessionKey = null; - }); - - mage.commandCenter.preSerialiseHook += (CommandBatch commandBatch) => { - if (!string.IsNullOrEmpty(sessionKey)) { - Dictionary sessionHeader = new Dictionary(); - sessionHeader.Add("name", "mage.session"); - sessionHeader.Add("key", sessionKey); - - commandBatch.batchHeaders.Add(sessionHeader); - } - }; - } - - // - public string GetSessionKey() { - return sessionKey; - } - - // - public string GetActorId() { - return actorId; +namespace Wizcorp.MageSDK.MageClient { + public class Session { + private Mage mage { get { return Mage.Instance; } } + + // + private string sessionKey; + private string actorId; + + // + public Session() { + mage.eventManager.on("session.set", (object sender, JToken session) => { + actorId = session["actorId"].ToString(); + sessionKey = session["key"].ToString(); + }); + + mage.eventManager.on("session.unset", (object sender, JToken reason) => { + actorId = null; + sessionKey = null; + }); + + mage.commandCenter.preSerialiseHook += (CommandBatch commandBatch) => { + if (!string.IsNullOrEmpty(sessionKey)) { + Dictionary sessionHeader = new Dictionary(); + sessionHeader.Add("name", "mage.session"); + sessionHeader.Add("key", sessionKey); + + commandBatch.batchHeaders.Add(sessionHeader); + } + }; + } + + // + public string GetSessionKey() { + return sessionKey; + } + + // + public string GetActorId() { + return actorId; + } } } diff --git a/Singleton/MonoSingleton.cs b/Singleton/MonoSingleton.cs index 1c26c28..ec841f1 100644 --- a/Singleton/MonoSingleton.cs +++ b/Singleton/MonoSingleton.cs @@ -1,38 +1,40 @@ -using UnityEngine; +using UnityEngine; -public class MonoSingleton : MonoBehaviour where T : MonoBehaviour { - // Instance functions - protected static T _Instance; - public static T Instance { - get { - if (_Instance == null) { - Instantiate(); - } +namespace Wizcorp.MageSDK.Utils { + public class MonoSingleton : MonoBehaviour where T : MonoBehaviour { + // Instance functions + protected static T _Instance; + public static T Instance { + get { + if (_Instance == null) { + Instantiate(); + } - return _Instance; - } - } - - // Instantiation function if you need to pre-instantiate rather than on demand - public static void Instantiate() { - if (_Instance != null) { - return; + return _Instance; + } } - GameObject newObject = new GameObject(typeof(T).Name); - GameObject.DontDestroyOnLoad(newObject); + // Instantiation function if you need to pre-instantiate rather than on demand + public static void Instantiate() { + if (_Instance != null) { + return; + } - _Instance = newObject.AddComponent(); - } + GameObject newObject = new GameObject(typeof(T).Name); + GameObject.DontDestroyOnLoad(newObject); - // Use this for initialization before any start methods are called - protected virtual void Awake() { - if (_Instance != null) { - GameObject.DestroyImmediate(gameObject); - return; + _Instance = newObject.AddComponent(); } - _Instance = (T)(object)this; - GameObject.DontDestroyOnLoad(gameObject); + // Use this for initialization before any start methods are called + protected virtual void Awake() { + if (_Instance != null) { + GameObject.DestroyImmediate(gameObject); + return; + } + + _Instance = (T)(object)this; + GameObject.DontDestroyOnLoad(gameObject); + } } } diff --git a/Singleton/SceneInstance.cs b/Singleton/SceneInstance.cs index 2148080..1e62c99 100644 --- a/Singleton/SceneInstance.cs +++ b/Singleton/SceneInstance.cs @@ -1,17 +1,19 @@ -using UnityEngine; +using UnityEngine; -public class SceneInstance : MonoBehaviour where T : class { - // - protected static T _Instance = null; - public static T Instance { get { return _Instance; } } +namespace Wizcorp.MageSDK.Utils { + public class SceneInstance : MonoBehaviour where T : class { + // + protected static T _Instance = null; + public static T Instance { get { return _Instance; } } - // Use this for initialization before any start methods are called - protected virtual void Awake () { - _Instance = (T)(object)this; - } + // Use this for initialization before any start methods are called + protected virtual void Awake() { + _Instance = (T)(object)this; + } - // Use this for destruction - protected virtual void OnDestroy() { - _Instance = null; + // Use this for destruction + protected virtual void OnDestroy() { + _Instance = null; + } } } diff --git a/Singleton/Singleton.cs b/Singleton/Singleton.cs index 0634e8a..2bae7c4 100644 --- a/Singleton/Singleton.cs +++ b/Singleton/Singleton.cs @@ -1,20 +1,22 @@ -using UnityEngine; +using UnityEngine; -public class Singleton where T : class, new() { - // Instance functions - private static T _Instance; - public static T Instance { - get { - if (_Instance == null) { - _Instance = new T(); +namespace Wizcorp.MageSDK.Utils { + public class Singleton where T : class, new() { + // Instance functions + private static T _Instance; + public static T Instance { + get { + if (_Instance == null) { + _Instance = new T(); + } + + return _Instance; } - - return _Instance; } - } - // Hack which makes sure the _instance property is set during the T class constructor - public Singleton () { - _Instance = (T)(object)this; + // Hack which makes sure the _instance property is set during the T class constructor + public Singleton() { + _Instance = (T)(object)this; + } } } diff --git a/Tomes/Tome.cs b/Tomes/Tome.cs index 812d1e3..16007ea 100644 --- a/Tomes/Tome.cs +++ b/Tomes/Tome.cs @@ -1,128 +1,131 @@ -using System; +using System; using System.Collections.Generic; + using Newtonsoft.Json.Linq; -public class Tome { - public delegate void OnChanged(JToken oldValue); - public delegate void OnDestroy(); - public delegate void OnAdd(JToken key); - public delegate void OnDel(JToken key); - - // - public static JToken Conjure(JToken data, JToken root = null) { - switch (data.Type) { - case JTokenType.Array: - return new TomeArray((JArray)data, root); - case JTokenType.Object: - return new TomeObject((JObject)data, root); - default: - return new TomeValue((JValue)data, root); - } - } +namespace Wizcorp.MageSDK.Tomes { + public class Tome { + public delegate void OnChanged(JToken oldValue); + public delegate void OnDestroy(); + public delegate void OnAdd(JToken key); + public delegate void OnDel(JToken key); - // - public static void Destroy(JToken data) { - switch (data.Type) { - case JTokenType.Array: - (data as TomeArray).Destroy(); - break; - case JTokenType.Object: - (data as TomeObject).Destroy(); - break; - default: - (data as TomeValue).Destroy(); - break; + // + public static JToken Conjure(JToken data, JToken root = null) { + switch (data.Type) { + case JTokenType.Array: + return new TomeArray((JArray)data, root); + case JTokenType.Object: + return new TomeObject((JObject)data, root); + default: + return new TomeValue((JValue)data, root); + } } - } - // - public static JToken PathValue(JToken value, JArray paths) { - foreach (JToken path in paths) { - value = PathValue(value, path); + // + public static void Destroy(JToken data) { + switch (data.Type) { + case JTokenType.Array: + (data as TomeArray).Destroy(); + break; + case JTokenType.Object: + (data as TomeObject).Destroy(); + break; + default: + (data as TomeValue).Destroy(); + break; + } } - return value; - } - - // - public static JToken PathValue(JToken value, List paths) { - foreach (string path in paths) { - value = PathValue(value, path); - } - - return value; - } + // + public static JToken PathValue(JToken value, JArray paths) { + foreach (JToken path in paths) { + value = PathValue(value, path); + } - // - public static JToken PathValue(JToken value, JToken key) { - if (value.Type == JTokenType.Array) { - return value[(int)key]; + return value; } - - return value[(string)key]; - } - - // - public static JToken PathValue(JToken value, string key) { - if (value.Type == JTokenType.Array) { - return value[int.Parse(key)]; - } - - return value[key]; - } - // - public static void EmitParentChange(JToken parent) { - switch (parent.Type) { - case JTokenType.Array: - TomeArray parentArray = parent as TomeArray; - if (parentArray.onChanged != null) { - parentArray.onChanged.Invoke(null); + // + public static JToken PathValue(JToken value, List paths) { + foreach (string path in paths) { + value = PathValue(value, path); } - break; - case JTokenType.Object: - TomeObject parentObject = parent as TomeObject; - if (parentObject.onChanged != null) { - parentObject.onChanged.Invoke(null); + + return value; + } + + // + public static JToken PathValue(JToken value, JToken key) { + if (value.Type == JTokenType.Array) { + return value[(int)key]; } - break; - case JTokenType.Property: - EmitParentChange(parent.Parent); - break; - default: - throw new Exception(parent.Type.ToString() + " cannot be a parent!"); + + return value[(string)key]; } - } - // - public static void ApplyDiff(JToken root, JArray operations) { - foreach (JObject operation in operations) { - try { - JToken value = PathValue(root, (JArray)operation["chain"]); - - string op = operation["op"].ToString(); - JToken val = operation["val"]; + // + public static JToken PathValue(JToken value, string key) { + if (value.Type == JTokenType.Array) { + return value[int.Parse(key)]; + } + + return value[key]; + } - switch (value.Type) { + // + public static void EmitParentChange(JToken parent) { + switch (parent.Type) { case JTokenType.Array: - (value as TomeArray).ApplyOperation(op, val, root); + TomeArray parentArray = parent as TomeArray; + if (parentArray.onChanged != null) { + parentArray.onChanged.Invoke(null); + } break; case JTokenType.Object: - (value as TomeObject).ApplyOperation(op, val, root); + TomeObject parentObject = parent as TomeObject; + if (parentObject.onChanged != null) { + parentObject.onChanged.Invoke(null); + } break; - default: - (value as TomeValue).ApplyOperation(op, val); + case JTokenType.Property: + EmitParentChange(parent.Parent); break; + default: + throw new Exception(parent.Type.ToString() + " cannot be a parent!"); + } + } + + // + public static void ApplyDiff(JToken root, JArray operations) { + foreach (JObject operation in operations) { + try { + JToken value = PathValue(root, (JArray)operation["chain"]); + + string op = operation["op"].ToString(); + JToken val = operation["val"]; + + switch (value.Type) { + case JTokenType.Array: + (value as TomeArray).ApplyOperation(op, val, root); + break; + case JTokenType.Object: + (value as TomeObject).ApplyOperation(op, val, root); + break; + default: + (value as TomeValue).ApplyOperation(op, val); + break; + } + } catch (Exception diffError) { + // TODO: NEED TO DECIDE IF TOMES SHOULD BE STANDALONE OR INSIDE MAGE. + // e.g. should it depend on mage.logger or UnityEngine.Debug for logging? + UnityEngine.Debug.LogError("Failed to apply diff operation:"); + UnityEngine.Debug.LogError(operation); + UnityEngine.Debug.LogError(diffError); + UnityEngine.Debug.LogError(root); + UnityEngine.Debug.LogError(PathValue(root, (JArray)operation["chain"])); + throw diffError; } - } catch (Exception diffError) { - // TODO: NEED TO DECIDE IF TOMES SHOULD BE STANDALONE OR INSIDE MAGE. - // e.g. should it depend on mage.logger or UnityEngine.Debug for logging? - UnityEngine.Debug.LogError("Failed to apply diff operation:"); - UnityEngine.Debug.LogError(operation); - UnityEngine.Debug.LogError(diffError); - UnityEngine.Debug.LogError(root); - UnityEngine.Debug.LogError(PathValue(root, (JArray)operation["chain"])); - throw diffError; } } } diff --git a/Tomes/TomeArray.cs b/Tomes/TomeArray.cs index 11f91b8..feac101 100644 --- a/Tomes/TomeArray.cs +++ b/Tomes/TomeArray.cs @@ -1,431 +1,436 @@ -using System; +using System; + using Newtonsoft.Json.Linq; -public class TomeArray : JArray { - // - public Tome.OnChanged onChanged; - public Tome.OnDestroy onDestroy; - public Tome.OnAdd onAdd; - public Tome.OnDel onDel; - - // - private JToken root; +using Wizcorp.MageSDK.MageClient; +namespace Wizcorp.MageSDK.Tomes { + public class TomeArray : JArray { + // + public Tome.OnChanged onChanged; + public Tome.OnDestroy onDestroy; + public Tome.OnAdd onAdd; + public Tome.OnDel onDel; - // - public TomeArray(JArray data, JToken _root) { // - root = _root; - if (root == null) { - root = this; - } + private JToken root; + // - for (int i = 0; i < data.Count; i += 1) { - this.Add(Tome.Conjure(data[i], root)); + public TomeArray(JArray data, JToken _root) { + // + root = _root; + if (root == null) { + root = this; + } + + // + for (int i = 0; i < data.Count; i += 1) { + this.Add(Tome.Conjure(data[i], root)); + } + + // + onChanged += EmitToParents; + onAdd += EmitChanged; + onDel += EmitChanged; } - + // - onChanged += EmitToParents; - onAdd += EmitChanged; - onDel += EmitChanged; - } - - // - private void EmitToParents(JToken oldValue) { - if (this != root) { - Tome.EmitParentChange(Parent); + private void EmitToParents(JToken oldValue) { + if (this != root) { + Tome.EmitParentChange(Parent); + } } - } - // - private void EmitChanged(JToken key) { - if (onChanged != null) { - onChanged.Invoke(null); + // + private void EmitChanged(JToken key) { + if (onChanged != null) { + onChanged.Invoke(null); + } } - } - // - public void Assign(JToken newValue) { - lock((object)this) { - switch (newValue.Type) { - case JTokenType.Array: - TomeArray newTomeArray = new TomeArray((JArray)newValue, root); - this.Replace(newTomeArray); - - if (this.Parent == null) { - // If replace was successfuly move over event handlers and call new onChanged handler - // The instance in which replace would not be successful, is when the old and new values are the same - onChanged -= EmitToParents; - onChanged += newTomeArray.onChanged; - newTomeArray.onChanged = onChanged; - newTomeArray.onDestroy = onDestroy; - onAdd -= EmitChanged; - onAdd += newTomeArray.onAdd; - newTomeArray.onAdd = onAdd; - onDel -= EmitChanged; - onDel += newTomeArray.onDel; - newTomeArray.onDel = onDel; - - if (newTomeArray.onChanged != null) { - newTomeArray.onChanged.Invoke(null); - } - } else { - // Otherwise call original onChanged handler - if (onChanged != null) { - onChanged.Invoke(null); - } + // + public void Assign(JToken newValue) { + lock ((object)this) { + switch (newValue.Type) { + case JTokenType.Array: + TomeArray newTomeArray = new TomeArray((JArray)newValue, root); + this.Replace(newTomeArray); + + if (this.Parent == null) { + // If replace was successfuly move over event handlers and call new onChanged handler + // The instance in which replace would not be successful, is when the old and new values are the same + onChanged -= EmitToParents; + onChanged += newTomeArray.onChanged; + newTomeArray.onChanged = onChanged; + newTomeArray.onDestroy = onDestroy; + onAdd -= EmitChanged; + onAdd += newTomeArray.onAdd; + newTomeArray.onAdd = onAdd; + onDel -= EmitChanged; + onDel += newTomeArray.onDel; + newTomeArray.onDel = onDel; + + if (newTomeArray.onChanged != null) { + newTomeArray.onChanged.Invoke(null); + } + } else { + // Otherwise call original onChanged handler + if (onChanged != null) { + onChanged.Invoke(null); + } + } + break; + case JTokenType.Object: + TomeObject newTomeObject = new TomeObject((JObject)newValue, root); + this.Replace(newTomeObject); + + if (this.Parent == null) { + // If replace was successfuly move over event handlers and call new onChanged handler + // The instance in which replace would not be successful, is when the old and new values are the same + onChanged -= EmitToParents; + onChanged += newTomeObject.onChanged; + newTomeObject.onChanged = onChanged; + newTomeObject.onDestroy = onDestroy; + onAdd -= EmitChanged; + onAdd += newTomeObject.onAdd; + newTomeObject.onAdd = onAdd; + onDel -= EmitChanged; + onDel += newTomeObject.onDel; + newTomeObject.onDel = onDel; + + if (newTomeObject.onChanged != null) { + newTomeObject.onChanged.Invoke(null); + } + } else { + // Otherwise call original onChanged handler + if (onChanged != null) { + onChanged.Invoke(null); + } + } + break; + default: + TomeValue newTomeValue = new TomeValue((JValue)newValue, root); + this.Replace(newTomeValue); + + if (this.Parent == null) { + // If replace was successfuly move over event handlers and call new onChanged handler + // The instance in which replace would not be successful, is when the old and new values are the same + onChanged -= EmitToParents; + onChanged += newTomeValue.onChanged; + newTomeValue.onChanged = onChanged; + newTomeValue.onDestroy = onDestroy; + + if (newTomeValue.onChanged != null) { + newTomeValue.onChanged.Invoke(null); + } + } else { + // Otherwise call original onChanged handler + if (onChanged != null) { + onChanged.Invoke(null); + } + } + break; } - break; - case JTokenType.Object: - TomeObject newTomeObject = new TomeObject((JObject)newValue, root); - this.Replace(newTomeObject); - - if (this.Parent == null) { - // If replace was successfuly move over event handlers and call new onChanged handler - // The instance in which replace would not be successful, is when the old and new values are the same - onChanged -= EmitToParents; - onChanged += newTomeObject.onChanged; - newTomeObject.onChanged = onChanged; - newTomeObject.onDestroy = onDestroy; - onAdd -= EmitChanged; - onAdd += newTomeObject.onAdd; - newTomeObject.onAdd = onAdd; - onDel -= EmitChanged; - onDel += newTomeObject.onDel; - newTomeObject.onDel = onDel; - - if (newTomeObject.onChanged != null) { - newTomeObject.onChanged.Invoke(null); - } - } else { - // Otherwise call original onChanged handler - if (onChanged != null) { - onChanged.Invoke(null); - } + } + } + + // + public void Destroy() { + lock ((object)this) { + foreach (JToken value in this) { + Tome.Destroy(value); } - break; - default: - TomeValue newTomeValue = new TomeValue((JValue)newValue, root); - this.Replace(newTomeValue); - - if (this.Parent == null) { - // If replace was successfuly move over event handlers and call new onChanged handler - // The instance in which replace would not be successful, is when the old and new values are the same - onChanged -= EmitToParents; - onChanged += newTomeValue.onChanged; - newTomeValue.onChanged = onChanged; - newTomeValue.onDestroy = onDestroy; - - if (newTomeValue.onChanged != null) { - newTomeValue.onChanged.Invoke(null); - } - } else { - // Otherwise call original onChanged handler - if (onChanged != null) { - onChanged.Invoke(null); - } + + if (onDestroy != null) { + onDestroy.Invoke(); } - break; + + onChanged = null; + onDestroy = null; + onAdd = null; + onDel = null; } } - } - - // - public void Destroy() { - lock((object)this) { - foreach (JToken value in this) { - Tome.Destroy(value); - } - if (onDestroy != null) { - onDestroy.Invoke(); - } + // + public void Set(int index, JToken value) { + lock ((object)this) { + // Make sure the property exists, filling in missing indexes + if (this.Count <= index) { + while (this.Count < index) { + this.Add(Tome.Conjure(JValue.CreateNull(), root)); + } - onChanged = null; - onDestroy = null; - onAdd = null; - onDel = null; - } - } - - // - public void Set(int index, JToken value) { - lock((object)this) { - // Make sure the property exists, filling in missing indexes - if (this.Count <= index) { - while (this.Count < index) { - this.Add(Tome.Conjure(JValue.CreateNull(), root)); + this.Add(Tome.Conjure(value, root)); + if (onAdd != null) { + onAdd.Invoke(index); + } + return; } - this.Add(Tome.Conjure(value, root)); - if (onAdd != null) { - onAdd.Invoke(index); + // Assign the property + JToken property = this[index]; + switch (property.Type) { + case JTokenType.Array: + (property as TomeArray).Assign(value); + break; + case JTokenType.Object: + (property as TomeObject).Assign(value); + break; + default: + if ((property as TomeValue) == null) { + Mage.Instance.logger("Tomes").data(property).error("property is not a tome value: " + index.ToString()); + UnityEngine.Debug.Log(this); + } + (property as TomeValue).Assign(value); + break; } - return; } + } + + // + public void Del(int index) { + lock ((object)this) { + JToken property = this[index]; + switch (property.Type) { + case JTokenType.Array: + (property as TomeArray).Destroy(); + break; + case JTokenType.Object: + (property as TomeObject).Destroy(); + break; + default: + if ((property as TomeValue) == null) { + Mage.Instance.logger("Tomes").data(property).error("property is not a tome value:" + index.ToString()); + UnityEngine.Debug.Log(this); + } + (property as TomeValue).Destroy(); + break; + } - // Assign the property - JToken property = this[index]; - switch (property.Type) { - case JTokenType.Array: - (property as TomeArray).Assign(value); - break; - case JTokenType.Object: - (property as TomeObject).Assign(value); - break; - default: - if ((property as TomeValue) == null) { - Mage.Instance.logger("Tomes").data(property).error("property is not a tome value: " + index.ToString()); - UnityEngine.Debug.Log(this); + this[index].Replace(JValue.CreateNull()); + if (onDel != null) { + onDel.Invoke(index); } - (property as TomeValue).Assign(value); - break; } } - } - - // - public void Del(int index) { - lock((object)this) { - JToken property = this[index]; - switch (property.Type) { - case JTokenType.Array: - (property as TomeArray).Destroy(); - break; - case JTokenType.Object: - (property as TomeObject).Destroy(); - break; - default: - if ((property as TomeValue) == null) { - Mage.Instance.logger("Tomes").data(property).error("property is not a tome value:" + index.ToString()); - UnityEngine.Debug.Log(this); + + // + public void Move(int fromKey, JToken newParent, JToken newKey) { + lock ((object)this) { + if (newParent.Type == JTokenType.Array) { + (newParent as TomeArray).Set((int)newKey, this[fromKey]); + } else { + (newParent as TomeObject).Set((string)newKey, this[fromKey]); } - (property as TomeValue).Destroy(); - break; - } - this[index].Replace(JValue.CreateNull()); - if (onDel != null) { - onDel.Invoke(index); - } - } - } - - // - public void Move(int fromKey, JToken newParent, JToken newKey) { - lock((object)this) { - if (newParent.Type == JTokenType.Array) { - (newParent as TomeArray).Set((int)newKey, this[fromKey]); - } else { - (newParent as TomeObject).Set((string)newKey, this[fromKey]); - } - - Del(fromKey); - } - } - - // - public void Rename(int wasKey, int isKey) { - lock((object)this) { - JToken wasValue = this[wasKey]; - Del(wasKey); - Set(isKey, wasValue); - } - } - - // - public void Swap(int firstKey, JToken secondParent, JToken secondKey) { - lock((object)this) { - JToken secondValue; - if (secondParent.Type == JTokenType.Array) { - secondValue = secondParent[(int)secondKey]; - secondParent[(int)secondKey].Replace(this[firstKey]); - } else { - secondValue = secondParent[(string)secondKey]; - secondParent[(string)secondKey].Replace(this[firstKey]); + Del(fromKey); } - - this[firstKey].Replace(secondValue); - if (onChanged != null) { - onChanged.Invoke(null); - } - } - } - - // - public void Push(JToken item) { - lock((object)this) { - this.Set(this.Count, item); } - } - // NOTE: Tome behavior for a del operation is to replace values with null. - // However a pop operation does in fact remove the item as well as - // firing the del event. Thus we do both below. - public JToken Pop() { - lock((object)this) { - JToken last = this[this.Count - 1]; - this.Del(this.Count - 1); - this.Last.Remove(); - return last; + // + public void Rename(int wasKey, int isKey) { + lock ((object)this) { + JToken wasValue = this[wasKey]; + Del(wasKey); + Set(isKey, wasValue); + } } - } - // NOTE: Tome behavior for a del operation is to replace values with null. - // However a shift operation does in fact remove the item as well as - // firing the del event. Thus we do both below. - public JToken Shift() { - lock((object)this) { - JToken first = this[0]; - this.Del(0); - this.First.Remove(); - return first; - } - } + // + public void Swap(int firstKey, JToken secondParent, JToken secondKey) { + lock ((object)this) { + JToken secondValue; + if (secondParent.Type == JTokenType.Array) { + secondValue = secondParent[(int)secondKey]; + secondParent[(int)secondKey].Replace(this[firstKey]); + } else { + secondValue = secondParent[(string)secondKey]; + secondParent[(string)secondKey].Replace(this[firstKey]); + } - // - public void UnShift(JToken item) { - lock((object)this) { - this.AddFirst(Tome.Conjure(item, root)); - if (onAdd != null) { - onAdd.Invoke(0); + this[firstKey].Replace(secondValue); + if (onChanged != null) { + onChanged.Invoke(null); + } } } - } - // - public void Reverse() { - lock((object)this) { - JArray oldOrder = new JArray(this as JArray); - for (int i = oldOrder.Count; i > 0; i -= 1) { - this[oldOrder.Count - i].Replace(oldOrder[i - 1]); + // + public void Push(JToken item) { + lock ((object)this) { + this.Set(this.Count, item); } + } - if (onChanged != null) { - onChanged.Invoke(null); + // NOTE: Tome behavior for a del operation is to replace values with null. + // However a pop operation does in fact remove the item as well as + // firing the del event. Thus we do both below. + public JToken Pop() { + lock ((object)this) { + JToken last = this[this.Count - 1]; + this.Del(this.Count - 1); + this.Last.Remove(); + return last; } } - } - // - public void Splice(int index, int deleteCount, JArray insertItems) { - lock((object)this) { - // Delete given item count starting at given index - for (int delI = index + deleteCount - 1; delI >= index; delI -= 1) { - if (delI > this.Count - 1) { - continue; - } - - Del(delI); - this[delI].Remove(); + // NOTE: Tome behavior for a del operation is to replace values with null. + // However a shift operation does in fact remove the item as well as + // firing the del event. Thus we do both below. + public JToken Shift() { + lock ((object)this) { + JToken first = this[0]; + this.Del(0); + this.First.Remove(); + return first; } + } - // Insert given items starting at given index - for (int addI = 0; addI < insertItems.Count; addI += 1) { - int insertI = index + addI; - this.Insert(insertI, Tome.Conjure(insertItems[addI])); + // + public void UnShift(JToken item) { + lock ((object)this) { + this.AddFirst(Tome.Conjure(item, root)); if (onAdd != null) { - onAdd.Invoke(insertI); + onAdd.Invoke(0); } } } - } + // + public void Reverse() { + lock ((object)this) { + JArray oldOrder = new JArray(this as JArray); + for (int i = oldOrder.Count; i > 0; i -= 1) { + this[oldOrder.Count - i].Replace(oldOrder[i - 1]); + } - // We implement this as when using JArray.IndexOf(JToken) it compares the reference but not the value. - public int IndexOf(string lookFor) { - lock((object)this) { - for (int i = 0; i < this.Count; i += 1) { - JToken value = this[i]; - if (value.Type == JTokenType.String && (string)value == lookFor) { - return i; + if (onChanged != null) { + onChanged.Invoke(null); } } - - return -1; } - } + // + public void Splice(int index, int deleteCount, JArray insertItems) { + lock ((object)this) { + // Delete given item count starting at given index + for (int delI = index + deleteCount - 1; delI >= index; delI -= 1) { + if (delI > this.Count - 1) { + continue; + } - // - public void ApplyOperation(string op, JToken val, JToken root) { - lock((object)this) { - switch (op) { - case "assign": - Assign(val); - break; - - case "set": - Set((int)val["key"], val["val"]); - break; - - case "del": - Del((int)val); - break; - - case "move": - int fromKey = (int)val["key"]; - JToken newParent = Tome.PathValue(root, val["newParent"] as JArray); - JToken toKey = (val["newKey"] != null) ? val["newKey"] : new JValue(fromKey); - Move(fromKey, newParent, toKey); - break; - - case "rename": - foreach (var property in val as JObject) { - int wasKey = int.Parse(property.Key); - int isKey = (int)property.Value; - Rename(wasKey, isKey); - } - break; - - case "swap": - int firstKey = (int)val["key"]; - JToken secondParent = Tome.PathValue(root, val["newParent"] as JArray); - JToken secondKey = (val["newKey"] != null) ? val["newKey"] : new JValue(firstKey); - Swap(firstKey, secondParent, secondKey); - break; - - case "push": - foreach (JToken item in val as JArray) { - Push(item); + Del(delI); + this[delI].Remove(); } - break; - - case "pop": - Pop(); - break; - - case "shift": - Shift(); - break; - case "unshift": - JArray unshiftItems = val as JArray; - for (int i = unshiftItems.Count; i > 0; i -= 1) { - UnShift(unshiftItems[i - 1]); + // Insert given items starting at given index + for (int addI = 0; addI < insertItems.Count; addI += 1) { + int insertI = index + addI; + this.Insert(insertI, Tome.Conjure(insertItems[addI])); + if (onAdd != null) { + onAdd.Invoke(insertI); + } } - break; + } + } - case "reverse": - Reverse(); - break; - case "splice": - int index = (int)val[0]; - int deleteCount = (int)val[1]; + // We implement this as when using JArray.IndexOf(JToken) it compares the reference but not the value. + public int IndexOf(string lookFor) { + lock ((object)this) { + for (int i = 0; i < this.Count; i += 1) { + JToken value = this[i]; + if (value.Type == JTokenType.String && (string)value == lookFor) { + return i; + } + } - JArray items = new JArray(val as JArray); - items.First.Remove(); - items.First.Remove(); + return -1; + } + } - Splice(index, deleteCount, items); - break; - default: - throw new Exception("TomeArray - Unsupported operation: " + op); + // + public void ApplyOperation(string op, JToken val, JToken root) { + lock ((object)this) { + switch (op) { + case "assign": + Assign(val); + break; + + case "set": + Set((int)val["key"], val["val"]); + break; + + case "del": + Del((int)val); + break; + + case "move": + int fromKey = (int)val["key"]; + JToken newParent = Tome.PathValue(root, val["newParent"] as JArray); + JToken toKey = (val["newKey"] != null) ? val["newKey"] : new JValue(fromKey); + Move(fromKey, newParent, toKey); + break; + + case "rename": + foreach (var property in val as JObject) { + int wasKey = int.Parse(property.Key); + int isKey = (int)property.Value; + Rename(wasKey, isKey); + } + break; + + case "swap": + int firstKey = (int)val["key"]; + JToken secondParent = Tome.PathValue(root, val["newParent"] as JArray); + JToken secondKey = (val["newKey"] != null) ? val["newKey"] : new JValue(firstKey); + Swap(firstKey, secondParent, secondKey); + break; + + case "push": + foreach (JToken item in val as JArray) { + Push(item); + } + break; + + case "pop": + Pop(); + break; + + case "shift": + Shift(); + break; + + case "unshift": + JArray unshiftItems = val as JArray; + for (int i = unshiftItems.Count; i > 0; i -= 1) { + UnShift(unshiftItems[i - 1]); + } + break; + + case "reverse": + Reverse(); + break; + + case "splice": + int index = (int)val[0]; + int deleteCount = (int)val[1]; + + JArray items = new JArray(val as JArray); + items.First.Remove(); + items.First.Remove(); + + Splice(index, deleteCount, items); + break; + + default: + throw new Exception("TomeArray - Unsupported operation: " + op); + } } } } -} \ No newline at end of file +} diff --git a/Tomes/TomeObject.cs b/Tomes/TomeObject.cs index 6a5269d..92551f7 100644 --- a/Tomes/TomeObject.cs +++ b/Tomes/TomeObject.cs @@ -1,298 +1,303 @@ -using System; +using System; using System.Collections.Generic; + using Newtonsoft.Json.Linq; -public class TomeObject : JObject { - // - public Tome.OnChanged onChanged; - public Tome.OnDestroy onDestroy; - public Tome.OnAdd onAdd; - public Tome.OnDel onDel; - - // - private JToken root; +using Wizcorp.MageSDK.MageClient; +namespace Wizcorp.MageSDK.Tomes { + public class TomeObject : JObject { + // + public Tome.OnChanged onChanged; + public Tome.OnDestroy onDestroy; + public Tome.OnAdd onAdd; + public Tome.OnDel onDel; - // - public TomeObject(JObject data, JToken _root) { // - root = _root; - if (root == null) { - root = this; - } - + private JToken root; + + // - foreach (JProperty property in data.Properties()) { - this.Add(property.Name, Tome.Conjure(property.Value, root)); + public TomeObject(JObject data, JToken _root) { + // + root = _root; + if (root == null) { + root = this; + } + + // + foreach (JProperty property in data.Properties()) { + this.Add(property.Name, Tome.Conjure(property.Value, root)); + } + + // + onChanged += EmitToParents; + onAdd += EmitChanged; + onDel += EmitChanged; } // - onChanged += EmitToParents; - onAdd += EmitChanged; - onDel += EmitChanged; - } - - // - private void EmitToParents(JToken oldValue) { - if (this != root) { - Tome.EmitParentChange(Parent); + private void EmitToParents(JToken oldValue) { + if (this != root) { + Tome.EmitParentChange(Parent); + } } - } - - // - private void EmitChanged(JToken key) { - if (onChanged != null) { - onChanged.Invoke(null); + + // + private void EmitChanged(JToken key) { + if (onChanged != null) { + onChanged.Invoke(null); + } } - } - // - public void Assign(JToken newValue) { - lock((object)this) { - switch (newValue.Type) { - case JTokenType.Array: - TomeArray newTomeArray = new TomeArray((JArray)newValue, root); - this.Replace(newTomeArray); - - if (this.Parent == null) { - // If replace was successfuly move over event handlers and call new onChanged handler - // The instance in which replace would not be successful, is when the old and new values are the same - onChanged -= EmitToParents; - onChanged += newTomeArray.onChanged; - newTomeArray.onChanged = onChanged; - newTomeArray.onDestroy = onDestroy; - onAdd -= EmitChanged; - onAdd += newTomeArray.onAdd; - newTomeArray.onAdd = onAdd; - onDel -= EmitChanged; - onDel += newTomeArray.onDel; - newTomeArray.onDel = onDel; - - if (newTomeArray.onChanged != null) { - newTomeArray.onChanged.Invoke(null); - } - } else { - // Otherwise call original onChanged handler - if (onChanged != null) { - onChanged.Invoke(null); - } - } - break; - case JTokenType.Object: - TomeObject newTomeObject = new TomeObject((JObject)newValue, root); - this.Replace(newTomeObject); - - if (this.Parent == null) { - // If replace was successfuly move over event handlers and call new onChanged handler - // The instance in which replace would not be successful, is when the old and new values are the same - onChanged -= EmitToParents; - onChanged += newTomeObject.onChanged; - newTomeObject.onChanged = onChanged; - newTomeObject.onDestroy = onDestroy; - onAdd -= EmitChanged; - onAdd += newTomeObject.onAdd; - newTomeObject.onAdd = onAdd; - onDel -= EmitChanged; - onDel += newTomeObject.onDel; - newTomeObject.onDel = onDel; - - if (newTomeObject.onChanged != null) { - newTomeObject.onChanged.Invoke(null); - } - } else { - // Otherwise call original onChanged handler - if (onChanged != null) { - onChanged.Invoke(null); - } - } - break; - default: - TomeValue newTomeValue = new TomeValue((JValue)newValue, root); - this.Replace(newTomeValue); - - if (this.Parent == null) { - // If replace was successfuly move over event handlers and call new onChanged handler - // The instance in which replace would not be successful, is when the old and new values are the same - onChanged -= EmitToParents; - onChanged += newTomeValue.onChanged; - newTomeValue.onChanged = onChanged; - newTomeValue.onDestroy = onDestroy; - - if (newTomeValue.onChanged != null) { - newTomeValue.onChanged.Invoke(null); - } - } else { - // Otherwise call original onChanged handler - if (onChanged != null) { - onChanged.Invoke(null); - } + // + public void Assign(JToken newValue) { + lock ((object)this) { + switch (newValue.Type) { + case JTokenType.Array: + TomeArray newTomeArray = new TomeArray((JArray)newValue, root); + this.Replace(newTomeArray); + + if (this.Parent == null) { + // If replace was successfuly move over event handlers and call new onChanged handler + // The instance in which replace would not be successful, is when the old and new values are the same + onChanged -= EmitToParents; + onChanged += newTomeArray.onChanged; + newTomeArray.onChanged = onChanged; + newTomeArray.onDestroy = onDestroy; + onAdd -= EmitChanged; + onAdd += newTomeArray.onAdd; + newTomeArray.onAdd = onAdd; + onDel -= EmitChanged; + onDel += newTomeArray.onDel; + newTomeArray.onDel = onDel; + + if (newTomeArray.onChanged != null) { + newTomeArray.onChanged.Invoke(null); + } + } else { + // Otherwise call original onChanged handler + if (onChanged != null) { + onChanged.Invoke(null); + } + } + break; + case JTokenType.Object: + TomeObject newTomeObject = new TomeObject((JObject)newValue, root); + this.Replace(newTomeObject); + + if (this.Parent == null) { + // If replace was successfuly move over event handlers and call new onChanged handler + // The instance in which replace would not be successful, is when the old and new values are the same + onChanged -= EmitToParents; + onChanged += newTomeObject.onChanged; + newTomeObject.onChanged = onChanged; + newTomeObject.onDestroy = onDestroy; + onAdd -= EmitChanged; + onAdd += newTomeObject.onAdd; + newTomeObject.onAdd = onAdd; + onDel -= EmitChanged; + onDel += newTomeObject.onDel; + newTomeObject.onDel = onDel; + + if (newTomeObject.onChanged != null) { + newTomeObject.onChanged.Invoke(null); + } + } else { + // Otherwise call original onChanged handler + if (onChanged != null) { + onChanged.Invoke(null); + } + } + break; + default: + TomeValue newTomeValue = new TomeValue((JValue)newValue, root); + this.Replace(newTomeValue); + + if (this.Parent == null) { + // If replace was successfuly move over event handlers and call new onChanged handler + // The instance in which replace would not be successful, is when the old and new values are the same + onChanged -= EmitToParents; + onChanged += newTomeValue.onChanged; + newTomeValue.onChanged = onChanged; + newTomeValue.onDestroy = onDestroy; + + if (newTomeValue.onChanged != null) { + newTomeValue.onChanged.Invoke(null); + } + } else { + // Otherwise call original onChanged handler + if (onChanged != null) { + onChanged.Invoke(null); + } + } + break; } - break; } } - } - - // - public void Destroy() { - lock((object)this) { - foreach (var property in this) { - Tome.Destroy(property.Value); - } - if (onDestroy != null) { - onDestroy.Invoke(); - } + // + public void Destroy() { + lock ((object)this) { + foreach (var property in this) { + Tome.Destroy(property.Value); + } - onChanged = null; - onDestroy = null; - onAdd = null; - onDel = null; - } - } - - // - public void Set(string propertyName, JToken value) { - lock((object)this) { - // Make sure the property exists - if (this[propertyName] == null) { - this.Add(propertyName, Tome.Conjure(value, root)); - if (onAdd != null) { - onAdd.Invoke(propertyName); + if (onDestroy != null) { + onDestroy.Invoke(); } - return; + + onChanged = null; + onDestroy = null; + onAdd = null; + onDel = null; } + } + + // + public void Set(string propertyName, JToken value) { + lock ((object)this) { + // Make sure the property exists + if (this[propertyName] == null) { + this.Add(propertyName, Tome.Conjure(value, root)); + if (onAdd != null) { + onAdd.Invoke(propertyName); + } + return; + } - // Assign the property - JToken property = this[propertyName]; - switch (property.Type) { - case JTokenType.Array: - (property as TomeArray).Assign(value); - break; - case JTokenType.Object: - (property as TomeObject).Assign(value); - break; - default: - if ((property as TomeValue) == null) { - Mage.Instance.logger("Tomes").data(property).error("property is not a tome value: " + propertyName.ToString()); - UnityEngine.Debug.Log(this); + // Assign the property + JToken property = this[propertyName]; + switch (property.Type) { + case JTokenType.Array: + (property as TomeArray).Assign(value); + break; + case JTokenType.Object: + (property as TomeObject).Assign(value); + break; + default: + if ((property as TomeValue) == null) { + Mage.Instance.logger("Tomes").data(property).error("property is not a tome value: " + propertyName.ToString()); + UnityEngine.Debug.Log(this); + } + (property as TomeValue).Assign(value); + break; } - (property as TomeValue).Assign(value); - break; } } - } - // - public void Del(string propertyName) { - lock((object)this) { - JToken property = this[propertyName]; - switch (property.Type) { - case JTokenType.Array: - (property as TomeArray).Destroy(); - break; - case JTokenType.Object: - (property as TomeObject).Destroy(); - break; - default: - if ((property as TomeValue) == null) { - Mage.Instance.logger("Tomes").data(property).error("property is not a tome value: " + propertyName.ToString()); - UnityEngine.Debug.Log(this); + // + public void Del(string propertyName) { + lock ((object)this) { + JToken property = this[propertyName]; + switch (property.Type) { + case JTokenType.Array: + (property as TomeArray).Destroy(); + break; + case JTokenType.Object: + (property as TomeObject).Destroy(); + break; + default: + if ((property as TomeValue) == null) { + Mage.Instance.logger("Tomes").data(property).error("property is not a tome value: " + propertyName.ToString()); + UnityEngine.Debug.Log(this); + } + (property as TomeValue).Destroy(); + break; } - (property as TomeValue).Destroy(); - break; - } - this.Remove(propertyName); - if (onDel != null) { - onDel.Invoke(propertyName); + this.Remove(propertyName); + if (onDel != null) { + onDel.Invoke(propertyName); + } } } - } - // - public void Move(string fromKey, JToken toParent, JToken toKey) { - lock((object)this) { - if (toParent.Type == JTokenType.Array) { - (toParent as TomeArray).Set((int)toKey, this[fromKey]); - } else { - (toParent as TomeObject).Set((string)toKey, this[fromKey]); - } + // + public void Move(string fromKey, JToken toParent, JToken toKey) { + lock ((object)this) { + if (toParent.Type == JTokenType.Array) { + (toParent as TomeArray).Set((int)toKey, this[fromKey]); + } else { + (toParent as TomeObject).Set((string)toKey, this[fromKey]); + } - Del(fromKey); + Del(fromKey); + } } - } - // - public void Rename(string wasKey, string isKey) { - lock((object)this) { - JToken wasValue = this[wasKey]; - Del(wasKey); - Set(isKey, wasValue); + // + public void Rename(string wasKey, string isKey) { + lock ((object)this) { + JToken wasValue = this[wasKey]; + Del(wasKey); + Set(isKey, wasValue); + } } - } - // - public void Swap(string firstKey, JToken secondParent, JToken secondKey) { - lock((object)this) { - JToken secondValue; - if (secondParent.Type == JTokenType.Array) { - secondValue = secondParent[(int)secondKey]; - secondParent[(int)secondKey].Replace(this[firstKey]); - } else { - secondValue = secondParent[(string)secondKey]; - secondParent[(string)secondKey].Replace(this[firstKey]); - } + // + public void Swap(string firstKey, JToken secondParent, JToken secondKey) { + lock ((object)this) { + JToken secondValue; + if (secondParent.Type == JTokenType.Array) { + secondValue = secondParent[(int)secondKey]; + secondParent[(int)secondKey].Replace(this[firstKey]); + } else { + secondValue = secondParent[(string)secondKey]; + secondParent[(string)secondKey].Replace(this[firstKey]); + } - this[firstKey].Replace(secondValue); - if (onChanged != null) { - onChanged.Invoke(null); + this[firstKey].Replace(secondValue); + if (onChanged != null) { + onChanged.Invoke(null); + } } } - } - // - public void ApplyOperation(string op, JToken val, JToken root) { - lock((object)this) { - switch (op) { - case "assign": - Assign(val); - break; - - case "set": - Set((string)val["key"], val["val"]); - break; - - case "del": - Del((string)val); - break; - - case "move": - string fromKey = (string)val["key"]; - JToken toParent = Tome.PathValue(root, val["newParent"] as JArray); - JToken toKey = (val["newKey"] != null) ? val["newKey"] : new JValue(fromKey); - Move(fromKey, toParent, toKey); - break; - - case "rename": - foreach (var property in val as JObject) { - string wasKey = property.Key; - string isKey = (string)property.Value; - Rename(wasKey, isKey); - } - break; + // + public void ApplyOperation(string op, JToken val, JToken root) { + lock ((object)this) { + switch (op) { + case "assign": + Assign(val); + break; + + case "set": + Set((string)val["key"], val["val"]); + break; - case "swap": - string firstKey = (string)val["key"]; - JToken secondParent = Tome.PathValue(root, val["newParent"] as JArray); - JToken secondKey = (val["newKey"] != null) ? val["newKey"] : new JValue(firstKey); - Swap(firstKey, secondParent, secondKey); - break; + case "del": + Del((string)val); + break; - default: - throw new Exception("TomeObject - Unsupported operation: " + op); + case "move": + string fromKey = (string)val["key"]; + JToken toParent = Tome.PathValue(root, val["newParent"] as JArray); + JToken toKey = (val["newKey"] != null) ? val["newKey"] : new JValue(fromKey); + Move(fromKey, toParent, toKey); + break; + + case "rename": + foreach (var property in val as JObject) { + string wasKey = property.Key; + string isKey = (string)property.Value; + Rename(wasKey, isKey); + } + break; + + case "swap": + string firstKey = (string)val["key"]; + JToken secondParent = Tome.PathValue(root, val["newParent"] as JArray); + JToken secondKey = (val["newKey"] != null) ? val["newKey"] : new JValue(firstKey); + Swap(firstKey, secondParent, secondKey); + break; + + default: + throw new Exception("TomeObject - Unsupported operation: " + op); + } } } } -} \ No newline at end of file +} diff --git a/Tomes/TomeValue.cs b/Tomes/TomeValue.cs index 001437c..92c7fdb 100644 --- a/Tomes/TomeValue.cs +++ b/Tomes/TomeValue.cs @@ -1,133 +1,137 @@ -using System; +using System; + using Newtonsoft.Json.Linq; -public class TomeValue : JValue { - // - public Tome.OnChanged onChanged; - public Tome.OnDestroy onDestroy; - // - private JToken root; +namespace Wizcorp.MageSDK.Tomes { + public class TomeValue : JValue { + // + public Tome.OnChanged onChanged; + public Tome.OnDestroy onDestroy; + + // + private JToken root; - // - public TomeValue(JValue value, JToken _root) : base(value) { // - root = _root; - if (root == null) { - root = this; + public TomeValue(JValue value, JToken _root) : base(value) { + // + root = _root; + if (root == null) { + root = this; + } + + // + onChanged += EmitToParents; } - - // - onChanged += EmitToParents; - } - // - private void EmitToParents(JToken oldValue) { - if (this != root) { - Tome.EmitParentChange(Parent); + // + private void EmitToParents(JToken oldValue) { + if (this != root) { + Tome.EmitParentChange(Parent); + } } - } - // - public void Assign(JToken newValue) { - lock((object)this) { - switch (newValue.Type) { - case JTokenType.Array: - TomeArray newTomeArray = new TomeArray((JArray)newValue, root); - this.Replace(newTomeArray); - - if (this.Parent == null) { - // If replace was successfuly move over event handlers and call new onChanged handler - // The instance in which replace would not be successful, is when the old and new values are the same - onChanged -= EmitToParents; - onChanged += newTomeArray.onChanged; - newTomeArray.onChanged = onChanged; - newTomeArray.onDestroy = onDestroy; - - if (newTomeArray.onChanged != null) { - newTomeArray.onChanged.Invoke(null); - } - } else { - // Otherwise call original onChanged handler - if (onChanged != null) { - onChanged.Invoke(null); - } - } - break; - case JTokenType.Object: - TomeObject newTomeObject = new TomeObject((JObject)newValue, root); - this.Replace(newTomeObject); - - if (this.Parent == null) { - // If replace was successfuly move over event handlers and call new onChanged handler - // The instance in which replace would not be successful, is when the old and new values are the same - onChanged -= EmitToParents; - onChanged += newTomeObject.onChanged; - newTomeObject.onChanged = onChanged; - newTomeObject.onDestroy = onDestroy; - - if (newTomeObject.onChanged != null) { - newTomeObject.onChanged.Invoke(null); - } - } else { - // Otherwise call original onChanged handler - if (onChanged != null) { - onChanged.Invoke(null); - } - } - break; - default: - TomeValue newTomeValue = new TomeValue((JValue)newValue, root); - this.Replace(newTomeValue); - - if (this.Parent == null) { - // If replace was successfuly move over event handlers and call new onChanged handler - // The instance in which replace would not be successful, is when the old and new values are the same - onChanged -= EmitToParents; - onChanged += newTomeValue.onChanged; - newTomeValue.onChanged = onChanged; - newTomeValue.onDestroy = onDestroy; - - if (newTomeValue.onChanged != null) { - newTomeValue.onChanged.Invoke(null); - } - } else { - // Otherwise call original onChanged handler - if (onChanged != null) { - onChanged.Invoke(null); - } + // + public void Assign(JToken newValue) { + lock ((object)this) { + switch (newValue.Type) { + case JTokenType.Array: + TomeArray newTomeArray = new TomeArray((JArray)newValue, root); + this.Replace(newTomeArray); + + if (this.Parent == null) { + // If replace was successfuly move over event handlers and call new onChanged handler + // The instance in which replace would not be successful, is when the old and new values are the same + onChanged -= EmitToParents; + onChanged += newTomeArray.onChanged; + newTomeArray.onChanged = onChanged; + newTomeArray.onDestroy = onDestroy; + + if (newTomeArray.onChanged != null) { + newTomeArray.onChanged.Invoke(null); + } + } else { + // Otherwise call original onChanged handler + if (onChanged != null) { + onChanged.Invoke(null); + } + } + break; + case JTokenType.Object: + TomeObject newTomeObject = new TomeObject((JObject)newValue, root); + this.Replace(newTomeObject); + + if (this.Parent == null) { + // If replace was successfuly move over event handlers and call new onChanged handler + // The instance in which replace would not be successful, is when the old and new values are the same + onChanged -= EmitToParents; + onChanged += newTomeObject.onChanged; + newTomeObject.onChanged = onChanged; + newTomeObject.onDestroy = onDestroy; + + if (newTomeObject.onChanged != null) { + newTomeObject.onChanged.Invoke(null); + } + } else { + // Otherwise call original onChanged handler + if (onChanged != null) { + onChanged.Invoke(null); + } + } + break; + default: + TomeValue newTomeValue = new TomeValue((JValue)newValue, root); + this.Replace(newTomeValue); + + if (this.Parent == null) { + // If replace was successfuly move over event handlers and call new onChanged handler + // The instance in which replace would not be successful, is when the old and new values are the same + onChanged -= EmitToParents; + onChanged += newTomeValue.onChanged; + newTomeValue.onChanged = onChanged; + newTomeValue.onDestroy = onDestroy; + + if (newTomeValue.onChanged != null) { + newTomeValue.onChanged.Invoke(null); + } + } else { + // Otherwise call original onChanged handler + if (onChanged != null) { + onChanged.Invoke(null); + } + } + break; } - break; } } - } - // - public void Destroy() { - lock((object)this) { - if (onDestroy != null) { - onDestroy.Invoke(); - } + // + public void Destroy() { + lock ((object)this) { + if (onDestroy != null) { + onDestroy.Invoke(); + } - onChanged = null; - onDestroy = null; + onChanged = null; + onDestroy = null; + } } - } - - // - public void ApplyOperation(string op, JToken val) { - lock((object)this) { - switch (op) { - case "assign": - Assign(val); - break; - default: - throw new Exception("TomeValue - Unsupported operation: " + op); + // + public void ApplyOperation(string op, JToken val) { + lock ((object)this) { + switch (op) { + case "assign": + Assign(val); + break; + + default: + throw new Exception("TomeValue - Unsupported operation: " + op); + } } } } -} \ No newline at end of file +} diff --git a/Unity/UnityApplicationState.cs b/Unity/UnityApplicationState.cs index 886905a..3019d15 100644 --- a/Unity/UnityApplicationState.cs +++ b/Unity/UnityApplicationState.cs @@ -1,6 +1,8 @@ using UnityEngine; using System.Collections; +using Wizcorp.MageSDK.Utils; + public class UnityApplicationState : MonoSingleton { public delegate void OnAppStateChanged(bool pauseStatus); public OnAppStateChanged onAppStateChanged; diff --git a/Unity/UnityEditorPlayMode.cs b/Unity/UnityEditorPlayMode.cs index 249c2da..793b7d0 100644 --- a/Unity/UnityEditorPlayMode.cs +++ b/Unity/UnityEditorPlayMode.cs @@ -1,64 +1,61 @@ -#if UNITY_EDITOR +#if UNITY_EDITOR using UnityEditor; +namespace Wizcorp.MageSDK.Editor { + public enum EditorPlayModeState { + Stopped, + Playing, + Paused + } -public enum EditorPlayModeState -{ - Stopped, - Playing, - Paused -} - -[InitializeOnLoad] -public class UnityEditorPlayMode { - private static EditorPlayModeState currentState = EditorPlayModeState.Stopped; - public delegate void OnEditorModeChanged(EditorPlayModeState newState); - public static OnEditorModeChanged onEditorModeChanged; + [InitializeOnLoad] + public class UnityEditorPlayMode { + private static EditorPlayModeState currentState = EditorPlayModeState.Stopped; + public delegate void OnEditorModeChanged(EditorPlayModeState newState); + public static OnEditorModeChanged onEditorModeChanged; - static UnityEditorPlayMode() - { - EditorApplication.playmodeStateChanged += OnUnityPlayModeChanged; - if (EditorApplication.isPaused) { - currentState = EditorPlayModeState.Paused; + static UnityEditorPlayMode() { + EditorApplication.playmodeStateChanged += OnUnityPlayModeChanged; + if (EditorApplication.isPaused) { + currentState = EditorPlayModeState.Paused; + } } - } - private static void OnUnityPlayModeChanged() - { - EditorPlayModeState newState = EditorPlayModeState.Stopped; - switch (currentState) { - case EditorPlayModeState.Stopped: - if (EditorApplication.isPlayingOrWillChangePlaymode) { - newState = EditorPlayModeState.Playing; - } else { - newState = EditorPlayModeState.Paused; + private static void OnUnityPlayModeChanged() { + EditorPlayModeState newState = EditorPlayModeState.Stopped; + switch (currentState) { + case EditorPlayModeState.Stopped: + if (EditorApplication.isPlayingOrWillChangePlaymode) { + newState = EditorPlayModeState.Playing; + } else { + newState = EditorPlayModeState.Paused; + } + break; + case EditorPlayModeState.Playing: + if (EditorApplication.isPaused) { + newState = EditorPlayModeState.Paused; + } else if (EditorApplication.isPlaying) { + newState = EditorPlayModeState.Playing; + } else { + newState = EditorPlayModeState.Stopped; + } + break; + case EditorPlayModeState.Paused: + if (EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPaused) { + newState = EditorPlayModeState.Playing; + } else if (EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPaused) { + newState = EditorPlayModeState.Paused; + } + break; } - break; - case EditorPlayModeState.Playing: - if (EditorApplication.isPaused) { - newState = EditorPlayModeState.Paused; - } else if (EditorApplication.isPlaying) { - newState = EditorPlayModeState.Playing; - } else { - newState = EditorPlayModeState.Stopped; - } - break; - case EditorPlayModeState.Paused: - if (EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPaused) { - newState = EditorPlayModeState.Playing; - } else if (EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPaused) { - newState = EditorPlayModeState.Paused; + + if (onEditorModeChanged != null) { + onEditorModeChanged.Invoke(newState); } - break; - } - if (onEditorModeChanged != null) { - onEditorModeChanged.Invoke(newState); + currentState = newState; } - - currentState = newState; } } - -#endif \ No newline at end of file +#endif