Example #1
0
        public override void OnWireReceived(UnsafeReader reader)
        {
            var taskId = RdId.Read(reader);
            var value  = ReadRequestDelegate(SerializationContext, reader);

            if (LogReceived.IsTraceEnabled())
            {
                LogReceived.Trace("endpoint `{0}`::({1}), taskId={2}, request = {3}", Location, RdId, taskId, value.PrintToString());
            }


            RdTask <TRes> rdTask;

            using (UsingDebugInfo()) //now supports only sync handlers
            {
                try
                {
                    rdTask = Handler(myBindLifetime, value);
                }
                catch (OperationCanceledException)
                {
                    rdTask = RdTask <TRes> .Cancelled();
                }
                catch (Exception e)
                {
                    rdTask = RdTask <TRes> .Faulted(e);
                }
            }

            rdTask.Result.Advise(myBindLifetime, result =>
            {
                if (LogSend.IsTraceEnabled())
                {
                    LogSend.Trace("endpoint `{0}`::({1}), taskId={2}, response = {3}", Location, RdId, taskId, result.PrintToString());
                }

                RdTaskResult <TRes> validatedResult;
                try
                {
                    if (result.Status == RdTaskStatus.Success)
                    {
                        AssertNullability(result.Result);
                    }
                    validatedResult = result;
                }
                catch (Exception e)
                {
                    LogSend.Error(e);
                    validatedResult = RdTaskResult <TRes> .Faulted(e);
                }

                Wire.Send(RdId, (writer) =>
                {
                    taskId.Write(writer);
                    RdTaskResult <TRes> .Write(WriteResponseDelegate, SerializationContext, writer, validatedResult);
                });
            });
        }
Example #2
0
        private void AdviseFrontendToUnityModel(Lifetime lifetime, FrontendBackendModel frontendBackendModel)
        {
            // BackendUnityModel is recreated frequently (e.g. on each AppDomain reload when changing play/edit mode).
            // So subscribe to the frontendBackendModel once and flow in changes only if backendUnityModel is available.
            // Note that we only flow changes, not the current value. Even though these properties are stateful,
            // frontendBackendModel is not the source of truth - values need to flow from backendUnityModel. Also, due
            // to model reload, we go through a few values before we stabilise. E.g.:
            // * User clicks play, fb.Play is true, flows into bu.Play which switches to play mode and causes an
            //   AppDomain reload.
            // * bu.Play becomes false due to AppDomain teardown, flows into fb.Play
            // * BackendUnityModel is torn down and recreated (<- WARNING!)
            // * bu.Play becomes true as Unity enters play mode, flows into fb.Play
            // If we flowed the current value of fb.Play into backendUnityModel when it is recreated, we'd set it to
            // false, triggering play mode to end.
            // Step is simply since it's a non-stateful ISource<T>
            var backendUnityModelProperty = myBackendUnityHost.BackendUnityModel;

            frontendBackendModel.PlayControls.Play.FlowChangesIntoRdDeferred(lifetime,
                                                                             () => backendUnityModelProperty.Maybe.ValueOrDefault?.PlayControls.Play);
            frontendBackendModel.PlayControls.Pause.FlowChangesIntoRdDeferred(lifetime,
                                                                              () => backendUnityModelProperty.Maybe.ValueOrDefault?.PlayControls.Pause);
            frontendBackendModel.PlayControls.Step.Advise(lifetime, () => backendUnityModelProperty.Maybe.ValueOrDefault?.PlayControls.Step.Fire());

            // Called from frontend to generate the UIElements schema files
            frontendBackendModel.GenerateUIElementsSchema.Set((l, u) =>
                                                              backendUnityModelProperty.Maybe.ValueOrDefault?.GenerateUIElementsSchema.Start(l, u).ToRdTask(l));

            // Signalled from frontend to select and ping the object in the Project view
            frontendBackendModel.ShowFileInUnity.Advise(lifetime, file =>
                                                        backendUnityModelProperty.Maybe.ValueOrDefault?.ShowFileInUnity.Fire(file));

            // Signalled from fronted to open the preferences window
            frontendBackendModel.ShowPreferences.Advise(lifetime, _ =>
                                                        backendUnityModelProperty.Maybe.ValueOrDefault?.ShowPreferences.Fire());

            // Called from frontend to run a method in unity
            frontendBackendModel.RunMethodInUnity.Set((l, data) =>
            {
                var backendUnityModel = backendUnityModelProperty.Maybe.ValueOrDefault;
                return(backendUnityModel == null
                    ? RdTask <RunMethodResult> .Cancelled()
                    : backendUnityModel.RunMethodInUnity.Start(l, data).ToRdTask(l));
            });

            frontendBackendModel.HasUnsavedScenes.Set((l, u) =>
                                                      backendUnityModelProperty.Maybe.ValueOrDefault?.HasUnsavedScenes.Start(l, u).ToRdTask(l));
        }