From 42645acab9a06a126e20d2a6abce49f413b60d5b Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Tue, 4 Jan 2011 14:19:44 -0800 Subject: [PATCH 1/4] Fix a bug and link-set objects can now be synched correctly. --- .../RegionSync/RegionSyncModule/RegionSyncServerModule.cs | 4 ++-- .../RegionSyncModule/SymmetricSync/RegionSyncModule.cs | 2 +- .../Framework/Scenes/Serialization/SceneObjectSerializer.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs index fc56777a0b..77fdf24b31 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs @@ -391,7 +391,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //when an object is deleted, this function (DeleteObject) could be triggered more than once. So we check //if the object part is already removed is the scene (part==null) - m_log.Debug("Inform script engine about the deleted object"); + //m_log.Debug("Inform script engine about the deleted object"); if(m_sceneToSESyncServer!=null) m_sceneToSESyncServer.SendToSE(rsm, part.ParentGroup); } @@ -572,7 +572,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //when an object is deleted, this function (DeleteObject) could be triggered more than once. So we check //if the object part is already removed is the scene (part==null) - m_log.Debug("Inform script engine about the deleted object"); + //m_log.Debug("Inform script engine about the deleted object"); m_sceneToSESyncServer.SendToSE(rsm, part.ParentGroup); } } diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 70b2d69f46..586fdf16a5 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -774,7 +774,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)e); SendSyncMessage(SymmetricSyncMessage.MsgType.NewObject, sogxml); - //m_log.Debug(LogHeader + ": " + sogxml); + m_log.Debug(LogHeader + ": " + sogxml); } } return; diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index efadf8dedf..8953ce31ba 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -217,7 +217,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization //SYMMETRIC SYNC //KittyL: 12/27/2010, added ActorID for symmetric synch model - part.SetLastUpdateActorID(); + //part.SetLastUpdateActorID(); // SceneObjectGroup.AddPart() tries to be smart and automatically set the LinkNum. // We override that here From 9b34d506437cceb1c7f28e48221a33f72449aafd Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Wed, 5 Jan 2011 13:46:48 -0800 Subject: [PATCH 2/4] Tried a temporary solution for propogating events across actors. See OnUpdateScript handlers. --- .../SymmetricSync/RegionSyncModule.cs | 128 +++++++++++++++++- .../SymmetricSync/ScriptEngineSyncModule.cs | 14 +- .../SymmetricSync/SymmetricSyncMessage.cs | 7 +- .../Region/Framework/Scenes/EventManager.cs | 25 +++- .../Framework/Scenes/Scene.Inventory.cs | 61 ++++++++- 5 files changed, 223 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 586fdf16a5..4d675512af 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -63,6 +63,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_active = true; + LogHeader += "-" + m_actorID; m_log.Warn("[REGION SYNC MODULE] Initialised for actor "+ m_actorID); //The ActorType configuration will be read in and process by an ActorSyncModule, not here. @@ -86,9 +87,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; InstallInterfaces(); - //Register for the OnPostSceneCreation event + //Register for Scene events m_scene.EventManager.OnPostSceneCreation += OnPostSceneCreation; m_scene.EventManager.OnObjectBeingRemovedFromScene += new EventManager.ObjectBeingRemovedFromScene(RegionSyncModule_OnObjectBeingRemovedFromScene); + + //Register for scene events that need to be propogated to other actors + m_scene.EventManager.OnUpdateScript += RegionSyncModule_OnUpdateScript; } //Called after AddRegion() has been called for all region modules of the scene @@ -393,7 +397,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //the actor operates on. private HashSet m_syncConnectors= new HashSet(); private object m_syncConnectorsLock = new object(); - + + //seq number for scene events that are sent out to other actors + private ulong m_eventSeq = 0; + //Timers for periodically status report has not been implemented yet. private System.Timers.Timer m_statsTimer = new System.Timers.Timer(1000); private void StatsTimerElapsed(object source, System.Timers.ElapsedEventArgs e) @@ -414,6 +421,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } } + private void SendSceneEventToRelevantSyncConnectors(string init_actorID, SymmetricSyncMessage rsm) + { + List syncConnectors = GetSyncConnectorsForSceneEvents(init_actorID, rsm); + + foreach (SyncConnector connector in syncConnectors) + { + connector.Send(rsm); + } + } + /// /// Check if we need to send out an update message for the given object. /// @@ -465,6 +482,39 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return syncConnectors; } + /// + /// Get the set of SyncConnectors to send certain scene events. + /// + /// + /// + private List GetSyncConnectorsForSceneEvents(string init_actorID, SymmetricSyncMessage rsm) + { + List syncConnectors = new List(); + if (m_isSyncRelay) + { + //This is a relay node in the synchronization overlay, forward it to all connectors, except the one that sends in the event + ForEachSyncConnector(delegate(SyncConnector connector) + { + if (connector.OtherSideActorID != init_actorID) + { + syncConnectors.Add(connector); + } + }); + } + else + { + //This is a end node in the synchronization overlay (e.g. a non ScenePersistence actor). Get the right set of synconnectors. + //For now, there is only one syncconnector that connects to ScenePersistence, due to the star topology. + //This may go more complex when an actor connects to several ScenePersistence actors. + ForEachSyncConnector(delegate(SyncConnector connector) + { + syncConnectors.Add(connector); + }); + } + + return syncConnectors; + } + //NOTE: We proably don't need to do this, and there might not be a need for OnPostSceneCreation event to let RegionSyncModule // and ActorSyncModules to gain some access to each other. We'll keep it here for a while, until we are sure it's not // needed. @@ -774,7 +824,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)e); SendSyncMessage(SymmetricSyncMessage.MsgType.NewObject, sogxml); - m_log.Debug(LogHeader + ": " + sogxml); + //m_log.Debug(LogHeader + ": " + sogxml); } } return; @@ -791,6 +841,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule HandleRemovedObject(msg); return; } + //EVENTS PROCESSING + case SymmetricSyncMessage.MsgType.OnUpdateScript: + { + HandleEvent_OnUpdateScript(msg); + return; + } default: return; } @@ -920,6 +976,36 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } } + /// + /// Handler for SymmetricSyncMessage.MsgType.OnUpdateScript + /// + /// + private void HandleEvent_OnUpdateScript(SymmetricSyncMessage msg) + { + m_log.Debug(LogHeader + ", " + m_actorID + ": received OnUpdateScript"); + + OSDMap data = DeserializeMessage(msg); + + //get the event parameters, trigger the event in the local scene + string init_actorID = data["actorID"].AsString(); + UUID agentID = data["agentID"].AsUUID(); + UUID itemID = data["itemID"].AsUUID(); + UUID primID = data["primID"].AsUUID(); + bool isRunning = data["running"].AsBoolean(); + UUID assetID = data["assetID"].AsUUID(); + //m_scene.EventManager.TriggerUpdateScript(agentID, itemID, primID, isRunning, assetID); + + //trigger the OnUpdateScriptBySync event, so that the handler of the event knows it is event initiated remotely + m_scene.EventManager.TriggerOnUpdateScriptBySync(agentID, itemID, primID, isRunning, assetID); + + + //if this is a relay node, forwards the event + if (m_isSyncRelay) + { + SendSceneEventToRelevantSyncConnectors(init_actorID, msg); + } + } + /// /// Send a sync message to remove the given objects in all connected actors, if this is a relay node. @@ -945,6 +1031,42 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } + /// + /// The handler for (locally initiated) event OnUpdateScript: publish it to other actors. + /// + /// + /// + /// + /// + /// + public void RegionSyncModule_OnUpdateScript(UUID agentID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) + { + m_log.Debug(LogHeader + " RegionSyncModule_OnUpdateScript"); + + OSDMap data = new OSDMap(); + data["agentID"] = OSD.FromUUID(agentID); + data["itemID"] = OSD.FromUUID(itemId); + data["primID"] = OSD.FromUUID(primId); + data["running"] = OSD.FromBoolean(isScriptRunning); + data["assetID"] = OSD.FromUUID(newAssetID); + + PublishSceneEvent(data); + } + + private void PublishSceneEvent(OSDMap data) + { + data["actorID"] = OSD.FromString(m_actorID); + data["seqNum"] = OSD.FromULong(GetNextEventSeq()); + + SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.OnUpdateScript, OSDParser.SerializeJsonString(data)); + SendSceneEventToRelevantSyncConnectors(m_actorID, rsm); + } + + private ulong GetNextEventSeq() + { + return m_eventSeq++; + } + #endregion //RegionSyncModule members and functions } diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs index 6c24792216..78471fb764 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs @@ -59,6 +59,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_active = true; + LogHeader += "-" + m_actorID; m_log.Warn(LogHeader + " Initialised"); } @@ -85,6 +86,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //Register for Scene/SceneGraph events m_scene.SceneGraph.OnObjectCreate += new ObjectCreateDelegate(ScriptEngine_OnObjectCreate); m_scene.EventManager.OnSymmetricSyncStop += ScriptEngine_OnSymmetricSyncStop; + + //for local OnUpdateScript, we'll handle it the same way as a remove OnUpdateScript. + //RegionSyncModule will capture a locally initiated OnUpdateScript event and publish it to other actors. + m_scene.EventManager.OnUpdateScript += ScriptEngine_OnUpdateScript; + m_scene.EventManager.OnUpdateScriptBySync += ScriptEngine_OnUpdateScript; } //Called after AddRegion() has been called for all region modules of the scene. @@ -176,9 +182,15 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_scene.DeleteAllSceneObjects(); } + //Assumption, when this function is triggered, the new script asset has already been saved. + public void ScriptEngine_OnUpdateScript(UUID agentID, UUID itemID, UUID primID, bool isScriptRunning, UUID newAssetID) + { + m_log.Debug(LogHeader + " ScriptEngine_OnUpdateScript"); + m_scene.SymSync_OnUpdateScript(agentID, itemID, primID, isScriptRunning, newAssetID); + } + #endregion //ScriptEngineSyncModule } - } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs index b4b960ace1..4785992374 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs @@ -25,17 +25,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule GetTerrain, GetObjects, - // SIM -> CM + // SIM <-> CM Terrain, NewObject, // objects UpdatedObject, // objects RemovedObject, // objects - // BIDIR - //EchoRequest, - //EchoResponse, RegionName, //RegionStatus, ActorID, + //events + OnUpdateScript, } #endregion diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 7ba4f39d97..08f56cece9 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -38,6 +38,8 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.Framework.Scenes { + //SYMMETRIC SYNC: Rename the original EventManager as EventManagerBase, and implement a new EventManager that inherits from EventManagerBase + /// /// A class for triggering remote scene events. /// @@ -2246,7 +2248,6 @@ namespace OpenSim.Region.Framework.Scenes //SYMMETRIC SYNC public event PostSceneCreation OnPostSceneCreation; public delegate void PostSceneCreation(Scene createdScene); - public void TriggerOnPostSceneCreation(Scene createdScene) { PostSceneCreation handler = OnPostSceneCreation; @@ -2291,6 +2292,28 @@ namespace OpenSim.Region.Framework.Scenes } } + public event UpdateScriptBySync OnUpdateScriptBySync; + public delegate void UpdateScriptBySync(UUID agentID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID); + public void TriggerOnUpdateScriptBySync(UUID agentID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) + { + UpdateScriptBySync handlerUpdateScriptBySync = OnUpdateScriptBySync; + if (handlerUpdateScriptBySync != null) + { + foreach (UpdateScriptBySync d in handlerUpdateScriptBySync.GetInvocationList()) + { + try + { + d(agentID, itemId, primId, isScriptRunning, newAssetID); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerOnUpdateScriptBySync failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } //end of SYMMETRIC SYNC } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 468d30e413..900b19ce2f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -251,6 +251,8 @@ namespace OpenSim.Region.Framework.Scenes AssetService.Store(asset); //REGION SYNC: if RegionSyncEnabled, move script related operations to be after update inventory item + //SYMMETRIC SYNC: commenting out old REGION SYNC code, the RemoveScriptInstance would be handled by ScriptEngineSyncModule + /* if (!RegionSyncEnabled) { if (isScriptRunning) @@ -258,6 +260,7 @@ namespace OpenSim.Region.Framework.Scenes part.Inventory.RemoveScriptInstance(item.ItemID, false); } } + * */ // Update item with new asset item.AssetID = asset.FullID; @@ -267,6 +270,8 @@ namespace OpenSim.Region.Framework.Scenes part.GetProperties(remoteClient); ////REGION SYNC + //SYMMETRIC SYNC: commenting out old REGION SYNC code, the RemoveScriptInstance would be handled by ScriptEngineSyncModule + /* if (!RegionSyncEnabled) { //Original OpenSim code below @@ -302,6 +307,18 @@ namespace OpenSim.Region.Framework.Scenes return errors; } + * */ + + //SYMMETRIC SYNC: Distributed Scene Graph implementation + m_log.Debug("Scene.Inventory: to call EventManager.TriggerUpdateTaskInventoryScriptAsset, agentID: " + remoteClient.AgentId); + //Trigger OnUpdateScript event. + EventManager.TriggerUpdateScript(remoteClient.AgentId, itemId, primId, isScriptRunning, item.AssetID); + + //For now, we simple tell client that script saved while waiting for remote script engine to re-rez the script. + //Later will change the BaseHttpServer's code to return error list to client. + //remoteClient.SendAgentAlertMessage("Script saved", false); + ArrayList errors = new ArrayList(); + return errors; } #region REGION SYNC @@ -314,8 +331,9 @@ namespace OpenSim.Region.Framework.Scenes public ArrayList OnUpdateScript(UUID avatarID, UUID itemID, UUID primID, bool isScriptRunning, UUID newAssetID) { ArrayList errors = new ArrayList(); - //This function is supposed to be executed only on a remote script engine, not an authorative Scene - if (!IsSyncedScriptEngine()) + + //In the old async model, this function is supposed to be executed only on a remote script engine, not an authorative Scene + if (RegionSyncModule==null && !IsSyncedScriptEngine()) { m_log.Warn("This is not the script engine. Should not have received OnUpdateScript event."); return errors; @@ -350,7 +368,44 @@ namespace OpenSim.Region.Framework.Scenes } #endregion - /// + #region SYMMETRIC SYNC + //only a script engine actor is supposed to call this function + public ArrayList SymSync_OnUpdateScript(UUID avatarID, UUID itemID, UUID primID, bool isScriptRunning, UUID newAssetID) + { + ArrayList errors = new ArrayList(); + + SceneObjectPart part = GetSceneObjectPart(primID); + SceneObjectGroup group = part.ParentGroup; + if (isScriptRunning) + { + m_log.Debug("To RemoveScriptInstance"); + part.Inventory.RemoveScriptInstance(itemID, false); + } + + // Retrieve item + TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemID); + + // Update item with new asset + item.AssetID = newAssetID; + group.UpdateInventoryItem(item); + m_log.Debug("UpdateInventoryItem on object "+group.UUID); + + if (isScriptRunning) + { + // Needs to determine which engine was running it and use that + m_log.Debug("To CreateScriptInstance"); + part.Inventory.CreateScriptInstance(itemID, 0, false, DefaultScriptEngine, 0); + errors = part.Inventory.GetScriptErrors(itemID); + } + + part.ParentGroup.ResumeScripts(); + + return errors; + } + #endregion //SYMMETRIC SYNC + + + /// /// CapsUpdateTaskInventoryScriptAsset(IClientAPI, UUID, UUID, bool, byte[]) /// public ArrayList CapsUpdateTaskInventoryScriptAsset(UUID avatarId, UUID itemId, From 837a77b24ac805dbbfb7a28d6ac9e8767444161d Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Wed, 5 Jan 2011 15:32:43 -0800 Subject: [PATCH 3/4] Abandoned the previous temporary solution of propogating events. Instead, rename legacy (Scene)EventManager as EventManagerBase, and implement a new EventManager, to enable handling local/remote events differently. Handlers for UpdateScript has been implemented as a sample case. --- .../SymmetricSync/RegionSyncModule.cs | 44 +++++++++--- .../SymmetricSync/ScriptEngineSyncModule.cs | 2 +- .../SymmetricSync/SymmetricSyncMessage.cs | 2 +- .../Framework/Interfaces/IRegionSyncModule.cs | 5 +- .../Region/Framework/Scenes/EventManager.cs | 69 ++++++++++++------- OpenSim/Region/Framework/Scenes/Scene.cs | 11 ++- 6 files changed, 93 insertions(+), 40 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 4d675512af..edeab2e66a 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -87,12 +87,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; InstallInterfaces(); - //Register for Scene events + //Register for local Scene events m_scene.EventManager.OnPostSceneCreation += OnPostSceneCreation; m_scene.EventManager.OnObjectBeingRemovedFromScene += new EventManager.ObjectBeingRemovedFromScene(RegionSyncModule_OnObjectBeingRemovedFromScene); - //Register for scene events that need to be propogated to other actors - m_scene.EventManager.OnUpdateScript += RegionSyncModule_OnUpdateScript; } //Called after AddRegion() has been called for all region modules of the scene @@ -842,9 +840,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return; } //EVENTS PROCESSING - case SymmetricSyncMessage.MsgType.OnUpdateScript: + case SymmetricSyncMessage.MsgType.UpdateScript: { - HandleEvent_OnUpdateScript(msg); + HandleRemoteEvent_OnUpdateScript(msg); return; } default: @@ -980,7 +978,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule /// Handler for SymmetricSyncMessage.MsgType.OnUpdateScript /// /// - private void HandleEvent_OnUpdateScript(SymmetricSyncMessage msg) + private void HandleRemoteEvent_OnUpdateScript(SymmetricSyncMessage msg) { m_log.Debug(LogHeader + ", " + m_actorID + ": received OnUpdateScript"); @@ -993,10 +991,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule UUID primID = data["primID"].AsUUID(); bool isRunning = data["running"].AsBoolean(); UUID assetID = data["assetID"].AsUUID(); - //m_scene.EventManager.TriggerUpdateScript(agentID, itemID, primID, isRunning, assetID); + m_scene.EventManager.TriggerUpdateScriptLocally(agentID, itemID, primID, isRunning, assetID); //trigger the OnUpdateScriptBySync event, so that the handler of the event knows it is event initiated remotely - m_scene.EventManager.TriggerOnUpdateScriptBySync(agentID, itemID, primID, isRunning, assetID); + //m_scene.EventManager.TriggerOnUpdateScriptBySync(agentID, itemID, primID, isRunning, assetID); //if this is a relay node, forwards the event @@ -1031,6 +1029,24 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } + public void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs) + { + switch (ev) + { + case EventManager.EventNames.UpdateScript: + if (evArgs.Length < 5) + { + m_log.Error(LogHeader + " not enough event args for UpdateScript"); + return; + } + m_log.Debug(LogHeader + " PublishSceneEvent UpdateScript"); + OnLocalUpdateScript((UUID)evArgs[0], (UUID)evArgs[1], (UUID)evArgs[2], (bool)evArgs[3], (UUID)evArgs[4]); + return; + default: + return; + } + } + /// /// The handler for (locally initiated) event OnUpdateScript: publish it to other actors. /// @@ -1039,7 +1055,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule /// /// /// - public void RegionSyncModule_OnUpdateScript(UUID agentID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) + private void OnLocalUpdateScript(UUID agentID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) { m_log.Debug(LogHeader + " RegionSyncModule_OnUpdateScript"); @@ -1050,9 +1066,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule data["running"] = OSD.FromBoolean(isScriptRunning); data["assetID"] = OSD.FromUUID(newAssetID); - PublishSceneEvent(data); + data["actorID"] = OSD.FromString(m_actorID); + data["seqNum"] = OSD.FromULong(GetNextEventSeq()); + + SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdateScript, OSDParser.SerializeJsonString(data)); + //send to actors who are interested in the event + SendSceneEventToRelevantSyncConnectors(m_actorID, rsm); } + + /* private void PublishSceneEvent(OSDMap data) { data["actorID"] = OSD.FromString(m_actorID); @@ -1061,6 +1084,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.OnUpdateScript, OSDParser.SerializeJsonString(data)); SendSceneEventToRelevantSyncConnectors(m_actorID, rsm); } + * */ private ulong GetNextEventSeq() { diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs index 78471fb764..cc9213b722 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScriptEngineSyncModule.cs @@ -90,7 +90,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //for local OnUpdateScript, we'll handle it the same way as a remove OnUpdateScript. //RegionSyncModule will capture a locally initiated OnUpdateScript event and publish it to other actors. m_scene.EventManager.OnUpdateScript += ScriptEngine_OnUpdateScript; - m_scene.EventManager.OnUpdateScriptBySync += ScriptEngine_OnUpdateScript; + //m_scene.EventManager.OnUpdateScriptBySync += ScriptEngine_OnUpdateScript; } //Called after AddRegion() has been called for all region modules of the scene. diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs index 4785992374..d8d925147a 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs @@ -34,7 +34,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //RegionStatus, ActorID, //events - OnUpdateScript, + UpdateScript, } #endregion diff --git a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs index 2cc75c962d..8733f8ec6d 100755 --- a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs @@ -26,7 +26,7 @@ */ //KittyL: Added to support running script engine actor - +using System; using System.Collections.Generic; using OpenMetaverse; @@ -65,6 +65,9 @@ namespace OpenSim.Region.Framework.Interfaces void SendTerrainUpdates(string lastUpdateActorID); //void SendDeleteObject(SceneObjectGroup sog); + //For propogating scene events to other actors + void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs); + //TODO LIST: //Special API for handling avatars //void QueuePresenceForTerseUpdate(ScenePresence presence) diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 08f56cece9..c178f563c3 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -41,9 +41,50 @@ namespace OpenSim.Region.Framework.Scenes //SYMMETRIC SYNC: Rename the original EventManager as EventManagerBase, and implement a new EventManager that inherits from EventManagerBase /// - /// A class for triggering remote scene events. + /// A wrapper class to implement handle event differently depending on if they are initiated locally or remotelly (i.e. by another actor) /// - public class EventManager + public class EventManager: EventManagerBase + { + private Scene m_scene; + + //the events that we'll handle specially in sym-sync + public enum EventNames + { + UpdateScript, + } + + public EventManager(Scene scene) + { + m_scene = scene; + } + public override void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) + { + //publish the event to other actors who are intersted in it + if (m_scene.RegionSyncModule != null) + { + Object[] eventArgs = new Object[5]; + eventArgs[0] = (Object) clientId; + eventArgs[1] = (Object)itemId; + eventArgs[2] = (Object)primId; + eventArgs[3] = (Object)isScriptRunning; + eventArgs[4] = (Object)newAssetID; + m_scene.RegionSyncModule.PublishSceneEvent(EventNames.UpdateScript, eventArgs); + } + + //trigger event locally, as the legacy code does + TriggerUpdateScriptLocally(clientId, itemId, primId, isScriptRunning, newAssetID); + } + + public void TriggerUpdateScriptLocally(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) + { + base.TriggerUpdateScript(clientId, itemId, primId, isScriptRunning, newAssetID); + } + } + + /// + /// A class for triggering scene events. + /// + public class EventManagerBase { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -2195,7 +2236,7 @@ namespace OpenSim.Region.Framework.Scenes //OnUpdateTaskInventoryScriptAsset: triggered after Scene receives client's upload of updated script and stores it as asset public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID); public event UpdateScript OnUpdateScript; - public void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) + public virtual void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) { UpdateScript handlerUpdateScript = OnUpdateScript; if (handlerUpdateScript != null) @@ -2292,28 +2333,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public event UpdateScriptBySync OnUpdateScriptBySync; - public delegate void UpdateScriptBySync(UUID agentID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID); - public void TriggerOnUpdateScriptBySync(UUID agentID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) - { - UpdateScriptBySync handlerUpdateScriptBySync = OnUpdateScriptBySync; - if (handlerUpdateScriptBySync != null) - { - foreach (UpdateScriptBySync d in handlerUpdateScriptBySync.GetInvocationList()) - { - try - { - d(agentID, itemId, primId, isScriptRunning, newAssetID); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[EVENT MANAGER]: Delegate for TriggerOnUpdateScriptBySync failed - continuing. {0} {1}", - e.Message, e.StackTrace); - } - } - } - } //end of SYMMETRIC SYNC } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 95ecfb3d5f..33abe9e0e9 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -821,7 +821,10 @@ namespace OpenSim.Region.Framework.Scenes m_physicalPrim = physicalPrim; m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor; - m_eventManager = new EventManager(); + //SYMMETRIC SYNC: pass Scene reference to EventManager + //m_eventManager = new EventManager(); + m_eventManager = new EventManager(this); + //end of SYMMETRIC SYNC m_permissions = new ScenePermissions(this); m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); @@ -1029,7 +1032,11 @@ namespace OpenSim.Region.Framework.Scenes BordersLocked = false; m_regInfo = regInfo; - m_eventManager = new EventManager(); + + //SYMMETRIC SYNC: pass Scene reference to EventManager + //m_eventManager = new EventManager(); + m_eventManager = new EventManager(this); + //end of SYMMETRIC SYNC m_lastUpdate = Util.EnvironmentTickCount(); } From 731a09bf9580d6409cdb20c7f3f3e287b6f923ea Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Wed, 5 Jan 2011 16:39:53 -0800 Subject: [PATCH 4/4] Added symc sync handlers for event ScriptReset. --- .../SymmetricSync/RegionSyncModule.cs | 98 ++++++++++++++++--- .../SymmetricSync/SymmetricSyncMessage.cs | 1 + .../Region/Framework/Scenes/EventManager.cs | 26 ++++- 3 files changed, 107 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index edeab2e66a..2ef9da3b7e 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -841,8 +841,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } //EVENTS PROCESSING case SymmetricSyncMessage.MsgType.UpdateScript: + case SymmetricSyncMessage.MsgType.ScriptReset: { - HandleRemoteEvent_OnUpdateScript(msg); + HandleRemoteEvent(msg); return; } default: @@ -975,27 +976,24 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } /// - /// Handler for SymmetricSyncMessage.MsgType.OnUpdateScript + /// The common actions for handling remote events (event initiated at other actors and propogated here) /// /// - private void HandleRemoteEvent_OnUpdateScript(SymmetricSyncMessage msg) + private void HandleRemoteEvent(SymmetricSyncMessage msg) { - m_log.Debug(LogHeader + ", " + m_actorID + ": received OnUpdateScript"); - OSDMap data = DeserializeMessage(msg); - - //get the event parameters, trigger the event in the local scene string init_actorID = data["actorID"].AsString(); - UUID agentID = data["agentID"].AsUUID(); - UUID itemID = data["itemID"].AsUUID(); - UUID primID = data["primID"].AsUUID(); - bool isRunning = data["running"].AsBoolean(); - UUID assetID = data["assetID"].AsUUID(); - m_scene.EventManager.TriggerUpdateScriptLocally(agentID, itemID, primID, isRunning, assetID); + ulong evSeqNum = data["seqNum"].AsULong(); - //trigger the OnUpdateScriptBySync event, so that the handler of the event knows it is event initiated remotely - //m_scene.EventManager.TriggerOnUpdateScriptBySync(agentID, itemID, primID, isRunning, assetID); - + switch (msg.Type) + { + case SymmetricSyncMessage.MsgType.UpdateScript: + HandleRemoteEvent_OnUpdateScript(init_actorID, evSeqNum, data); + break; + case SymmetricSyncMessage.MsgType.ScriptReset: + HandleRemoteEvent_OnScriptReset(init_actorID, evSeqNum, data); + break; + } //if this is a relay node, forwards the event if (m_isSyncRelay) @@ -1004,6 +1002,45 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } } + /// + /// Special actions for remote event UpdateScript + /// + /// OSDMap data of event args + private void HandleRemoteEvent_OnUpdateScript(string actorID, ulong evSeqNum, OSDMap data) + { + m_log.Debug(LogHeader + ", " + m_actorID + ": received UpdateScript"); + + UUID agentID = data["agentID"].AsUUID(); + UUID itemID = data["itemID"].AsUUID(); + UUID primID = data["primID"].AsUUID(); + bool isRunning = data["running"].AsBoolean(); + UUID assetID = data["assetID"].AsUUID(); + + //trigger the event in the local scene + m_scene.EventManager.TriggerUpdateScriptLocally(agentID, itemID, primID, isRunning, assetID); + } + + /// + /// Special actions for remote event UpdateScript + /// + /// OSDMap data of event args + private void HandleRemoteEvent_OnScriptReset(string actorID, ulong evSeqNum, OSDMap data) + { + m_log.Debug(LogHeader + ", " + m_actorID + ": received ScriptReset"); + + UUID agentID = data["agentID"].AsUUID(); + UUID itemID = data["itemID"].AsUUID(); + UUID primID = data["primID"].AsUUID(); + + SceneObjectPart part = m_scene.GetSceneObjectPart(primID); + if (part == null || part.ParentGroup.IsDeleted) + { + m_log.Warn(LogHeader + " part " + primID + " not exist, all is deleted"); + return; + } + m_scene.EventManager.TriggerScriptResetLocally(part.LocalId, itemID); + } + /// /// Send a sync message to remove the given objects in all connected actors, if this is a relay node. @@ -1042,6 +1079,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_log.Debug(LogHeader + " PublishSceneEvent UpdateScript"); OnLocalUpdateScript((UUID)evArgs[0], (UUID)evArgs[1], (UUID)evArgs[2], (bool)evArgs[3], (UUID)evArgs[4]); return; + case EventManager.EventNames.ScriptReset: + if (evArgs.Length < 2) + { + m_log.Error(LogHeader + " not enough event args for ScriptReset"); + return; + } + OnLocalScriptReset((uint)evArgs[0], (UUID)evArgs[1]); + return; default: return; } @@ -1074,6 +1119,27 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule SendSceneEventToRelevantSyncConnectors(m_actorID, rsm); } + private void OnLocalScriptReset(uint localID, UUID itemID) + { + //we will use the prim's UUID as the identifier, not the localID, to publish the event for the prim + SceneObjectPart part = m_scene.GetSceneObjectPart(localID); + + OSDMap data = new OSDMap(); + data["primID"] = OSD.FromUUID(part.UUID); + data["itemID"] = OSD.FromUUID(itemID); + + SendSceneEvent(SymmetricSyncMessage.MsgType.ScriptReset, data); + } + + private void SendSceneEvent(SymmetricSyncMessage.MsgType msgType, OSDMap data) + { + data["actorID"] = OSD.FromString(m_actorID); + data["seqNum"] = OSD.FromULong(GetNextEventSeq()); + SymmetricSyncMessage rsm = new SymmetricSyncMessage(msgType, OSDParser.SerializeJsonString(data)); + + //send to actors who are interested in the event + SendSceneEventToRelevantSyncConnectors(m_actorID, rsm); + } /* private void PublishSceneEvent(OSDMap data) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs index d8d925147a..0b47f16234 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs @@ -35,6 +35,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule ActorID, //events UpdateScript, + ScriptReset, } #endregion diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index c178f563c3..f26db672cc 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -51,12 +51,15 @@ namespace OpenSim.Region.Framework.Scenes public enum EventNames { UpdateScript, + ScriptReset, } public EventManager(Scene scene) { m_scene = scene; } + +#region UpdateScript public override void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) { //publish the event to other actors who are intersted in it @@ -74,11 +77,29 @@ namespace OpenSim.Region.Framework.Scenes //trigger event locally, as the legacy code does TriggerUpdateScriptLocally(clientId, itemId, primId, isScriptRunning, newAssetID); } - public void TriggerUpdateScriptLocally(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) { base.TriggerUpdateScript(clientId, itemId, primId, isScriptRunning, newAssetID); } +#endregion //UpdateScript + + #region ScriptReset + public virtual void TriggerScriptReset(uint localID, UUID itemID) + { + if (m_scene.RegionSyncModule != null) + { + Object[] eventArgs = new Object[2]; + eventArgs[0] = (Object)localID; + eventArgs[1] = (Object)itemID; + m_scene.RegionSyncModule.PublishSceneEvent(EventNames.ScriptReset, eventArgs); + } + } + public virtual void TriggerScriptResetLocally(uint localID, UUID itemID) + { + base.TriggerScriptReset(localID, itemID); + } + + #endregion //UpdateScript } /// @@ -948,7 +969,8 @@ namespace OpenSim.Region.Framework.Scenes } } - public void TriggerScriptReset(uint localID, UUID itemID) + //public void TriggerScriptReset(uint localID, UUID itemID) + public virtual void TriggerScriptReset(uint localID, UUID itemID) { ScriptResetDelegate handlerScriptReset = OnScriptReset; if (handlerScriptReset != null)