[Opensim-dev] Adding virtual to many methods on Region/Framework/* for experimentation

Justin Clark-Casey jjustincc at googlemail.com
Thu Jul 2 16:10:17 UTC 2009


Cristina Videira Lopes wrote:

> 
> I've done this before (the traffic simulation). I love synthetic objects 
> that extend SOG, and all applications I'm involved with use them 
> heavily. Their only weakness right now is not being able to cross 
> borders like the other ones, because the deserialization routine 
> hardcodes the class. We should fix that at some point.

I actually have a patch which starts to do that - essentially it manually emulates the current automatic serialization 
to write out parts of SOP (but not yet read).  This was done as a basis for future evolution of the serialization which 
doesn't involve the accumulation of confusing cruft both code side and data format side, as proposed on this list about 
a month back.

It was tested in various scenarios but not exhaustively enough where I was happy to put it in (since naturally it's 
critical to get this right).  Everything was fine except for certain situations involving writing out certain flag 
states.  There's a method WriteFlagsEnum(Enum eenum) in the patch which starts to address this problem but it is not yet 
used (and very probably it's not yet right).

Unfortunately, I have other tasks heavily contending for my time so I haven't been able to do any work on it and 
probably won't for some time.  The existing patch follows.  If anyone does pick it up then please let me know.



Index: OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
===================================================================
--- OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs	(revision 9849)
+++ OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs	(working copy)
@@ -26,6 +26,7 @@
   */

  using System;
+using System.Drawing;
  using System.IO;
  using System.Reflection;
  using System.Xml;
@@ -185,9 +186,118 @@
              //m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", Name, 
System.Environment.TickCount - time);
          }

-        protected static void ToOriginalXmlFormat(SceneObjectPart part, XmlTextWriter writer)
+        protected static void ToOriginalXmlFormat(SceneObjectPart part, XmlTextWriter xtw)
          {
-            part.ToXml(writer);
+            xtw.WriteStartElement("SceneObjectPart");
+
+            xtw.WriteElementString("AllowedDrop", XmlConvert.ToString(part.AllowedDrop));
+            WriteUuid(xtw, "CreatorID", part.CreatorID);
+            WriteUuid(xtw, "FolderID", part.FolderID);
+            xtw.WriteElementString("InventorySerial", XmlConvert.ToString(part.InventorySerial));
+
+            xtw.WriteStartElement("TaskInventory");
+            part.TaskInventory.WriteXml(xtw);
+            xtw.WriteEndElement();
+
+            xtw.WriteElementString("ObjectFlags", part.ObjectFlags.ToString());
+            WriteUuid(xtw, "UUID", part.UUID);
+            xtw.WriteElementString("LocalId", XmlConvert.ToString(part.LocalId));
+            xtw.WriteElementString("Name", part.Name);
+            xtw.WriteElementString("Material", XmlConvert.ToString(part.Material));
+            xtw.WriteElementString("PassTouches", XmlConvert.ToString(part.PassTouches));
+            xtw.WriteElementString("RegionHandle", XmlConvert.ToString(part.RegionHandle));
+            xtw.WriteElementString("ScriptAccessPin", XmlConvert.ToString(part.ScriptAccessPin));
+            WriteVector(xtw, "GroupPosition", part.GroupPosition);
+            WriteVector(xtw, "OffsetPosition", part.OffsetPosition);
+            WriteQuaternion(xtw, "RotationOffset", part.RotationOffset);
+            WriteVector(xtw, "Velocity", part.Velocity);
+            WriteVector(xtw, "RotationalVelocity", part.RotationalVelocity);
+            WriteVector(xtw, "AngularVelocity", part.AngularVelocity);
+            WriteVector(xtw, "Acceleration", part.Acceleration);
+            xtw.WriteElementString("Description", part.Description);
+            WriteColor(xtw, "Color", part.Color);
+            xtw.WriteElementString("Text", part.Text);
+            xtw.WriteElementString("SitName", part.SitName);
+            xtw.WriteElementString("TouchName", part.TouchName);
+            xtw.WriteElementString("LinkNum", XmlConvert.ToString(part.LinkNum));
+            xtw.WriteElementString("ClickAction", XmlConvert.ToString(part.ClickAction));
+
+            PrimitiveBaseShape shape = part.Shape;
+            xtw.WriteStartElement("Shape");
+                xtw.WriteElementString("ProfileCurve", XmlConvert.ToString(shape.ProfileCurve));
+                xtw.WriteElementString("TextureEntry", Convert.ToBase64String(shape.TextureEntry));
+                xtw.WriteElementString("ExtraParams", Convert.ToBase64String(shape.ExtraParams));
+                xtw.WriteElementString("PathBegin", XmlConvert.ToString(shape.PathBegin));
+                xtw.WriteElementString("PathCurve", XmlConvert.ToString(shape.PathCurve));
+                xtw.WriteElementString("PathEnd", XmlConvert.ToString(shape.PathEnd));
+                xtw.WriteElementString("PathRadiusOffset", XmlConvert.ToString(shape.PathRadiusOffset));
+                xtw.WriteElementString("PathRevolutions", XmlConvert.ToString(shape.PathRevolutions));
+                xtw.WriteElementString("PathScaleX", XmlConvert.ToString(shape.PathScaleX));
+                xtw.WriteElementString("PathScaleY", XmlConvert.ToString(shape.PathScaleY));
+                xtw.WriteElementString("PathShearX", XmlConvert.ToString(shape.PathShearX));
+                xtw.WriteElementString("PathShearY", XmlConvert.ToString(shape.PathShearX));
+                xtw.WriteElementString("PathSkew", XmlConvert.ToString(shape.PathSkew));
+                xtw.WriteElementString("PathTaperX", XmlConvert.ToString(shape.PathTaperX));
+                xtw.WriteElementString("PathTaperY", XmlConvert.ToString(shape.PathTaperY));
+                xtw.WriteElementString("PathTwist", XmlConvert.ToString(shape.PathTwist));
+                xtw.WriteElementString("PathTwistBegin", XmlConvert.ToString(shape.PathTwistBegin));
+                xtw.WriteElementString("PCode", XmlConvert.ToString(shape.PCode));
+                xtw.WriteElementString("ProfileBegin", XmlConvert.ToString(shape.ProfileBegin));
+                xtw.WriteElementString("ProfileEnd", XmlConvert.ToString(shape.ProfileEnd));
+                xtw.WriteElementString("ProfileHollow", XmlConvert.ToString(shape.ProfileHollow));
+                WriteVector(xtw, "Scale", shape.Scale);
+                xtw.WriteElementString("State", XmlConvert.ToString(shape.State));
+                xtw.WriteElementString("ProfileShape", shape.ProfileShape.ToString());
+                xtw.WriteElementString("HollowShape", shape.HollowShape.ToString());
+                WriteUuid(xtw, "SculptTexture", shape.SculptTexture);
+                xtw.WriteElementString("SculptType", XmlConvert.ToString(shape.SculptType));
+                xtw.WriteElementString("SculptData", Convert.ToBase64String(shape.SculptData));
+                xtw.WriteElementString("FlexiSoftness", XmlConvert.ToString(shape.FlexiSoftness));
+                xtw.WriteElementString("FlexiTension", XmlConvert.ToString(shape.FlexiTension));
+                xtw.WriteElementString("FlexiDrag", XmlConvert.ToString(shape.FlexiDrag));
+                xtw.WriteElementString("FlexiGravity", XmlConvert.ToString(shape.FlexiGravity));
+                xtw.WriteElementString("FlexiWind", XmlConvert.ToString(shape.FlexiWind));
+                xtw.WriteElementString("FlexiForceX", XmlConvert.ToString(shape.FlexiForceX));
+                xtw.WriteElementString("FlexiForceY", XmlConvert.ToString(shape.FlexiForceY));
+                xtw.WriteElementString("FlexiForceZ", XmlConvert.ToString(shape.FlexiForceZ));
+                xtw.WriteElementString("LightColorR", XmlConvert.ToString(shape.LightColorR));
+                xtw.WriteElementString("LightColorG", XmlConvert.ToString(shape.LightColorG));
+                xtw.WriteElementString("LightColorB", XmlConvert.ToString(shape.LightColorB));
+                xtw.WriteElementString("LightColorA", XmlConvert.ToString(shape.LightColorA));
+                xtw.WriteElementString("LightRadius", XmlConvert.ToString(shape.LightRadius));
+                xtw.WriteElementString("LightCutoff", XmlConvert.ToString(shape.LightCutoff));
+                xtw.WriteElementString("LightFalloff", XmlConvert.ToString(shape.LightFalloff));
+                xtw.WriteElementString("LightIntensity", XmlConvert.ToString(shape.LightIntensity));
+                xtw.WriteElementString("FlexiEntry", XmlConvert.ToString(shape.FlexiEntry));
+                xtw.WriteElementString("LightEntry", XmlConvert.ToString(shape.LightEntry));
+                xtw.WriteElementString("SculptEntry", XmlConvert.ToString(shape.SculptEntry));
+            xtw.WriteEndElement();
+
+            WriteVector(xtw, "Scale", part.Scale);
+            xtw.WriteElementString("UpdateFlag", XmlConvert.ToString(part.UpdateFlag));
+            WriteQuaternion(xtw, "SitTargetOrientation", part.SitTargetOrientation);
+            WriteVector(xtw, "SitTargetPosition", part.SitTargetPosition);
+            WriteVector(xtw, "SitTargetPositionLL", part.SitTargetPositionLL);
+            WriteQuaternion(xtw, "SitTargetOrientationLL", part.SitTargetOrientationLL);
+            xtw.WriteElementString("ParentID", XmlConvert.ToString(part.ParentID));
+            xtw.WriteElementString("CreationDate", XmlConvert.ToString(part.CreationDate));
+            xtw.WriteElementString("Category", XmlConvert.ToString(part.Category));
+            xtw.WriteElementString("SalePrice", XmlConvert.ToString(part.SalePrice));
+            xtw.WriteElementString("ObjectSaleType", XmlConvert.ToString(part.ObjectSaleType));
+            xtw.WriteElementString("OwnershipCost", XmlConvert.ToString(part.OwnershipCost));
+            WriteUuid(xtw, "GroupID", part.GroupID);
+            WriteUuid(xtw, "OwnerID", part.OwnerID);
+            WriteUuid(xtw, "LastOwnerID", part.LastOwnerID);
+            xtw.WriteElementString("BaseMask", XmlConvert.ToString(part.BaseMask));
+            xtw.WriteElementString("OwnerMask", XmlConvert.ToString(part.OwnerMask));
+            xtw.WriteElementString("GroupMask", XmlConvert.ToString(part.GroupMask));
+            xtw.WriteElementString("EveryoneMask", XmlConvert.ToString(part.EveryoneMask));
+            xtw.WriteElementString("NextOwnerMask", XmlConvert.ToString(part.NextOwnerMask));
+            xtw.WriteElementString("Flags", part.Flags.ToString());
+            WriteUuid(xtw, "CollisionSound", part.CollisionSound);
+            xtw.WriteElementString("CollisionSoundVolume", XmlConvert.ToString(part.CollisionSoundVolume));
+
+            xtw.WriteEndElement();
          }

          public static SceneObjectGroup FromXml2Format(string xmlData)
@@ -297,6 +407,113 @@
              writer.WriteEndElement(); // End of SceneObjectGroup

              //m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0} to XML2, {1}ms", Name, 
System.Environment.TickCount - time);
-        }
+        }
+
+        /// <summary>
+        /// Write a flags enumeration.
+        /// </summary>
+        /// Unfortunately, XML serialization separates values with a space, while Enum.ToString() separates with a
+        /// comma
+        /// <param name="eenum"></param>
+        protected static void WriteFlagsEnum(Enum eenum)
+        {
+            // TODO: Is it possible to automatically determine if the enum is a flags one?
+
+            StringBuilder sb = new StringBuilder();
+            long[] values = Enum.GetValues(eenum.GetType());
+            string[] names = Enum.GetValues(eenum.GetType());
+
+            int length = ids.Length;
+            long initialValue = ((IConvertible)eenum).ToInt64(CultureInfo.CurrentCulture);
+            long valueToProcess = initialValue;
+            int zeroValue = -1;
+
+            for (int i = 0; i < length; i ++)
+            {
+                if (values[i] == 0)
+                {
+                    zeroValue = i;
+                }
+                else
+                {
+                    if (valueToProcess == 0)
+                        break;
+
+                    if ((values[i] & initialValue) == values[i])
+                    {
+                        if (sb.Length != 0)
+                            sb.Append (' ');
+
+                        sb.Append(values[i]);
+                        valueToProcess &= ~values[i];
+                    }
+                }
+            }
+
+            if (sb.Length == 0 && zeroValue != -1)
+                sb.Append(values[zeroValue]);
+
+            return sb.ToString();
+        }
+
+        /// <summary>
+        /// Write common UUID xml
+        /// </summary>
+        /// <param name="writer"></param>
+        /// <param name="name"></param>
+        /// <param name="vec"></param>
+        protected static void WriteUuid(XmlTextWriter writer, string name, UUID id)
+        {
+            writer.WriteStartElement(name);
+            writer.WriteElementString("Guid", XmlConvert.ToString(id.Guid));
+            writer.WriteEndElement();
+        }
+
+        /// <summary>
+        /// Write common vector xml
+        /// </summary>
+        /// <param name="writer"></param>
+        /// <param name="name"></param>
+        /// <param name="vec"></param>
+        protected static void WriteVector(XmlTextWriter writer, string name, Vector3 vec)
+        {
+            writer.WriteStartElement(name);
+            writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture));
+            writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture));
+            writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture));
+            writer.WriteEndElement();
+        }
+
+        /// <summary>
+        /// Write common quaternion xml
+        /// </summary>
+        /// <param name="writer"></param>
+        /// <param name="name"></param>
+        /// <param name="quat"></param>
+        protected static void WriteQuaternion(XmlTextWriter writer, string name, Quaternion quat)
+        {
+            writer.WriteStartElement(name);
+            writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture));
+            writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture));
+            writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture));
+            writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture));
+            writer.WriteEndElement();
+        }
+
+        /// <summary>
+        /// Write common color xml
+        /// </summary>
+        /// <param name="writer"></param>
+        /// <param name="name"></param>
+        /// <param name="col"></param>
+        protected static void WriteColor(XmlTextWriter writer, string name, Color col)
+        {
+            writer.WriteStartElement(name);
+            writer.WriteElementString("R", col.R.ToString(Utils.EnUsCulture));
+            writer.WriteElementString("G", col.G.ToString(Utils.EnUsCulture));
+            writer.WriteElementString("B", col.B.ToString(Utils.EnUsCulture));
+            writer.WriteElementString("A", col.A.ToString(Utils.EnUsCulture));
+            writer.WriteEndElement();
+        }
      }
  }

-- 
justincc
Justin Clark-Casey
http://justincc.wordpress.com



More information about the Opensim-dev mailing list