diff options
author | Melanie | 2012-04-13 03:00:48 +0100 |
---|---|---|
committer | Melanie | 2012-04-13 03:00:48 +0100 |
commit | fe65b518765a8c88c1f3067b47d775b9b1142961 (patch) | |
tree | 3a97f13715090d8c925543ae49ecae1930578d5d /OpenSim/Region | |
parent | Merge branch 'master' into careminster (diff) | |
parent | Mantis 55025 Implement script time. (diff) | |
download | opensim-SC-fe65b518765a8c88c1f3067b47d775b9b1142961.zip opensim-SC-fe65b518765a8c88c1f3067b47d775b9b1142961.tar.gz opensim-SC-fe65b518765a8c88c1f3067b47d775b9b1142961.tar.bz2 opensim-SC-fe65b518765a8c88c1f3067b47d775b9b1142961.tar.xz |
Merge branch 'master' into careminster
Conflicts:
OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
Diffstat (limited to 'OpenSim/Region')
7 files changed, 176 insertions, 107 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 4d70888..8732ec0 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs | |||
@@ -174,7 +174,17 @@ namespace OpenSim.Region.Framework.Interfaces | |||
174 | /// If no inventory item has that name then an empty list is returned. | 174 | /// If no inventory item has that name then an empty list is returned. |
175 | /// </returns> | 175 | /// </returns> |
176 | List<TaskInventoryItem> GetInventoryItems(string name); | 176 | List<TaskInventoryItem> GetInventoryItems(string name); |
177 | 177 | ||
178 | /// <summary> | ||
179 | /// Get inventory items by type. | ||
180 | /// </summary> | ||
181 | /// <param type="name"></param> | ||
182 | /// <returns> | ||
183 | /// A list of inventory items of that type. | ||
184 | /// If no inventory items of that type then an empty list is returned. | ||
185 | /// </returns> | ||
186 | List<TaskInventoryItem> GetInventoryItems(InventoryType type); | ||
187 | |||
178 | /// <summary> | 188 | /// <summary> |
179 | /// Get the scene object referenced by an inventory item. | 189 | /// Get the scene object referenced by an inventory item. |
180 | /// </summary> | 190 | /// </summary> |
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index 4f8be10..143af48 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs | |||
@@ -85,6 +85,14 @@ namespace OpenSim.Region.Framework.Interfaces | |||
85 | void StartProcessing(); | 85 | void StartProcessing(); |
86 | 86 | ||
87 | /// <summary> | 87 | /// <summary> |
88 | /// Get the execution times of all scripts in the given array if they are currently running. | ||
89 | /// </summary> | ||
90 | /// <returns> | ||
91 | /// A float the value is a representative execution time in milliseconds of all scripts in that Array. | ||
92 | /// </returns> | ||
93 | float GetScriptExecutionTime(List<UUID> itemIDs); | ||
94 | |||
95 | /// <summary> | ||
88 | /// Get the execution times of all scripts in each object. | 96 | /// Get the execution times of all scripts in each object. |
89 | /// </summary> | 97 | /// </summary> |
90 | /// <returns> | 98 | /// <returns> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 5786f48..ced3fb5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -4032,6 +4032,45 @@ namespace OpenSim.Region.Framework.Scenes | |||
4032 | } | 4032 | } |
4033 | 4033 | ||
4034 | /// <summary> | 4034 | /// <summary> |
4035 | /// A float the value is a representative execution time in milliseconds of all scripts in the link set. | ||
4036 | /// </summary> | ||
4037 | public float ScriptExecutionTime() | ||
4038 | { | ||
4039 | IScriptModule[] engines = Scene.RequestModuleInterfaces<IScriptModule>(); | ||
4040 | |||
4041 | if (engines.Length == 0) // No engine at all | ||
4042 | return 0.0f; | ||
4043 | |||
4044 | float time = 0.0f; | ||
4045 | |||
4046 | // get all the scripts in all parts | ||
4047 | SceneObjectPart[] parts = m_parts.GetArray(); | ||
4048 | List<TaskInventoryItem> scripts = new List<TaskInventoryItem>(); | ||
4049 | for (int i = 0; i < parts.Length; i++) | ||
4050 | { | ||
4051 | scripts.AddRange(parts[i].Inventory.GetInventoryItems(InventoryType.LSL)); | ||
4052 | } | ||
4053 | // extract the UUIDs | ||
4054 | List<UUID> ids = new List<UUID>(scripts.Count); | ||
4055 | foreach (TaskInventoryItem script in scripts) | ||
4056 | { | ||
4057 | if (!ids.Contains(script.ItemID)) | ||
4058 | { | ||
4059 | ids.Add(script.ItemID); | ||
4060 | } | ||
4061 | } | ||
4062 | // Offer the list of script UUIDs to each engine found and accumulate the time | ||
4063 | foreach (IScriptModule e in engines) | ||
4064 | { | ||
4065 | if (e != null) | ||
4066 | { | ||
4067 | time += e.GetScriptExecutionTime(ids); | ||
4068 | } | ||
4069 | } | ||
4070 | return time; | ||
4071 | } | ||
4072 | |||
4073 | /// <summary> | ||
4035 | /// Returns a count of the number of running scripts in this groups parts. | 4074 | /// Returns a count of the number of running scripts in this groups parts. |
4036 | /// </summary> | 4075 | /// </summary> |
4037 | public int RunningScriptCount() | 4076 | public int RunningScriptCount() |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 7e629c0..36cb09a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -267,14 +267,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
267 | /// </summary> | 267 | /// </summary> |
268 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) | 268 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) |
269 | { | 269 | { |
270 | Items.LockItemsForRead(true); | 270 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); |
271 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | 271 | foreach (TaskInventoryItem item in scripts) |
272 | Items.LockItemsForRead(false); | 272 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); |
273 | foreach (TaskInventoryItem item in items) | ||
274 | { | ||
275 | if ((int)InventoryType.LSL == item.InvType) | ||
276 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | ||
277 | } | ||
278 | } | 273 | } |
279 | 274 | ||
280 | public ArrayList GetScriptErrors(UUID itemID) | 275 | public ArrayList GetScriptErrors(UUID itemID) |
@@ -305,17 +300,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
305 | /// </param> | 300 | /// </param> |
306 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) | 301 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) |
307 | { | 302 | { |
308 | Items.LockItemsForRead(true); | 303 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); |
309 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | 304 | foreach (TaskInventoryItem item in scripts) |
310 | Items.LockItemsForRead(false); | ||
311 | |||
312 | foreach (TaskInventoryItem item in items) | ||
313 | { | 305 | { |
314 | if ((int)InventoryType.LSL == item.InvType) | 306 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); |
315 | { | 307 | m_part.RemoveScriptEvents(item.ItemID); |
316 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | ||
317 | m_part.RemoveScriptEvents(item.ItemID); | ||
318 | } | ||
319 | } | 308 | } |
320 | } | 309 | } |
321 | 310 | ||
@@ -1291,17 +1280,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1291 | public int ScriptCount() | 1280 | public int ScriptCount() |
1292 | { | 1281 | { |
1293 | int count = 0; | 1282 | int count = 0; |
1294 | lock (m_items) | 1283 | Items.LockItemsForRead(true); |
1284 | foreach (TaskInventoryItem item in m_items.Values) | ||
1295 | { | 1285 | { |
1296 | foreach (TaskInventoryItem item in m_items.Values) | 1286 | if (item.InvType == (int)InventoryType.LSL) |
1297 | { | 1287 | { |
1298 | if (item.InvType == (int)InventoryType.LSL) | 1288 | count++; |
1299 | { | ||
1300 | count++; | ||
1301 | } | ||
1302 | } | 1289 | } |
1303 | } | 1290 | } |
1304 | 1291 | Items.LockItemsForRead(false); | |
1305 | return count; | 1292 | return count; |
1306 | } | 1293 | } |
1307 | /// <summary> | 1294 | /// <summary> |
@@ -1315,7 +1302,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1315 | return 0; | 1302 | return 0; |
1316 | 1303 | ||
1317 | int count = 0; | 1304 | int count = 0; |
1318 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 1305 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); |
1319 | 1306 | ||
1320 | foreach (TaskInventoryItem item in scripts) | 1307 | foreach (TaskInventoryItem item in scripts) |
1321 | { | 1308 | { |
@@ -1347,22 +1334,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1347 | { | 1334 | { |
1348 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1335 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1349 | 1336 | ||
1350 | lock (m_items) | 1337 | Items.LockItemsForRead(true); |
1351 | ret = new List<TaskInventoryItem>(m_items.Values); | 1338 | ret = new List<TaskInventoryItem>(m_items.Values); |
1339 | Items.LockItemsForRead(false); | ||
1352 | 1340 | ||
1353 | return ret; | 1341 | return ret; |
1354 | } | 1342 | } |
1355 | 1343 | ||
1356 | public List<TaskInventoryItem> GetInventoryScripts() | 1344 | public List<TaskInventoryItem> GetInventoryItems(InventoryType type) |
1357 | { | 1345 | { |
1358 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1346 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1359 | 1347 | ||
1360 | lock (m_items) | 1348 | Items.LockItemsForRead(true); |
1361 | { | 1349 | |
1362 | foreach (TaskInventoryItem item in m_items.Values) | 1350 | foreach (TaskInventoryItem item in m_items.Values) |
1363 | if (item.InvType == (int)InventoryType.LSL) | 1351 | if (item.InvType == (int)type) |
1364 | ret.Add(item); | 1352 | ret.Add(item); |
1365 | } | 1353 | |
1354 | Items.LockItemsForRead(false); | ||
1366 | 1355 | ||
1367 | return ret; | 1356 | return ret; |
1368 | } | 1357 | } |
@@ -1384,35 +1373,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
1384 | if (engines.Length == 0) // No engine at all | 1373 | if (engines.Length == 0) // No engine at all |
1385 | return ret; | 1374 | return ret; |
1386 | 1375 | ||
1387 | Items.LockItemsForRead(true); | 1376 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); |
1388 | foreach (TaskInventoryItem item in m_items.Values) | 1377 | |
1378 | foreach (TaskInventoryItem item in scripts) | ||
1389 | { | 1379 | { |
1390 | if (item.InvType == (int)InventoryType.LSL) | 1380 | foreach (IScriptModule e in engines) |
1391 | { | 1381 | { |
1392 | foreach (IScriptModule e in engines) | 1382 | if (e != null) |
1393 | { | 1383 | { |
1394 | if (e != null) | 1384 | string n = e.GetXMLState(item.ItemID); |
1385 | if (n != String.Empty) | ||
1395 | { | 1386 | { |
1396 | string n = e.GetXMLState(item.ItemID); | 1387 | if (oldIDs) |
1397 | if (n != String.Empty) | 1388 | { |
1389 | if (!ret.ContainsKey(item.OldItemID)) | ||
1390 | ret[item.OldItemID] = n; | ||
1391 | } | ||
1392 | else | ||
1398 | { | 1393 | { |
1399 | if (oldIDs) | 1394 | if (!ret.ContainsKey(item.ItemID)) |
1400 | { | 1395 | ret[item.ItemID] = n; |
1401 | if (!ret.ContainsKey(item.OldItemID)) | ||
1402 | ret[item.OldItemID] = n; | ||
1403 | } | ||
1404 | else | ||
1405 | { | ||
1406 | if (!ret.ContainsKey(item.ItemID)) | ||
1407 | ret[item.ItemID] = n; | ||
1408 | } | ||
1409 | break; | ||
1410 | } | 1396 | } |
1397 | break; | ||
1411 | } | 1398 | } |
1412 | } | 1399 | } |
1413 | } | 1400 | } |
1414 | } | 1401 | } |
1415 | Items.LockItemsForRead(false); | ||
1416 | return ret; | 1402 | return ret; |
1417 | } | 1403 | } |
1418 | 1404 | ||
@@ -1422,27 +1408,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1422 | if (engines.Length == 0) | 1408 | if (engines.Length == 0) |
1423 | return; | 1409 | return; |
1424 | 1410 | ||
1411 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); | ||
1425 | 1412 | ||
1426 | Items.LockItemsForRead(true); | 1413 | foreach (TaskInventoryItem item in scripts) |
1427 | |||
1428 | foreach (TaskInventoryItem item in m_items.Values) | ||
1429 | { | 1414 | { |
1430 | if (item.InvType == (int)InventoryType.LSL) | 1415 | foreach (IScriptModule engine in engines) |
1431 | { | 1416 | { |
1432 | foreach (IScriptModule engine in engines) | 1417 | if (engine != null) |
1433 | { | 1418 | { |
1434 | if (engine != null) | 1419 | if (item.OwnerChanged) |
1435 | { | 1420 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); |
1436 | if (item.OwnerChanged) | 1421 | item.OwnerChanged = false; |
1437 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); | 1422 | engine.ResumeScript(item.ItemID); |
1438 | item.OwnerChanged = false; | ||
1439 | engine.ResumeScript(item.ItemID); | ||
1440 | } | ||
1441 | } | 1423 | } |
1442 | } | 1424 | } |
1443 | } | 1425 | } |
1444 | |||
1445 | Items.LockItemsForRead(false); | ||
1446 | } | 1426 | } |
1447 | } | 1427 | } |
1448 | } | 1428 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0cb1556..fd7f7d8 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -3541,6 +3541,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
3541 | } | 3541 | } |
3542 | 3542 | ||
3543 | /// <summary> | 3543 | /// <summary> |
3544 | /// A float the value is a representative execution time in milliseconds of all scripts in all attachments. | ||
3545 | /// </summary> | ||
3546 | public float ScriptExecutionTime() | ||
3547 | { | ||
3548 | float time = 0.0f; | ||
3549 | lock (m_attachments) | ||
3550 | { | ||
3551 | foreach (SceneObjectGroup gobj in m_attachments) | ||
3552 | { | ||
3553 | if (gobj != null) | ||
3554 | { | ||
3555 | time += gobj.ScriptExecutionTime(); | ||
3556 | } | ||
3557 | } | ||
3558 | } | ||
3559 | return time; | ||
3560 | } | ||
3561 | |||
3562 | /// <summary> | ||
3544 | /// Returns the total count of running scripts in all parts. | 3563 | /// Returns the total count of running scripts in all parts. |
3545 | /// </summary> | 3564 | /// </summary> |
3546 | public int RunningScriptCount() | 3565 | public int RunningScriptCount() |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 76106a0..783650c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -11176,7 +11176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11176 | ret.Add(new LSL_Integer(av.RunningScriptCount() * 16384)); | 11176 | ret.Add(new LSL_Integer(av.RunningScriptCount() * 16384)); |
11177 | break; | 11177 | break; |
11178 | case ScriptBaseClass.OBJECT_SCRIPT_TIME: | 11178 | case ScriptBaseClass.OBJECT_SCRIPT_TIME: |
11179 | ret.Add(new LSL_Float(0)); | 11179 | ret.Add(new LSL_Float(av.ScriptExecutionTime() / 1000.0f)); |
11180 | break; | 11180 | break; |
11181 | case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: | 11181 | case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: |
11182 | ret.Add(new LSL_Integer(1)); | 11182 | ret.Add(new LSL_Integer(1)); |
@@ -11244,9 +11244,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11244 | ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount() * 16384)); | 11244 | ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount() * 16384)); |
11245 | break; | 11245 | break; |
11246 | case ScriptBaseClass.OBJECT_SCRIPT_TIME: | 11246 | case ScriptBaseClass.OBJECT_SCRIPT_TIME: |
11247 | // Average cpu time per simulator frame expended on all scripts in the object | 11247 | // Average cpu time in seconds per simulator frame expended on all scripts in the object |
11248 | // Not currently available at Object level | 11248 | ret.Add(new LSL_Float(obj.ParentGroup.ScriptExecutionTime() / 1000.0f)); |
11249 | ret.Add(new LSL_Float(0)); | ||
11250 | break; | 11249 | break; |
11251 | case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: | 11250 | case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: |
11252 | // according to the SL wiki A prim or linkset will have prim | 11251 | // according to the SL wiki A prim or linkset will have prim |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 1e0f01f..bfe7418 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -1997,45 +1997,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1997 | if (!topScripts.ContainsKey(si.LocalID)) | 1997 | if (!topScripts.ContainsKey(si.LocalID)) |
1998 | topScripts[si.RootLocalID] = 0; | 1998 | topScripts[si.RootLocalID] = 0; |
1999 | 1999 | ||
2000 | // long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; | 2000 | topScripts[si.RootLocalID] += CalculateAdjustedExectionTime(si, tickNow); |
2001 | // float framesElapsed = ticksElapsed / (18.1818 * TimeSpan.TicksPerMillisecond); | 2001 | } |
2002 | 2002 | } | |
2003 | // Execution time of the script adjusted by it's measurement period to make scripts started at | ||
2004 | // different times comparable. | ||
2005 | // float adjustedExecutionTime | ||
2006 | // = (float)si.MeasurementPeriodExecutionTime | ||
2007 | // / ((float)(tickNow - si.MeasurementPeriodTickStart) / ScriptInstance.MaxMeasurementPeriod) | ||
2008 | // / TimeSpan.TicksPerMillisecond; | ||
2009 | |||
2010 | long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; | ||
2011 | |||
2012 | // Avoid divide by zerp | ||
2013 | if (ticksElapsed == 0) | ||
2014 | ticksElapsed = 1; | ||
2015 | 2003 | ||
2016 | // Scale execution time to the ideal 55 fps frame time for these reasons. | 2004 | return topScripts; |
2017 | // | 2005 | } |
2018 | // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no | ||
2019 | // 'script execution time per frame', which is the original purpose of this value. | ||
2020 | // | ||
2021 | // 2) Giving the raw execution times is misleading since scripts start at different times, making | ||
2022 | // it impossible to compare scripts. | ||
2023 | // | ||
2024 | // 3) Scaling the raw execution time to the time that the script has been running is better but | ||
2025 | // is still misleading since a script that has just been rezzed may appear to have been running | ||
2026 | // for much longer. | ||
2027 | // | ||
2028 | // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect | ||
2029 | // since the figure does not represent actual execution time and very hard running scripts will | ||
2030 | // never exceed 18ms (though this is a very high number for script execution so is a warning sign). | ||
2031 | float adjustedExecutionTime | ||
2032 | = ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f; | ||
2033 | 2006 | ||
2034 | topScripts[si.RootLocalID] += adjustedExecutionTime; | 2007 | public float GetScriptExecutionTime(List<UUID> itemIDs) |
2008 | { | ||
2009 | if (itemIDs == null|| itemIDs.Count == 0) | ||
2010 | { | ||
2011 | return 0.0f; | ||
2012 | } | ||
2013 | float time = 0.0f; | ||
2014 | long tickNow = Util.EnvironmentTickCount(); | ||
2015 | IScriptInstance si; | ||
2016 | // Calculate the time for all scripts that this engine is executing | ||
2017 | // Ignore any others | ||
2018 | foreach (UUID id in itemIDs) | ||
2019 | { | ||
2020 | si = GetInstance(id); | ||
2021 | if (si != null && si.Running) | ||
2022 | { | ||
2023 | time += CalculateAdjustedExectionTime(si, tickNow); | ||
2035 | } | 2024 | } |
2036 | } | 2025 | } |
2026 | return time; | ||
2027 | } | ||
2037 | 2028 | ||
2038 | return topScripts; | 2029 | private float CalculateAdjustedExectionTime(IScriptInstance si, long tickNow) |
2030 | { | ||
2031 | long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; | ||
2032 | |||
2033 | // Avoid divide by zero | ||
2034 | if (ticksElapsed == 0) | ||
2035 | ticksElapsed = 1; | ||
2036 | |||
2037 | // Scale execution time to the ideal 55 fps frame time for these reasons. | ||
2038 | // | ||
2039 | // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no | ||
2040 | // 'script execution time per frame', which is the original purpose of this value. | ||
2041 | // | ||
2042 | // 2) Giving the raw execution times is misleading since scripts start at different times, making | ||
2043 | // it impossible to compare scripts. | ||
2044 | // | ||
2045 | // 3) Scaling the raw execution time to the time that the script has been running is better but | ||
2046 | // is still misleading since a script that has just been rezzed may appear to have been running | ||
2047 | // for much longer. | ||
2048 | // | ||
2049 | // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect | ||
2050 | // since the figure does not represent actual execution time and very hard running scripts will | ||
2051 | // never exceed 18ms (though this is a very high number for script execution so is a warning sign). | ||
2052 | return ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f; | ||
2039 | } | 2053 | } |
2040 | 2054 | ||
2041 | public void SuspendScript(UUID itemID) | 2055 | public void SuspendScript(UUID itemID) |