From 9b66108081a8c8cf79faaa6c541554091c40850e Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Fri, 6 Feb 2009 16:55:34 +0000 Subject: This changeset is the step 1 of 2 in refactoring OpenSim.Region.Environment into a "framework" part and a modules only part. This first changeset refactors OpenSim.Region.Environment.Scenes, OpenSim.Region.Environment.Interfaces, and OpenSim.Region.Interfaces into OpenSim.Region.Framework.{Interfaces,Scenes} leaving only region modules in OpenSim.Region.Environment. The next step will be to move region modules up from OpenSim.Region.Environment.Modules to OpenSim.Region.CoreModules and then sort out which modules are really core modules and which should move out to forge. I've been very careful to NOT BREAK anything. i hope i've succeeded. as this is the work of a whole week i hope i managed to keep track with the applied patches of the last week --- could any of you that did check in stuff have a look at whether it survived? thx! --- OpenSim/Region/Framework/Scenes/SceneBase.cs | 419 +++++++++++++++++++++++++++ 1 file changed, 419 insertions(+) create mode 100644 OpenSim/Region/Framework/Scenes/SceneBase.cs (limited to 'OpenSim/Region/Framework/Scenes/SceneBase.cs') diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs new file mode 100644 index 0000000..6d61e9f --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -0,0 +1,419 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; +using OpenMetaverse; +using log4net; +using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Region.Framework.Interfaces; + +namespace OpenSim.Region.Framework.Scenes +{ + public abstract class SceneBase : IScene + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + #region Events + + public event restart OnRestart; + + #endregion + + #region Fields + + /// + /// All the region modules attached to this scene. + /// + public Dictionary Modules + { + get { return m_modules; } + } + protected Dictionary m_modules = new Dictionary(); + + /// + /// The module interfaces available from this scene. + /// + protected Dictionary > ModuleInterfaces = new Dictionary >(); + + protected Dictionary ModuleAPIMethods = new Dictionary(); + protected Dictionary m_moduleCommanders = new Dictionary(); + + /// + /// Registered classes that are capable of creating entities. + /// + protected Dictionary m_entityCreators = new Dictionary(); + + //API module interfaces + + /// + /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is + /// dispensed. + /// + protected uint m_lastAllocatedLocalId = 720000; + + private readonly Mutex _primAllocateMutex = new Mutex(false); + + private readonly ClientManager m_clientManager = new ClientManager(); + + public ClientManager ClientManager + { + get { return m_clientManager; } + } + + protected ulong m_regionHandle; + protected string m_regionName; + protected RegionInfo m_regInfo; + + //public TerrainEngine Terrain; + public ITerrainChannel Heightmap; + + /// + /// Allows retrieval of land information for this scene. + /// + public ILandChannel LandChannel; + + /// + /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules + /// to subscribe to scene events. + /// + public EventManager EventManager + { + get { return m_eventManager; } + } + protected EventManager m_eventManager; + + protected ScenePermissions m_permissions; + public ScenePermissions Permissions + { + get { return m_permissions; } + } + + protected string m_datastore; + + private AssetCache m_assetCache; + + public AssetCache AssetCache + { + get { return m_assetCache; } + set { m_assetCache = value; } + } + + protected RegionStatus m_regStatus; + + public RegionStatus Region_Status + { + get { return m_regStatus; } + set { m_regStatus = value; } + } + + #endregion + + #region Update Methods + + /// + /// Normally called once every frame/tick to let the world preform anything required (like running the physics simulation) + /// + public abstract void Update(); + + #endregion + + #region Terrain Methods + + /// + /// Loads the World heightmap + /// + public abstract void LoadWorldMap(); + + /// + /// Send the region heightmap to the client + /// + /// Client to send to + public virtual void SendLayerData(IClientAPI RemoteClient) + { + RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); + } + + #endregion + + #region Add/Remove Agent/Avatar + + /// + /// Register the new client with the scene. The client starts off as a child agent - the later agent crossing + /// will promote it to a root agent during login. + /// + /// + /// Remove a client from the scene + /// + /// + public abstract void RemoveClient(UUID agentID); + + public abstract void CloseAllAgents(uint circuitcode); + + #endregion + + /// + /// + /// + /// + public virtual RegionInfo RegionInfo + { + get { return m_regInfo; } + } + + #region admin stuff + + /// + /// Region Restart - Seconds till restart. + /// + /// + public virtual void Restart(int seconds) + { + m_log.Error("[REGION]: passing Restart Message up the namespace"); + restart handlerPhysicsCrash = OnRestart; + if (handlerPhysicsCrash != null) + handlerPhysicsCrash(RegionInfo); + } + + public virtual bool PresenceChildStatus(UUID avatarID) + { + return false; + } + + public abstract bool OtherRegionUp(RegionInfo thisRegion); + + public virtual string GetSimulatorVersion() + { + return "OpenSimulator Server"; + } + + #endregion + + #region Shutdown + + /// + /// Tidy before shutdown + /// + public virtual void Close() + { + // Shut down all non shared modules. + foreach (IRegionModule module in Modules.Values) + { + if (!module.IsSharedModule) + { + module.Close(); + } + } + Modules.Clear(); + + try + { + EventManager.TriggerShutdown(); + } + catch (Exception e) + { + m_log.Error("[SCENE]: SceneBase.cs: Close() - Failed with exception " + e.ToString()); + } + } + + #endregion + + /// + /// Returns a new unallocated local ID + /// + /// A brand new local ID + protected internal uint AllocateLocalId() + { + uint myID; + + _primAllocateMutex.WaitOne(); + myID = ++m_lastAllocatedLocalId; + _primAllocateMutex.ReleaseMutex(); + + return myID; + } + + #region Module Methods + + /// + /// Add a module to this scene. + /// + /// + /// + public void AddModule(string name, IRegionModule module) + { + if (!Modules.ContainsKey(name)) + { + Modules.Add(name, module); + } + } + + public void RegisterModuleCommander(ICommander commander) + { + lock (m_moduleCommanders) + { + m_moduleCommanders.Add(commander.Name, commander); + } + } + + /// + /// Get a module commander + /// + /// + /// The module commander, null if no module commander with that name was found + public ICommander GetCommander(string name) + { + lock (m_moduleCommanders) + { + if (m_moduleCommanders.ContainsKey(name)) + return m_moduleCommanders[name]; + } + + return null; + } + + public Dictionary GetCommanders() + { + return m_moduleCommanders; + } + + /// + /// Register an interface to a region module. This allows module methods to be called directly as + /// well as via events. If there is already a module registered for this interface, it is not replaced + /// (is this the best behaviour?) + /// + /// + public void RegisterModuleInterface(M mod) + { + if (!ModuleInterfaces.ContainsKey(typeof(M))) + { + List l = new List(); + l.Add(mod); + ModuleInterfaces.Add(typeof(M), l); + + if (mod is IEntityCreator) + { + IEntityCreator entityCreator = (IEntityCreator)mod; + foreach (PCode pcode in entityCreator.CreationCapabilities) + { + m_entityCreators[pcode] = entityCreator; + } + } + } + } + + public void StackModuleInterface(M mod) + { + List l; + if (ModuleInterfaces.ContainsKey(typeof(M))) + l = ModuleInterfaces[typeof(M)]; + else + l = new List(); + + if (l.Contains(mod)) + return; + + l.Add(mod); + + if (mod is IEntityCreator) + { + IEntityCreator entityCreator = (IEntityCreator)mod; + foreach (PCode pcode in entityCreator.CreationCapabilities) + { + m_entityCreators[pcode] = entityCreator; + } + } + + ModuleInterfaces[typeof(M)] = l; + } + + /// + /// For the given interface, retrieve the region module which implements it. + /// + /// null if there is no registered module implementing that interface + public T RequestModuleInterface() + { + if (ModuleInterfaces.ContainsKey(typeof(T))) + { + return (T)ModuleInterfaces[typeof(T)][0]; + } + else + { + return default(T); + } + } + + /// + /// For the given interface, retrieve an array of region modules that implement it. + /// + /// an empty array if there are no registered modules implementing that interface + public T[] RequestModuleInterfaces() + { + if (ModuleInterfaces.ContainsKey(typeof(T))) + { + List ret = new List(); + + foreach (Object o in ModuleInterfaces[typeof(T)]) + ret.Add((T)o); + return ret.ToArray(); + } + else + { + return new T[] { default(T) }; + } + } + + #endregion + + /// + /// Shows various details about the sim based on the parameters supplied by the console command in openSimMain. + /// + /// What to show + public virtual void Show(string[] showParams) + { + switch (showParams[0]) + { + case "modules": + m_log.Error("The currently loaded modules in " + RegionInfo.RegionName + " are:"); + foreach (IRegionModule module in Modules.Values) + { + if (!module.IsSharedModule) + { + m_log.Error("Region Module: " + module.Name); + } + } + break; + } + } + } +} -- cgit v1.1