Unity 捕获IronPython脚本错误

北战南征 提交于 2020-03-23 13:10:01
版权声明:本文为博主原创文章。未经博主同意不得转载。 https://blog.csdn.net/akof1314/article/details/36048747

捕获的方法摘自《IronPython in Action》一书,代码例如以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Runtime.Exceptions;
using Microsoft.Scripting;
using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Hosting;

using Plugins;


namespace EmbeddingPlugin
{
    internal class PythonStream: MemoryStream
    {
        TextBox _output;
        public PythonStream(TextBox textbox)
        {
            _output = textbox;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            _output.AppendText(Encoding.UTF8.GetString(buffer, offset, count));
        }
    }

    internal class Engine
    {
        ScriptEngine _engine;
        ScriptRuntime _runtime;
        TextBox _box;

        public List<PluginBase> Plugins
        {
            get { return PluginStore.Plugins; }
        }


        public Engine(TextBox textbox)
        {
            _engine = Python.CreateEngine();
            _runtime = _engine.Runtime;
            _box = textbox;

            SetStreams();
            string rootDir = AddAssemblies();
            LoadPlugins(rootDir);
        }

        public void SetStreams()
        {
            PythonStream stream = new PythonStream(_box);
            _runtime.IO.SetOutput(stream, Encoding.UTF8);
            _runtime.IO.SetErrorOutput(stream, Encoding.UTF8);
        }

        public string AddAssemblies()
        {
            Assembly mainAssembly = Assembly.GetExecutingAssembly();

            string rootDir = Directory.GetParent(mainAssembly.Location).FullName;
            string pluginsPath = Path.Combine(rootDir, "Plugins.dll");

            Assembly pluginsAssembly = Assembly.LoadFile(pluginsPath);

            _runtime.LoadAssembly(mainAssembly);
            _runtime.LoadAssembly(pluginsAssembly);
            _runtime.LoadAssembly(typeof(String).Assembly);
            _runtime.LoadAssembly(typeof(Uri).Assembly);

            return rootDir;
        }

        public void LoadPlugins(string rootDir)
        {
            string pluginsDir = Path.Combine(rootDir, "plugins");
            foreach (string path in Directory.GetFiles(pluginsDir))
            {
                if (path.ToLower().EndsWith(".py"))
                {
                    CreatePlugin(path);
                }
            }
        }

        public void CreatePlugin(string path)
        {
            try
            {
                ScriptSource script = _engine.CreateScriptSourceFromFile(path);
                CompiledCode code = script.Compile();
                ScriptScope scope = _engine.CreateScope();
                script.Execute(scope);
            }
            catch (SyntaxErrorException e)
            {
                string msg = "Syntax error in \"{0}\"";
                ShowError(msg, Path.GetFileName(path), e);
            }
            catch (SystemExitException e)
            {
                string msg = "SystemExit in \"{0}\"";
                ShowError(msg, Path.GetFileName(path), e);
            }

            catch (Exception e)
            {
                string msg = "Error loading plugin \"{0}\"";
                ShowError(msg, Path.GetFileName(path), e);
            }
        }

        public void ShowError(string title, string name, Exception e)
        {
            string caption = String.Format(title, name);
            ExceptionOperations eo = _engine.GetService<ExceptionOperations>();
            string error = eo.FormatException(e);
            MessageBox.Show(error, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);

        }

        public void ExecutePluginAtIndex(int index)
        {
            PluginBase plugin = Plugins[index];

            try
            {
                plugin.Execute(_box);
            }
            catch (Exception e)
            {
                string msg = "Error executing plugin \"{0}\"";
                ShowError(msg, plugin.Name, e);
            }
        }
    }
}

结果如:

移植到Unity中。则仅仅取关键性代码就可以。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!