aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/ScriptManager.cs
blob: 3452b0376e3c33dd7e7dc2dbab7f672fa6b3195c (plain)
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using System.Threading;
using log4net;
using OpenMetaverse;
using OpenSim.Region.ScriptEngine.Shared;
using OpenSim.ScriptEngine.Shared;
using EventParams=OpenSim.ScriptEngine.Shared.EventParams;

namespace OpenSim.ScriptEngine.Components.DotNetEngine.Scheduler
{
    public partial class ScriptManager: IScriptExecutor
    {
        private const int NoWorkSleepMs = 50;
        private const int NoWorkSleepMsInc = 1;                 // How much time to increase wait with on every iteration
        private const int NoWorkSleepMsIncMax = 300;            // Max time to wait

        internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        public string Name { get { return "SECS.DotNetEngine.ScriptManager"; } }
        private static Thread ScriptLoadUnloadThread;
        public Dictionary<uint, Dictionary<UUID, ScriptStructure>> Scripts = new Dictionary<uint, Dictionary<UUID, ScriptStructure>>();

        private RegionInfoStructure CurrentRegion;
        public void Initialize(RegionInfoStructure currentRegion)
        {
            CurrentRegion = currentRegion;
        }

        public ScriptManager()
        {
            ScriptLoadUnloadThread = new Thread(LoadUnloadLoop);
            ScriptLoadUnloadThread.Name = "ScriptLoadUnloadThread";
            ScriptLoadUnloadThread.IsBackground = true;
            ScriptLoadUnloadThread.Start();
        }
        public void Close() { }

        private void LoadUnloadLoop ()
        {
            int _NoWorkSleepMsInc = 0;
            while (true)
            {
                if (DoScriptLoadUnload())
                {
                    // We found work, reset counter
                    _NoWorkSleepMsInc = NoWorkSleepMs;
                } else
                {
                    // We didn't find work
                    // Sleep
                    Thread.Sleep(NoWorkSleepMs + NoWorkSleepMsInc);
                    // Increase sleep delay
                    _NoWorkSleepMsInc += NoWorkSleepMsInc;
                    // Make sure we don't exceed max
                    if (_NoWorkSleepMsInc > NoWorkSleepMsIncMax)
                        _NoWorkSleepMsInc = NoWorkSleepMsIncMax;
                }
            }
        }

        #region Add/Remove/Find script functions for our Script memory structure
        private void MemAddScript(ScriptStructure script)
        {
            lock (scriptLock)
            {
                // Create object if it doesn't exist
                if (!Scripts.ContainsKey(script.LocalID))
                    Scripts.Add(script.LocalID, new Dictionary<UUID, ScriptStructure>());

                // Delete script if it exists
                Dictionary<UUID, ScriptStructure> Obj;
                if (Scripts.TryGetValue(script.LocalID, out Obj))
                    if (Obj.ContainsKey(script.ItemID) == true)
                        Obj.Remove(script.ItemID);

                // Add to object
                Obj.Add(script.ItemID, script);
            }
        }
        private void MemRemoveScript(uint LocalID, UUID ItemID)
        {
            // TODO: Also clean up command queue and async commands for object
            lock (scriptLock)
            {
                // Create object if it doesn't exist
                if (!Scripts.ContainsKey(LocalID))
                    return;

                // Delete script if it exists
                Dictionary<UUID, ScriptStructure> Obj;
                if (Scripts.TryGetValue(LocalID, out Obj))
                    if (Obj.ContainsKey(ItemID) == true)
                        Obj.Remove(ItemID);

                // Empty?
                if (Obj.Count == 0)
                    Scripts.Remove(LocalID);

            }
        }
        public bool TryGetScript(uint localID, UUID itemID, ref ScriptStructure script)
        {
            lock (scriptLock)
            {

                if (Scripts.ContainsKey(localID) == false)
                    return false;

                Dictionary<UUID, ScriptStructure> Obj;
                if (Scripts.TryGetValue(localID, out Obj))
                    if (Obj.ContainsKey(itemID) == false)
                        return false;

                // Get script
                return Obj.TryGetValue(itemID, out script);
            }
        }
        public ScriptStructure GetScript(uint localID, UUID itemID)
        {
            lock (scriptLock)
            {

                if (Scripts.ContainsKey(localID) == false)
                    throw new Exception("No script with LocalID " + localID + " was found.");

                Dictionary<UUID, ScriptStructure> Obj;
                if (Scripts.TryGetValue(localID, out Obj))
                    if (Obj.ContainsKey(itemID) == false)
                        throw new Exception("No script with ItemID " + itemID + " was found.");

                // Get script
                return Obj[itemID];
            }
        }
        public bool TryGetScripts(uint localID, ref Dictionary<UUID, ScriptStructure> returnList)
        {
            Dictionary<UUID, ScriptStructure> getList = GetScripts(localID);
                if (getList != null)
                {
                    returnList = getList;
                    return true;
                }
            return false;
        }
        public Dictionary<UUID, ScriptStructure> GetScripts(uint localID)
        {
            lock (scriptLock)
            {

                if (Scripts.ContainsKey(localID) == false)
                    return null;
                return Scripts[localID];
            }
        }
        #endregion

        public void ExecuteCommand(EventParams p)
        {
            ScriptStructure ss = new ScriptStructure();
            if (TryGetScript(p.LocalID, p.ItemID, ref ss))
                ExecuteCommand(ref ss, p);
        }

        public void ExecuteCommand(ref ScriptStructure scriptContainer, EventParams p)
        {
            m_log.DebugFormat("[{0}] ######################################################", Name);
            m_log.DebugFormat("[{0}] Command execution ItemID {1}: \"{2}\".", Name, scriptContainer.ItemID, p.EventName);
            scriptContainer.ExecuteEvent(p);
            m_log.DebugFormat("[{0}] ######################################################", Name);
        }

    }
}