diff --git a/OpenSim/Framework/SerializableDictionary.cs b/OpenSim/Framework/SerializableDictionary.cs new file mode 100644 index 0000000000..27d36495d3 --- /dev/null +++ b/OpenSim/Framework/SerializableDictionary.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; +using System.Xml.Serialization; + +namespace OpenSim.Framework +{ + + [XmlRoot("dictionary")] + public class SerializableDictionary + : Dictionary, 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 + } +} diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index bb9e6d4c73..2007727752 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -648,8 +648,8 @@ 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} STACK: {2}", packetObject.Pack, e.ToString(),e.StackTrace), e); + } } #endregion Packet Handling diff --git a/OpenSim/Region/CoreModules/World/Objects/Components/ComponentManagerModule.cs b/OpenSim/Region/CoreModules/World/Objects/Components/ComponentManagerModule.cs index 4ea914a965..a1e5010fb0 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Components/ComponentManagerModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Components/ComponentManagerModule.cs @@ -60,17 +60,24 @@ namespace OpenSim.Region.CoreModules.World.Objects.Components #region Implementation of IComponentManagerModule - public void CreateComponent(SceneObjectPart target, Type componentType, IComponentState state) + public void CreateComponent(SceneObjectPart target, string componentType, ComponentState state) { - foreach (OnCreateComponentDelegate h in OnCreateComponent.GetInvocationList()) + if (OnCreateComponent != null) { - IComponent x = h(componentType, state); - if(x != null) + foreach (OnCreateComponentDelegate h in OnCreateComponent.GetInvocationList()) { - target.SetComponent(x); - x.SetParent(target); - return; + 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?"); diff --git a/OpenSim/Region/Framework/Interfaces/IComponentManagerModule.cs b/OpenSim/Region/Framework/Interfaces/IComponentManagerModule.cs index 763c5f4d39..4aacbf47ba 100644 --- a/OpenSim/Region/Framework/Interfaces/IComponentManagerModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IComponentManagerModule.cs @@ -4,11 +4,11 @@ using OpenSim.Region.Framework.Scenes.Components; namespace OpenSim.Region.Framework.Interfaces { - public delegate IComponent OnCreateComponentDelegate(Type componentType, IComponentState componentState); + public delegate IComponent OnCreateComponentDelegate(string componentType, ComponentState componentState); public interface IComponentManagerModule { - void CreateComponent(SceneObjectPart part, Type componentType, IComponentState state); + void CreateComponent(SceneObjectPart part, string componentType, ComponentState state); event OnCreateComponentDelegate OnCreateComponent; } } diff --git a/OpenSim/Region/Framework/Scenes/Components/ComponentFactory.cs b/OpenSim/Region/Framework/Scenes/Components/ComponentFactory.cs index 22ffbc4a32..0ba3034bb0 100644 --- a/OpenSim/Region/Framework/Scenes/Components/ComponentFactory.cs +++ b/OpenSim/Region/Framework/Scenes/Components/ComponentFactory.cs @@ -11,6 +11,6 @@ namespace OpenSim.Region.Framework.Scenes.Components cmm.OnCreateComponent += CreateComponent; } - protected abstract IComponent CreateComponent(Type componentType, IComponentState componentState); + protected abstract IComponent CreateComponent(string componentType, ComponentState componentState); } } diff --git a/OpenSim/Region/Framework/Scenes/Components/ComponentState.cs b/OpenSim/Region/Framework/Scenes/Components/ComponentState.cs index 05663aa335..bb9832df03 100644 --- a/OpenSim/Region/Framework/Scenes/Components/ComponentState.cs +++ b/OpenSim/Region/Framework/Scenes/Components/ComponentState.cs @@ -4,6 +4,7 @@ using System.Runtime.Serialization; namespace OpenSim.Region.Framework.Scenes.Components { + [Serializable] public class ComponentState : IComponentState { private readonly Dictionary m_stateData = new Dictionary(); diff --git a/OpenSim/Region/Framework/Scenes/Components/IComponent.cs b/OpenSim/Region/Framework/Scenes/Components/IComponent.cs index b6c6524087..7749dcc563 100644 --- a/OpenSim/Region/Framework/Scenes/Components/IComponent.cs +++ b/OpenSim/Region/Framework/Scenes/Components/IComponent.cs @@ -16,7 +16,7 @@ namespace OpenSim.Region.Framework.Scenes.Components /// /// A representation of the current state of the component, to be deserialised later. /// - IComponentState State { get; } + ComponentState State { get; } void SetParent(SceneObjectPart part); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 8a30523f0e..94f3da08cf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4804,16 +4804,9 @@ namespace OpenSim.Region.Framework.Scenes #region Components [NonSerializedAttribute] // Component serialisation occurs manually. - private Dictionary m_components = new Dictionary(); + private Dictionary m_components = new Dictionary(); - private IDictionary m_componentStates = new Dictionary(); - - public void InitComponents(IDictionary states) - { - m_componentStates = states; - - InitComponents(); - } + public SerializableDictionary ComponentStates = new SerializableDictionary(); [NonSerializedAttribute] private bool m_componentsInit = false; @@ -4823,15 +4816,24 @@ namespace OpenSim.Region.Framework.Scenes if(m_componentsInit) return; - IDictionary states = m_componentStates; + SerializableDictionary states = ComponentStates; if(ParentGroup.Scene != null) { m_log.Info("[COMPONENTS] Initialising components..."); IComponentManagerModule cmm = ParentGroup.Scene.RequestModuleInterface(); - foreach(KeyValuePair kvp in states) + foreach(KeyValuePair kvp in states) { m_log.Info("[COMPONENTS] Adding component " + kvp.Key + " to SceneObjectPart."); - cmm.CreateComponent(this,kvp.Key,kvp.Value); + + 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 @@ -4842,12 +4844,15 @@ namespace OpenSim.Region.Framework.Scenes public void SaveComponents() { - foreach (KeyValuePair keyValuePair in m_components) + m_log.Info("[COMPONENTS] Saving components..."); + foreach (KeyValuePair keyValuePair in m_components) { - IComponentState state = keyValuePair.Value.State; - Type baseType = keyValuePair.Value.BaseType; + ComponentState state = keyValuePair.Value.State; + string baseType = keyValuePair.Value.BaseType.ToString(); - m_componentStates[baseType] = state; + m_log.Info("[COMPONENTS] Saving component " + baseType); + + ComponentStates[baseType] = state; } } @@ -4868,7 +4873,7 @@ namespace OpenSim.Region.Framework.Scenes public bool TryGet(out T val) { - if(m_components.ContainsKey(typeof(T))) + if(m_components.ContainsKey(typeof(T).ToString())) { val = Get(); return true; @@ -4880,13 +4885,13 @@ namespace OpenSim.Region.Framework.Scenes public bool Contains() { - return m_components.ContainsKey(typeof (T)); + return m_components.ContainsKey(typeof (T).ToString()); } public void SetComponent(IComponent val) { Type T = val.BaseType; - m_components[T] = val; + m_components[T.ToString()] = val; } #endregion } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index b99c71cfcc..4072049fa9 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -288,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); diff --git a/OpenSim/Region/OptionalModules/World/TestComponent/TestComponent.cs b/OpenSim/Region/OptionalModules/World/TestComponent/TestComponent.cs index 7a152a7cf5..1f6b971712 100644 --- a/OpenSim/Region/OptionalModules/World/TestComponent/TestComponent.cs +++ b/OpenSim/Region/OptionalModules/World/TestComponent/TestComponent.cs @@ -6,7 +6,10 @@ using OpenSim.Region.Framework.Scenes.Components; namespace OpenSim.Region.OptionalModules.World.TestComponent { - class TestComponent : IComponent + /// + /// Components must be public classes + /// + public class TestComponent : IComponent { private int m_theAnswerToTheQuestionOfLifeTheUniverseAndEverything = 42; @@ -15,7 +18,15 @@ namespace OpenSim.Region.OptionalModules.World.TestComponent #region Implementation of IComponent - public TestComponent(IComponentState state) + /// + /// Components MUST have a parameterless constructor + /// + public TestComponent() + { + + } + + public TestComponent(ComponentState state) { m_log.Info("Its alive!"); } @@ -25,7 +36,7 @@ namespace OpenSim.Region.OptionalModules.World.TestComponent get { return typeof (TestComponent); } } - public IComponentState State + public ComponentState State { get { diff --git a/OpenSim/Region/OptionalModules/World/TestComponent/TestComponentFactoryModule.cs b/OpenSim/Region/OptionalModules/World/TestComponent/TestComponentFactoryModule.cs index 840a36dd69..bea678c3aa 100644 --- a/OpenSim/Region/OptionalModules/World/TestComponent/TestComponentFactoryModule.cs +++ b/OpenSim/Region/OptionalModules/World/TestComponent/TestComponentFactoryModule.cs @@ -20,9 +20,10 @@ namespace OpenSim.Region.OptionalModules.World.TestComponent #region Overrides of ComponentFactory - protected override IComponent CreateComponent(Type componentType, IComponentState componentState) + protected override IComponent CreateComponent(string componentType, ComponentState componentState) { - if(componentType == typeof(TestComponent)) + m_log.Info("[TestComponentFactory] Recieved CreateComponent for " + componentType); + if(componentType == typeof(TestComponent).ToString()) { string tmp; if(componentState.TryGet("Hello", out tmp)) @@ -97,6 +98,8 @@ namespace OpenSim.Region.OptionalModules.World.TestComponent } } + InitComponentHandler(m_scenes[0]); + m_log.Info("[TESTCOMPONENT] Test factory loaded"); }