예제 #1
0
        private void InitScriptApi(Yengine engine, string api, IScriptApi scriptApi)
        {
            // Set up m_ApiManager_<APINAME> = instance pointer.
            engine.m_XMRInstanceApiCtxFieldInfos[api].SetValue(this, scriptApi);

            // Initialize the API instance.
            scriptApi.Initialize(m_Engine, m_Part, m_Item);
            this.InitApi(api, scriptApi);
        }
예제 #2
0
        public void StartThreadWorker(int i)
        {
            Thread thd;

            if (i >= 0)
            {
                thd = Yengine.StartMyThread(RunScriptThread, "YScript" + i.ToString(), ThreadPriority.BelowNormal);
            }
            else
            {
                thd = Yengine.StartMyThread(RunScriptThread, "YScript", ThreadPriority.BelowNormal);
            }
            lock (m_WakeUpLock)
                m_RunningInstances.Add(thd.ManagedThreadId, null);
        }
예제 #3
0
        public void StartThreadWorker(int i, ThreadPriority priority, string sceneName)
        {
            Thread thd;

            if (i >= 0)
            {
                thd = Yengine.StartMyThread(RunScriptThread, "YScript" + i.ToString() + " (" + sceneName + ")", priority);
            }
            else
            {
                thd = Yengine.StartMyThread(RunScriptThread, "YScript", priority);
            }
            lock (m_WakeUpLock)
                m_RunningInstances.Add(thd.ManagedThreadId, null);
        }
예제 #4
0
        /****************************************************************************\
        *  The only method of interest to outside this module is the Initializer.  *
        *                                                                          *
        *  The rest of this module contains support routines for the Initializer.  *
        \****************************************************************************/

        /**
         * @brief Initializer, loads script in memory and all ready for running.
         * @param engine = YEngine instance this is part of
         * @param scriptBasePath = directory name where files are
         * @param stackSize = number of bytes to allocate for stacks
         * @param errors = return compiler errors in this array
         * @param forceRecomp = force recompile
         * Throws exception if any error, so it was successful if it returns.
         */
        public void Initialize(Yengine engine, string scriptBasePath,
                               int stackSize, int heapSize, ArrayList errors)
        {
            if (stackSize < 16384)
            {
                stackSize = 16384;
            }
            if (heapSize < 16384)
            {
                heapSize = 16384;
            }

            // Save all call parameters in instance vars for easy access.
            m_Engine         = engine;
            m_ScriptBasePath = scriptBasePath;
            m_StackSize      = stackSize;
            m_StackLeft      = stackSize;
            m_HeapSize       = heapSize;
            m_localsHeapUsed = 0;
            m_arraysHeapUsed = 0;
            m_CompilerErrors = errors;
            m_StateFileName  = GetStateFileName(scriptBasePath, m_ItemID);

            // Not in any XMRInstQueue.
            m_NextInst = this;
            m_PrevInst = this;

            // Set up list of API calls it has available.
            // This also gets the API modules ready to accept setup data, such as
            // active listeners being restored.
            IScriptApi scriptApi;
            ApiManager am = new ApiManager();

            foreach (string api in am.GetApis())
            {
                // Instantiate the API for this script instance.
                if (api != "LSL")
                {
                    scriptApi = am.CreateApi(api);
                }
                else
                {
                    scriptApi = m_XMRLSLApi = new XMRLSL_Api();
                }

                // Connect it up to the instance.
                InitScriptApi(engine, api, scriptApi);
            }

            m_XMRLSLApi.InitXMRLSLApi(this);

            // Get object loaded, compiling script and reading .state file as
            // necessary to restore the state.
            suspendOnCheckRunHold = true;
            InstantiateScript();
            m_SourceCode = null;
            if (m_ObjCode == null)
            {
                throw new ArgumentNullException("m_ObjCode");
            }
            if (m_ObjCode.scriptEventHandlerTable == null)
            {
                throw new ArgumentNullException("m_ObjCode.scriptEventHandlerTable");
            }

            suspendOnCheckRunHold = false;
            suspendOnCheckRunTemp = false;
        }
예제 #5
0
        /**
         * @brief Thread that runs the scripts.
         *
         *        There are NUMSCRIPTHREADWKRS of these.
         *        Each sits in a loop checking the Start and Yield queues for
         *        a script to run and calls the script as a microthread.
         */
        private void RunScriptThread()
        {
            int         tid = System.Threading.Thread.CurrentThread.ManagedThreadId;
            ThreadStart thunk;
            XMRInstance inst;
            bool        didevent;

            m_ScriptThreadTID = tid;

            while (!m_Exiting)
            {
                Yengine.UpdateMyThread();

                lock (m_WakeUpLock)
                {
                    // Maybe there are some scripts waiting to be migrated in or out.
                    thunk = null;
                    if (m_ThunkQueue.Count > 0)
                    {
                        thunk = m_ThunkQueue.Dequeue();
                    }

                    // Handle 'xmr resume/suspend' commands.
                    else if (m_SuspendScriptThreadFlag && !m_Exiting)
                    {
                        Monitor.Wait(m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2);
                        Yengine.UpdateMyThread();
                        continue;
                    }
                }

                if (thunk != null)
                {
                    thunk();
                    continue;
                }

                if (m_StartProcessing)
                {
                    // If event just queued to any idle scripts
                    // start them right away.  But only start so
                    // many so we can make some progress on yield
                    // queue.
                    int numStarts;
                    didevent = false;
                    for (numStarts = 5; numStarts >= 0; --numStarts)
                    {
                        lock (m_StartQueue)
                            inst = m_StartQueue.RemoveHead();

                        if (inst == null)
                        {
                            break;
                        }
                        if (inst.m_IState == XMRInstState.SUSPENDED)
                        {
                            continue;
                        }
                        if (inst.m_IState != XMRInstState.ONSTARTQ)
                        {
                            throw new Exception("bad state");
                        }
                        RunInstance(inst, tid);
                        if (m_SuspendScriptThreadFlag || m_Exiting)
                        {
                            continue;
                        }
                        didevent = true;
                    }

                    // If there is something to run, run it
                    // then rescan from the beginning in case
                    // a lot of things have changed meanwhile.
                    //
                    // These are considered lower priority than
                    // m_StartQueue as they have been taking at
                    // least one quantum of CPU time and event
                    // handlers are supposed to be quick.
                    lock (m_YieldQueue)
                        inst = m_YieldQueue.RemoveHead();

                    if (inst != null)
                    {
                        if (inst.m_IState == XMRInstState.SUSPENDED)
                        {
                            continue;
                        }
                        if (inst.m_IState != XMRInstState.ONYIELDQ)
                        {
                            throw new Exception("bad state");
                        }
                        RunInstance(inst, tid);
                        continue;
                    }

                    // If we left something dangling in the m_StartQueue or m_YieldQueue, go back to check it.
                    if (didevent)
                    {
                        continue;
                    }
                }

                // Nothing to do, sleep.
                lock (m_WakeUpLock)
                {
                    if (!m_WakeUpThis && (m_WakeUpOne <= 0) && !m_Exiting)
                    {
                        Monitor.Wait(m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2);
                    }

                    m_WakeUpThis = false;
                    if ((m_WakeUpOne > 0) && (--m_WakeUpOne > 0))
                    {
                        Monitor.Pulse(m_WakeUpLock);
                    }
                }
            }
            lock (m_WakeUpLock)
                m_RunningInstances.Remove(tid);

            Yengine.MyThreadExiting();
        }