-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMaverickHost.cs
158 lines (124 loc) · 4.66 KB
/
MaverickHost.cs
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
146
147
148
149
150
151
152
153
154
155
156
157
158
using Goose;
using NLua;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Maverick
{
class MaverickHost
{
AppManifest _appManifest;
VM _vm;
IMaverickLog _log;
public MaverickHost(params string[] args)
{
//provide a default log
ServiceLocator.MapType<IMaverickLog, Log>();
_log = ServiceLocator.Resolve<IMaverickLog>();
_log.Write("Initializing Configuration...");
Configuration.Initialize(args);
_log.Write("Initializing ServiceLocator...");
ServiceLocator.Initialize();
_log.Write("Preparing Lua virtual machine...");
_vm = new VM();
_vm.Import(Assembly.GetExecutingAssembly());
_vm.DoString("require \"lib/Maverick\"");
_vm["maverick"] = this;
if (Configuration.REPL) { repl(); return; }
//if (Configuration.Drone) { drone(); return; }
_appManifest = AppCompiler.Make(_vm, Configuration.AppPath);
foreach (Assembly assembly in _appManifest.Assemblies)
{
initializeAssembly(assembly);
}
//resolve the log service again in case it has been remapped
_log = ServiceLocator.Resolve<IMaverickLog>();
}
void initializeAssembly(Assembly assembly)
{
IEnumerable<MethodInfo> initializerMethods = from type in assembly.GetExportedTypes() from method in type.GetMethods() where method.IsDefined(typeof(MaverickAssemblyInitializer), false) select method;
foreach (MethodInfo initializerMethod in initializerMethods)
{
if (!initializerMethod.IsStatic) throw new Exception("Unable to invoke non-static assembly initializer: " + initializerMethod.Name);
if (initializerMethod.GetParameters().Count() > 0) throw new Exception("Unable to invoke assembly initializer with parameters: " + initializerMethod.Name);
_log.Write("Initializing assembly " + assembly.FullName + " with method " + initializerMethod.Name);
initializerMethod.Invoke(null, null);
}
}
private void repl()
{
string line;
while (true)
{
try
{
Console.Write(">");
line = Console.ReadLine();
object[] res = _vm.DoString(line);
if (res != null) { Console.Write(res); }
}
catch (Exception e)
{
Console.WriteLine(Utility.ExceptionToString(e));
}
}
}
internal void Run()
{
_log.Write("Executing root script body...");
_vm.DoString(_appManifest.Body);
foreach (string include in _appManifest.Includes)
{
_log.Write("Executing included script...");
_vm.DoString(include);
}
if (_appContainers.Count > 0)
{
_log.Write("Executing " + _appContainers.Count + " app containers...");
foreach(MaverickApp app in _appContainers.Reverse<MaverickApp>()) { app.Run(); }
}
_log.Write("Starting scheduler...");
Scheduler.Run();
_log.Write("Scheduler stopped.");
}
List<MaverickApp> _appContainers = new List<MaverickApp>();
public MaverickApp app(Action func)
{
_log.Write("Registering app container...");
MaverickApp app = new MaverickApp(func);
_appContainers.Add(app);
return app;
}
public void debug()
{
System.Diagnostics.Debugger.Break();
}
public void debug(object data)
{
System.Diagnostics.Debugger.Break();
}
public void log(string message)
{
log(message, false);
}
public void log(string message, bool verboseOnly)
{
if (verboseOnly) { _log.WriteIfVerbose(message); }
else
{
_log.Write(message);
}
}
public void die(string message)
{
_log.Write(message);
Environment.Exit(0);
}
public void registerFunction(string path,object target, Delegate func)
{
_vm.RegisterFunction(path, target, func.Method);
}
}
}