diff --git a/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs b/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs index d9f8c086cf..559d2a638b 100644 --- a/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs +++ b/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs @@ -26,7 +26,6 @@ */ using System.IO; -using System.Threading; namespace OpenSim.Region.Environment.Interfaces { @@ -38,6 +37,10 @@ namespace OpenSim.Region.Environment.Interfaces /// /// Archive the region to the given path /// + /// + /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to + /// the EventManager.OnOarFileSaved event. + /// /// void ArchiveRegion(string savePath); @@ -45,21 +48,27 @@ namespace OpenSim.Region.Environment.Interfaces /// Archive the region to a stream. /// /// + /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to + /// the EventManager.OnOarFileSaved event. + /// /// - /// - /// Pass in a wait handle if you want to be signalled when the operation completes. - /// - void ArchiveRegion(Stream saveStream, EventWaitHandle waitHandle); + void ArchiveRegion(Stream saveStream); /// /// Dearchive the given region archive into the scene /// + /// + /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event. + /// /// void DearchiveRegion(string loadPath); /// - /// Dearchive a region from a stream + /// Dearchive a region from a stream. /// + /// + /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event. + /// /// void DearchiveRegion(Stream loadStream); } diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveReadRequest.cs index ee4323ccb1..4e9fcef170 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveReadRequest.cs @@ -233,8 +233,8 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver { sceneObject.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 0); } + m_scene.EventManager.TriggerOarFileLoaded(m_errorMessage); - } /// diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs index 8eec38dce1..179b82a0e5 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs @@ -29,7 +29,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Reflection; -using System.Threading; using System.Xml; using OpenMetaverse; using log4net; @@ -45,7 +44,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver /// Method called when all the necessary assets for an archive request have been received. /// public delegate void AssetsRequestCallback(IDictionary assetsFound, ICollection assetsNotFoundUuids); - + /// /// Execute the write of an archive once we have received all the necessary data /// @@ -56,27 +55,25 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver protected ITerrainModule m_terrainModule; protected IRegionSerialiserModule m_serialiser; protected List m_sceneObjects; - protected RegionInfo m_regionInfo; + protected Scene m_scene; protected Stream m_saveStream; - protected EventWaitHandle m_signalWhenDoneEvent; public ArchiveWriteRequestExecution( List sceneObjects, ITerrainModule terrainModule, IRegionSerialiserModule serialiser, - RegionInfo regionInfo, - Stream saveStream, - EventWaitHandle signalWhenDoneEvent) + Scene scene, + Stream saveStream) { m_sceneObjects = sceneObjects; m_terrainModule = terrainModule; m_serialiser = serialiser; - m_regionInfo = regionInfo; + m_scene = scene; m_saveStream = saveStream; - m_signalWhenDoneEvent = signalWhenDoneEvent; } - protected internal void ReceivedAllAssets(IDictionary assetsFound, ICollection assetsNotFoundUuids) + protected internal void ReceivedAllAssets( + IDictionary assetsFound, ICollection assetsNotFoundUuids) { foreach (UUID uuid in assetsNotFoundUuids) { @@ -95,11 +92,14 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver archive.AddFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p2ControlFile()); // Write out region settings - string settingsPath = String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_regionInfo.RegionName); - archive.AddFile(settingsPath, RegionSettingsSerializer.Serialize(m_regionInfo.RegionSettings)); + string settingsPath + = String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName); + archive.AddFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings)); // Write out terrain - string terrainPath = String.Format("{0}{1}.r32", ArchiveConstants.TERRAINS_PATH, m_regionInfo.RegionName); + string terrainPath + = String.Format("{0}{1}.r32", ArchiveConstants.TERRAINS_PATH, m_scene.RegionInfo.RegionName); + MemoryStream ms = new MemoryStream(); m_terrainModule.SaveToStream(terrainPath, ms); archive.AddFile(terrainPath, ms.ToArray()); @@ -129,10 +129,9 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver archive.WriteTar(m_saveStream); - m_log.InfoFormat("[ARCHIVER]: Wrote out OpenSimulator archive for {0}", m_regionInfo.RegionName); + m_log.InfoFormat("[ARCHIVER]: Wrote out OpenSimulator archive for {0}", m_scene.RegionInfo.RegionName); - if (m_signalWhenDoneEvent != null) - m_signalWhenDoneEvent.Set(); + m_scene.EventManager.TriggerOarFileSaved(String.Empty); } /// diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs index b3c9a91df7..a5f477000d 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -53,7 +53,6 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver protected Scene m_scene; protected Stream m_saveStream; - protected EventWaitHandle m_signalWhenDoneEvent; /// /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate @@ -80,11 +79,10 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver /// /// /// The stream to which to save data. - public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, EventWaitHandle signalWhenDoneEvent) + public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream) { m_scene = scene; m_saveStream = saveStream; - m_signalWhenDoneEvent = signalWhenDoneEvent; } /// @@ -326,9 +324,8 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver sceneObjects, m_scene.RequestModuleInterface(), m_scene.RequestModuleInterface(), - m_scene.RegionInfo, - m_saveStream, - m_signalWhenDoneEvent); + m_scene, + m_saveStream); new AssetsRequest(assetUuids.Keys, m_scene.AssetCache, awre.ReceivedAllAssets).Execute(); } diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs index e3dfda2241..9d9f81e515 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs @@ -73,9 +73,9 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver new ArchiveWriteRequestPreparation(m_scene, savePath).ArchiveRegion(); } - public void ArchiveRegion(Stream saveStream, EventWaitHandle waitHandle) + public void ArchiveRegion(Stream saveStream) { - new ArchiveWriteRequestPreparation(m_scene, saveStream, waitHandle).ArchiveRegion(); + new ArchiveWriteRequestPreparation(m_scene, saveStream).ArchiveRegion(); } public void DearchiveRegion(string loadPath) diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs index 95064e2669..43df685874 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs @@ -44,13 +44,20 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver.Tests [TestFixture] public class ArchiverTests { + private EventWaitHandle m_waitHandle = new AutoResetEvent(false); + + private void SaveCompleted(string errorMessage) + { + m_waitHandle.Set(); + } + /// /// Test saving a V0.2 OpenSim Region Archive. /// [Test] public void TestSaveOarV0p2() { - //log4net.Config.XmlConfigurator.Configure(); + log4net.Config.XmlConfigurator.Configure(); ArchiverModule archiverModule = new ArchiverModule(); SerialiserModule serialiserModule = new SerialiserModule(); @@ -71,11 +78,12 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver.Tests ownerId, shape, groupPosition, rotationOffset, offsetPosition); part.Name = partName; - scene.AddNewSceneObject(new SceneObjectGroup(part), false); - EventWaitHandle waitHandle = new ManualResetEvent(false); + scene.AddNewSceneObject(new SceneObjectGroup(part), false); MemoryStream archiveWriteStream = new MemoryStream(); - archiverModule.ArchiveRegion(archiveWriteStream, waitHandle); - waitHandle.WaitOne(60000, true); + + scene.EventManager.OnOarFileSaved += SaveCompleted; + archiverModule.ArchiveRegion(archiveWriteStream); + m_waitHandle.WaitOne(60000, true); byte[] archive = archiveWriteStream.ToArray(); MemoryStream archiveReadStream = new MemoryStream(archive); diff --git a/OpenSim/Region/Environment/Scenes/EventManager.cs b/OpenSim/Region/Environment/Scenes/EventManager.cs index 1543bf04b2..618e6b578f 100644 --- a/OpenSim/Region/Environment/Scenes/EventManager.cs +++ b/OpenSim/Region/Environment/Scenes/EventManager.cs @@ -273,6 +273,13 @@ namespace OpenSim.Region.Environment.Scenes /// public delegate void OarFileLoaded(string message); public event OarFileLoaded OnOarFileLoaded; + + /// + /// Called when an oar file has finished saving + /// Message is non empty string if there were problems saving the oar file + /// + public delegate void OarFileSaved(string message); + public event OarFileSaved OnOarFileSaved; /// /// Called when the script compile queue becomes empty @@ -415,6 +422,8 @@ namespace OpenSim.Region.Environment.Scenes private OnSetRootAgentSceneDelegate handlerSetRootAgentScene = null; private OarFileLoaded handlerOarFileLoaded = null; + private OarFileSaved handlerOarFileSaved = null; + private EmptyScriptCompileQueue handlerEmptyScriptCompileQueue = null; public void TriggerGetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID) @@ -925,6 +934,13 @@ namespace OpenSim.Region.Environment.Scenes if (handlerOarFileLoaded != null) handlerOarFileLoaded(message); } + + public void TriggerOarFileSaved(string message) + { + handlerOarFileSaved = OnOarFileSaved; + if (handlerOarFileSaved != null) + handlerOarFileSaved(message); + } public void TriggerEmptyScriptCompileQueue(int numScriptsFailed, string message) {