Exemple #1
0
        private IEnumerator <object> RemoteCallTask(ProcessInfo process)
        {
            var channel    = process.GetNamedChannel("remotecall");
            var serializer = new JavaScriptSerializer();

            while (true)
            {
                var fNext = channel.Receive();
                using (fNext)
                    yield return(fNext);

                object[] callTuple    = serializer.Deserialize <object[]>(fNext.Result.DecodeAsciiZ());
                string   scriptName   = callTuple[0] as string;
                string   methodName   = callTuple[1] as string;
                object[] rawArguments = callTuple[2] as object[];
                long?    resultId     = null;

                if (callTuple.Length >= 4)
                {
                    resultId = Convert.ToInt64(callTuple[3]);
                }

                object[] functionArguments;
                if (rawArguments == null)
                {
                    functionArguments = new object[] { process };
                }
                else
                {
                    functionArguments = new object[rawArguments.Length + 1];

                    functionArguments[0] = process;

                    for (int i = 0; i < rawArguments.Length; i++)
                    {
                        functionArguments[i + 1] = rawArguments[i];
                    }
                }

                ScriptName sn;
                if (!Program.PythonModuleToScript.TryGetValue(scriptName, out sn))
                {
                    sn = new ScriptName(scriptName);
                }

                IManagedScript instance = Program.GetScriptInstance(sn);

                if (instance == null)
                {
                    LogPrint(process,
                             "Remote call attempted on script '{0}' that isn't loaded.", scriptName
                             );
                    continue;
                }

                IEnumerator <object> resultTask = null;
                object    result = null;
                Exception error  = null;

                try {
                    result = instance.GetType().InvokeMember(
                        methodName, BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, instance, functionArguments
                        );
                } catch (Exception ex) {
                    error = ex;
                }

                if (error != null)
                {
                    if (resultId.HasValue)
                    {
                        yield return(SendRemoteCallResult(process, resultId.Value, null, error));
                    }
                    else
                    {
                        Program.Scheduler.OnTaskError(error);
                    }
                }
                else
                {
                    resultTask = result as IEnumerator <object>;

                    if (resultTask != null)
                    {
                        var fResult = Program.Scheduler.Start(
                            resultTask, TaskExecutionPolicy.RunWhileFutureLives
                            );
                        process.OwnedFutures.Add(fResult);

                        if (resultId.HasValue)
                        {
                            fResult.RegisterOnComplete((_) => {
                                object r;
                                Exception e;
                                _.GetResult(out r, out e);
                                Program.Scheduler.Start(SendRemoteCallResult(process, resultId.Value, r, e));
                            });
                        }
                    }
                    else
                    {
                        if (resultId.HasValue)
                        {
                            yield return(SendRemoteCallResult(process, resultId.Value, result, null));
                        }
                    }
                }
            }
        }