예제 #1
0
        public override Dictionary <string, object> Evaluate(EvaluationPackage evalpackage)
        {
            var engine = IronPython.Hosting.Python.CreateEngine();

            scope = engine.CreateScope();
            //http://techartsurvival.blogspot.com/2013/12/techartists-doin-it-for-themselves.html#gpluscomments
            engine.Runtime.LoadAssembly(typeof(PythonIOModule).Assembly);
            engine.Runtime.LoadAssembly(typeof(GameObject).Assembly);
            engine.Runtime.LoadAssembly(typeof(Editor).Assembly);
            string dllpath = System.IO.Path.GetDirectoryName(
                (typeof(ScriptEngine)).Assembly.Location).Replace(
                "\\", "/");


            // load needed modules and paths
            StringBuilder init = new StringBuilder();

            init.AppendLine("import sys");
            init.AppendFormat("sys.path.append(\"{0}\")\n", dllpath + "/Lib");
            init.AppendFormat("sys.path.append(\"{0}\")\n", dllpath + "/DLLs");
            init.AppendLine("import UnityEngine as unity");
            init.AppendLine("import UnityEditor as editor");
            init.AppendLine("import StringIO");
            init.AppendLine("unity.Debug.Log(\"Python console initialized\")");


            var OutputNames       = evalpackage.OutputNames;
            var variableNames     = evalpackage.VariableNames;
            var variableValues    = evalpackage.VariableValues;
            var ExecutionPointers = evalpackage.ExecutionPointers;
            var script            = evalpackage.Code;

            foreach (var variable in variableNames)
            {
                var index = variableNames.IndexOf(variable);
                // do we need to do some conversion of this type...TODO
                scope.SetVariable(variable, variableValues[index]);
                Debug.Log("setting" + variable + "to" + variableValues[index].ToString());
            }

            foreach (var pointer in ExecutionPointers)
            {
                scope.SetVariable(pointer.First, pointer.Second);
                Debug.Log("setting " + pointer.First + " to " + pointer.Second.ToString() + " in python context");
                //TODO if this list is empty or if the script never exposes these triggers then we need
                //complain at compile time, throw an exception, or just inject one at the end of the
                //script or after this eval returns
            }


            using (var memoryStream = new MemoryStream())
            {
                engine.Runtime.IO.SetOutput(memoryStream, new StreamWriter(memoryStream));
                try
                {
                    engine.CreateScriptSourceFromString(init.ToString() + script).Execute(scope);
                }
                catch (Exception e)
                {
                    string error = engine.GetService <ExceptionOperations>().FormatException(e);
                    Debug.LogException(e);
                }
                finally
                {
                    var length = (int)memoryStream.Length;
                    var bytes  = new byte[length];
                    memoryStream.Seek(0, SeekOrigin.Begin);
                    memoryStream.Read(bytes, 0, length);
                    StdOut = Encoding.UTF8.GetString(bytes, 0, length).Trim();
                    Debug.Log("<color=yellow>Python Std:</color>" + StdOut);
                }
                //TODO we need a way to push values from the python context to the nodeModel
                //during execution, not sure if this is possible, for example, to gather
                //some intermediate outputs during a for loop execution, possible implementation
                //can just inject some logic into the callOutput method, that gathers all output
                //variables, if they are not set or cannot be found, just continue execution
                // but don't fail, they just might not be set yet


                var outdict = PollScopeForOutputs(OutputNames);



                return(outdict);
            }
        }
예제 #2
0
        //
        public override Dictionary <string, object> Evaluate(EvaluationPackage evalpackage)
        {
            var outputNames       = evalpackage.OutputNames;
            var variableNames     = evalpackage.VariableNames;
            var variableValues    = evalpackage.VariableValues;
            var executionPointers = evalpackage.ExecutionPointers;

            Code = evalpackage.CodePointer;
            //Debug.Log("CODE is of type" + Code.GetType().ToString());
            using (var memoryStream = new MemoryStream())
            {
                //TODO I think this needs to only happen once, or on a null check,
                //this dictionary will get overwritten anytime this function is called currently...
                //build the intermediatedict and assign keys from the output names
                var outdict = new Dictionary <string, object>();
                foreach (var outname in outputNames)
                {
                    if (outdict.ContainsKey(outname))
                    {
                        outdict[outname] = "overwrote the previous entry";
                    }
                    else
                    {
                        //Debug.Log("added a space in the outdict in the csharp evaluator with name " + outname);
                        outdict[outname] = null;
                    }
                }


                //we expose all input variables and trigger delegates in the inputdict which we will pass to compiled eval
                var inputdict = new Dictionary <string, object>();
                foreach (var variable in variableNames)
                {
                    var index = variableNames.IndexOf(variable);
                    inputdict[variable] = variableValues[index];
                    //Debug.Log("setting" + variable + "to" + variableValues[index].ToString());
                }

                foreach (var pointer in executionPointers)
                {
                    inputdict[pointer.First] = pointer.Second;
                    //Debug.Log("setting " + pointer.First + " to " + pointer.Second.ToString() + " in csharp context");
                }

                //redirect the output for this delegate
                //Console.SetOut (new StreamWriter(memoryStream));

                try
                {
                    outdict = CompiledEvaluation(inputdict, ref outdict);
                }
                catch (Exception e)
                {
                    string error = e.Message + e.StackTrace;
                    Debug.LogException(e);
                }
                finally
                {
                    var length = (int)memoryStream.Length;
                    var bytes  = new byte[length];
                    memoryStream.Seek(0, SeekOrigin.Begin);
                    memoryStream.Read(bytes, 0, length);
                    StdOut = Encoding.UTF8.GetString(bytes, 0, length).Trim();
                }
                //Console.OpenStandardOutput();
                return(outdict);
            }
        }