aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
authorDr Scofield2009-04-22 18:09:55 +0000
committerDr Scofield2009-04-22 18:09:55 +0000
commit7dbcf0570f0f5d521373df6d381c2d75dc2845d3 (patch)
tree63d7b2429f78b4b66e9194c5ee35476ac9b1e5e0 /OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
parentmore cleanup (diff)
downloadopensim-SC-7dbcf0570f0f5d521373df6d381c2d75dc2845d3.zip
opensim-SC-7dbcf0570f0f5d521373df6d381c2d75dc2845d3.tar.gz
opensim-SC-7dbcf0570f0f5d521373df6d381c2d75dc2845d3.tar.bz2
opensim-SC-7dbcf0570f0f5d521373df6d381c2d75dc2845d3.tar.xz
From: Alan Webb <alan_webb@us.ibm.com>
Changes to enable script state persistence across non-restart serialization situations (inventory/OAR/attachments) Also fixing test cases for OAR and IAR so they don't barf with the new code.
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs210
1 files changed, 143 insertions, 67 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 2552a3d..364da72 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -169,6 +169,8 @@ namespace OpenSim.Region.Framework.Scenes
169 private bool m_scriptListens_atTarget = false; 169 private bool m_scriptListens_atTarget = false;
170 private bool m_scriptListens_notAtTarget = false; 170 private bool m_scriptListens_notAtTarget = false;
171 171
172 internal Dictionary<UUID, string> m_savedScriptState = null;
173
172 #region Properties 174 #region Properties
173 175
174 /// <summary> 176 /// <summary>
@@ -423,6 +425,7 @@ namespace OpenSim.Region.Framework.Scenes
423 /// </param> 425 /// </param>
424 public SceneObjectGroup(UUID fromUserInventoryItemID, string xmlData, bool isOriginalXmlFormat) 426 public SceneObjectGroup(UUID fromUserInventoryItemID, string xmlData, bool isOriginalXmlFormat)
425 { 427 {
428
426 if (!isOriginalXmlFormat) 429 if (!isOriginalXmlFormat)
427 throw new Exception("This constructor must specify the xml is in OpenSim's original format"); 430 throw new Exception("This constructor must specify the xml is in OpenSim's original format");
428 431
@@ -436,50 +439,60 @@ namespace OpenSim.Region.Framework.Scenes
436 // Handle Nested <UUID><UUID> property 439 // Handle Nested <UUID><UUID> property
437 xmlData = xmlData.Replace("<Guid><Guid>", "<UUID><Guid>"); 440 xmlData = xmlData.Replace("<Guid><Guid>", "<UUID><Guid>");
438 xmlData = xmlData.Replace("</Guid></Guid>", "</Guid></UUID>"); 441 xmlData = xmlData.Replace("</Guid></Guid>", "</Guid></UUID>");
439 StringReader sr = new StringReader(xmlData);
440 XmlTextReader reader = new XmlTextReader(sr);
441 442
442 try 443 try
443 { 444 {
444 reader.Read();
445 reader.ReadStartElement("SceneObjectGroup");
446 reader.ReadStartElement("RootPart");
447 SetRootPart(SceneObjectPart.FromXml(fromUserInventoryItemID, reader));
448 445
449 reader.ReadEndElement(); 446 StringReader sr;
447 XmlTextReader reader;
448 XmlNodeList parts;
449 XmlDocument doc;
450 int linkNum;
451
452 doc = new XmlDocument();
453 doc.LoadXml(xmlData);
454 parts = doc.GetElementsByTagName("RootPart");
450 455
451 while (reader.Read()) 456 if(parts.Count == 0)
452 { 457 {
453 switch (reader.NodeType) 458 throw new Exception("[SCENE] Invalid Xml format - no root part");
454 { 459 }
455 case XmlNodeType.Element: 460 else
456 if (reader.Name == "Part") 461 {
457 { 462 sr = new StringReader(parts[0].InnerXml);
458 reader.Read(); 463 reader = new XmlTextReader(sr);
459 SceneObjectPart part = SceneObjectPart.FromXml(reader); 464 SetRootPart(SceneObjectPart.FromXml(fromUserInventoryItemID, reader));
460 465 reader.Close();
461 // We reset the link number in order to make sure that the persisted linkset order is 466 sr.Close();
462 int linkNum = part.LinkNum; 467 }
463 AddPart(part); 468
464 part.LinkNum = linkNum; 469 parts = doc.GetElementsByTagName("Part");
465 470
466 part.TrimPermissions(); 471 for (int i=0; i<parts.Count ; i++)
467 part.StoreUndoState(); 472 {
468 } 473 sr = new StringReader(parts[i].InnerXml);
469 break; 474 reader = new XmlTextReader(sr);
470 475 SceneObjectPart part = SceneObjectPart.FromXml(reader);
471 case XmlNodeType.EndElement: 476 linkNum = part.LinkNum;
472 break; 477 AddPart(part);
473 } 478 part.LinkNum = linkNum;
479 part.TrimPermissions();
480 part.StoreUndoState();
481 reader.Close();
482 sr.Close();
474 } 483 }
484
485 // Script state may, or may not, exist. Not having any, is NOT
486 // ever a problem.
487
488 LoadScriptState(doc);
489
475 } 490 }
476 catch (XmlException e) 491 catch (Exception e)
477 { 492 {
478 m_log.ErrorFormat("[SCENE]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); 493 m_log.ErrorFormat("[SCENE]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData);
479 } 494 }
480 495
481 reader.Close();
482 sr.Close();
483 //m_log.DebugFormat("[SOG]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); 496 //m_log.DebugFormat("[SOG]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time);
484 } 497 }
485 498
@@ -493,6 +506,7 @@ namespace OpenSim.Region.Framework.Scenes
493 506
494 protected void SetFromXml(string xmlData) 507 protected void SetFromXml(string xmlData)
495 { 508 {
509
496 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); 510 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG");
497 //int time = System.Environment.TickCount; 511 //int time = System.Environment.TickCount;
498 512
@@ -504,43 +518,47 @@ namespace OpenSim.Region.Framework.Scenes
504 xmlData = xmlData.Replace("<Guid><Guid>", "<UUID><Guid>"); 518 xmlData = xmlData.Replace("<Guid><Guid>", "<UUID><Guid>");
505 xmlData = xmlData.Replace("</Guid></Guid>", "</Guid></UUID>"); 519 xmlData = xmlData.Replace("</Guid></Guid>", "</Guid></UUID>");
506 520
507 StringReader sr = new StringReader(xmlData); 521 try
508 XmlTextReader reader = new XmlTextReader(sr); 522 {
509 reader.Read(); 523
524 XmlDocument doc = new XmlDocument();
525 doc.LoadXml(xmlData);
526
527 XmlNodeList parts = doc.GetElementsByTagName("SceneObjectPart");
510 528
511 reader.ReadStartElement("SceneObjectGroup"); 529 // Process the root part first
512 SetRootPart(CreatePartFromXml(reader)); 530 if(parts.Count > 0)
531 {
532 StringReader sr = new StringReader(parts[0].OuterXml);
533 XmlTextReader reader = new XmlTextReader(sr);
534 SetRootPart(CreatePartFromXml(reader));
535 reader.Close();
536 sr.Close();
537 }
513 538
514 reader.Read(); 539 // Then deal with the rest
515 bool more = true; 540 for(int i=1; i<parts.Count; i++)
541 {
542 StringReader sr = new StringReader(parts[i].OuterXml);
543 XmlTextReader reader = new XmlTextReader(sr);
544 SceneObjectPart part = CreatePartFromXml(reader);
545 AddPart(part);
546 part.StoreUndoState();
547 reader.Close();
548 sr.Close();
549 }
516 550
517 while (more) 551 // Script state may, or may not, exist. Not having any, is NOT
552 // ever a problem.
553
554 LoadScriptState(doc);
555
556 }
557 catch (Exception e)
518 { 558 {
519 switch (reader.NodeType) 559 m_log.ErrorFormat("[SCENE]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData);
520 {
521 case XmlNodeType.Element:
522 if (reader.Name == "SceneObjectPart")
523 {
524 SceneObjectPart part = CreatePartFromXml(reader);
525 AddPart(part);
526 part.StoreUndoState();
527 }
528 else
529 {
530 m_log.Warn("found unexpected element: " + reader.Name);
531 reader.Read();
532 }
533 break;
534 case XmlNodeType.EndElement:
535 reader.Read();
536 break;
537 }
538 more = !reader.EOF;
539 } 560 }
540 561
541 reader.Close();
542 sr.Close();
543
544 //m_log.DebugFormat("[SOG]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); 562 //m_log.DebugFormat("[SOG]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time);
545 } 563 }
546 564
@@ -567,6 +585,23 @@ namespace OpenSim.Region.Framework.Scenes
567 { 585 {
568 } 586 }
569 587
588 private void LoadScriptState(XmlDocument doc)
589 {
590 XmlNodeList nodes = doc.GetElementsByTagName("SavedScriptState");
591 if(nodes.Count > 0)
592 {
593 m_savedScriptState = new Dictionary<UUID, string>();
594 foreach(XmlNode node in nodes)
595 {
596 if(node.Attributes["UUID"] != null)
597 {
598 UUID itemid = new UUID(node.Attributes["UUID"].Value);
599 m_savedScriptState.Add(itemid, node.InnerXml);
600 }
601 }
602 }
603 }
604
570 public void SetFromAssetID(UUID AssetId) 605 public void SetFromAssetID(UUID AssetId)
571 { 606 {
572 lock (m_parts) 607 lock (m_parts)
@@ -748,8 +783,9 @@ namespace OpenSim.Region.Framework.Scenes
748 } 783 }
749 } 784 }
750 785
751 writer.WriteEndElement(); 786 writer.WriteEndElement(); // OtherParts
752 writer.WriteEndElement(); 787 SaveScriptedState(writer);
788 writer.WriteEndElement(); // SceneObjectGroup
753 789
754 //m_log.DebugFormat("[SOG]: Finished serialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); 790 //m_log.DebugFormat("[SOG]: Finished serialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time);
755 } 791 }
@@ -769,6 +805,7 @@ namespace OpenSim.Region.Framework.Scenes
769 805
770 public void ToXml2(XmlTextWriter writer) 806 public void ToXml2(XmlTextWriter writer)
771 { 807 {
808
772 //m_log.DebugFormat("[SOG]: Starting serialization of SOG {0} to XML2", Name); 809 //m_log.DebugFormat("[SOG]: Starting serialization of SOG {0} to XML2", Name);
773 //int time = System.Environment.TickCount; 810 //int time = System.Environment.TickCount;
774 811
@@ -787,9 +824,48 @@ namespace OpenSim.Region.Framework.Scenes
787 } 824 }
788 } 825 }
789 826
790 writer.WriteEndElement(); 827 writer.WriteEndElement(); // End of OtherParts
791 writer.WriteEndElement(); 828 SaveScriptedState(writer);
829 writer.WriteEndElement(); // End of SceneObjectGroup
830
792 //m_log.DebugFormat("[SOG]: Finished serialization of SOG {0} to XML2, {1}ms", Name, System.Environment.TickCount - time); 831 //m_log.DebugFormat("[SOG]: Finished serialization of SOG {0} to XML2, {1}ms", Name, System.Environment.TickCount - time);
832
833 }
834
835 private void SaveScriptedState(XmlTextWriter writer)
836 {
837
838 XmlDocument doc = new XmlDocument();
839 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
840
841 // Capture script state while holding the lock
842 lock (m_parts)
843 {
844 foreach (SceneObjectPart part in m_parts.Values)
845 {
846 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
847 foreach (UUID itemid in pstates.Keys)
848 {
849 states.Add(itemid, pstates[itemid]);
850 }
851 }
852 }
853
854 if(states.Count > 0)
855 {
856 // Now generate the necessary XML wrappings
857 writer.WriteStartElement(String.Empty, "GroupScriptStates", String.Empty);
858 foreach(UUID itemid in states.Keys)
859 {
860 doc.LoadXml(states[itemid]);
861 writer.WriteStartElement(String.Empty, "SavedScriptState", String.Empty);
862 writer.WriteAttributeString(String.Empty, "UUID", String.Empty, itemid.ToString());
863 writer.WriteRaw(doc.DocumentElement.OuterXml); // Writes ScriptState element
864 writer.WriteEndElement(); // End of SavedScriptState
865 }
866 writer.WriteEndElement(); // End of GroupScriptStates
867 }
868
793 } 869 }
794 870
795 /// <summary> 871 /// <summary>