Make the concept of namespaces explicit in dynamic attributes

This is in order to reduce the likelihood of naming clashes, make it easier to filter in/out attributes, ensure uniformity, etc.
All dynattrs in the opensim distro itself or likely future ones should be in the "OpenSim" namespace.
This does alter the underlying dynattrs data structure.  All data in previous structures may not be available, though old structures should not cause errors.
This is done without notice since this feature has been explicitly labelled as experimental, subject to change and has not been in a release.
However, existing materials data is being preserved by moving it to the "Materials" store in the "OpenSim" namespace.
cpu-performance
Justin Clark-Casey (justincc) 2013-06-27 23:14:28 +01:00
parent f78d2ef166
commit f7d09b898a
11 changed files with 270 additions and 185 deletions

View File

@ -2100,7 +2100,7 @@ VALUES
parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum));
parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl));
if (prim.DynAttrs.Count > 0)
if (prim.DynAttrs.CountNamespaces > 0)
parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml()));
else
parameters.Add(_Database.CreateParameter("DynAttrs", null));

View File

@ -1679,7 +1679,7 @@ namespace OpenSim.Data.MySQL
else
cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]);
if (prim.DynAttrs.Count > 0)
if (prim.DynAttrs.CountNamespaces > 0)
cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml());
else
cmd.Parameters.AddWithValue("DynAttrs", null);

View File

@ -2176,7 +2176,7 @@ namespace OpenSim.Data.SQLite
row["MediaURL"] = prim.MediaUrl;
if (prim.DynAttrs.Count > 0)
if (prim.DynAttrs.CountNamespaces > 0)
row["DynAttrs"] = prim.DynAttrs.ToXml();
else
row["DynAttrs"] = null;

View File

@ -29,10 +29,12 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using log4net;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
@ -48,13 +50,20 @@ namespace OpenSim.Framework
/// within their data store. However, avoid storing large amounts of data because that
/// would slow down database access.
/// </remarks>
public class DAMap : IDictionary<string, OSDMap>, IXmlSerializable
public class DAMap : IXmlSerializable
{
private static readonly int MIN_STORE_NAME_LENGTH = 4;
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected OSDMap m_map;
public DAMap() { m_map = new OSDMap(); }
private static readonly int MIN_NAMESPACE_LENGTH = 4;
private OSDMap m_map = new OSDMap();
// WARNING: this is temporary for experimentation only, it will be removed!!!!
public OSDMap TopLevelMap
{
get { return m_map; }
set { m_map = value; }
}
public XmlSchema GetSchema() { return null; }
@ -64,39 +73,34 @@ namespace OpenSim.Framework
map.ReadXml(rawXml);
return map;
}
public void ReadXml(XmlReader reader)
{
ReadXml(reader.ReadInnerXml());
}
public void ReadXml(string rawXml)
{
// System.Console.WriteLine("Trying to deserialize [{0}]", rawXml);
lock (this)
{
m_map = (OSDMap)OSDParser.DeserializeLLSDXml(rawXml);
}
// WARNING: this is temporary for experimentation only, it will be removed!!!!
public OSDMap TopLevelMap
{
get { return m_map; }
set { m_map = value; }
}
public void ReadXml(XmlReader reader)
{
ReadXml(reader.ReadInnerXml());
}
public string ToXml()
{
lock (this)
return OSDParser.SerializeLLSDXmlString(m_map);
SanitiseMap(this);
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteRaw(ToXml());
}
public string ToXml()
{
lock (this)
return OSDParser.SerializeLLSDXmlString(m_map);
}
public void CopyFrom(DAMap other)
{
// Deep copy
@ -104,7 +108,7 @@ namespace OpenSim.Framework
string data = null;
lock (other)
{
if (other.Count > 0)
if (other.CountNamespaces > 0)
{
data = OSDParser.SerializeLLSDXmlString(other.m_map);
}
@ -120,59 +124,133 @@ namespace OpenSim.Framework
}
/// <summary>
/// Returns the number of data stores.
/// Sanitise the map to remove any namespaces or stores that are not OSDMap.
/// </summary>
public int Count { get { lock (this) { return m_map.Count; } } }
public bool IsReadOnly { get { return false; } }
/// <summary>
/// Returns the names of the data stores.
/// </summary>
public ICollection<string> Keys { get { lock (this) { return m_map.Keys; } } }
/// <summary>
/// Returns all the data stores.
/// </summary>
public ICollection<OSDMap> Values
/// <param name='map'>
/// </param>
public static void SanitiseMap(DAMap daMap)
{
get
List<string> keysToRemove = null;
// Hard-coded special case that needs to be removed in the future. Normally, modules themselves should
// handle reading data from old locations
bool osMaterialsMigrationRequired = false;
OSDMap namespacesMap = daMap.m_map;
foreach (string key in namespacesMap.Keys)
{
lock (this)
// Console.WriteLine("Processing ns {0}", key);
if (!(namespacesMap[key] is OSDMap))
{
List<OSDMap> stores = new List<OSDMap>(m_map.Count);
foreach (OSD llsd in m_map.Values)
stores.Add((OSDMap)llsd);
return stores;
if (keysToRemove == null)
keysToRemove = new List<string>();
keysToRemove.Add(key);
}
else if (key == "OS:Materials")
{
osMaterialsMigrationRequired = true;
}
}
if (keysToRemove != null)
{
foreach (string key in keysToRemove)
{
// Console.WriteLine ("Removing bad ns {0}", key);
namespacesMap.Remove(key);
}
}
// Hard-coded special case that needs to be removed in the future. Normally, modules themselves should
// handle reading data from old locations
if (osMaterialsMigrationRequired)
daMap.SetStore("OpenSim", "Materials", (OSDMap)namespacesMap["OS:Materials"]);
foreach (OSD nsOsd in namespacesMap.Values)
{
OSDMap nsOsdMap = (OSDMap)nsOsd;
keysToRemove = null;
foreach (string key in nsOsdMap.Keys)
{
if (!(nsOsdMap[key] is OSDMap))
{
if (keysToRemove == null)
keysToRemove = new List<string>();
keysToRemove.Add(key);
}
}
if (keysToRemove != null)
foreach (string key in keysToRemove)
nsOsdMap.Remove(key);
}
}
/// <summary>
/// Gets or sets one data store.
/// Get the number of namespaces
/// </summary>
/// <param name="key">Store name</param>
/// <returns></returns>
public OSDMap this[string key]
{
get
{
OSD llsd;
public int CountNamespaces { get { lock (this) { return m_map.Count; } } }
/// <summary>
/// Get the number of stores.
/// </summary>
public int CountStores
{
get
{
int count = 0;
lock (this)
{
if (m_map.TryGetValue(key, out llsd))
return (OSDMap)llsd;
else
return null;
foreach (OSD osdNamespace in m_map)
{
count += ((OSDMap)osdNamespace).Count;
}
}
}
set
return count;
}
}
public OSDMap GetStore(string ns, string storeName)
{
OSD namespaceOsd;
lock (this)
{
ValidateKey(key);
lock (this)
m_map[key] = value;
if (m_map.TryGetValue(ns, out namespaceOsd))
{
OSD store;
if (((OSDMap)namespaceOsd).TryGetValue(storeName, out store))
return (OSDMap)store;
}
}
return null;
}
public void SetStore(string ns, string storeName, OSDMap store)
{
ValidateNamespace(ns);
OSDMap nsMap;
lock (this)
{
if (!m_map.ContainsKey(ns))
{
nsMap = new OSDMap();
m_map[ns] = nsMap;
}
nsMap = (OSDMap)m_map[ns];
// m_log.DebugFormat("[DA MAP]: Setting store to {0}:{1}", ns, storeName);
nsMap[storeName] = store;
}
}
@ -180,54 +258,46 @@ namespace OpenSim.Framework
/// Validate the key used for storing separate data stores.
/// </summary>
/// <param name='key'></param>
public static void ValidateKey(string key)
public static void ValidateNamespace(string ns)
{
if (key.Length < MIN_STORE_NAME_LENGTH)
throw new Exception("Minimum store name length is " + MIN_STORE_NAME_LENGTH);
if (ns.Length < MIN_NAMESPACE_LENGTH)
throw new Exception("Minimum namespace length is " + MIN_NAMESPACE_LENGTH);
}
public bool ContainsKey(string key)
public bool ContainsStore(string ns, string storeName)
{
lock (this)
return m_map.ContainsKey(key);
}
OSD namespaceOsd;
public void Add(string key, OSDMap store)
{
ValidateKey(key);
lock (this)
m_map.Add(key, store);
}
public void Add(KeyValuePair<string, OSDMap> kvp)
{
ValidateKey(kvp.Key);
lock (this)
m_map.Add(kvp.Key, kvp.Value);
}
public bool Remove(string key)
{
lock (this)
return m_map.Remove(key);
}
public bool TryGetValue(string key, out OSDMap store)
{
lock (this)
{
OSD llsd;
if (m_map.TryGetValue(key, out llsd))
if (m_map.TryGetValue(ns, out namespaceOsd))
{
store = (OSDMap)llsd;
return true;
}
else
{
store = null;
return false;
return ((OSDMap)namespaceOsd).ContainsKey(storeName);
}
}
return false;
}
public bool TryGetStore(string ns, string storeName, out OSDMap store)
{
OSD namespaceOsd;
lock (this)
{
if (m_map.TryGetValue(ns, out namespaceOsd))
{
OSD storeOsd;
bool result = ((OSDMap)namespaceOsd).TryGetValue(storeName, out storeOsd);
store = (OSDMap)storeOsd;
return result;
}
}
store = null;
return false;
}
public void Clear()
@ -235,39 +305,25 @@ namespace OpenSim.Framework
lock (this)
m_map.Clear();
}
public bool Contains(KeyValuePair<string, OSDMap> kvp)
public bool RemoveStore(string ns, string storeName)
{
OSD namespaceOsd;
lock (this)
return m_map.ContainsKey(kvp.Key);
}
{
if (m_map.TryGetValue(ns, out namespaceOsd))
{
OSDMap namespaceOsdMap = (OSDMap)namespaceOsd;
namespaceOsdMap.Remove(storeName);
public void CopyTo(KeyValuePair<string, OSDMap>[] array, int index)
{
throw new NotImplementedException();
}
// Don't keep empty namespaces around
if (namespaceOsdMap.Count <= 0)
m_map.Remove(ns);
}
}
public bool Remove(KeyValuePair<string, OSDMap> kvp)
{
lock (this)
return m_map.Remove(kvp.Key);
}
public System.Collections.IDictionaryEnumerator GetEnumerator()
{
lock (this)
return m_map.GetEnumerator();
}
IEnumerator<KeyValuePair<string, OSDMap>> IEnumerable<KeyValuePair<string, OSDMap>>.GetEnumerator()
{
return null;
}
IEnumerator IEnumerable.GetEnumerator()
{
lock (this)
return m_map.GetEnumerator();
}
return false;
}
}
}

View File

@ -42,22 +42,22 @@ namespace OpenSim.Framework
/// This class stores and retrieves dynamic objects.
/// </summary>
/// <remarks>
/// Experimental - DO NOT USE.
/// Experimental - DO NOT USE. Does not yet have namespace support.
/// </remarks>
public class DOMap
{
private IDictionary<string, object> m_map;
public void Add(string key, object dynObj)
public void Add(string ns, string objName, object dynObj)
{
DAMap.ValidateKey(key);
DAMap.ValidateNamespace(ns);
lock (this)
{
if (m_map == null)
m_map = new Dictionary<string, object>();
m_map.Add(key, dynObj);
m_map.Add(objName, dynObj);
}
}

View File

@ -44,11 +44,12 @@ namespace OpenSim.Region.CoreModules.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
private readonly bool ENABLED = false; // enable for testing
public const string DANamespace = "DAExample Module";
public const string Namespace = "Example";
public const string StoreName = "DA";
protected Scene m_scene;
protected IDialogModule m_dialogMod;
@ -65,6 +66,8 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
m_scene = scene;
m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove;
m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>();
m_log.DebugFormat("[DA EXAMPLE MODULE]: Added region {0}", m_scene.Name);
}
}
@ -91,7 +94,7 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
if (sop == null)
return true;
if (!sop.DynAttrs.TryGetValue(DANamespace, out attrs))
if (!sop.DynAttrs.TryGetStore(Namespace, StoreName, out attrs))
attrs = new OSDMap();
OSDInteger newValue;
@ -106,12 +109,14 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
attrs["moves"] = newValue;
sop.DynAttrs[DANamespace] = attrs;
sop.DynAttrs.SetStore(Namespace, StoreName, attrs);
}
sop.ParentGroup.HasGroupChanged = true;
m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue));
string msg = string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue);
m_log.DebugFormat("[DA EXAMPLE MODULE]: {0}", msg);
m_dialogMod.SendGeneralAlert(msg);
return true;
}

View File

@ -64,8 +64,8 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
private Scene m_scene;
private IDialogModule m_dialogMod;
public string Name { get { return "DOExample Module"; } }
public string Name { get { return "DO"; } }
public Type ReplaceableInterface { get { return null; } }
public void Initialise(IConfigSource source) {}
@ -106,7 +106,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
// Console.WriteLine("Here for {0}", so.Name);
if (rootPart.DynAttrs.TryGetValue(DAExampleModule.DANamespace, out attrs))
if (rootPart.DynAttrs.TryGetStore(DAExampleModule.Namespace, DAExampleModule.StoreName, out attrs))
{
movesSoFar = attrs["moves"].AsInteger();
@ -114,7 +114,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
"[DO EXAMPLE MODULE]: Found saved moves {0} for {1} in {2}", movesSoFar, so.Name, m_scene.Name);
}
rootPart.DynObjs.Add(Name, new MyObject(movesSoFar));
rootPart.DynObjs.Add(DAExampleModule.Namespace, Name, new MyObject(movesSoFar));
}
private bool OnSceneGroupMove(UUID groupId, Vector3 delta)

View File

@ -144,7 +144,20 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
<Flags>None</Flags>
<CollisionSound><Guid>00000000-0000-0000-0000-000000000000</Guid></CollisionSound>
<CollisionSoundVolume>0</CollisionSoundVolume>
<DynAttrs><llsd><map><key>MyStore</key><map><key>the answer</key><integer>42</integer></map></map></llsd></DynAttrs>
<DynAttrs>
<llsd>
<map>
<key>MyNamespace</key>
<map>
<key>MyStore</key>
<map>
<key>the answer</key>
<integer>42</integer>
</map>
</map>
</map>
</llsd>
</DynAttrs>
</SceneObjectPart>
</RootPart>
<OtherParts />
@ -333,7 +346,20 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
<EveryoneMask>0</EveryoneMask>
<NextOwnerMask>2147483647</NextOwnerMask>
<Flags>None</Flags>
<DynAttrs><llsd><map><key>MyStore</key><map><key>last words</key><string>Rosebud</string></map></map></llsd></DynAttrs>
<DynAttrs>
<llsd>
<map>
<key>MyNamespace</key>
<map>
<key>MyStore</key>
<map>
<key>last words</key>
<string>Rosebud</string>
</map>
</map>
</map>
</llsd>
</DynAttrs>
<SitTargetAvatar><UUID>00000000-0000-0000-0000-000000000000</UUID></SitTargetAvatar>
</SceneObjectPart>
<OtherParts />
@ -362,7 +388,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790")));
Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d")));
Assert.That(rootPart.Name, Is.EqualTo("PrimMyRide"));
OSDMap store = rootPart.DynAttrs["MyStore"];
OSDMap store = rootPart.DynAttrs.GetStore("MyNamespace", "MyStore");
Assert.AreEqual(42, store["the answer"].AsInteger());
// TODO: Check other properties
@ -414,13 +440,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
rp.CreatorID = rpCreatorId;
rp.Shape = shape;
string daNamespace = "MyNamespace";
string daStoreName = "MyStore";
string daKey = "foo";
string daValue = "bar";
OSDMap myStore = new OSDMap();
myStore.Add(daKey, daValue);
rp.DynAttrs = new DAMap();
rp.DynAttrs[daStoreName] = myStore;
rp.DynAttrs.SetStore(daNamespace, daStoreName, myStore);
SceneObjectGroup so = new SceneObjectGroup(rp);
@ -481,7 +508,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
Assert.That(name, Is.EqualTo(rpName));
Assert.That(creatorId, Is.EqualTo(rpCreatorId));
Assert.NotNull(daMap);
Assert.AreEqual(daValue, daMap[daStoreName][daKey].AsString());
Assert.AreEqual(daValue, daMap.GetStore(daNamespace, daStoreName)[daKey].AsString());
}
[Test]
@ -496,7 +523,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
Assert.That(rootPart.UUID, Is.EqualTo(new UUID("9be68fdd-f740-4a0f-9675-dfbbb536b946")));
Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("b46ef588-411e-4a8b-a284-d7dcfe8e74ef")));
Assert.That(rootPart.Name, Is.EqualTo("PrimFun"));
OSDMap store = rootPart.DynAttrs["MyStore"];
OSDMap store = rootPart.DynAttrs.GetStore("MyNamespace", "MyStore");
Assert.AreEqual("Rosebud", store["last words"].AsString());
// TODO: Check other properties
@ -522,13 +549,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
rp.CreatorID = rpCreatorId;
rp.Shape = shape;
string daNamespace = "MyNamespace";
string daStoreName = "MyStore";
string daKey = "foo";
string daValue = "bar";
OSDMap myStore = new OSDMap();
myStore.Add(daKey, daValue);
rp.DynAttrs = new DAMap();
rp.DynAttrs[daStoreName] = myStore;
rp.DynAttrs.SetStore(daNamespace, daStoreName, myStore);
SceneObjectGroup so = new SceneObjectGroup(rp);
@ -585,7 +613,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
Assert.That(name, Is.EqualTo(rpName));
Assert.That(creatorId, Is.EqualTo(rpCreatorId));
Assert.NotNull(daMap);
Assert.AreEqual(daValue, daMap[daStoreName][daKey].AsString());
Assert.AreEqual(daValue, daMap.GetStore(daNamespace, daStoreName)[daKey].AsString());
}
}
}

View File

@ -1290,7 +1290,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
if (sop.MediaUrl != null)
writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString());
if (sop.DynAttrs.Count > 0)
if (sop.DynAttrs.CountNamespaces > 0)
{
writer.WriteStartElement("DynAttrs");
sop.DynAttrs.WriteXml(writer);

View File

@ -212,7 +212,6 @@ namespace OpenSim.Region.Framework.Scenes
// }
// }
/// <summary>
/// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps
/// </summary>
@ -221,20 +220,23 @@ namespace OpenSim.Region.Framework.Scenes
public void GatherMaterialsUuids(SceneObjectPart part, IDictionary<UUID, AssetType> assetUuids)
{
// scan thru the dynAttrs map of this part for any textures used as materials
OSDMap OSMaterials = null;
OSD osdMaterials = null;
lock (part.DynAttrs)
{
if (part.DynAttrs.ContainsKey("OS:Materials"))
OSMaterials = part.DynAttrs["OS:Materials"];
if (OSMaterials != null && OSMaterials.ContainsKey("Materials"))
if (part.DynAttrs.ContainsStore("OpenSim", "Materials"))
{
OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials");
materialsStore.TryGetValue("Materials", out osdMaterials);
}
if (osdMaterials != null)
{
OSD osd = OSMaterials["Materials"];
//m_log.Info("[UUID Gatherer]: found Materials: " + OSDParser.SerializeJsonString(osd));
if (osd is OSDArray)
if (osdMaterials is OSDArray)
{
OSDArray matsArr = osd as OSDArray;
OSDArray matsArr = osdMaterials as OSDArray;
foreach (OSDMap matMap in matsArr)
{
try

View File

@ -178,7 +178,7 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule
void GetStoredMaterialsForPart(SceneObjectPart part)
{
OSDMap OSMaterials = null;
OSD OSMaterials = null;
OSDArray matsArr = null;
if (part.DynAttrs == null)
@ -188,23 +188,20 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule
lock (part.DynAttrs)
{
if (part.DynAttrs.ContainsKey("OS:Materials"))
OSMaterials = part.DynAttrs["OS:Materials"];
if (OSMaterials != null && OSMaterials.ContainsKey("Materials"))
if (part.DynAttrs.ContainsStore("OpenSim", "Materials"))
{
OSD osd = OSMaterials["Materials"];
if (osd is OSDArray)
matsArr = osd as OSDArray;
OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials");
materialsStore.TryGetValue("Materials", out OSMaterials);
}
if (OSMaterials != null && OSMaterials is OSDArray)
matsArr = OSMaterials as OSDArray;
else
return;
}
if (OSMaterials == null)
return;
m_log.Info("[MaterialsDemoModule]: OSMaterials: " + OSDParser.SerializeJsonString(OSMaterials));
if (matsArr == null)
{
m_log.Info("[MaterialsDemoModule]: matsArr is null :( ");
@ -215,7 +212,6 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule
{
if (elemOsd != null && elemOsd is OSDMap)
{
OSDMap matMap = elemOsd as OSDMap;
if (matMap.ContainsKey("ID") && matMap.ContainsKey("Material"))
{
@ -232,7 +228,6 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule
}
}
void StoreMaterialsForPart(SceneObjectPart part)
{
try
@ -277,7 +272,7 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule
OSMaterials["Materials"] = matsArr;
lock (part.DynAttrs)
part.DynAttrs["OS:Materials"] = OSMaterials;
part.DynAttrs.SetStore("OpenSim", "Materials", OSMaterials);
}
catch (Exception e)
{
@ -285,7 +280,6 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule
}
}
public string RenderMaterialsPostCap(string request, string path,
string param, IOSHttpRequest httpRequest,
IOSHttpResponse httpResponse)