diff options
7 files changed, 162 insertions, 2 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Host.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Host.cs index 94796e4..193461d 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Host.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Host.cs | |||
@@ -38,11 +38,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
38 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 38 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
39 | private readonly IGraphics m_graphics; | 39 | private readonly IGraphics m_graphics; |
40 | private readonly IExtension m_extend; | 40 | private readonly IExtension m_extend; |
41 | private readonly IMicrothreader m_threader; | ||
41 | //private Scene m_scene; | 42 | //private Scene m_scene; |
42 | 43 | ||
43 | public Host(IObject m_obj, Scene m_scene, IExtension m_extend) | 44 | public Host(IObject m_obj, Scene m_scene, IExtension m_extend, IMicrothreader m_threader) |
44 | { | 45 | { |
45 | this.m_obj = m_obj; | 46 | this.m_obj = m_obj; |
47 | this.m_threader = m_threader; | ||
46 | this.m_extend = m_extend; | 48 | this.m_extend = m_extend; |
47 | //this.m_scene = m_scene; | 49 | //this.m_scene = m_scene; |
48 | 50 | ||
@@ -68,5 +70,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
68 | { | 70 | { |
69 | get { return m_extend; } | 71 | get { return m_extend; } |
70 | } | 72 | } |
73 | |||
74 | public IMicrothreader Microthreads | ||
75 | { | ||
76 | get { return m_threader; } | ||
77 | } | ||
71 | } | 78 | } |
72 | } | 79 | } |
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IHost.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IHost.cs index fd73ffd..cf63fd6 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IHost.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IHost.cs | |||
@@ -39,5 +39,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
39 | ILog Console { get; } | 39 | ILog Console { get; } |
40 | IGraphics Graphics { get; } | 40 | IGraphics Graphics { get; } |
41 | IExtension Extensions { get; } | 41 | IExtension Extensions { get; } |
42 | IMicrothreader Microthreads { get; } | ||
42 | } | 43 | } |
43 | } | 44 | } |
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IMicrothreader.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IMicrothreader.cs new file mode 100644 index 0000000..22d3a99 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IMicrothreader.cs | |||
@@ -0,0 +1,12 @@ | |||
1 | using System; | ||
2 | using System.Collections; | ||
3 | using System.Collections.Generic; | ||
4 | using System.Text; | ||
5 | |||
6 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule.Interfaces | ||
7 | { | ||
8 | public interface IMicrothreader | ||
9 | { | ||
10 | void Run(IEnumerable microthread); | ||
11 | } | ||
12 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs index a7b63b0..73eb98f 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs | |||
@@ -52,6 +52,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
52 | 52 | ||
53 | private static readonly CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); | 53 | private static readonly CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); |
54 | 54 | ||
55 | private readonly MicroScheduler m_microthreads = new MicroScheduler(); | ||
56 | |||
55 | public void RegisterExtension<T>(T instance) | 57 | public void RegisterExtension<T>(T instance) |
56 | { | 58 | { |
57 | m_extensions[typeof (T)] = instance; | 59 | m_extensions[typeof (T)] = instance; |
@@ -66,6 +68,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
66 | m_log.Info("[MRM] Enabling MRM Module"); | 68 | m_log.Info("[MRM] Enabling MRM Module"); |
67 | m_scene = scene; | 69 | m_scene = scene; |
68 | scene.EventManager.OnRezScript += EventManager_OnRezScript; | 70 | scene.EventManager.OnRezScript += EventManager_OnRezScript; |
71 | scene.EventManager.OnFrame += EventManager_OnFrame; | ||
69 | 72 | ||
70 | scene.RegisterModuleInterface<IMRMModule>(this); | 73 | scene.RegisterModuleInterface<IMRMModule>(this); |
71 | } | 74 | } |
@@ -80,6 +83,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
80 | } | 83 | } |
81 | } | 84 | } |
82 | 85 | ||
86 | void EventManager_OnFrame() | ||
87 | { | ||
88 | m_microthreads.Tick(1000); | ||
89 | } | ||
90 | |||
91 | static string ConvertMRMKeywords(string script) | ||
92 | { | ||
93 | script = script.Replace("microthreaded void ", "IEnumerable"); | ||
94 | script = script.Replace("relax;", "yield return null;"); | ||
95 | |||
96 | return script; | ||
97 | } | ||
98 | |||
83 | void EventManager_OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource) | 99 | void EventManager_OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource) |
84 | { | 100 | { |
85 | if (script.StartsWith("//MRM:C#")) | 101 | if (script.StartsWith("//MRM:C#")) |
@@ -87,11 +103,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
87 | if (m_scene.GetSceneObjectPart(localID).OwnerID != m_scene.RegionInfo.MasterAvatarAssignedUUID) | 103 | if (m_scene.GetSceneObjectPart(localID).OwnerID != m_scene.RegionInfo.MasterAvatarAssignedUUID) |
88 | return; | 104 | return; |
89 | 105 | ||
106 | script = ConvertMRMKeywords(script); | ||
107 | |||
90 | try | 108 | try |
91 | { | 109 | { |
92 | m_log.Info("[MRM] Found C# MRM"); | 110 | m_log.Info("[MRM] Found C# MRM"); |
93 | IWorld m_world = new World(m_scene); | 111 | IWorld m_world = new World(m_scene); |
94 | IHost m_host = new Host(new SOPObject(m_scene, localID), m_scene, new ExtensionHandler(m_extensions)); | 112 | IHost m_host = new Host(new SOPObject(m_scene, localID), m_scene, new ExtensionHandler(m_extensions), |
113 | m_microthreads); | ||
95 | 114 | ||
96 | MRMBase mmb = (MRMBase)AppDomain.CurrentDomain.CreateInstanceFromAndUnwrap( | 115 | MRMBase mmb = (MRMBase)AppDomain.CurrentDomain.CreateInstanceFromAndUnwrap( |
97 | CompileFromDotNetText(script, itemID.ToString()), | 116 | CompileFromDotNetText(script, itemID.ToString()), |
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MicroScheduler.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MicroScheduler.cs new file mode 100644 index 0000000..a5da87b --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MicroScheduler.cs | |||
@@ -0,0 +1,38 @@ | |||
1 | using System; | ||
2 | using System.Collections; | ||
3 | using System.Collections.Generic; | ||
4 | using System.Text; | ||
5 | using OpenSim.Region.OptionalModules.Scripting.Minimodule.Interfaces; | ||
6 | |||
7 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
8 | { | ||
9 | public class MicroScheduler : IMicrothreader | ||
10 | { | ||
11 | private readonly List<IEnumerator> m_threads = new List<IEnumerator>(); | ||
12 | |||
13 | public void Run(IEnumerable microthread) | ||
14 | { | ||
15 | lock (m_threads) | ||
16 | m_threads.Add(microthread.GetEnumerator()); | ||
17 | } | ||
18 | |||
19 | public void Tick(int count) | ||
20 | { | ||
21 | lock (m_threads) | ||
22 | { | ||
23 | if(m_threads.Count == 0) | ||
24 | return; | ||
25 | |||
26 | int i = 0; | ||
27 | while (m_threads.Count > 0 && i < count) | ||
28 | { | ||
29 | i++; | ||
30 | bool running = m_threads[i%m_threads.Count].MoveNext(); | ||
31 | |||
32 | if (!running) | ||
33 | m_threads.Remove(m_threads[i%m_threads.Count]); | ||
34 | } | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/Microthreads/MicrothreadSample.txt b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/Microthreads/MicrothreadSample.txt new file mode 100644 index 0000000..dc15c47 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/Microthreads/MicrothreadSample.txt | |||
@@ -0,0 +1,40 @@ | |||
1 | //MRM:C# | ||
2 | using System.Collections; | ||
3 | using System.Collections.Generic; | ||
4 | using OpenSim.Region.OptionalModules.Scripting.Minimodule; | ||
5 | |||
6 | namespace OpenSim | ||
7 | { | ||
8 | class MiniModule : MRMBase | ||
9 | { | ||
10 | public microthreaded void MicroThreadFunction(string testparam) | ||
11 | { | ||
12 | Host.Object.Say("Hello " + testparam); | ||
13 | |||
14 | relax; // the 'relax' keyword gives up processing time. | ||
15 | // and should be inserted before, after or in | ||
16 | // any computationally "heavy" zones. | ||
17 | |||
18 | int c = 500; | ||
19 | while(c-- < 0) { | ||
20 | Host.Object.Say("C=" + c); | ||
21 | relax; // Putting 'relax' in microthreaded loops | ||
22 | // is an easy way to lower the CPU tax | ||
23 | // on your script. | ||
24 | } | ||
25 | |||
26 | } | ||
27 | |||
28 | public override void Start() | ||
29 | { | ||
30 | Host.Microthreads.Run( | ||
31 | MicroThreadFunction("World!") | ||
32 | ); | ||
33 | } | ||
34 | |||
35 | public override void Stop() | ||
36 | { | ||
37 | |||
38 | } | ||
39 | } | ||
40 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/TestModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/TestModule.cs index 702ac74..73af7f0 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/TestModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/TestModule.cs | |||
@@ -25,12 +25,55 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Collections; | ||
29 | using System.Collections.Generic; | ||
28 | using OpenSim.Region.OptionalModules.Scripting.Minimodule; | 30 | using OpenSim.Region.OptionalModules.Scripting.Minimodule; |
29 | 31 | ||
30 | namespace OpenSim | 32 | namespace OpenSim |
31 | { | 33 | { |
32 | class MiniModule : MRMBase | 34 | class MiniModule : MRMBase |
33 | { | 35 | { |
36 | // private microthreaded Function(params...) | ||
37 | private IEnumerable TestMicrothread(string param) | ||
38 | { | ||
39 | Host.Console.Info("Microthreaded " + param); | ||
40 | // relax; | ||
41 | yield return null; | ||
42 | Host.Console.Info("Microthreaded 2" + param); | ||
43 | yield return null; | ||
44 | int c = 100; | ||
45 | while(c-- < 0) | ||
46 | { | ||
47 | Host.Console.Info("Microthreaded Looped " + c + " " + param); | ||
48 | yield return null; | ||
49 | } | ||
50 | } | ||
51 | |||
52 | public void Microthread(IEnumerable thread) | ||
53 | { | ||
54 | |||
55 | } | ||
56 | |||
57 | public void RunMicrothread() | ||
58 | { | ||
59 | List<IEnumerator> threads = new List<IEnumerator>(); | ||
60 | threads.Add(TestMicrothread("A").GetEnumerator()); | ||
61 | threads.Add(TestMicrothread("B").GetEnumerator()); | ||
62 | threads.Add(TestMicrothread("C").GetEnumerator()); | ||
63 | |||
64 | Microthread(TestMicrothread("Ohai")); | ||
65 | |||
66 | int i = 0; | ||
67 | while(threads.Count > 0) | ||
68 | { | ||
69 | i++; | ||
70 | bool running = threads[i%threads.Count].MoveNext(); | ||
71 | |||
72 | if (!running) | ||
73 | threads.Remove(threads[i%threads.Count]); | ||
74 | } | ||
75 | } | ||
76 | |||
34 | public override void Start() | 77 | public override void Start() |
35 | { | 78 | { |
36 | // Say Hello | 79 | // Say Hello |