/// <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; }