public void log(string info) { // 将日志保存到当前缓冲中 mLogListLock.waitForUnlock(); mLogBufferList[mLogIndex].Add(info); mLogListLock.unlock(); }
// 返回值表示是否是new出来的对象,false则为从回收列表中重复使用的对象 public List <T> newList <T>(out List <T> obj) { obj = null; // 锁定期间不能调用任何其他非库函数,否则可能会发生死锁 mListLock.waitForUnlock(); try { Type elementType = typeof(T); // 先从未使用的列表中查找是否有可用的对象 if (mUnusedList.ContainsKey(elementType) && mUnusedList[elementType].Count > 0) { obj = mUnusedList[elementType].Pop() as List <T>; } // 未使用列表中没有,创建一个新的 else { obj = createInstance <List <T> >(typeof(List <T>)); } // 标记为已使用 addInuse(obj); } catch (Exception e) { logError(e.Message); } mListLock.unlock(); return(obj); }
// 切换缓冲区,获得可读列表,在遍历可读列表期间,不能再次调用getReadList,否则会出现不可预知的错误,并且该函数只能在一个线程中调用 public List <T> getReadList() { mBufferLock.waitForUnlock(); swap(ref mReadIndex, ref mWriteIndex); mBufferLock.unlock(); return(mBufferList[mReadIndex]); }
public void startConnect(bool async) { if (!isUnconnected()) { return; } notifyNetState(NET_STATE.CONNECTING); // 创建socket mSocketLock.waitForUnlock(); if (mSocket != null) { logError("当前Socket不为空"); } mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); mSocketLock.unlock(); if (async) { mSocket.BeginConnect(mIPAddress, mPort, onConnectEnd, mSocket); } else { try { mSocket.Connect(mIPAddress, mPort); } catch (SocketException e) { log("init socket exception : " + e.Message, LOG_LEVEL.FORCE); socketException(e); return; } notifyNetState(NET_STATE.CONNECTED); } }
// 返回值表示是否是new出来的对象,false则为从回收列表中重复使用的对象 public IClassObject newClass(out bool isNewObject) { mListLock.waitForUnlock(); isNewObject = false; IClassObject obj = null; // 先从未使用的列表中查找是否有可用的对象 if (mUnusedList.Count > 0) { foreach (var item in mUnusedList) { obj = item; break; } mUnusedList.Remove(obj); } // 未使用列表中没有,创建一个新的 else { obj = createInstance <IClassObject>(mType); // 创建实例时重置是为了与后续复用的实例状态保持一致 obj.resetProperty(); isNewObject = true; } obj.setAssignID(++mAssignIDSeed); obj.setDestroy(false); // 添加到已使用列表 mInusedList.Add(obj); mListLock.unlock(); return(obj); }
// 返回值表示是否是new出来的对象,false则为从回收列表中重复使用的对象 public bool newClass(out IClassObject obj, Type type) { bool isNewObject = false; obj = null; // 锁定期间不能调用任何其他非库函数,否则可能会发生死锁 mListLock.waitForUnlock(); try { // 先从未使用的列表中查找是否有可用的对象 if (mUnusedList.ContainsKey(type) && mUnusedList[type].Count > 0) { obj = mUnusedList[type].Pop(); isNewObject = false; } // 未使用列表中没有,创建一个新的 else { obj = createInstance <IClassObject>(type); isNewObject = true; } // 添加到已使用列表 addInuse(obj); } catch (Exception e) { logError(e.Message); } mListLock.unlock(); // 重置实例 obj?.resetProperty(); return(isNewObject); }
public void sendMessage(SocketPacket packet) { // 将消息包中的数据准备好,然后放入发送列表中 packet.fillData(); mOutputLock.waitForUnlock(); mOutputList.Add(new OUTPUT_STREAM(packet.getData(), packet.getSize())); mOutputLock.unlock(); }
public override void destroy() { base.destroy(); mBufferLock.unlock(); mSqlLiteLock.unlock(); mSendThread.destroy(); logInfo("完成退出日志"); }
public void sendPacket(SerialPortPacket packet) { mSendPacketLock.waitForUnlock(); if (mSendPacket.Count < MAX_SEND_PACKET_COUNT) { mSendPacket.Add(packet); } mSendPacketLock.unlock(); }
protected void processReceived() { mReceivedPacketLock.waitForUnlock(); int count = mReceivedPacket.Count; for (int i = 0; i < count; ++i) { mReceivedPacket[i].execute(); } mReceivedPacket.Clear(); mReceivedPacketLock.unlock(); }
protected void syncCommandBuffer() { mBufferLock.waitForUnlock(LOCK_TYPE.LT_READ); int inputCount = mCommandBufferInput.Count; for (int i = 0; i < inputCount; ++i) { mCommandBufferProcess.Add(mCommandBufferInput[i]); } mCommandBufferInput.Clear(); mBufferLock.unlock(LOCK_TYPE.LT_READ); }
public override void destroy() { base.destroy(); if (mSQLite != null) { mSQLite.destroy(); mSQLite = null; } mBufferLock.unlock(); mSqlLiteLock.unlock(); mSendThread.destroy(); UnityUtility.logInfo("完成退出日志"); }
public override void update(float elapsedTime) { base.update(elapsedTime); #if UNITY_EDITOR mListLock.waitForUnlock(); foreach (var item in mInusedList) { logError("有临时对象正在使用中,是否在申请后忘记回收到池中!"); break; } mListLock.unlock(); #endif }
public void upload(string fullURL, string fileName, string uploadPath, StartCallback start, FinishCallback finish) { mUploadListLock.waitForUnlock(); DownloadInfo info = new DownloadInfo(); info.mURL = StringUtility.strReplaceAll(fullURL, " ", "%20"); info.mFileName = fileName; info.mUploadPath = uploadPath; info.mStartCallback = start; info.mFinishCallback = finish; mUploadList.Add(info); mUploadListLock.unlock(); }
//------------------------------------------------------------------------------------------------------------------ protected void addInuse(Command cmd) { mInuseLock.waitForUnlock(); // 添加到使用列表中 Type type = cmd.getType(); if (!mInusedList.ContainsKey(type)) { mInusedList.Add(type, new List <Command>()); } mInusedList[type].Add(cmd); mInuseLock.unlock(); }
protected void addUnuse(Command cmd) { mUnuseLock.waitForUnlock(); // 添加到未使用列表中 Type t = cmd.getType(); if (!mUnusedList.ContainsKey(t)) { mUnusedList.Add(t, new List <Command>()); } mUnusedList[t].Add(cmd); mUnuseLock.unlock(); }
public void disconnectSocket(uint client) { mClientRecvLock.waitForUnlock(); mClientSendLock.waitForUnlock(); if (mClientList.ContainsKey(client)) { logInfo("客户端断开连接:角色ID:" + uintToString(mClientList[client].getCharacterGUID()) + ",原因:" + mClientList[client].getDeadReason() + ", 剩余连接数:" + (mClientList.Count - 1)); mClientList[client].destroy(); mClientList.Remove(client); } mClientRecvLock.unlock(); mClientSendLock.unlock(); }
public void disconnectSocket(uint clientID) { mClientRecvLock.waitForUnlock(); mClientSendLock.waitForUnlock(); if (mClientList.TryGetValue(clientID, out NetClient cient)) { log("客户端断开连接:角色ID:" + uintToString(cient.getCharacterGUID()) + ",原因:" + cient.getDeadReason() + ", 剩余连接数:" + (mClientList.Count - 1)); cient.destroy(); mClientList.Remove(clientID); } mClientRecvLock.unlock(); mClientSendLock.unlock(); }
protected void sendLog(ref bool run) { // 将日志缓存同步到发送列表中 mSendLock.waitForUnlock(); mBufferLock.waitForUnlock(); if (mLogBufferList.Count > 0) { for (int i = 0; i < mLogBufferList.Count; ++i) { LogData data = mLogBufferList[i]; mLogSendList.Add(data.mGuid.ToString(), data); } mLogBufferList.Clear(); } mBufferLock.unlock(); // 复制一份列表,然后解锁列表,避免其他线程阻塞 Dictionary <string, LogData> tempList = new Dictionary <string, LogData>(mLogSendList); mSendLock.unlock(); foreach (var item in tempList) { // 找到未上传的数据 if (item.Value.mState == LOG_STATE.LS_UNUPLOAD) { LogData data = item.Value; // 设置为正在上传状态 data.mState = LOG_STATE.LS_UPLOADING; if (data.mType.ToString().Length >= 64 || data.mTime.ToString("G").Length >= 32 || data.mInfo.Length >= 256 || data.mGuid.ToString().Length >= 64) { continue; } mSqlLiteLock.waitForUnlock(); SQLiteLogData logData = new SQLiteLogData(); logData.mUserID = mUserID; logData.mLogType = data.mType.ToString(); logData.mTime = data.mTime.ToString("G"); logData.mLogInfo = data.mInfo; logData.mGUID = data.mGuid.ToString(); logData.mUploaded = 0; mSQLiteLog.insert(logData); mSqlLiteLock.unlock(); // 将日志上传服务器,并且记录到本地数据库 string uploadData = ""; prepareData(data, ref uploadData); //HttpUtility.httpWebRequestPost(GameDefine.GAME_LOG_URL, GameDefine.HTTP_URL_GAMEDATA + uploadData, onDataUploadResult, data.mGuid.ToString(), false); } } }
//------------------------------------------------------------------------------------------------------------------ protected void addInuse(Command cmd) { mInuseLock.waitForUnlock(LOCK_TYPE.LT_WRITE); // 添加到使用列表中 Type t = cmd.getType(); if (!mInusedList.ContainsKey(t)) { mInusedList.Add(t, new List <Command>()); } List <Command> list = mInusedList[t]; list.Add(cmd); mInuseLock.unlock(LOCK_TYPE.LT_WRITE); }
public override void destroy() { ThreadListLock.waitForUnlock(); int count = mHttpThreadList.Count; for (int i = 0; i < count; ++i) { mHttpThreadList[i].Abort(); mHttpThreadList[i] = null; } mHttpThreadList.Clear(); mHttpThreadList = null; ThreadListLock.unlock(); base.destroy(); }
protected bool receiveThread() { if (!isDeviceConnect()) { return(true); } const int MaxRecvCount = 32; if (mRecvBytes == null) { mRecvBytes = new byte[MaxRecvCount]; } // 只接收23个字节,如果不是23个字节,则丢弃该数据 int readCount = mHIDDevice.read(ref mRecvBytes, 23); if (readCount != 0) { BinaryUtility.memmove(ref mRecvBytes, 0, 1, MaxRecvCount - 1); readCount -= 4; // 去除第一个字节和最后3个字节 mInputBufferLock.waitForUnlock(); addDataToInputBuffer(mRecvBytes, readCount); mInputBufferLock.unlock(); } // 先同步发送列表 mSendPacketLock.waitForUnlock(); int count = mSendPacket.Count; for (int i = 0; i < count; ++i) { mOutputBufferList.Add(mSendPacket[i].toBytes()); } mSendPacket.Clear(); mSendPacketLock.unlock(); // 发送所有需要发送的数据 int sendCount = mOutputBufferList.Count; for (int i = 0; i < sendCount; ++i) { if (mOutputBufferList[i] != null) { mHIDDevice.write(mOutputBufferList[i]); } } mOutputBufferList.Clear(); return(true); }
public void download(string fullURL, string fileName, long offset, DownloadingCallback downloading, TimeoutCallback timeout, StartCallback start, FinishCallback finish) { mDownloadListLock.waitForUnlock(); DownloadInfo info = new DownloadInfo(); // 下载地址里需要将空格替换为%20 info.mURL = StringUtility.strReplaceAll(fullURL, " ", "%20"); info.mFileName = fileName; info.mDownloadingCallback = downloading; info.mStartCallback = start; info.mFinishCallback = finish; info.mTimeoutCallback = timeout; info.mDownloadOffset = offset; mDownloadList.Add(info); mDownloadListLock.unlock(); }
//------------------------------------------------------------------------------------------------------------------------- // 处理接收到的所有消息 protected void processInput() { // 等待解锁接收流的读写,并锁定接收流 mReceiveLock.waitForUnlock(); int receiveCount = mRecieveList.Count; for (int i = 0; i < receiveCount; ++i) { INPUT_ELEMENT element = mRecieveList[i]; SocketPacket packetReply = createPacket(element.mType); packetReply.read(element.mData); packetReply.execute(); } mRecieveList.Clear(); mReceiveLock.unlock(); }
public Command newCmd(Type type, bool show = true, bool delay = false) { mNewCmdLock.waitForUnlock(); // 首先从未使用的列表中获取,获取不到再重新创建一个 Command cmd = null; if (mUnusedList.ContainsKey(type)) { var list = mUnusedList[type]; if (list.Count > 0) { // 从未使用列表中移除 mUnuseLock.waitForUnlock(); cmd = list.Pop(); mUnuseLock.unlock(); } } // 没有找到可以用的,则创建一个 if (cmd == null) { cmd = createInstance <Command>(type); cmd.setID(mIDSeed++); cmd.init(); cmd.setType(type); ++mNewCount; } // 设置为可用命令 cmd.setValid(true); if (delay) { cmd.setAssignID(mAssignIDSeed++); } else { cmd.setAssignID(-1); } cmd.setShowDebugInfo(show); cmd.setDelayCommand(delay); // 加入已使用列表 addInuse(cmd); mNewCmdLock.unlock(); return(cmd); }
// 返回值表示是否是new出来的对象,false则为从回收列表中重复使用的对象 public IClassObject newClass(Type type, out bool isNewObject) { isNewObject = false; if (type == null) { return(null); } // 锁定期间不能调用任何其他非库函数,否则可能会发生死锁 mListLock.waitForUnlock(); // 先从未使用的列表中查找是否有可用的对象 if (!mPoolList.TryGetValue(type, out ClassPoolSingle singlePool)) { singlePool = new ClassPoolSingle(); singlePool.setType(type); mPoolList.Add(type, singlePool); } mListLock.unlock(); return(singlePool.newClass(out isNewObject)); }
// delayExecute是命令延时执行的时间,默认为0,只有new出来的命令才能延时执行 // 子线程中发出的命令必须是延时执行的命令! public new void pushDelayCommand(Command cmd, CommandReceiver cmdReceiver, float delayExecute = 0.001f) { // 如果命令系统已经销毁了,则不能再发送命令 if (mSystemDestroy) { return; } if (cmd == null) { logError("cmd is null! receiver : " + (cmdReceiver != null ? cmdReceiver.getName() : "")); return; } if (cmdReceiver == null) { logError("receiver is null! cmd : " + (cmd != null ? cmd.getType().ToString() : "")); return; } if (!cmd.isValid()) { logError("cmd is invalid! make sure create cmd use CommandSystem.newCmd! pushDelayCommand cmd type : " + cmd.GetType().ToString() + "cmd id : " + cmd.mAssignID); return; } if (!cmd.isDelayCommand()) { logError("cmd is not a delay command, Command : " + cmd.mAssignID + ", " + cmd.showDebugInfo()); return; } if (delayExecute < 0.0f) { delayExecute = 0.0f; } if (cmd.getShowDebugInfo()) { logInfo("CommandSystem : delay cmd : " + cmd.mAssignID + ", " + delayExecute + ", info : " + cmd.showDebugInfo() + ", receiver : " + cmdReceiver.getName(), LOG_LEVEL.LL_NORMAL); } DelayCommand delayCommand = new DelayCommand(delayExecute, cmd, cmdReceiver); mBufferLock.waitForUnlock(); mCommandBufferInput.Add(delayCommand); mBufferLock.unlock(); }
// delayExecute是命令延时执行的时间,默认为0,只有new出来的命令才能延时执行 // 子线程中发出的命令必须是延时执行的命令! public new void pushDelayCommand(Command cmd, CommandReceiver cmdReceiver, float delayExecute, IDelayCmdWatcher watcher) { // 如果命令系统已经销毁了,则不能再发送命令 if (mDestroy) { return; } if (cmd == null) { logError("cmd is null! receiver : " + (cmdReceiver != null ? cmdReceiver.getName() : EMPTY)); return; } if (cmdReceiver == null) { logError("receiver is null! cmd : " + (cmd != null ? cmd.GetType().ToString() : EMPTY)); return; } if (cmd.isDestroy()) { logError("cmd is invalid! make sure create cmd use CommandSystem.newCmd! pushDelayCommand cmd type : " + Typeof(cmd) + "cmd id : " + cmd.getAssignID()); return; } if (!cmd.isDelayCommand()) { logError("cmd is not a delay command, Command : " + cmd.getAssignID() + ", " + cmd.showDebugInfo()); return; } clampMin(ref delayExecute); if (cmd.isShowDebugInfo()) { #if UNITY_EDITOR || DEVELOPMENT_BUILD log("CMD : delay cmd : " + cmd.getAssignID() + ", " + delayExecute + ", info : " + cmd.showDebugInfo() + ", receiver : " + cmdReceiver.getName(), LOG_LEVEL.NORMAL); #endif } cmd.setDelayTime(delayExecute); cmd.setReceiver(cmdReceiver); mBufferLock.waitForUnlock(); mCommandBufferInput.Add(cmd); mBufferLock.unlock(); watcher?.addDelayCmd(cmd); }
// 切换缓冲区,获得可读列表,在遍历可读列表期间,不能再次调用get,否则会出现不可预知的错误,并且该函数不能在多个线程中调用 public List <T> get() { int curThreadID = Thread.CurrentThread.ManagedThreadId; mBufferLock.waitForUnlock(); if (mReadThreadID == 0) { mReadThreadID = curThreadID; } swap(ref mReadIndex, ref mWriteIndex); List <T> readList = mBufferList[mReadIndex]; mBufferLock.unlock(); if (mReadThreadID != curThreadID) { logError("不能在不同线程中获得可读列表"); return(null); } return(readList); }
public override void update(float elapsedTime) { base.update(elapsedTime); #if UNITY_EDITOR mListLock.waitForUnlock(); foreach (var item in mInusedList) { if (item.Value.Count == 0) { continue; } foreach (var itemList in item.Value) { logError("有临时列表对象正在使用中,是否在申请后忘记回收到池中! type:" + Typeof(itemList)); break; } } mListLock.unlock(); #endif }