public static void InvokeTransformChange(string tree, TransformSpec ts) => OnTransformChange?.Invoke(tree, ts);
 public static void InvokeMarkerTransform(string marker, TransformSpec ts) => OnMarkerTransform?.Invoke(marker, ts);
            public List <KeyValuePair <string, string> > Morph(object args)
            {
                // Transform the args into a bag of key-value strings.
                var outputArgs = new List <KeyValuePair <string, string> >();

                if (args != null)
                {
                    if (!_noImplicitTransforms)
                    {
                        // given the type, fetch the implicit transforms for that type and put it in the implicitTransforms variable.
                        Type          argType = args.GetType();
                        TransformSpec implicitTransforms;

                        // First check the one-element cache _firstImplicitTransformsEntry
                        ImplicitTransformEntry cacheEntry = _firstImplicitTransformsEntry;
                        if (cacheEntry != null && cacheEntry.Type == argType)
                        {
                            implicitTransforms = cacheEntry.Transforms;     // Yeah we hit the cache.
                        }
                        else if (cacheEntry == null)
                        {
                            // _firstImplicitTransformsEntry is empty, we should fill it.
                            // Note that it is OK that two threads may race and both call MakeImplicitTransforms on their own
                            // (that is we don't expect exactly once initialization of _firstImplicitTransformsEntry)
                            implicitTransforms = MakeImplicitTransforms(argType);
                            Interlocked.CompareExchange(ref _firstImplicitTransformsEntry,
                                                        new ImplicitTransformEntry()
                            {
                                Type = argType, Transforms = implicitTransforms
                            }, null);
                        }
                        else
                        {
                            // This should only happen when you are wildcarding your events (reasonably rare).
                            // In that case you will probably need many types
                            // Note currently we don't limit the cache size, but it is limited by the number of
                            // distinct types of objects passed to DiagnosticSource.Write.
                            if (_implicitTransformsTable == null)
                            {
                                Interlocked.CompareExchange(ref _implicitTransformsTable,
                                                            new ConcurrentDictionary <Type, TransformSpec>(1, 8), null);
                            }
                            implicitTransforms = _implicitTransformsTable.GetOrAdd(argType, type => MakeImplicitTransforms(type));
                        }

                        // implicitTransformas now fetched from cache or constructed, use it to Fetch all the implicit fields.
                        if (implicitTransforms != null)
                        {
                            for (TransformSpec serializableArg = implicitTransforms; serializableArg != null; serializableArg = serializableArg.Next)
                            {
                                outputArgs.Add(serializableArg.Morph(args));
                            }
                        }
                    }

                    if (_explicitTransforms != null)
                    {
                        for (var explicitTransform = _explicitTransforms; explicitTransform != null; explicitTransform = explicitTransform.Next)
                        {
                            var keyValue = explicitTransform.Morph(args);
                            if (keyValue.Value != null)
                            {
                                outputArgs.Add(keyValue);
                            }
                        }
                    }
                }
                return(outputArgs);
            }
            /// <summary>
            /// Creates one FilterAndTransform specification from filterAndPayloadSpec starting at 'startIdx' and ending just before 'endIdx'.
            /// This FilterAndTransform will subscribe to DiagnosticSources specified by the specification and forward them to 'eventSource.
            /// For convenience, the 'Next' field is set to the 'next' parameter, so you can easily form linked lists.
            /// </summary>
            public FilterAndTransform(string filterAndPayloadSpec, int startIdx, int endIdx, DiagnosticSourceEventSource eventSource, FilterAndTransform next)
            {
                Debug.Assert(filterAndPayloadSpec != null && startIdx >= 0 && startIdx <= endIdx && endIdx <= filterAndPayloadSpec.Length);
                Next         = next;
                _eventSource = eventSource;

                string listenerNameFilter = null;       // Means WildCard.
                string eventNameFilter    = null;       // Means WildCard.
                string activityName       = null;

                var startTransformIdx = startIdx;
                var endEventNameIdx   = endIdx;
                var colonIdx          = filterAndPayloadSpec.IndexOf(':', startIdx, endIdx - startIdx);

                if (0 <= colonIdx)
                {
                    endEventNameIdx   = colonIdx;
                    startTransformIdx = colonIdx + 1;
                }

                // Parse the Source/Event name into listenerNameFilter and eventNameFilter
                var slashIdx = filterAndPayloadSpec.IndexOf('/', startIdx, endEventNameIdx - startIdx);

                if (0 <= slashIdx)
                {
                    listenerNameFilter = filterAndPayloadSpec.Substring(startIdx, slashIdx - startIdx);

                    var atIdx = filterAndPayloadSpec.IndexOf('@', slashIdx + 1, endEventNameIdx - slashIdx - 1);
                    if (0 <= atIdx)
                    {
                        activityName    = filterAndPayloadSpec.Substring(atIdx + 1, endEventNameIdx - atIdx - 1);
                        eventNameFilter = filterAndPayloadSpec.Substring(slashIdx + 1, atIdx - slashIdx - 1);
                    }
                    else
                    {
                        eventNameFilter = filterAndPayloadSpec.Substring(slashIdx + 1, endEventNameIdx - slashIdx - 1);
                    }
                }
                else if (startIdx < endEventNameIdx)
                {
                    listenerNameFilter = filterAndPayloadSpec.Substring(startIdx, endEventNameIdx - startIdx);
                }

                _eventSource.Message("DiagnosticSource: Enabling '" + (listenerNameFilter ?? "*") + "/" + (eventNameFilter ?? "*") + "'");

                // If the transform spec begins with a - it means you don't want implicit transforms.
                if (startTransformIdx < endIdx && filterAndPayloadSpec[startTransformIdx] == '-')
                {
                    _eventSource.Message("DiagnosticSource: suppressing implicit transforms.");
                    _noImplicitTransforms = true;
                    startTransformIdx++;
                }

                // Parse all the explicit transforms, if present
                if (startTransformIdx < endIdx)
                {
                    for (;;)
                    {
                        int specStartIdx = startTransformIdx;
                        int semiColonIdx = filterAndPayloadSpec.LastIndexOf(';', endIdx - 1, endIdx - startTransformIdx);
                        if (0 <= semiColonIdx)
                        {
                            specStartIdx = semiColonIdx + 1;
                        }

                        // Ignore empty specifications.
                        if (specStartIdx < endIdx)
                        {
                            if (_eventSource.IsEnabled(EventLevel.Informational, Keywords.Messages))
                            {
                                _eventSource.Message("DiagnosticSource: Parsing Explicit Transform '" + filterAndPayloadSpec.Substring(specStartIdx, endIdx - specStartIdx) + "'");
                            }

                            _explicitTransforms = new TransformSpec(filterAndPayloadSpec, specStartIdx, endIdx, _explicitTransforms);
                        }
                        if (startTransformIdx == specStartIdx)
                        {
                            break;
                        }
                        endIdx = semiColonIdx;
                    }
                }

                Action <string, string, IEnumerable <KeyValuePair <string, string> > > writeEvent = null;

                if (activityName != null && activityName.Contains("Activity"))
                {
                    MethodInfo writeEventMethodInfo = typeof(DiagnosticSourceEventSource).GetTypeInfo().GetDeclaredMethod(activityName);
                    if (writeEventMethodInfo != null)
                    {
                        // This looks up the activityName (which needs to be a name of an event on DiagnosticSourceEventSource
                        // like Activity1Start and returns that method).   This allows us to have a number of them and this code
                        // just works.
                        try
                        {
                            writeEvent = (Action <string, string, IEnumerable <KeyValuePair <string, string> > >)
                                         writeEventMethodInfo.CreateDelegate(typeof(Action <string, string, IEnumerable <KeyValuePair <string, string> > >), _eventSource);
                        }
                        catch (Exception) { }
                    }
                    if (writeEvent == null)
                    {
                        _eventSource.Message("DiagnosticSource: Could not find Event to log Activity " + activityName);
                    }
                }

                if (writeEvent == null)
                {
#if !NO_EVENTSOURCE_COMPLEX_TYPE_SUPPORT
                    writeEvent = _eventSource.Event;
#else
                    writeEvent = delegate(string sourceName, string eventName, IEnumerable <KeyValuePair <string, string> > arguments)
                    {
                        _eventSource.EventJson(sourceName, eventName, ToJson(arguments));
                    };
#endif
                }

                // Set up a subscription that watches for the given Diagnostic Sources and events which will call back
                // to the EventSource.
                _diagnosticsListenersSubscription = DiagnosticListener.AllListeners.Subscribe(new CallbackObserver <DiagnosticListener>(delegate(DiagnosticListener newListener)
                {
                    if (listenerNameFilter == null || listenerNameFilter == newListener.Name)
                    {
                        _eventSource.NewDiagnosticListener(newListener.Name);
                        Predicate <string> eventNameFilterPredicate = null;
                        if (eventNameFilter != null)
                        {
                            eventNameFilterPredicate = (string eventName) => eventNameFilter == eventName;
                        }

                        var subscription = newListener.Subscribe(new CallbackObserver <KeyValuePair <string, object> >(delegate(KeyValuePair <string, object> evnt)
                        {
                            // The filter given to the DiagnosticSource may not work if users don't is 'IsEnabled' as expected.
                            // Thus we look for any events that may have snuck through and filter them out before forwarding.
                            if (eventNameFilter != null && eventNameFilter != evnt.Key)
                            {
                                return;
                            }

                            var outputArgs = this.Morph(evnt.Value);
                            var eventName  = evnt.Key;
                            writeEvent(newListener.Name, eventName, outputArgs);
                        }), eventNameFilterPredicate);
                        _liveSubscriptions = new Subscriptions(subscription, _liveSubscriptions);
                    }
                }));
            }
Exemple #5
0
            /// <summary>
            /// Creates one FilterAndTransform specification from filterAndPayloadSpec starting at 'startIdx' and ending just before 'endIdx'.
            /// This FilterAndTransform will subscribe to DiagnosticSources specified by the specification and forward them to 'eventSource.
            /// For convenience, the 'Next' field is set to the 'next' parameter, so you can easily form linked lists.
            /// </summary>
            public FilterAndTransform(string filterAndPayloadSpec, int startIdx, int endIdx, DiagnosticSourceEventSource eventSource, FilterAndTransform next)
            {
#if DEBUG
                string spec = filterAndPayloadSpec.Substring(startIdx, endIdx - startIdx);
#endif
                Next         = next;
                _eventSource = eventSource;

                string listenerNameFilter = null;       // Means WildCard.
                string eventNameFilter    = null;       // Means WildCard.

                var startTransformIdx = startIdx;
                var endEventNameIdx   = endIdx;
                var colonIdx          = filterAndPayloadSpec.IndexOf(':', startIdx, endIdx - startIdx);
                if (0 <= colonIdx)
                {
                    endEventNameIdx   = colonIdx;
                    startTransformIdx = colonIdx + 1;
                }

                // Parse the Source/Event name into listenerNameFilter and eventNameFilter
                var slashIdx = filterAndPayloadSpec.IndexOf('/', startIdx, endEventNameIdx - startIdx);
                if (0 <= slashIdx)
                {
                    listenerNameFilter = filterAndPayloadSpec.Substring(startIdx, slashIdx - startIdx);
                    eventNameFilter    = filterAndPayloadSpec.Substring(slashIdx + 1, endEventNameIdx - slashIdx - 1);
                }
                else if (startIdx < endEventNameIdx)
                {
                    listenerNameFilter = filterAndPayloadSpec.Substring(startIdx, endEventNameIdx - startIdx);
                }


                _eventSource.Message("DiagnosticSource: Enabling '" + (listenerNameFilter ?? "*") + "/" + (eventNameFilter ?? "*") + "'");

                // If the transform spec begins with a - it means you don't want implicit transforms.
                if (startTransformIdx < endIdx && filterAndPayloadSpec[startTransformIdx] == '-')
                {
                    _eventSource.Message("DiagnosticSource: suppressing implicit transforms.");
                    _noImplicitTransforms = true;
                    startTransformIdx++;
                }

                // Parse all the explicit transforms, if present
                if (startTransformIdx < endIdx)
                {
                    for (;;)
                    {
                        int specStartIdx = startTransformIdx;
                        int semiColonIdx = filterAndPayloadSpec.LastIndexOf(';', endIdx - 1, endIdx - startTransformIdx);
                        if (0 <= semiColonIdx)
                        {
                            specStartIdx = semiColonIdx + 1;
                        }

                        // Ignore empty specifications.
                        if (specStartIdx < endIdx)
                        {
                            if (_eventSource.IsEnabled(EventLevel.Informational, Keywords.Messages))
                            {
                                _eventSource.Message("DiagnosticSource: Parsing Explicit Transform '" + filterAndPayloadSpec.Substring(specStartIdx, endIdx - specStartIdx) + "'");
                            }

                            _explicitTransforms = new TransformSpec(filterAndPayloadSpec, specStartIdx, endIdx, _explicitTransforms);
                        }
                        if (startTransformIdx == specStartIdx)
                        {
                            break;
                        }
                        endIdx = semiColonIdx;
                    }
                }

                // Set up a subscription that watches for the given Diagnostic Sources and events which will call back
                // to the EventSource.
                _diagnosticsListenersSubscription = DiagnosticListener.AllListeners.Subscribe(new CallbackObserver <DiagnosticListener>(delegate(DiagnosticListener newListener)
                {
                    if (listenerNameFilter == null || listenerNameFilter == newListener.Name)
                    {
                        Predicate <string> eventNameFilterPredicate = null;
                        if (eventNameFilter != null)
                        {
                            eventNameFilterPredicate = (string eventName) => eventNameFilter == eventName;
                        }

                        var subscription = newListener.Subscribe(new CallbackObserver <KeyValuePair <string, object> >(delegate(KeyValuePair <string, object> evnt)
                        {
                            // The filter given to the DiagnosticSource may not work if users don't is 'IsEnabled' as expected.
                            // Thus we look for any events that may have snuck through and filter them out before forwarding.
                            if (eventNameFilter != null && eventNameFilter != evnt.Key)
                            {
                                return;
                            }

                            var outputArgs = this.Morph(evnt.Value);
#if !NO_EVENTSOURCE_COMPLEX_TYPE_SUPPORT
                            _eventSource.Event(newListener.Name, evnt.Key, outputArgs);
#else
                            _eventSource.EventJson(newListener.Name, evnt.Key, ToJson(outputArgs));
#endif
                        }), eventNameFilterPredicate);
                        _liveSubscriptions = new Subscriptions(subscription, _liveSubscriptions);
                    }
                }));
            }
Exemple #6
0
    void Update()
    {
        bool doTryConnect = true;

        doTryConnect = doTryConnect && !connected && UriString != "";
        if (cws != null)
        {
            doTryConnect = doTryConnect && (cws.State == WebSocketState.Closed || cws.State == WebSocketState.Aborted);
        }

        if (doTryConnect)
        {
            connected = true;
            cws       = null;
            TryConnect();
        }

        CKARNetworkState state;

        while (stateQueue.Dequeue(out state))
        {
            EventManager.InvokeNetworkStateChange(state);
        }

        string msgString;

        while (queue.Dequeue(out msgString))
        {
            Debug.Log(msgString);
            if (msgString.Contains("\"type\": \"transform\""))
            {
                WebsocketJsonTransform msg = JsonUtility.FromJson <WebsocketJsonTransform>(msgString);
                TransformSpec          ts  = new TransformSpec(msg.position, msg.scale, msg.rotation);
                if (msg.tree.Contains("marker"))
                {
                    EventManager.InvokeMarkerTransform(msg.tree, ts);
                }
                else if (msg.tree.Contains("master"))
                {
                    EventManager.InvokeMasterTransform(ts);
                }
                else
                {
                    lsysController.DispatchTransform(msg.tree, ts);
                }
            }
            else if (msgString.Contains("\"type\": \"shape\""))
            {
                WebsocketJsonShape msg = JsonUtility.FromJson <WebsocketJsonShape>(msgString);
                lsysController.DispatchShape(msg.tree, msg.shape);
            }
            else if (msgString.Contains("\"type\": \"value\""))
            {
                WebsocketJsonValue msg  = JsonUtility.FromJson <WebsocketJsonValue>(msgString);
                string[]           keys = msg.key.Split(',');
                foreach (string key in keys)
                {
                    ValueStore.Set(key, msg.payload); // will also invoke event
                }
            }
            else
            {
                WebsocketJsonMessage msg = JsonUtility.FromJson <WebsocketJsonMessage>(msgString);
                if (msg.type == "lsys")
                {
                    lsysController.Dispatch(msg.payload);
                }

                if (msg.type == "console")
                {
                    EventManager.InvokeConsole(msg.payload);
                }

                if (msg.type == "consoleStatus")
                {
                    EventManager.InvokeConsoleStatus(msg.payload);
                }

                if (msg.type == "view")
                {
                    EventManager.InvokeViewChange(msg.payload);
                }

                if (msg.type == "serverEvent")
                {
                    if (msg.payload == "endMarkerConfig")
                    {
                        EventManager.InvokeServerEventEndMarkerConfig();
                    }
                }
            }
        }
    }
 public void DispatchTransform(string key, TransformSpec ts)
 {
     GetLSystem(key).TransformSpec = ts;
     EventManager.InvokeTransformChange(key, ts);
 }