Esempio n. 1
0
    /// <summary>
    /// <para>等待下一条消息触发</para>
    /// <para>当所在的上下文被重复触发时则会直接返回<see langword="false"/></para>
    /// </summary>
    internal object WaitForNextMessage(long sourceUid, string[]  commandExps, MatchType matchType,
                                       RegexOptions regexOptions, TimeSpan?timeout,
                                       Func <ValueTask> timeoutTask, long sourceGroup = 0)
    {
        //生成指令上下文
        WaitingInfo waitInfo =
            CommandManager.GenerateWaitingCommandInfo(sourceUid, sourceGroup, commandExps, matchType, SourceType,
                                                      regexOptions, SoraApi.ConnectionId, SoraApi.ServiceId);

        //检查是否为初始指令重复触发
        if (StaticVariable.WaitingDict.Any(i => i.Value.IsSameSource(waitInfo)))
        {
            return(null);
        }
        //连续指令不再触发后续事件
        IsContinueEventChain = false;
        var sessionId = Guid.NewGuid();

        //添加上下文并等待信号量
        StaticVariable.WaitingDict.TryAdd(sessionId, waitInfo);
        //是否正常接受到触发信号
        bool receiveSignal =
            //等待信号量
            StaticVariable.WaitingDict[sessionId].Semaphore.WaitOne(timeout ?? TimeSpan.FromMilliseconds(-1));
        //取出匹配指令的事件参数并删除上一次的上下文
        object retEventArgs = receiveSignal ? StaticVariable.WaitingDict[sessionId].EventArgs : null;

        StaticVariable.WaitingDict.TryRemove(sessionId, out _);
        //在超时时执行超时任务
        if (!receiveSignal && timeoutTask != null)
        {
            Task.Run(timeoutTask.Invoke);
        }
        return(retEventArgs);
    }
        public override void DoTextureLoad(EntityName textureEntityName, AssetType typ, DownloadFinishedCallback finishCall)
        {
            EntityNameLL textureEnt = new EntityNameLL(textureEntityName);
            string       worldID    = textureEnt.EntityPart;

            OMV.UUID binID = new OMV.UUID(worldID);

            if (m_basePath == null)
            {
                return;
            }

            // do we already have the file?
            string textureFilename = Path.Combine(CacheDirBase, textureEnt.CacheFilename);

            lock (FileSystemAccessLock) {
                if (File.Exists(textureFilename))
                {
                    m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Texture file already exists for " + worldID);
                    bool hasTransparancy = CheckTextureFileForTransparancy(textureFilename);
                    // make the callback happen on a new thread so things don't get tangled (caller getting the callback)
                    Object[] finishCallParams = { finishCall, textureEntityName.Name, hasTransparancy };
                    m_completionWork.DoLater(FinishCallDoLater, finishCallParams);
                    // m_completionWork.DoLater(new FinishCallDoLater(finishCall, textureEntityName.Name, hasTransparancy));
                }
                else
                {
                    bool sendRequest = false;
                    lock (m_waiting) {
                        // if this is already being requested, don't waste our time
                        if (m_waiting.ContainsKey(binID))
                        {
                            m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Already waiting for " + worldID);
                        }
                        else
                        {
                            WaitingInfo wi = new WaitingInfo(binID, finishCall);
                            wi.filename = textureFilename;
                            wi.type     = typ;
                            m_waiting.Add(binID, wi);
                            sendRequest = true;
                        }
                    }
                    if (sendRequest)
                    {
                        // this is here because RequestTexture might immediately call the callback
                        //   and we should be outside the lock
                        m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Requesting: " + textureEntityName);
                        // m_texturePipe.RequestTexture(binID, OMV.ImageType.Normal, 50f, 0, 0, OnACDownloadFinished, false);
                        // m_comm.GridClient.Assets.RequestImage(binID, OMV.ImageType.Normal, 101300f, 0, 0, OnACDownloadFinished, false);
                        // m_comm.GridClient.Assets.RequestImage(binID, OMV.ImageType.Normal, 50f, 0, 0, OnACDownloadFinished, false);
                        ThrottleTextureRequests(binID);
                    }
                }
            }
            return;
        }
        public override void DoTextureLoad(EntityName textureEntityName, AssetType typ, DownloadFinishedCallback finishCall)
        {
            EntityNameLL textureEnt = new EntityNameLL(textureEntityName);
            string worldID = textureEnt.EntityPart;
            OMV.UUID binID = new OMV.UUID(worldID);

            if (m_basePath == null) return;

            // do we already have the file?
            string textureFilename = Path.Combine(CacheDirBase, textureEnt.CacheFilename);
            lock (FileSystemAccessLock) {
            if (File.Exists(textureFilename)) {
                m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Texture file already exists for " + worldID);
                bool hasTransparancy = CheckTextureFileForTransparancy(textureFilename);
                // make the callback happen on a new thread so things don't get tangled (caller getting the callback)
                Object[] finishCallParams = { finishCall, textureEntityName.Name, hasTransparancy };
                m_completionWork.DoLater(FinishCallDoLater, finishCallParams);
                // m_completionWork.DoLater(new FinishCallDoLater(finishCall, textureEntityName.Name, hasTransparancy));
            }
            else {
                bool sendRequest = false;
                lock (m_waiting) {
                    // if this is already being requested, don't waste our time
                    if (m_waiting.ContainsKey(binID)) {
                        m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Already waiting for " + worldID);
                    }
                    else {
                        WaitingInfo wi = new WaitingInfo(binID, finishCall);
                        wi.filename = textureFilename;
                        wi.type = typ;
                        m_waiting.Add(binID, wi);
                        sendRequest = true;
                    }
                }
                if (sendRequest) {
                    // this is here because RequestTexture might immediately call the callback
                    //   and we should be outside the lock
                    m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Requesting: " + textureEntityName);
                    // m_texturePipe.RequestTexture(binID, OMV.ImageType.Normal, 50f, 0, 0, OnACDownloadFinished, false);
                    // m_comm.GridClient.Assets.RequestImage(binID, OMV.ImageType.Normal, 101300f, 0, 0, OnACDownloadFinished, false);
                    // m_comm.GridClient.Assets.RequestImage(binID, OMV.ImageType.Normal, 50f, 0, 0, OnACDownloadFinished, false);
                    ThrottleTextureRequests(binID);
                }
            }
            }
            return;
        }