From 5920abbf8d1b1770c03bc6232f1afe0551b4a331 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Thu, 14 Feb 2013 09:48:11 -0800
Subject: Add EventManager events triggered when a SOP is added or removed from
the physical scene. Invocations added in SceneObjectPart.
---
OpenSim/Region/Framework/Scenes/EventManager.cs | 55 ++++++++++++++++++++++
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +
2 files changed, 57 insertions(+)
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 9ee1520..59d0148 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -791,6 +791,19 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj);
///
+ /// Triggered when an object is placed into the physical scene (PhysicsActor created).
+ ///
+ public event Action OnObjectAddedToPhysicalScene;
+ ///
+ /// Triggered when an object is removed from the physical scene (PhysicsActor destroyed).
+ ///
+ ///
+ /// Note: this is triggered just before the PhysicsActor is removed from the
+ /// physics engine so the receiver can do any necessary cleanup before its destruction.
+ ///
+ public event Action OnObjectRemovedFromPhysicalScene;
+
+ ///
/// Triggered when an object is removed from the scene.
///
///
@@ -1516,6 +1529,48 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ public void TriggerObjectAddedToPhysicalScene(SceneObjectPart obj)
+ {
+ Action handler = OnObjectAddedToPhysicalScene;
+ if (handler != null)
+ {
+ foreach (Action d in handler.GetInvocationList())
+ {
+ try
+ {
+ d(obj);
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat(
+ "[EVENT MANAGER]: Delegate for TriggerObjectAddedToPhysicalScene failed - continuing. {0} {1}",
+ e.Message, e.StackTrace);
+ }
+ }
+ }
+ }
+
+ public void TriggerObjectRemovedFromPhysicalScene(SceneObjectPart obj)
+ {
+ Action handler = OnObjectRemovedFromPhysicalScene;
+ if (handler != null)
+ {
+ foreach (Action d in handler.GetInvocationList())
+ {
+ try
+ {
+ d(obj);
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat(
+ "[EVENT MANAGER]: Delegate for TriggerObjectRemovedFromPhysicalScene failed - continuing. {0} {1}",
+ e.Message, e.StackTrace);
+ }
+ }
+ }
+ }
+
public void TriggerShutdown()
{
Action handlerShutdown = OnShutdown;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 9b29973..cce8b21 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -4316,6 +4316,7 @@ namespace OpenSim.Region.Framework.Scenes
}
PhysActor = pa;
+ ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
}
///
@@ -4328,6 +4329,7 @@ namespace OpenSim.Region.Framework.Scenes
///
public void RemoveFromPhysics()
{
+ ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
PhysActor = null;
}
--
cgit v1.1
From a52dfd43b6c7f5b1893bf027d949c7cc15c233b3 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 14 Feb 2013 21:03:07 +0000
Subject: Make new JsonStore script constants separated with underscores, to be
consistent with existing LSL/OSSL, etc script constants.
Agreed with cmickeyb
---
.../Scripting/JsonStore/JsonStoreScriptModule.cs | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index 3955bff..669d752 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -215,19 +215,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
#endregion
-#region ScriptConstantInteface
+#region ScriptConstantsInterface
[ScriptConstant]
- public static readonly int JSONTYPEUNDEF = (int)JsonStoreNodeType.Undefined;
+ public static readonly int JSON_TYPE_UNDEF = (int)JsonStoreNodeType.Undefined;
[ScriptConstant]
- public static readonly int JSONTYPEOBJECT = (int)JsonStoreNodeType.Object;
+ public static readonly int JSON_TYPE_OBJECT = (int)JsonStoreNodeType.Object;
[ScriptConstant]
- public static readonly int JSONTYPEARRAY = (int)JsonStoreNodeType.Array;
+ public static readonly int JSON_TYPE_ARRAY = (int)JsonStoreNodeType.Array;
[ScriptConstant]
- public static readonly int JSONTYPEVALUE = (int)JsonStoreNodeType.Value;
+ public static readonly int JSON_TYPE_VALUE = (int)JsonStoreNodeType.Value;
#endregion
--
cgit v1.1
From edb99dcc19d20980ab8fc1a0a272017855e1f266 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 14 Feb 2013 21:11:58 +0000
Subject: Rename new JsonScript functions JsonPathType() -> JsonGetPathType()
and JsonArrayLength() -> JsonGetArrayLength()
This is for consistentency with the verb:noun naming approach existing json script functions and other script functions.
Corresponding c# methods also changed since verb:noun is also the .net c# method naming guideline (as used by OpenSimulator) and for consistency with script functions.
As agreed with cmickeyb
---
OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs | 4 ++--
.../Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs | 4 ++--
.../OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs | 8 ++++----
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
index d7907e3..b40d24f 100644
--- a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
@@ -49,7 +49,7 @@ namespace OpenSim.Region.Framework.Interfaces
bool CreateStore(string value, ref UUID result);
bool DestroyStore(UUID storeID);
- JsonStoreNodeType PathType(UUID storeID, string path);
+ JsonStoreNodeType GetPathType(UUID storeID, string path);
bool TestStore(UUID storeID);
bool TestPath(UUID storeID, string path, bool useJson);
@@ -60,6 +60,6 @@ namespace OpenSim.Region.Framework.Interfaces
void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
- int ArrayLength(UUID storeID, string path);
+ int GetArrayLength(UUID storeID, string path);
}
}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
index eec86ef..fb35068 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -270,7 +270,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
///
///
// -----------------------------------------------------------------
- public JsonStoreNodeType PathType(UUID storeID, string path)
+ public JsonStoreNodeType GetPathType(UUID storeID, string path)
{
if (! m_enabled) return JsonStoreNodeType.Undefined;
@@ -407,7 +407,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
///
///
// -----------------------------------------------------------------
- public int ArrayLength(UUID storeID, string path)
+ public int GetArrayLength(UUID storeID, string path)
{
if (! m_enabled) return -1;
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index 669d752..1ed7df7 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -336,9 +336,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
///
// -----------------------------------------------------------------
[ScriptInvocation]
- public int JsonPathType(UUID hostID, UUID scriptID, UUID storeID, string path)
+ public int JsonGetPathType(UUID hostID, UUID scriptID, UUID storeID, string path)
{
- return (int)m_store.PathType(storeID,path);
+ return (int)m_store.GetPathType(storeID,path);
}
[ScriptInvocation]
@@ -387,9 +387,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
///
// -----------------------------------------------------------------
[ScriptInvocation]
- public int JsonArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path)
+ public int JsonGetArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path)
{
- return m_store.ArrayLength(storeID,path);
+ return m_store.GetArrayLength(storeID,path);
}
// -----------------------------------------------------------------
--
cgit v1.1
From 0ad07eb44d38fd1b57ef40c5aaf073663bc0694c Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 14 Feb 2013 21:29:35 +0000
Subject: minor: remove some mono compiler warnings
---
.../Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs | 2 +-
.../Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index d1ad74f..b67c0df 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
public class AssetTransactionModule : INonSharedRegionModule,
IAgentAssetTransactions
{
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected Scene m_Scene;
private bool m_dumpAssetsToFile = false;
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
index d36f65a..37131b9 100644
--- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
@@ -44,7 +44,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")]
public class DAExampleModule : INonSharedRegionModule
{
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly bool ENABLED = false; // enable for testing
--
cgit v1.1
From 6fe771f27e08f516a93ba7c04010a3157841b061 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 14 Feb 2013 21:31:34 +0000
Subject: Add regression TestJsonGetPathType()
---
.../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 47 ++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
index f25f290..e5555d6 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -399,6 +399,53 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
}
[Test]
+ public void TestJsonGetPathType()
+ {
+ TestHelpers.InMethod();
+// TestHelpers.EnableLogging();
+
+ UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }");
+
+ {
+ int result = (int)InvokeOp("JsonGetPathType", storeId, ".");
+ Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_OBJECT));
+ }
+
+ {
+ int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello");
+ Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_OBJECT));
+ }
+
+ {
+ int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World");
+ Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_ARRAY));
+ }
+
+ {
+ int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World[0]");
+ Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE));
+ }
+
+ {
+ int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World[1]");
+ Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE));
+ }
+
+ // Test for non-existant path
+ {
+ int result = (int)InvokeOp("JsonGetPathType", storeId, "foo");
+ Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF));
+ }
+
+ // Test for non-existant store
+ {
+ UUID fakeStoreId = TestHelpers.ParseTail(0x500);
+ int result = (int)InvokeOp("JsonGetPathType", fakeStoreId, ".");
+ Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF));
+ }
+ }
+
+ [Test]
public void TestJsonSetValue()
{
TestHelpers.InMethod();
--
cgit v1.1
From 13d4f6f747d3432f7b7d2f3e1d383dcdce91c01b Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 14 Feb 2013 21:34:57 +0000
Subject: Add regression TestGetArrayLength()
---
.../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 33 ++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
index e5555d6..a457c7b 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -399,6 +399,39 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
}
[Test]
+ public void TestGetArrayLength()
+ {
+ TestHelpers.InMethod();
+// TestHelpers.EnableLogging();
+
+ UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }");
+
+ {
+ int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello.World");
+ Assert.That(result, Is.EqualTo(2));
+ }
+
+ // Test path which is not an array
+ {
+ int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello");
+ Assert.That(result, Is.EqualTo(-1));
+ }
+
+ // Test fake path
+ {
+ int result = (int)InvokeOp("JsonGetArrayLength", storeId, "foo");
+ Assert.That(result, Is.EqualTo(-1));
+ }
+
+ // Test fake store
+ {
+ UUID fakeStoreId = TestHelpers.ParseTail(0x500);
+ int result = (int)InvokeOp("JsonGetArrayLength", fakeStoreId, "Hello.World");
+ Assert.That(result, Is.EqualTo(-1));
+ }
+ }
+
+ [Test]
public void TestJsonGetPathType()
{
TestHelpers.InMethod();
--
cgit v1.1
From c22276a169125e97b39d72c2e9ca55f5e1807320 Mon Sep 17 00:00:00 2001
From: teravus
Date: Thu, 14 Feb 2013 18:43:53 -0500
Subject: * gracefully handle a Situation where a double close is called on the
WebSocket handler
---
OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
index cfb1605..bb8825b 100644
--- a/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
@@ -535,6 +535,8 @@ namespace OpenSim.Framework.Servers.HttpServer
///
public void Close(string message)
{
+ if (_networkContext == null)
+ return;
if (_networkContext.Stream != null)
{
if (_networkContext.Stream.CanWrite)
--
cgit v1.1
From 71862f34b6e97e19fceefd9ccb813ce09ef0a0c3 Mon Sep 17 00:00:00 2001
From: teravus
Date: Thu, 14 Feb 2013 18:52:11 -0500
Subject: * Handle null check on configs in module startup so that the the code
can be run on 'stop on handled and unhandled null reference exceptions' mode
without pausing during startup a bunch of times. I don't think exceptions
were really meant for replacing a single if statement...
---
.../Framework/Statistics/Logging/BinaryLoggingModule.cs | 2 +-
.../Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs | 14 ++++++++------
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
index fb74cc6..f3436d1 100644
--- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
@@ -57,7 +57,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
try
{
IConfig statConfig = source.Configs["Statistics.Binary"];
- if (statConfig.Contains("enabled") && statConfig.GetBoolean("enabled"))
+ if (statConfig != null && statConfig.Contains("enabled") && statConfig.GetBoolean("enabled"))
{
if (statConfig.Contains("collect_region_stats"))
{
diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
index 385f5ad..cbffca7 100644
--- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
@@ -111,13 +111,15 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
m_rpcPending = new Dictionary();
m_rpcPendingResponses = new Dictionary();
m_pendingSRDResponses = new Dictionary();
-
- try
- {
- m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort);
- }
- catch (Exception)
+ if (config.Configs["XMLRPC"] != null)
{
+ try
+ {
+ m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort);
+ }
+ catch (Exception)
+ {
+ }
}
}
--
cgit v1.1
From cc40517863a9a32d3c5af1293623c4466c736c13 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 15 Feb 2013 00:27:30 +0000
Subject: Add regression TestJsonList2Path()
---
.../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 29 ++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
index a457c7b..68eed1d 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -53,6 +53,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
private Scene m_scene;
private MockScriptEngine m_engine;
private ScriptModuleCommsModule m_smcm;
+ private JsonStoreScriptModule m_jssm;
[TestFixtureSetUp]
public void FixtureInit()
@@ -82,10 +83,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
m_engine = new MockScriptEngine();
m_smcm = new ScriptModuleCommsModule();
JsonStoreModule jsm = new JsonStoreModule();
- JsonStoreScriptModule jssm = new JsonStoreScriptModule();
+ m_jssm = new JsonStoreScriptModule();
m_scene = new SceneHelpers().SetupScene();
- SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, jssm);
+ SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, m_jssm);
try
{
@@ -479,6 +480,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
}
[Test]
+ public void TestJsonList2Path()
+ {
+ TestHelpers.InMethod();
+// TestHelpers.EnableLogging();
+
+ // Invoking these methods directly since I just couldn't get comms module invocation to work for some reason
+ // - some confusion with the methods that take a params object[] invocation.
+ {
+ string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo" });
+ Assert.That(result, Is.EqualTo("{foo}"));
+ }
+
+ {
+ string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", "bar" });
+ Assert.That(result, Is.EqualTo("{foo}.{bar}"));
+ }
+
+ {
+ string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", 1, "bar" });
+ Assert.That(result, Is.EqualTo("{foo}.[1].{bar}"));
+ }
+ }
+
+ [Test]
public void TestJsonSetValue()
{
TestHelpers.InMethod();
--
cgit v1.1
From 0b2608d8f4c715acf693565d57d2919dda4d7f18 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 15 Feb 2013 00:32:20 +0000
Subject: Comment out regression TestJsonTestPath and TestJsonTestPathJson as
these will go away soon
---
.../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 124 ++++++++++-----------
1 file changed, 62 insertions(+), 62 deletions(-)
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
index 68eed1d..1c4737b 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -335,69 +335,69 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
}
}
- [Test]
- public void TestJsonTestPath()
- {
- TestHelpers.InMethod();
-// TestHelpers.EnableLogging();
-
- UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }");
-
- {
- int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World");
- Assert.That(result, Is.EqualTo(1));
- }
-
- // Test for path which does not resolve to a value.
- {
- int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
- Assert.That(result, Is.EqualTo(0));
- }
-
- {
- int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo");
- Assert.That(result2, Is.EqualTo(0));
- }
-
- // Test with fake store
- {
- UUID fakeStoreId = TestHelpers.ParseTail(0x500);
- int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello");
- Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
- }
- }
-
- [Test]
- public void TestJsonTestPathJson()
- {
- TestHelpers.InMethod();
-// TestHelpers.EnableLogging();
-
- UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }");
-
- {
- int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World");
- Assert.That(result, Is.EqualTo(1));
- }
-
- // Test for path which does not resolve to a value.
- {
- int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello");
- Assert.That(result, Is.EqualTo(1));
- }
-
- {
- int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo");
- Assert.That(result2, Is.EqualTo(0));
- }
+// [Test]
+// public void TestJsonTestPath()
+// {
+// TestHelpers.InMethod();
+//// TestHelpers.EnableLogging();
+//
+// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }");
+//
+// {
+// int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World");
+// Assert.That(result, Is.EqualTo(1));
+// }
+//
+// // Test for path which does not resolve to a value.
+// {
+// int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
+// Assert.That(result, Is.EqualTo(0));
+// }
+//
+// {
+// int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo");
+// Assert.That(result2, Is.EqualTo(0));
+// }
+//
+// // Test with fake store
+// {
+// UUID fakeStoreId = TestHelpers.ParseTail(0x500);
+// int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello");
+// Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
+// }
+// }
- // Test with fake store
- {
- UUID fakeStoreId = TestHelpers.ParseTail(0x500);
- int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello");
- Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
- }
- }
+// [Test]
+// public void TestJsonTestPathJson()
+// {
+// TestHelpers.InMethod();
+//// TestHelpers.EnableLogging();
+//
+// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }");
+//
+// {
+// int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World");
+// Assert.That(result, Is.EqualTo(1));
+// }
+//
+// // Test for path which does not resolve to a value.
+// {
+// int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello");
+// Assert.That(result, Is.EqualTo(1));
+// }
+//
+// {
+// int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo");
+// Assert.That(result2, Is.EqualTo(0));
+// }
+//
+// // Test with fake store
+// {
+// UUID fakeStoreId = TestHelpers.ParseTail(0x500);
+// int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello");
+// Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
+// }
+// }
[Test]
public void TestGetArrayLength()
--
cgit v1.1
From 61f18d15e1115275588e9e5a27f5d148ed762b4e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 15 Feb 2013 00:38:07 +0000
Subject: Rename JsonSetValueJson() -> JsonSetJson() and JsonGetValueJson() ->
JsonGetJson()
This is because JsonGetJson() is getting json from anywhere in the structure, not just values.
Equally, JsonSetJson() is setting any type of json, not just json which represents a value.
Agreed with cmickeyb
---
.../Scripting/JsonStore/JsonStoreScriptModule.cs | 4 ++--
.../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 26 +++++++++++-----------
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index 1ed7df7..ef08c05 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -365,7 +365,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
}
[ScriptInvocation]
- public int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
+ public int JsonSetJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
{
return m_store.SetValue(storeID,path,value,true) ? 1 : 0;
}
@@ -406,7 +406,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
}
[ScriptInvocation]
- public string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
+ public string JsonGetJson(UUID hostID, UUID scriptID, UUID storeID, string path)
{
string value = String.Empty;
m_store.GetValue(storeID,path,true, out value);
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
index 1c4737b..ffa8250 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -209,7 +209,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
}
[Test]
- public void TestJsonGetValueJson()
+ public void TestJsonGetJson()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
@@ -217,26 +217,26 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }");
{
- string value = (string)InvokeOp("JsonGetValueJson", storeId, "Hello.World");
+ string value = (string)InvokeOp("JsonGetJson", storeId, "Hello.World");
Assert.That(value, Is.EqualTo("'Two'"));
}
// Test get of path section instead of leaf
{
- string value = (string)InvokeOp("JsonGetValueJson", storeId, "Hello");
+ string value = (string)InvokeOp("JsonGetJson", storeId, "Hello");
Assert.That(value, Is.EqualTo("{\"World\":\"Two\"}"));
}
// Test get of non-existing value
{
- string fakeValueGet = (string)InvokeOp("JsonGetValueJson", storeId, "foo");
+ string fakeValueGet = (string)InvokeOp("JsonGetJson", storeId, "foo");
Assert.That(fakeValueGet, Is.EqualTo(""));
}
// Test get from non-existing store
{
UUID fakeStoreId = TestHelpers.ParseTail(0x500);
- string fakeStoreValueGet = (string)InvokeOp("JsonGetValueJson", fakeStoreId, "Hello");
+ string fakeStoreValueGet = (string)InvokeOp("JsonGetJson", fakeStoreId, "Hello");
Assert.That(fakeStoreValueGet, Is.EqualTo(""));
}
}
@@ -294,7 +294,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
Assert.That(result, Is.EqualTo(0));
- string returnValue2 = (string)InvokeOp("JsonGetValueJson", storeId, "Hello");
+ string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello");
Assert.That(returnValue2, Is.EqualTo(""));
}
@@ -315,7 +315,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]");
Assert.That(stringReturnValue, Is.EqualTo("value2"));
- stringReturnValue = (string)InvokeOp("JsonGetValueJson", storeId, "Hello[1]");
+ stringReturnValue = (string)InvokeOp("JsonGetJson", storeId, "Hello[1]");
Assert.That(stringReturnValue, Is.EqualTo(""));
}
@@ -689,7 +689,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
}
[Test]
- public void TestJsonSetValueJson()
+ public void TestJsonSetJson()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
@@ -698,7 +698,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
{
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
- int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "'Times'");
+ int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "'Times'");
Assert.That(result, Is.EqualTo(1));
string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
@@ -709,7 +709,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
{
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
- int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "{ 'Filled' : 'Times' }");
+ int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "{ 'Filled' : 'Times' }");
Assert.That(result, Is.EqualTo(1));
string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Filled");
@@ -720,7 +720,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
{
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
- int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "Times");
+ int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "Times");
Assert.That(result, Is.EqualTo(0));
string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
@@ -731,7 +731,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
{
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
- int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun.Circus", "'Times'");
+ int result = (int)InvokeOp("JsonSetJson", storeId, "Fun.Circus", "'Times'");
Assert.That(result, Is.EqualTo(0));
string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus");
@@ -741,7 +741,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
// Test with fake store
{
UUID fakeStoreId = TestHelpers.ParseTail(0x500);
- int fakeStoreValueSet = (int)InvokeOp("JsonSetValueJson", fakeStoreId, "Hello", "'World'");
+ int fakeStoreValueSet = (int)InvokeOp("JsonSetJson", fakeStoreId, "Hello", "'World'");
Assert.That(fakeStoreValueSet, Is.EqualTo(0));
}
}
--
cgit v1.1
From 8d5fe5c22232e23b414531b07c5a8b343bb4b886 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 15 Feb 2013 01:00:49 +0000
Subject: Enable one sub-test in TestJsonSetValue() which now works (using
identifier with embedded .).
Need to look further at other still commented tests.
Still need to check coverage against some of Mic's scripts.
---
.../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 30 ++++++++++------------
1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
index ffa8250..3d9ad16 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -519,17 +519,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
Assert.That(value, Is.EqualTo("Times"));
}
- // Commented out as this currently unexpectedly fails.
// Test setting a key containing periods with delineation
-// {
-// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
-//
-// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times");
-// Assert.That(result, Is.EqualTo(1));
-//
-// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}");
-// Assert.That(value, Is.EqualTo("Times"));
-// }
+ {
+ UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
+
+ int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times");
+ Assert.That(result, Is.EqualTo(1));
+
+ string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}");
+ Assert.That(value, Is.EqualTo("Times"));
+ }
// *** Test [] ***
@@ -599,7 +598,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
Assert.That(value, Is.EqualTo("Times"));
}
- // Commented out as this currently unexpectedly fails.
+// // Commented out as this currently unexpectedly fails.
// // Test setting a key containing brackets around an integer with delineation
// {
// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
@@ -607,7 +606,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[0]Circus}", "Times");
// Assert.That(result, Is.EqualTo(1));
//
-// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}");
+// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[0]Circus}");
// Assert.That(value, Is.EqualTo("Times"));
// }
@@ -635,16 +634,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
Assert.That(value, Is.EqualTo(""));
}
- // Commented out as this currently unexpectedly fails.
+// // Commented out as this currently unexpectedly fails.
// // Test setting a key containing unbalanced }
// {
// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
//
// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun}Circus}", "Times");
-// Assert.That(result, Is.EqualTo(1));
-//
-// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun}Circus}");
-// Assert.That(value, Is.EqualTo("Times"));
+// Assert.That(result, Is.EqualTo(0));
// }
// Test setting a key containing unbalanced { with delineation
--
cgit v1.1
From afeb5d4917506ced2a1e4098aeb4bc94ae64fc06 Mon Sep 17 00:00:00 2001
From: Dan Lake
Date: Thu, 14 Feb 2013 20:05:42 -0800
Subject: Use SortedDictionary in StatsManager instead of regular Dictionary so
stats will interate and print in a defined order
---
.../Framework/Monitoring/SimExtraStatsCollector.cs | 4 +--
OpenSim/Framework/Monitoring/StatsManager.cs | 40 +++++++++++-----------
2 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
index aa86202..3765efb 100644
--- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
@@ -359,11 +359,11 @@ Asset service request failures: {3}" + Environment.NewLine,
inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
- Dictionary> sceneStats;
+ SortedDictionary> sceneStats;
if (StatsManager.TryGetStats("scene", out sceneStats))
{
- foreach (KeyValuePair> kvp in sceneStats)
+ foreach (KeyValuePair> kvp in sceneStats)
{
foreach (Stat stat in kvp.Value.Values)
{
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 0762b01..910907e 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -51,8 +51,8 @@ namespace OpenSim.Framework.Monitoring
///
/// Do not add or remove directly from this dictionary.
///
- public static Dictionary>> RegisteredStats
- = new Dictionary>>();
+ public static SortedDictionary>> RegisteredStats
+ = new SortedDictionary>>();
private static AssetStatsCollector assetStats;
private static UserStatsCollector userStats;
@@ -101,7 +101,7 @@ namespace OpenSim.Framework.Monitoring
}
else
{
- Dictionary> category;
+ SortedDictionary> category;
if (!RegisteredStats.TryGetValue(categoryName, out category))
{
con.OutputFormat("No such category as {0}", categoryName);
@@ -120,7 +120,7 @@ namespace OpenSim.Framework.Monitoring
}
private static void OutputCategoryStatsToConsole(
- ICommandConsole con, Dictionary> category)
+ ICommandConsole con, SortedDictionary> category)
{
foreach (var container in category.Values)
{
@@ -160,8 +160,8 @@ namespace OpenSim.Framework.Monitoring
///
public static bool RegisterStat(Stat stat)
{
- Dictionary> category = null, newCategory;
- Dictionary container = null, newContainer;
+ SortedDictionary> category = null, newCategory;
+ SortedDictionary container = null, newContainer;
lock (RegisteredStats)
{
@@ -175,14 +175,14 @@ namespace OpenSim.Framework.Monitoring
// This means that we don't need to lock or copy them on iteration, which will be a much more
// common operation after startup.
if (container != null)
- newContainer = new Dictionary(container);
+ newContainer = new SortedDictionary(container);
else
- newContainer = new Dictionary();
+ newContainer = new SortedDictionary();
if (category != null)
- newCategory = new Dictionary>(category);
+ newCategory = new SortedDictionary>(category);
else
- newCategory = new Dictionary>();
+ newCategory = new SortedDictionary>();
newContainer[stat.ShortName] = stat;
newCategory[stat.Container] = newContainer;
@@ -196,21 +196,21 @@ namespace OpenSim.Framework.Monitoring
/// Deregister a statistic
/// >
///
- ///
public static bool DeregisterStat(Stat stat)
{
- Dictionary> category = null, newCategory;
- Dictionary container = null, newContainer;
+ SortedDictionary> category = null, newCategory;
+ SortedDictionary container = null, newContainer;
lock (RegisteredStats)
{
if (!TryGetStat(stat, out category, out container))
return false;
- newContainer = new Dictionary(container);
+ newContainer = new SortedDictionary(container);
newContainer.Remove(stat.ShortName);
- newCategory = new Dictionary>(category);
+ newCategory = new SortedDictionary>(category);
newCategory.Remove(stat.Container);
newCategory[stat.Container] = newContainer;
@@ -220,15 +220,15 @@ namespace OpenSim.Framework.Monitoring
}
}
- public static bool TryGetStats(string category, out Dictionary> stats)
+ public static bool TryGetStats(string category, out SortedDictionary> stats)
{
return RegisteredStats.TryGetValue(category, out stats);
}
public static bool TryGetStat(
Stat stat,
- out Dictionary> category,
- out Dictionary container)
+ out SortedDictionary> category,
+ out SortedDictionary container)
{
category = null;
container = null;
@@ -252,9 +252,9 @@ namespace OpenSim.Framework.Monitoring
{
lock (RegisteredStats)
{
- foreach (Dictionary> category in RegisteredStats.Values)
+ foreach (SortedDictionary> category in RegisteredStats.Values)
{
- foreach (Dictionary container in category.Values)
+ foreach (SortedDictionary container in category.Values)
{
foreach (Stat stat in container.Values)
{
--
cgit v1.1