Compare commits
10 Commits
master
...
soprefacto
Author | SHA1 | Date |
---|---|---|
unknown | e2d5ae87fd | |
unknown | daa0d83e3a | |
unknown | 13079df156 | |
unknown | 64547c23ad | |
unknown | f73d73fcfe | |
unknown | a46b7dd34b | |
unknown | 553f99027d | |
Melanie | 4f6e4c7b5b | |
unknown | 9ff5868910 | |
unknown | 952c69ae56 |
|
@ -0,0 +1,71 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
|
||||
[XmlRoot("dictionary")]
|
||||
public class SerializableDictionary<TKey, TValue>
|
||||
: Dictionary<TKey, TValue>, IXmlSerializable
|
||||
{
|
||||
#region IXmlSerializable Members
|
||||
public System.Xml.Schema.XmlSchema GetSchema()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void ReadXml(System.Xml.XmlReader reader)
|
||||
{
|
||||
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
|
||||
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
|
||||
|
||||
bool wasEmpty = reader.IsEmptyElement;
|
||||
reader.Read();
|
||||
|
||||
if (wasEmpty)
|
||||
return;
|
||||
|
||||
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
|
||||
{
|
||||
reader.ReadStartElement("item");
|
||||
|
||||
reader.ReadStartElement("key");
|
||||
TKey key = (TKey)keySerializer.Deserialize(reader);
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("value");
|
||||
TValue value = (TValue)valueSerializer.Deserialize(reader);
|
||||
reader.ReadEndElement();
|
||||
|
||||
this.Add(key, value);
|
||||
|
||||
reader.ReadEndElement();
|
||||
reader.MoveToContent();
|
||||
}
|
||||
reader.ReadEndElement();
|
||||
}
|
||||
|
||||
public void WriteXml(System.Xml.XmlWriter writer)
|
||||
{
|
||||
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
|
||||
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
|
||||
|
||||
foreach (TKey key in this.Keys)
|
||||
{
|
||||
writer.WriteStartElement("item");
|
||||
|
||||
writer.WriteStartElement("key");
|
||||
keySerializer.Serialize(writer, key);
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("value");
|
||||
TValue value = this[key];
|
||||
valueSerializer.Serialize(writer, value);
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -648,7 +648,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
// Make sure that we see any exception caused by the asynchronous operation.
|
||||
m_log.Error(
|
||||
string.Format("[LLCLIENTVIEW]: Caught exception while processing {0}", packetObject.Pack), e);
|
||||
string.Format("[LLCLIENTVIEW]: Caught exception while processing {0} {1}", packetObject.Pack, e.ToString()), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -552,9 +552,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
// process causes some clients to fail to display the attachment properly.
|
||||
m_Scene.AddNewSceneObject(group, true, false);
|
||||
|
||||
// This is required for Group.Scene to be valid
|
||||
group.SetScene(m_Scene);
|
||||
|
||||
// m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
|
||||
// if attachment we set it's asset id so object updates can reflect that
|
||||
// if not, we set it's position in world.
|
||||
// if not, we set it's position in world.);
|
||||
if (!attachment)
|
||||
{
|
||||
group.ScheduleGroupForFullUpdate();
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Components;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.World.Objects.Components
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ComponentManagerModule")]
|
||||
class ComponentManagerModule : IComponentManagerModule, ISharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "ComponentManager";
|
||||
}
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return typeof (IComponentManagerModule); }
|
||||
}
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
scene.RegisterModuleInterface<IComponentManagerModule>(this);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#region Implementation of IComponentManagerModule
|
||||
|
||||
public void CreateComponent(SceneObjectPart target, string componentType, OSDMap state)
|
||||
{
|
||||
if (OnCreateComponent != null)
|
||||
{
|
||||
foreach (OnCreateComponentDelegate h in OnCreateComponent.GetInvocationList())
|
||||
{
|
||||
IComponent x = h(componentType, state);
|
||||
if (x != null)
|
||||
{
|
||||
target.SetComponent(x);
|
||||
x.SetParent(target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
m_log.Warn("[Components] No component handlers loaded. Are you missing a region module?");
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.Warn("[Components] Unable to create component " + componentType + ". No ComponentFactory was able to recognize it. Could you be missing a region module?");
|
||||
}
|
||||
|
||||
public event OnCreateComponentDelegate OnCreateComponent;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Components;
|
||||
|
||||
namespace OpenSim.Region.Framework.Interfaces
|
||||
{
|
||||
public delegate IComponent OnCreateComponentDelegate(string componentType, OSDMap componentState);
|
||||
|
||||
public interface IComponentManagerModule
|
||||
{
|
||||
void CreateComponent(SceneObjectPart part, string componentType, OSDMap state);
|
||||
event OnCreateComponentDelegate OnCreateComponent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Framework.Scenes.Components
|
||||
{
|
||||
public abstract class ComponentFactory
|
||||
{
|
||||
public void InitComponentHandler(Scene x)
|
||||
{
|
||||
IComponentManagerModule cmm = x.RequestModuleInterface<IComponentManagerModule>();
|
||||
cmm.OnCreateComponent += CreateComponent;
|
||||
}
|
||||
|
||||
protected abstract IComponent CreateComponent(string componentType, OSDMap componentState);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
namespace OpenSim.Region.Framework.Scenes.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// A component on an object
|
||||
/// TODO: Better documentation
|
||||
/// </summary>
|
||||
public interface IComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of the component, only one of each 'type' can be loaded.
|
||||
/// </summary>
|
||||
Type BaseType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A representation of the current state of the component, to be deserialised later.
|
||||
/// </summary>
|
||||
OSDMap State { get; }
|
||||
|
||||
void SetParent(SceneObjectPart part);
|
||||
}
|
||||
}
|
|
@ -568,6 +568,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
ApplyPhysics(m_scene.m_physicalPrim);
|
||||
|
||||
InitPartComponents();
|
||||
|
||||
// Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
|
||||
// for the same object with very different properties. The caller must schedule the update.
|
||||
//ScheduleGroupForFullUpdate();
|
||||
|
@ -1133,6 +1135,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="scene"></param>
|
||||
public void SetScene(Scene scene)
|
||||
{
|
||||
InitPartComponents();
|
||||
|
||||
m_scene = scene;
|
||||
}
|
||||
|
||||
|
@ -3579,6 +3583,17 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
#region Components
|
||||
|
||||
public void InitPartComponents()
|
||||
{
|
||||
m_log.Info("[COMPONENTS] Initialising part components");
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
part.InitComponents();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISceneObject
|
||||
|
||||
public virtual ISceneObject CloneForNewScene()
|
||||
|
|
|
@ -30,14 +30,15 @@ using System.Collections.Generic;
|
|||
using System.Drawing;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes.Components;
|
||||
using OpenSim.Region.Framework.Scenes.Scripting;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
|
@ -3492,6 +3493,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public void SetParent(SceneObjectGroup parent)
|
||||
{
|
||||
m_parentGroup = parent;
|
||||
|
||||
InitComponents();
|
||||
}
|
||||
|
||||
// Use this for attachments! LocalID should be avatar's localid
|
||||
|
@ -4053,6 +4056,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="xmlWriter"></param>
|
||||
public void ToXml(XmlWriter xmlWriter)
|
||||
{
|
||||
SaveComponents(); // Gather all the component data
|
||||
serializer.Serialize(xmlWriter, this);
|
||||
}
|
||||
|
||||
|
@ -4797,5 +4801,106 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
Color color = Color;
|
||||
return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
|
||||
}
|
||||
|
||||
#region Components
|
||||
|
||||
[NonSerializedAttribute] // Component serialisation occurs manually.
|
||||
private Dictionary<string, IComponent> m_components = new Dictionary<string, IComponent>();
|
||||
|
||||
public SerializableDictionary<string, string> ComponentStates = new SerializableDictionary<string, string>();
|
||||
|
||||
[NonSerializedAttribute]
|
||||
private bool m_componentsInit = false;
|
||||
|
||||
public void InitComponents()
|
||||
{
|
||||
if(m_componentsInit)
|
||||
return;
|
||||
|
||||
Dictionary<string,OSDMap> states = new Dictionary<string, OSDMap>();
|
||||
foreach (KeyValuePair<string, string> componentState in ComponentStates)
|
||||
{
|
||||
states.Add(componentState.Key, OSDParser.DeserializeJson(componentState.Value) as OSDMap);
|
||||
}
|
||||
//SerializableDictionary<string, OSDMap> states = ComponentStates;
|
||||
|
||||
|
||||
if(ParentGroup.Scene != null)
|
||||
{
|
||||
m_log.Info("[COMPONENTS] Initialising components...");
|
||||
IComponentManagerModule cmm = ParentGroup.Scene.RequestModuleInterface<IComponentManagerModule>();
|
||||
foreach (KeyValuePair<string, OSDMap> kvp in states)
|
||||
{
|
||||
m_log.Info("[COMPONENTS] Adding component " + kvp.Key + " to SceneObjectPart.");
|
||||
|
||||
try
|
||||
{
|
||||
cmm.CreateComponent(this, kvp.Key, kvp.Value);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
m_log.Error("Error creating component " + e.ToString());
|
||||
m_log.Error("Stacktrace: " + e.StackTrace);
|
||||
}
|
||||
}
|
||||
m_componentsInit = true;
|
||||
} else
|
||||
{
|
||||
m_log.Warn("[COMPONENTS] Trying to initialise component which is not attached to a scene.");
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveComponents()
|
||||
{
|
||||
m_log.Info("[COMPONENTS] Saving components...");
|
||||
foreach (KeyValuePair<string, IComponent> keyValuePair in m_components)
|
||||
{
|
||||
OSDMap state = keyValuePair.Value.State;
|
||||
string baseType = keyValuePair.Value.BaseType.ToString();
|
||||
|
||||
m_log.Info("[COMPONENTS] Saving component " + baseType);
|
||||
|
||||
ComponentStates[baseType] = OSDParser.SerializeJsonString(state);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accesses a component
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public T C<T>()
|
||||
{
|
||||
return Get<T>();
|
||||
}
|
||||
|
||||
public T Get<T>()
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public bool TryGet<T>(out T val)
|
||||
{
|
||||
if(m_components.ContainsKey(typeof(T).ToString()))
|
||||
{
|
||||
val = Get<T>();
|
||||
return true;
|
||||
}
|
||||
|
||||
val = default(T);
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Contains<T>()
|
||||
{
|
||||
return m_components.ContainsKey(typeof (T).ToString());
|
||||
}
|
||||
|
||||
public void SetComponent(IComponent val)
|
||||
{
|
||||
Type T = val.BaseType;
|
||||
m_components[T.ToString()] = val;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
// Script state may, or may not, exist. Not having any, is NOT
|
||||
// ever a problem.
|
||||
sceneObject.LoadScriptState(doc);
|
||||
sceneObject.InitPartComponents();
|
||||
|
||||
return sceneObject;
|
||||
}
|
||||
|
@ -240,6 +241,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
// ever a problem.
|
||||
|
||||
sceneObject.LoadScriptState(doc);
|
||||
sceneObject.InitPartComponents();
|
||||
|
||||
return sceneObject;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -285,6 +288,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
{
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
{
|
||||
part.SaveComponents();
|
||||
|
||||
if (part.UUID != sceneObject.RootPart.UUID)
|
||||
{
|
||||
part.ToXml(writer);
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Components;
|
||||
|
||||
namespace OpenSim.Region.OptionalModules.World.TestComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Components must be public classes
|
||||
/// </summary>
|
||||
public class TestComponent : IComponent
|
||||
{
|
||||
private int m_theAnswerToTheQuestionOfLifeTheUniverseAndEverything = 42;
|
||||
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
#region Implementation of IComponent
|
||||
|
||||
public TestComponent()
|
||||
{
|
||||
m_log.Info("Its alive! (for the very first time...!)");
|
||||
}
|
||||
|
||||
public TestComponent(OSDMap state)
|
||||
{
|
||||
m_log.Info("Its alive!");
|
||||
}
|
||||
|
||||
public Type BaseType
|
||||
{
|
||||
get { return typeof (TestComponent); }
|
||||
}
|
||||
|
||||
public OSDMap State
|
||||
{
|
||||
get
|
||||
{
|
||||
OSDMap x = new OSDMap();
|
||||
x["Hello"] = "World";
|
||||
x["HitchhikersReference"] = m_theAnswerToTheQuestionOfLifeTheUniverseAndEverything;
|
||||
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetParent(SceneObjectPart part)
|
||||
{
|
||||
m_log.Info("My parent's name is: " + part.Name);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Components;
|
||||
|
||||
namespace OpenSim.Region.OptionalModules.World.TestComponent
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class TestComponentFactoryModule : ComponentFactory, ISharedRegionModule
|
||||
{
|
||||
private List<Scene> m_scenes = new List<Scene>();
|
||||
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
#region Overrides of ComponentFactory
|
||||
|
||||
protected override IComponent CreateComponent(string componentType, OSDMap componentState)
|
||||
{
|
||||
m_log.Info("[TestComponentFactory] Recieved CreateComponent for " + componentType);
|
||||
if(componentType == typeof(TestComponent).ToString())
|
||||
{
|
||||
if(componentState.ContainsKey("Hello"))
|
||||
{
|
||||
m_log.Info("[TestComponentFactory] Successfully recovered '" + componentState["Hello"] + "' from a component via serialisation.");
|
||||
}
|
||||
return new TestComponent(componentState);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IRegionModuleBase
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "TestComponentFactoryModule"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return typeof (TestComponentFactoryModule); }
|
||||
}
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
m_log.Info("[TESTCOMPONENT] Loading test factory...");
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
m_log.Info("[TESTCOMPONENT] Loading test factory for " + scene.RegionInfo.RegionName);
|
||||
m_scenes.Add(scene);
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
foreach (Scene scene in m_scenes)
|
||||
{
|
||||
m_log.Info("[TESTCOMPONENT] Adding new test component to Scene");
|
||||
List<EntityBase> sogs = scene.Entities.GetAllByType<SceneObjectGroup>();
|
||||
foreach (EntityBase entityBase in sogs)
|
||||
{
|
||||
SceneObjectGroup sog = (SceneObjectGroup) entityBase;
|
||||
m_log.Info("[TESTCOMPONENT] Adding new test component to SOG");
|
||||
foreach (SceneObjectPart part in sog.GetParts())
|
||||
{
|
||||
m_log.Info("[TESTCOMPONENT] Adding new test component to SOP");
|
||||
part.SetComponent(new TestComponent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InitComponentHandler(m_scenes[0]);
|
||||
|
||||
m_log.Info("[TESTCOMPONENT] Test factory loaded");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue