diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
5 files changed, 84 insertions, 79 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs index 583d2ff..51fd41a 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs | |||
@@ -132,12 +132,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
132 | /// </summary> | 132 | /// </summary> |
133 | private void Start() | 133 | private void Start() |
134 | { | 134 | { |
135 | EventQueueThread = new Thread(EventQueueThreadLoop); | 135 | EventQueueThread = Watchdog.StartThread(EventQueueThreadLoop, "EventQueueManagerThread_" + ThreadCount, MyThreadPriority, true); |
136 | EventQueueThread.IsBackground = true; | ||
137 | |||
138 | EventQueueThread.Priority = MyThreadPriority; | ||
139 | EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount; | ||
140 | EventQueueThread.Start(); | ||
141 | 136 | ||
142 | // Look at this... Don't you wish everyone did that solid | 137 | // Look at this... Don't you wish everyone did that solid |
143 | // coding everywhere? :P | 138 | // coding everywhere? :P |
@@ -184,6 +179,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
184 | while (true) | 179 | while (true) |
185 | { | 180 | { |
186 | DoProcessQueue(); | 181 | DoProcessQueue(); |
182 | Watchdog.UpdateThread(); | ||
187 | } | 183 | } |
188 | } | 184 | } |
189 | catch (ThreadAbortException) | 185 | catch (ThreadAbortException) |
@@ -214,6 +210,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
214 | m_log.ErrorFormat("[{0}]: Exception {1} thrown", ScriptEngineName, e.GetType().ToString()); | 210 | m_log.ErrorFormat("[{0}]: Exception {1} thrown", ScriptEngineName, e.GetType().ToString()); |
215 | throw e; | 211 | throw e; |
216 | } | 212 | } |
213 | |||
214 | Watchdog.UpdateThread(); | ||
217 | } | 215 | } |
218 | } | 216 | } |
219 | catch (ThreadAbortException) | 217 | catch (ThreadAbortException) |
@@ -226,6 +224,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
226 | "[{0}]: Event queue thread terminating with exception. PLEASE REBOOT YOUR SIM - SCRIPT EVENTS WILL NOT WORK UNTIL YOU DO. Exception is {1}", | 224 | "[{0}]: Event queue thread terminating with exception. PLEASE REBOOT YOUR SIM - SCRIPT EVENTS WILL NOT WORK UNTIL YOU DO. Exception is {1}", |
227 | ScriptEngineName, e); | 225 | ScriptEngineName, e); |
228 | } | 226 | } |
227 | |||
228 | Watchdog.RemoveThread(); | ||
229 | } | 229 | } |
230 | 230 | ||
231 | public void DoProcessQueue() | 231 | public void DoProcessQueue() |
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/MaintenanceThread.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/MaintenanceThread.cs index 7ffdb1a..87fdf1f 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/MaintenanceThread.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/MaintenanceThread.cs | |||
@@ -93,10 +93,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
93 | { | 93 | { |
94 | if (MaintenanceThreadThread == null) | 94 | if (MaintenanceThreadThread == null) |
95 | { | 95 | { |
96 | MaintenanceThreadThread = new Thread(MaintenanceLoop); | 96 | MaintenanceThreadThread = Watchdog.StartThread(MaintenanceLoop, "ScriptMaintenanceThread", ThreadPriority.Normal, true); |
97 | MaintenanceThreadThread.Name = "ScriptMaintenanceThread"; | ||
98 | MaintenanceThreadThread.IsBackground = true; | ||
99 | MaintenanceThreadThread.Start(); | ||
100 | } | 97 | } |
101 | } | 98 | } |
102 | 99 | ||
@@ -164,56 +161,54 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
164 | MaintenanceLoopTicks_ScriptLoadUnload_Count++; | 161 | MaintenanceLoopTicks_ScriptLoadUnload_Count++; |
165 | MaintenanceLoopTicks_Other_Count++; | 162 | MaintenanceLoopTicks_Other_Count++; |
166 | 163 | ||
167 | 164 | foreach (ScriptEngine m_ScriptEngine in new ArrayList(ScriptEngine.ScriptEngines)) | |
168 | //lock (ScriptEngine.ScriptEngines) | 165 | { |
169 | //{ | 166 | // lastScriptEngine = m_ScriptEngine; |
170 | foreach (ScriptEngine m_ScriptEngine in new ArrayList(ScriptEngine.ScriptEngines)) | 167 | // Re-reading config every x seconds |
168 | if (MaintenanceLoopTicks_Other_Count >= MaintenanceLoopTicks_Other) | ||
171 | { | 169 | { |
172 | // lastScriptEngine = m_ScriptEngine; | 170 | MaintenanceLoopTicks_Other_ResetCount = true; |
173 | // Re-reading config every x seconds | 171 | if (m_ScriptEngine.RefreshConfigFilens > 0) |
174 | if (MaintenanceLoopTicks_Other_Count >= MaintenanceLoopTicks_Other) | ||
175 | { | 172 | { |
176 | MaintenanceLoopTicks_Other_ResetCount = true; | 173 | // Check if its time to re-read config |
177 | if (m_ScriptEngine.RefreshConfigFilens > 0) | 174 | if (DateTime.Now.Ticks - Last_ReReadConfigFilens > |
175 | m_ScriptEngine.RefreshConfigFilens) | ||
178 | { | 176 | { |
179 | // Check if its time to re-read config | 177 | //m_log.Debug("Time passed: " + (DateTime.Now.Ticks - Last_ReReadConfigFilens) + ">" + m_ScriptEngine.RefreshConfigFilens); |
180 | if (DateTime.Now.Ticks - Last_ReReadConfigFilens > | 178 | // Its time to re-read config file |
181 | m_ScriptEngine.RefreshConfigFilens) | 179 | m_ScriptEngine.ReadConfig(); |
182 | { | 180 | Last_ReReadConfigFilens = DateTime.Now.Ticks; // Reset time |
183 | //m_log.Debug("Time passed: " + (DateTime.Now.Ticks - Last_ReReadConfigFilens) + ">" + m_ScriptEngine.RefreshConfigFilens); | 181 | } |
184 | // Its time to re-read config file | ||
185 | m_ScriptEngine.ReadConfig(); | ||
186 | Last_ReReadConfigFilens = DateTime.Now.Ticks; // Reset time | ||
187 | } | ||
188 | 182 | ||
189 | 183 | ||
190 | // Adjust number of running script threads if not correct | 184 | // Adjust number of running script threads if not correct |
191 | if (m_ScriptEngine.m_EventQueueManager != null) | 185 | if (m_ScriptEngine.m_EventQueueManager != null) |
192 | m_ScriptEngine.m_EventQueueManager.AdjustNumberOfScriptThreads(); | 186 | m_ScriptEngine.m_EventQueueManager.AdjustNumberOfScriptThreads(); |
193 | 187 | ||
194 | // Check if any script has exceeded its max execution time | 188 | // Check if any script has exceeded its max execution time |
195 | if (EventQueueManager.EnforceMaxExecutionTime) | 189 | if (EventQueueManager.EnforceMaxExecutionTime) |
190 | { | ||
191 | // We are enforcing execution time | ||
192 | if (DateTime.Now.Ticks - Last_maxFunctionExecutionTimens > | ||
193 | EventQueueManager.maxFunctionExecutionTimens) | ||
196 | { | 194 | { |
197 | // We are enforcing execution time | 195 | // Its time to check again |
198 | if (DateTime.Now.Ticks - Last_maxFunctionExecutionTimens > | 196 | m_ScriptEngine.m_EventQueueManager.CheckScriptMaxExecTime(); // Do check |
199 | EventQueueManager.maxFunctionExecutionTimens) | 197 | Last_maxFunctionExecutionTimens = DateTime.Now.Ticks; // Reset time |
200 | { | ||
201 | // Its time to check again | ||
202 | m_ScriptEngine.m_EventQueueManager.CheckScriptMaxExecTime(); // Do check | ||
203 | Last_maxFunctionExecutionTimens = DateTime.Now.Ticks; // Reset time | ||
204 | } | ||
205 | } | 198 | } |
206 | } | 199 | } |
207 | } | 200 | } |
208 | if (MaintenanceLoopTicks_ScriptLoadUnload_Count >= MaintenanceLoopTicks_ScriptLoadUnload) | ||
209 | { | ||
210 | MaintenanceLoopTicks_ScriptLoadUnload_ResetCount = true; | ||
211 | // LOAD / UNLOAD SCRIPTS | ||
212 | if (m_ScriptEngine.m_ScriptManager != null) | ||
213 | m_ScriptEngine.m_ScriptManager.DoScriptLoadUnload(); | ||
214 | } | ||
215 | } | 201 | } |
216 | //} | 202 | if (MaintenanceLoopTicks_ScriptLoadUnload_Count >= MaintenanceLoopTicks_ScriptLoadUnload) |
203 | { | ||
204 | MaintenanceLoopTicks_ScriptLoadUnload_ResetCount = true; | ||
205 | // LOAD / UNLOAD SCRIPTS | ||
206 | if (m_ScriptEngine.m_ScriptManager != null) | ||
207 | m_ScriptEngine.m_ScriptManager.DoScriptLoadUnload(); | ||
208 | } | ||
209 | } | ||
210 | |||
211 | Watchdog.UpdateThread(); | ||
217 | } | 212 | } |
218 | } | 213 | } |
219 | catch(ThreadAbortException) | 214 | catch(ThreadAbortException) |
@@ -225,6 +220,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
225 | m_log.ErrorFormat("Exception in MaintenanceLoopThread. Thread will recover after 5 sec throttle. Exception: {0}", ex.ToString()); | 220 | m_log.ErrorFormat("Exception in MaintenanceLoopThread. Thread will recover after 5 sec throttle. Exception: {0}", ex.ToString()); |
226 | } | 221 | } |
227 | } | 222 | } |
223 | |||
224 | Watchdog.RemoveThread(); | ||
228 | } | 225 | } |
229 | #endregion | 226 | #endregion |
230 | 227 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs index 1607d34..9d97cb2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs | |||
@@ -137,11 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
137 | if (cmdHandlerThread == null) | 137 | if (cmdHandlerThread == null) |
138 | { | 138 | { |
139 | // Start the thread that will be doing the work | 139 | // Start the thread that will be doing the work |
140 | cmdHandlerThread = new Thread(CmdHandlerThreadLoop); | 140 | cmdHandlerThread = Watchdog.StartThread(CmdHandlerThreadLoop, "AsyncLSLCmdHandlerThread", ThreadPriority.Normal, true); |
141 | cmdHandlerThread.Name = "AsyncLSLCmdHandlerThread"; | ||
142 | cmdHandlerThread.Priority = ThreadPriority.BelowNormal; | ||
143 | cmdHandlerThread.IsBackground = true; | ||
144 | cmdHandlerThread.Start(); | ||
145 | } | 141 | } |
146 | } | 142 | } |
147 | 143 | ||
@@ -185,6 +181,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
185 | Thread.Sleep(cmdHandlerThreadCycleSleepms); | 181 | Thread.Sleep(cmdHandlerThreadCycleSleepms); |
186 | 182 | ||
187 | DoOneCmdHandlerPass(); | 183 | DoOneCmdHandlerPass(); |
184 | |||
185 | Watchdog.UpdateThread(); | ||
188 | } | 186 | } |
189 | } | 187 | } |
190 | catch | 188 | catch |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 11f255f..3849558 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -1267,12 +1267,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1267 | protected void SetScale(SceneObjectPart part, LSL_Vector scale) | 1267 | protected void SetScale(SceneObjectPart part, LSL_Vector scale) |
1268 | { | 1268 | { |
1269 | // TODO: this needs to trigger a persistance save as well | 1269 | // TODO: this needs to trigger a persistance save as well |
1270 | |||
1271 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | 1270 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
1272 | return; | 1271 | return; |
1273 | 1272 | if (scale.x < 0.01) | |
1274 | if (scale.x < 0.01 || scale.y < 0.01 || scale.z < 0.01) | 1273 | scale.x = 0.01; |
1275 | return; | 1274 | if (scale.y < 0.01) |
1275 | scale.y = 0.01; | ||
1276 | if (scale.z < 0.01) | ||
1277 | scale.z = 0.01; | ||
1276 | 1278 | ||
1277 | if (part.ParentGroup.RootPart.PhysActor != null && part.ParentGroup.RootPart.PhysActor.IsPhysical) | 1279 | if (part.ParentGroup.RootPart.PhysActor != null && part.ParentGroup.RootPart.PhysActor.IsPhysical) |
1278 | { | 1280 | { |
@@ -1283,12 +1285,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1283 | if (scale.z > World.m_maxPhys) | 1285 | if (scale.z > World.m_maxPhys) |
1284 | scale.z = World.m_maxPhys; | 1286 | scale.z = World.m_maxPhys; |
1285 | } | 1287 | } |
1288 | |||
1286 | if (scale.x > World.m_maxNonphys) | 1289 | if (scale.x > World.m_maxNonphys) |
1287 | scale.x = World.m_maxNonphys; | 1290 | scale.x = World.m_maxNonphys; |
1288 | if (scale.y > World.m_maxNonphys) | 1291 | if (scale.y > World.m_maxNonphys) |
1289 | scale.y = World.m_maxNonphys; | 1292 | scale.y = World.m_maxNonphys; |
1290 | if (scale.z > World.m_maxNonphys) | 1293 | if (scale.z > World.m_maxNonphys) |
1291 | scale.z = World.m_maxNonphys; | 1294 | scale.z = World.m_maxNonphys; |
1295 | |||
1292 | Vector3 tmp = part.Scale; | 1296 | Vector3 tmp = part.Scale; |
1293 | tmp.X = (float)scale.x; | 1297 | tmp.X = (float)scale.x; |
1294 | tmp.Y = (float)scale.y; | 1298 | tmp.Y = (float)scale.y; |
@@ -2043,7 +2047,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2043 | if (local != 0) | 2047 | if (local != 0) |
2044 | force *= llGetRot(); | 2048 | force *= llGetRot(); |
2045 | 2049 | ||
2046 | m_host.ParentGroup.RootPart.SetForce(new PhysicsVector((float)force.x, (float)force.y, (float)force.z)); | 2050 | m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z)); |
2047 | } | 2051 | } |
2048 | } | 2052 | } |
2049 | } | 2053 | } |
@@ -2058,7 +2062,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2058 | { | 2062 | { |
2059 | if (!m_host.ParentGroup.IsDeleted) | 2063 | if (!m_host.ParentGroup.IsDeleted) |
2060 | { | 2064 | { |
2061 | PhysicsVector tmpForce = m_host.ParentGroup.RootPart.GetForce(); | 2065 | Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); |
2062 | force.x = tmpForce.X; | 2066 | force.x = tmpForce.X; |
2063 | force.y = tmpForce.Y; | 2067 | force.y = tmpForce.Y; |
2064 | force.z = tmpForce.Z; | 2068 | force.z = tmpForce.Z; |
@@ -4176,7 +4180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4176 | { | 4180 | { |
4177 | applied_linear_impulse *= m_host.GetWorldRotation(); | 4181 | applied_linear_impulse *= m_host.GetWorldRotation(); |
4178 | } | 4182 | } |
4179 | pusheeav.PhysicsActor.AddForce(new PhysicsVector(applied_linear_impulse.X, applied_linear_impulse.Y, applied_linear_impulse.Z), true); | 4183 | pusheeav.PhysicsActor.AddForce(applied_linear_impulse, true); |
4180 | } | 4184 | } |
4181 | } | 4185 | } |
4182 | } | 4186 | } |
@@ -6084,7 +6088,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6084 | if (!m_host.ParentGroup.IsDeleted) | 6088 | if (!m_host.ParentGroup.IsDeleted) |
6085 | { | 6089 | { |
6086 | m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, | 6090 | m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, |
6087 | new PhysicsVector((float)vec.x, (float)vec.y, (float)vec.z)); | 6091 | new Vector3((float)vec.x, (float)vec.y, (float)vec.z)); |
6088 | } | 6092 | } |
6089 | } | 6093 | } |
6090 | } | 6094 | } |
@@ -7223,13 +7227,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7223 | public LSL_Integer llGetNumberOfPrims() | 7227 | public LSL_Integer llGetNumberOfPrims() |
7224 | { | 7228 | { |
7225 | m_host.AddScriptLPS(1); | 7229 | m_host.AddScriptLPS(1); |
7226 | List<ScenePresence> presences = World.GetScenePresences(); | 7230 | ScenePresence[] presences = World.GetScenePresences(); |
7227 | if (presences.Count == 0) | 7231 | if (presences.Length == 0) |
7228 | return 0; | 7232 | return 0; |
7229 | 7233 | ||
7230 | int avatarCount = 0; | 7234 | int avatarCount = 0; |
7231 | foreach (ScenePresence presence in presences) | 7235 | for (int i = 0; i < presences.Length; i++) |
7232 | { | 7236 | { |
7237 | ScenePresence presence = presences[i]; | ||
7238 | |||
7233 | if (!presence.IsChildAgent && presence.ParentID != 0) | 7239 | if (!presence.IsChildAgent && presence.ParentID != 0) |
7234 | { | 7240 | { |
7235 | if (m_host.ParentGroup.HasChildPrim(presence.ParentID)) | 7241 | if (m_host.ParentGroup.HasChildPrim(presence.ParentID)) |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index a09c8db..b75a2e4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs | |||
@@ -404,7 +404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
404 | 404 | ||
405 | private List<SensedEntity> doAgentSensor(SenseRepeatClass ts) | 405 | private List<SensedEntity> doAgentSensor(SenseRepeatClass ts) |
406 | { | 406 | { |
407 | List<ScenePresence> Presences; | 407 | List<ScenePresence> presences; |
408 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); | 408 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); |
409 | 409 | ||
410 | // If this is an avatar sense by key try to get them directly | 410 | // If this is an avatar sense by key try to get them directly |
@@ -414,16 +414,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
414 | ScenePresence p = m_CmdManager.m_ScriptEngine.World.GetScenePresence(ts.keyID); | 414 | ScenePresence p = m_CmdManager.m_ScriptEngine.World.GetScenePresence(ts.keyID); |
415 | if (p == null) | 415 | if (p == null) |
416 | return sensedEntities; | 416 | return sensedEntities; |
417 | Presences = new List<ScenePresence>(); | 417 | presences = new List<ScenePresence>(); |
418 | Presences.Add(p); | 418 | presences.Add(p); |
419 | } | 419 | } |
420 | else | 420 | else |
421 | { | 421 | { |
422 | Presences = m_CmdManager.m_ScriptEngine.World.GetScenePresences(); | 422 | presences = new List<ScenePresence>(m_CmdManager.m_ScriptEngine.World.GetScenePresences()); |
423 | } | 423 | } |
424 | 424 | ||
425 | // If nobody about quit fast | 425 | // If nobody about quit fast |
426 | if (Presences.Count == 0) | 426 | if (presences.Count == 0) |
427 | return sensedEntities; | 427 | return sensedEntities; |
428 | 428 | ||
429 | SceneObjectPart SensePoint = ts.host; | 429 | SceneObjectPart SensePoint = ts.host; |
@@ -440,8 +440,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
440 | Vector3 toRegionPos; | 440 | Vector3 toRegionPos; |
441 | double dis; | 441 | double dis; |
442 | 442 | ||
443 | foreach (ScenePresence presence in Presences) | 443 | for (int i = 0; i < presences.Count; i++) |
444 | { | 444 | { |
445 | ScenePresence presence = presences[i]; | ||
445 | bool keep = true; | 446 | bool keep = true; |
446 | 447 | ||
447 | if (presence.IsDeleted) | 448 | if (presence.IsDeleted) |
@@ -515,16 +516,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
515 | { | 516 | { |
516 | List<Object> data = new List<Object>(); | 517 | List<Object> data = new List<Object>(); |
517 | 518 | ||
518 | foreach (SenseRepeatClass ts in SenseRepeaters) | 519 | lock (SenseRepeatListLock) |
519 | { | 520 | { |
520 | if (ts.itemID == itemID) | 521 | foreach (SenseRepeatClass ts in SenseRepeaters) |
521 | { | 522 | { |
522 | data.Add(ts.interval); | 523 | if (ts.itemID == itemID) |
523 | data.Add(ts.name); | 524 | { |
524 | data.Add(ts.keyID); | 525 | data.Add(ts.interval); |
525 | data.Add(ts.type); | 526 | data.Add(ts.name); |
526 | data.Add(ts.range); | 527 | data.Add(ts.keyID); |
527 | data.Add(ts.arc); | 528 | data.Add(ts.type); |
529 | data.Add(ts.range); | ||
530 | data.Add(ts.arc); | ||
531 | } | ||
528 | } | 532 | } |
529 | } | 533 | } |
530 | return data.ToArray(); | 534 | return data.ToArray(); |