// ==========================================================================
        public override bool AfterAllModulesLoaded()
        {
            // allow others to get our statistics
            m_restHandler = new RestHandler("/stats/" + m_moduleName + "/detailStats", m_stats);

            #region OGRE STATS
            // Setup the shared piece of memory that Ogre can place statistics in
            m_ogreStatsPinned = new int[Ogr.StatSize];
            for (int ii = 0; ii < Ogr.StatSize; ii++) m_ogreStatsPinned[ii] = 0;
            if (ModuleParams.ParamBool("Renderer.Ogre.CollectOgreStats")) {
            m_ogreStatsHandle = GCHandle.Alloc(m_ogreStatsPinned, GCHandleType.Pinned);
            Ogr.SetStatsBlock(m_ogreStatsHandle.AddrOfPinnedObject());
            // m_ogreStatsPinned = (int[])Marshal.AllocHGlobal(Ogr.StatSize * 4);
            // Ogr.SetStatsBlock(m_ogreStatsPinned);
            }

            // Create a ParameterSet that can be read externally via REST/JSON
            m_ogreStats = new ParameterSet();
            // add an initial parameter that calculates frames per sec
            m_ogreStats.Add("FramesPerSecond",
            delegate(string xx) {
                // Ogre passed the number *1000 so  there can be some decimal points
                float fps = (float)m_ogreStatsPinned[Ogr.StatFramesPerSec] / 1000f;
                return new OMVSD.OSDString(fps.ToString());
            }, "Frames per second"
            );
            m_ogreStats.Add("LastFrameMS", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatLastFrameMs].ToString()); },
                "Milliseconds used rendering last frame");
            m_ogreStats.Add("TotalFrames", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatTotalFrames].ToString()); },
                "Number of frames rendered");
            m_ogreStats.Add("VisibleToVisible", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatVisibleToVisible].ToString()); },
                "Meshes at were visible that are still visible in last frame");
            m_ogreStats.Add("InvisibleToVisible", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatInvisibleToVisible].ToString()); },
                "Meshes that were invisible that are now visible in last frame");
            m_ogreStats.Add("VisibleToInvisible", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatVisibleToInvisible].ToString()); },
                "Meshes that were visible that are now invisible in last frame");
            m_ogreStats.Add("InvisibleToInvisible", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatInvisibleToInvisible].ToString()); },
                "Meshes that were invisible that are still invisible in last frame");
            m_ogreStats.Add("CullMeshesLoaded", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatCullMeshesLoaded].ToString()); },
                "Total meshes loaded due to unculling");
            m_ogreStats.Add("CullTexturesLoaded", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatCullTexturesLoaded].ToString()); },
                "Total textures loaded due to unculling");
            m_ogreStats.Add("CullMeshesUnloaded", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatCullMeshesUnloaded].ToString()); },
                "Total meshes unloaded due to culling");
            m_ogreStats.Add("CullTexturesUnloaded", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatCullTexturesUnloaded].ToString()); },
                "Total textures unloaded due to culling");
            m_ogreStats.Add("CullMeshesQueuedToLoad", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatCullMeshesQueuedToLoad].ToString()); },
                "Meshes currently queued to load due to unculling");
            // between frame work
            m_ogreStats.Add("BetweenFrameworkItems", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatBetweenFrameWorkItems].ToString()); },
                "Number of between frame work items waiting");
            m_ogreStats.Add("BetweenFrameworkDiscardedDups", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatBetweenFrameDiscardedDups].ToString()); },
                "Between frame work requests which duplicated existing requests");
            m_ogreStats.Add("TotalBetweenFrameRefreshResource", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatBetweenFrameRefreshResource].ToString()); },
                "Number of 'refresh resource' work items queued");
            m_ogreStats.Add("TotalBetweenFrameRemoveSceneNode", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatBetweenFrameRemoveSceneNode].ToString()); },
                "Number of 'remove scene node' work items queued");
            m_ogreStats.Add("TotalBetweenFrameCreateMaterialResource", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatBetweenFrameCreateMaterialResource].ToString()); },
                "Number of 'create material resource' work items queued");
            m_ogreStats.Add("TotalBetweenFrameCreateMeshResource", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatBetweenFrameCreateMeshResource].ToString()); },
                "Number of 'create mesh resource' work items queued");
            m_ogreStats.Add("TotalBetweenFrameCreateMeshScenenode", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatBetweenFrameCreateMeshSceneNode].ToString()); },
                "Number of 'create mesh scene node' work items queued");
            m_ogreStats.Add("TotalBetweenFrameAddLoadedMesh", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatBetweenFrameAddLoadedMesh].ToString()); },
                "Number of 'add loaded mesh' work items queued");
            m_ogreStats.Add("TotalBetweenframeupdatescenenode", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatBetweenFrameUpdateSceneNode].ToString()); },
                "Number of 'update scene node' work items queued");
            m_ogreStats.Add("TotalBetweenFrameUnknownProcess", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatBetweenFrameUnknownProcess].ToString()); },
                "Number of work items with unknow process codes");
            m_ogreStats.Add("TotalBetweenFrameTotalProcessed", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatBetweenFrameTotalProcessed].ToString()); },
                "Total number of work items actually processed");
            // material processing queues
            m_ogreStats.Add("MaterialUpdatesRemaining", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatMaterialUpdatesRemaining].ToString()); },
                "Number of material updates waiting");
            // mesh processing queues
            m_ogreStats.Add("MeshTrackerLoadQueued", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatMeshTrackerLoadQueued].ToString()); },
                "Number of mesh loads queued");
            m_ogreStats.Add("MeshTrackerUnloadQueued", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatMeshTrackerUnloadQueued].ToString()); },
                "Number of mesh unloads queued");
            m_ogreStats.Add("MeshTrackerSerializedQueued", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatMeshTrackerSerializedQueued].ToString()); },
                "Number of mesh serializations queued");
            m_ogreStats.Add("MeshTrackerTotalQueued", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatMeshTrackerTotalQueued].ToString()); },
                "Total mesh tracker requests queued");
            m_ogreStats.Add("LockParity", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatLockParity].ToString()); },
                "Parity of LG locks");
            m_ogreStats.Add("RoutineInOut", delegate(string xx) {
                return new OMVSD.OSDString(m_ogreStatsPinned[Ogr.StatInOut].ToString()); },
                "Entry and exit of routines");

            // make the values accessable from outside
            m_ogreStatsHandler = new RestHandler("/stats/" + m_moduleName + "/ogreStats", m_ogreStats);
            #endregion OGRE STATS

            // Load the input system we're supposed to be using
            // The input system is a module tha we get given the name of. Go find it and link it in.
            String uiModule = ModuleParams.ParamString(m_moduleName + ".Ogre.InputSystem.Name");
            if (uiModule != null && uiModule.Length > 0) {
            try {
                m_log.Log(LogLevel.DRENDER, "Loading UI processor '{0}'", uiModule);
                m_userInterface = (IUserInterfaceProvider)ModuleManager.Instance.Module(uiModule);
                if (m_userInterface == null) {
                    m_log.Log(LogLevel.DBADERROR, "FATAL: Could not find user interface class {0}", uiModule);
                    return false;
                }
            }
            catch (Exception e) {
                m_log.Log(LogLevel.DBADERROR, "FATAL: Could not load user interface class {0}: {1}", uiModule, e.ToString());
                return false;
            }
            }
            else {
            m_log.Log(LogLevel.DBADERROR, "Using null user interfare");
            m_userInterface = new UserInterfaceNull();
            }

            // if we are doing detail logging, enable logging by  the LookingGlassOgre code
            if (m_log.WouldLog(LogLevel.DOGREDETAIL)) {
            m_log.Log(LogLevel.DRENDER, "Logging detail high enough to enable unmanaged code log messages");
            debugLogCallbackHandle = new Ogr.DebugLogCallback(OgrLogger);
            Ogr.SetDebugLogCallback(debugLogCallbackHandle);
            }
            // push the callback pointers into the LookingGlassOgre code
            fetchParameterCallbackHandle = new Ogr.FetchParameterCallback(GetAParameter);
            Ogr.SetFetchParameterCallback(fetchParameterCallbackHandle);
            checkKeepRunningCallbackHandle = new Ogr.CheckKeepRunningCallback(CheckKeepRunning);
            Ogr.SetCheckKeepRunningCallback(checkKeepRunningCallbackHandle);

            // link the input devices to and turn on low level IO reception
            if (m_userInterface.NeedsRendererLinkage()) {
            userIOCallbackHandle = new Ogr.UserIOCallback(ReceiveUserIOConv);
            Ogr.SetUserIOCallback(userIOCallbackHandle);
            }

            // handles so unmanaged code can call back to managed code
            requestResourceCallbackHandle = new Ogr.RequestResourceCallback(RequestResource);
            Ogr.SetRequestResourceCallback(requestResourceCallbackHandle);
            betweenFramesCallbackHandle = new Ogr.BetweenFramesCallback(ProcessBetweenFrames);
            Ogr.SetBetweenFramesCallback(betweenFramesCallbackHandle);

            m_sceneMagnification = float.Parse(ModuleParams.ParamString(m_moduleName + ".Ogre.LL.SceneMagnification"));

            m_shouldForceMeshRebuild = ModuleParams.ParamBool(m_moduleName + ".Ogre.ForceMeshRebuild");
            m_shouldRenderOnMainThread = ModuleParams.ParamBool(m_moduleName + ".ShouldRenderOnMainThread");
            m_shouldPrebuildMesh = ModuleParams.ParamBool(ModuleName + ".Ogre.PrebuildMesh");

            // pick up a bunch of parameterized values
            m_betweenFrameTotalCost = ModuleParams.ParamInt(m_moduleName + ".Ogre.BetweenFrame.Costs.Total");

            // start up the Ogre renderer
            try {
            Ogr.InitializeOgre();
            }
            catch (Exception e) {
            m_log.Log(LogLevel.DBADERROR, "EXCEPTION INITIALIZING OGRE: {0}", e.ToString());
            return false;
            }
            m_sceneMgr = new OgreSceneMgr(Ogr.GetSceneMgr());

            // if we get here, rendering is set up and running
            return true;
        }
 public void AddOverrideParameter(string key, string value)
 {
     m_overrideParams.Add(key, value);
 }
 public void AddUserParameter(string key, string value, string desc)
 {
     m_userParams.Add(key, value);
 }
 public void AddIniParameter(string key, string value, string desc)
 {
     m_iniParams.Add(key, value);
 }
 public void AddDefaultParameter(string key, string value, string desc)
 {
     m_defaultParams.Add(key, value, desc);
 }
        private OMVSD.OSDMap PostActionLogin(OMVSD.OSD body)
        {
            OMVSD.OSDMap ret = new OMVSD.OSDMap();
            ParameterSet loginParams = new ParameterSet();
            try {
            OMVSD.OSDMap paramMap = (OMVSD.OSDMap)body;
            loginParams.Add(CommLLLP.FIELDFIRST, paramMap["LOGINFIRST"].AsString());
            loginParams.Add(CommLLLP.FIELDLAST, paramMap["LOGINLAST"].AsString());
            loginParams.Add(CommLLLP.FIELDPASS, paramMap["LOGINPASS"].AsString());
            loginParams.Add(CommLLLP.FIELDGRID, paramMap["LOGINGRID"].AsString());
            loginParams.Add(CommLLLP.FIELDSIM, paramMap["LOGINSIM"].AsString());
            }
            catch {
            m_log.Log(LogLevel.DBADERROR, "MISFORMED POST REQUEST: ");
            ret.Add(RestHandler.RESTREQUESTERRORCODE, new OMVSD.OSDInteger(1));
            ret.Add(RestHandler.RESTREQUESTERRORMSG, new OMVSD.OSDString("Misformed POST request"));
            return ret;
            }

            try {
            if (!m_comm.Connect(loginParams)) {
                m_log.Log(LogLevel.DBADERROR, "CONNECT FAILED");
                ret.Add(RestHandler.RESTREQUESTERRORCODE, new OMVSD.OSDInteger(1));
                ret.Add(RestHandler.RESTREQUESTERRORMSG, new OMVSD.OSDString("Could not log in"));
                return ret;
            }
            }
            catch (Exception e) {
            m_log.Log(LogLevel.DBADERROR, "CONNECT EXCEPTION: " + e.ToString());
            ret.Add(RestHandler.RESTREQUESTERRORCODE, new OMVSD.OSDInteger(1));
            ret.Add(RestHandler.RESTREQUESTERRORMSG, new OMVSD.OSDString("Connection threw exception: " + e.ToString()));
            return ret;
            }

            return ret;
        }