524 lines
17 KiB
C#
524 lines
17 KiB
C#
using System;
|
||
using System.Runtime.InteropServices;
|
||
using BrewMonster.Scripts.Task;
|
||
using UnityEngine;
|
||
|
||
namespace BrewMonster.Scripts.Task
|
||
{
|
||
public class TaskProcess
|
||
{
|
||
|
||
}
|
||
[Flags]
|
||
public enum TaskState : byte
|
||
{
|
||
TASK_STATE_FINISHED = 0x01, // Is finished
|
||
TASK_STATE_SUCCESS = 0x02, // Is successful
|
||
TASK_STATE_GIVEUP = 0x04, // Is given up
|
||
TASK_STATE_ERR_REPORTED = 0x08, // Error has been reported to client
|
||
TASK_STATE_AWARD_NOTIFY_TEAM = 0x10, // Award has been notified to team
|
||
TASK_STATE_CONTRIBUTION_FINISH = 0x20 // Contribution finished
|
||
}
|
||
|
||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||
// Cur Size 21 bytes
|
||
public class TASK_ENTRY_FIXED_DATA
|
||
{
|
||
public ushort m_ID; // ID
|
||
public char m_ParentIndex; // Parent node index
|
||
public char m_PrevSblIndex; // Previous sibling node index
|
||
public char m_NextSblIndex; // Next sibling node index
|
||
public char m_ChildIndex; // Child node index
|
||
public char m_uState; // Task state
|
||
public uint m_ulTaskTime; // Timestamp
|
||
public ushort m_uCapTaskId; // Captain task ID
|
||
public uint m_ulTemplAddr; // Template address
|
||
public uint m_ulCapTemplAddr; // Captain task template address
|
||
|
||
};
|
||
|
||
// ´óСΪTASK_DATA_BUF_MAX_LEN
|
||
public class ActiveTaskEntry : TASK_ENTRY_FIXED_DATA
|
||
{
|
||
// Buffer union simplified (C# does not support union directly)
|
||
// unsigned char m_BufData[TASK_DATA_BUF_MAX_LEN-sizeof(TASK_ENTRY_FIXED_DATA)];
|
||
public byte[] m_BufData = new byte[TaskInterfaceConstants.TASK_DATA_BUF_MAX_LEN - Marshal.SizeOf<TASK_ENTRY_FIXED_DATA>() ]; // Raw data buffer
|
||
// nsigned short m_wMonsterNum[MAX_MONSTER_WANTED];
|
||
public ushort[] m_wMonsterNum // Monster numbers
|
||
{
|
||
get
|
||
{
|
||
ushort[] monsterNums = new ushort[TaskInterfaceConstants.MAX_MONSTER_WANTED];
|
||
for (int i = 0; i < TaskInterfaceConstants.MAX_MONSTER_WANTED; i++)
|
||
{
|
||
monsterNums[i] = BitConverter.ToUInt16(m_BufData, i * 2);
|
||
}
|
||
return monsterNums;
|
||
}
|
||
set
|
||
{
|
||
for (int i = 0; i < TaskInterfaceConstants.MAX_MONSTER_WANTED; i++)
|
||
{
|
||
byte[] bytes = BitConverter.GetBytes(value[i]);
|
||
m_BufData[i * 2] = bytes[0];
|
||
m_BufData[i * 2 + 1] = bytes[1];
|
||
}
|
||
}
|
||
}
|
||
|
||
public int m_iUsefulData1
|
||
{
|
||
get => BitConverter.ToInt32(m_BufData, TaskInterfaceConstants.MAX_MONSTER_WANTED * 2);
|
||
set
|
||
{
|
||
byte[] bytes = BitConverter.GetBytes(value);
|
||
Array.Copy(bytes, 0, m_BufData, TaskInterfaceConstants.MAX_MONSTER_WANTED * 2, 4);
|
||
}
|
||
}
|
||
|
||
public byte m_iUsefulData2 // char in C++, but using byte here for simplicity
|
||
{
|
||
get => m_BufData[TaskInterfaceConstants.MAX_MONSTER_WANTED * 2 + 4];
|
||
set => m_BufData[TaskInterfaceConstants.MAX_MONSTER_WANTED * 2 + 4] = value;
|
||
}
|
||
|
||
public void ReadFromBuffer(byte[] buffer, ref int offset)
|
||
{
|
||
m_ID = BitConverter.ToUInt16(buffer, offset);
|
||
offset += 2;
|
||
m_ParentIndex = (char)buffer[offset++];
|
||
m_PrevSblIndex = (char)buffer[offset++];
|
||
m_NextSblIndex = (char)buffer[offset++];
|
||
m_ChildIndex = (char)buffer[offset++];
|
||
m_uState = (char)buffer[offset++];
|
||
m_ulTaskTime = BitConverter.ToUInt32(buffer, offset);
|
||
offset += 4;
|
||
m_uCapTaskId = BitConverter.ToUInt16(buffer, offset);
|
||
offset += 2;
|
||
m_ulTemplAddr = BitConverter.ToUInt32(buffer, offset);
|
||
offset += 4;
|
||
m_ulCapTemplAddr = BitConverter.ToUInt32(buffer, offset);
|
||
offset += 4;
|
||
|
||
// int localOffset = offset; // store current offset for reading additional fields from union
|
||
|
||
// Read remaining buffer data
|
||
Array.Copy(buffer, offset, m_BufData, 0, m_BufData.Length);
|
||
offset += m_BufData.Length; // in C++ have union, so we dont plus offset here
|
||
|
||
// // Additional fields can be read here as needed
|
||
// m_wMonsterNum = new ushort[TaskInterfaceConstants.MAX_MONSTER_WANTED];
|
||
// for (int i = 0; i < TaskInterfaceConstants.MAX_MONSTER_WANTED; i++)
|
||
// {
|
||
// m_wMonsterNum[i] = BitConverter.ToUInt16(buffer, localOffset);
|
||
// localOffset += 2; // in C++ have union, so we dont plus offset here
|
||
// }
|
||
//
|
||
// m_iUsefulData1 = BitConverter.ToInt32(buffer, localOffset);
|
||
// localOffset += 4; // in C++ have union, so we dont plus offset here
|
||
//
|
||
// m_iUsefulData2 = buffer[localOffset++]; // in C++ have union, so we dont plus offset here
|
||
|
||
|
||
}
|
||
|
||
// bool IsFinished() const { return (m_uState & TASK_STATE_FINISHED) != 0; }
|
||
// bool IsErrReported() const { return (m_uState & TASK_STATE_ERR_REPORTED) != 0; }
|
||
// bool IsAwardNotifyTeam() const { return (m_uState & TASK_STATE_AWARD_NOTIFY_TEAM) != 0; }
|
||
// bool IsContributionFinish() const { return (m_uState & TASK_STATE_CONTRIBUTION_FINISH) != 0; }
|
||
// --- State check methods ---
|
||
public bool IsFinished() => (m_uState & (byte)TaskState.TASK_STATE_FINISHED) != 0;
|
||
public bool IsSuccess() => (m_uState & (byte)TaskState.TASK_STATE_SUCCESS) != 0;
|
||
public bool IsGiveUp() => (m_uState & (byte)TaskState.TASK_STATE_GIVEUP) != 0;
|
||
public bool IsErrReported() => (m_uState & (byte)TaskState.TASK_STATE_ERR_REPORTED) != 0;
|
||
public bool IsAwardNotifyTeam() => (m_uState & (byte)TaskState.TASK_STATE_AWARD_NOTIFY_TEAM) != 0;
|
||
public bool IsContributionFinish() => (m_uState & (byte)TaskState.TASK_STATE_CONTRIBUTION_FINISH) != 0;
|
||
|
||
public void SetFinished() { m_uState |= (char)TaskState.TASK_STATE_FINISHED; }
|
||
// void ClearFinished() { m_uState &= ~TASK_STATE_FINISHED; }
|
||
// void SetSuccess() { m_uState |= TASK_STATE_SUCCESS; }
|
||
public void ClearSuccess() { m_uState &= (char)~TaskState.TASK_STATE_SUCCESS; }
|
||
public void SetGiveUp() { m_uState |= (char)TaskState.TASK_STATE_GIVEUP; }
|
||
// void ClearGiveUp() { m_uState &= ~TASK_STATE_GIVEUP; }
|
||
// void SetErrReported() { m_uState |= TASK_STATE_ERR_REPORTED; }
|
||
// void ClearErrReported() { m_uState &= ~TASK_STATE_ERR_REPORTED; }
|
||
// void SetAwardNotifyTeam() { m_uState |= TASK_STATE_AWARD_NOTIFY_TEAM; }
|
||
// void ClearAwardNotifyTeam() { m_uState &= ~TASK_STATE_AWARD_NOTIFY_TEAM; }
|
||
// void SetContributionFinish() { m_uState |= TASK_STATE_CONTRIBUTION_FINISH; }
|
||
// void ClearContributionFinish() { m_uState &= ~TASK_STATE_CONTRIBUTION_FINISH; }
|
||
//
|
||
public ATaskTempl GetTempl()
|
||
{
|
||
// Managed fallback: resolve via template manager by ID
|
||
try
|
||
{
|
||
var man = BrewMonster.Network.EC_Game.GetTaskTemplateMan();
|
||
if (man != null)
|
||
{
|
||
var templ = man.GetTaskTemplByID(m_ID);
|
||
if (templ != null) return templ;
|
||
}
|
||
}
|
||
catch { }
|
||
|
||
// Legacy pointer path (likely unused in managed port)
|
||
if (m_ulTemplAddr != 0)
|
||
{
|
||
try
|
||
{
|
||
return Marshal.PtrToStructure<ATaskTempl>(new IntPtr(unchecked((long)m_ulTemplAddr)));
|
||
}
|
||
catch { }
|
||
}
|
||
return null;
|
||
}
|
||
// const ATaskTempl* GetCap() const { return reinterpret_cast<const ATaskTempl*>(m_ulCapTemplAddr); }
|
||
// const ATaskTempl* GetCapOrSelf() const
|
||
// {
|
||
// if (m_ulCapTemplAddr) return GetCap();
|
||
// else return GetTempl();
|
||
// }
|
||
// bool HasParent() const { return m_ParentIndex != 0xff; }
|
||
// bool HasChildren() const { return m_ChildIndex != 0xff; }
|
||
// bool IsValid(unsigned char uIndex, unsigned char uMaxCount) const
|
||
// {
|
||
// if (m_ParentIndex != 0xff)
|
||
// {
|
||
// if (m_ParentIndex >= uIndex || m_ParentIndex >= uMaxCount)
|
||
// return false;
|
||
// }
|
||
//
|
||
// if (m_PrevSblIndex != 0xff)
|
||
// {
|
||
// if (m_PrevSblIndex >= uIndex || m_PrevSblIndex >= uMaxCount)
|
||
// return false;
|
||
// }
|
||
//
|
||
// if (m_NextSblIndex != 0xff)
|
||
// {
|
||
// if (m_NextSblIndex <= uIndex || m_NextSblIndex >= uMaxCount)
|
||
// return false;
|
||
// }
|
||
//
|
||
// if (m_ChildIndex != 0xff)
|
||
// {
|
||
// if (m_ChildIndex <= uIndex || m_ChildIndex >= uMaxCount)
|
||
// return false;
|
||
// }
|
||
//
|
||
// return true;
|
||
// }
|
||
};
|
||
|
||
public class ActiveTaskList
|
||
{
|
||
// --- Header Fields ---
|
||
// NOTE: union
|
||
public byte[] header = new byte[TaskInterfaceConstants.TASK_ACTIVE_LIST_HEADER_LEN];
|
||
|
||
public byte m_uTaskCount // number of tasks
|
||
{
|
||
get => header[0];
|
||
set => header[0] = value;
|
||
}
|
||
|
||
public byte m_uUsedCount // used count
|
||
{
|
||
get => header[1];
|
||
set => header[1] = value;
|
||
}
|
||
|
||
public ushort m_Version // version
|
||
{
|
||
get => BitConverter.ToUInt16(header, 2);
|
||
set
|
||
{
|
||
byte[] bytes = BitConverter.GetBytes(value);
|
||
header[2] = bytes[0];
|
||
header[3] = bytes[1];
|
||
}
|
||
}
|
||
|
||
public byte m_uTopShowTaskCount // top show task count
|
||
{
|
||
get => header[4];
|
||
set => header[4] = value;
|
||
}
|
||
|
||
public byte m_uListState // list state
|
||
{
|
||
get => header[5];
|
||
set => header[5] = value;
|
||
}
|
||
public byte m_uTopHideTaskCount // top hide task count
|
||
{
|
||
get => header[6];
|
||
set => header[6] = value;
|
||
}
|
||
|
||
private byte _flags // simulate bitfield (1 bit + 7 bits)
|
||
{
|
||
get => header[7];
|
||
set => header[7] = value;
|
||
}
|
||
|
||
public bool m_uMaxSimultaneousCount
|
||
{
|
||
get => (_flags & 0x01) != 0;
|
||
set
|
||
{
|
||
if (value) _flags |= 0x01;
|
||
else _flags &= unchecked((byte)~0x01);
|
||
}
|
||
}
|
||
|
||
public byte m_uTitleTaskCount
|
||
{
|
||
get => (byte)((_flags & 0xFE) >> 1);
|
||
set => _flags = (byte)((_flags & 0x01) | ((value & 0x7F) << 1));
|
||
}
|
||
|
||
// ActiveTaskEntry m_TaskEntries[TASK_ACTIVE_LIST_MAX_LEN];
|
||
public ActiveTaskEntry[] m_TaskEntries = new ActiveTaskEntry[TaskInterfaceConstants.TASK_ACTIVE_LIST_MAX_LEN];
|
||
|
||
// --- Methods ---
|
||
public void ReadFromBuffer(byte[] buffer)
|
||
{
|
||
// NOTE: union
|
||
// cause C++ use union here, header use same data slot with the rest of properties like m_uTaskCount etc.
|
||
// so, we dont need to read other properties again, just copy the header part
|
||
int offset = 0;
|
||
Array.Copy(buffer, offset, header, 0, header.Length);
|
||
offset += header.Length;
|
||
|
||
// m_uTaskCount = buffer[offset++];
|
||
// m_uUsedCount = buffer[offset++];
|
||
// m_Version = BitConverter.ToUInt16(buffer, offset);
|
||
// offset += 2;
|
||
// m_uTopShowTaskCount = buffer[offset++];
|
||
// m_uListState = buffer[offset++];
|
||
// m_uTopHideTaskCount = buffer[offset++];
|
||
// _flags = buffer[offset++];
|
||
|
||
for (int i = 0; i < m_uTaskCount; i++)
|
||
{
|
||
ActiveTaskEntry entry = new ActiveTaskEntry();
|
||
entry.ReadFromBuffer(buffer, ref offset);
|
||
m_TaskEntries[i] = entry;
|
||
}
|
||
}
|
||
|
||
// void UpdateTaskMask(unsigned long& ulMask) const;
|
||
// void UpdateUsedCount();
|
||
void RealignTask(ActiveTaskEntry pEntry, byte uReserve)
|
||
{
|
||
// TODO: implement RealignTask logic
|
||
// // unsigned char uCurIndex = static_cast<unsigned char>(pEntry - m_TaskEntries);
|
||
// byte uCurIndex = (byte)Array.IndexOf(m_TaskEntries, pEntry);
|
||
//
|
||
// uint ulCount = (uint)m_uTaskCount - uCurIndex; // ʣ���������
|
||
//
|
||
// if (ulCount == 0) return; // ���һ������
|
||
//
|
||
// byte uEmptyCount = 0;
|
||
// for (int uEmpty = uCurIndex; uEmpty < TaskInterfaceConstants.TASK_ACTIVE_LIST_MAX_LEN; uEmpty++)
|
||
// {
|
||
// if (m_TaskEntries[uEmpty].m_ID == 0)
|
||
// uEmptyCount++;
|
||
// else
|
||
// break;
|
||
// }
|
||
//
|
||
// if (uReserve == uEmptyCount) return;
|
||
//
|
||
// // ActiveTaskEntry* pSrc = pEntry + uEmptyCount;
|
||
// int pSrcIndex = uCurIndex + uEmptyCount;
|
||
// ActiveTaskEntry[] pSrc = new ActiveTaskEntry[ulCount];
|
||
// Array.Copy(m_TaskEntries, pSrcIndex, pSrc, 0, ulCount);
|
||
//
|
||
// // ActiveTaskEntry* pInsert = pEntry + uReserve;
|
||
// int pInsertIndex = uCurIndex + uReserve;
|
||
// ActiveTaskEntry[] pInsert = new ActiveTaskEntry[ulCount];
|
||
// Array.Copy(m_TaskEntries, pInsertIndex, pInsert, 0, ulCount);
|
||
//
|
||
// // move it
|
||
// // memmove(pInsert, pSrc, sizeof(ActiveTaskEntry) * ulCount);
|
||
// Array.Copy(pSrc, 0, m_TaskEntries, 0, ulCount);
|
||
//
|
||
// // clear reserve part
|
||
// ActiveTaskEntry[] pClearStart, pClearEnd;
|
||
// int pClearStartIndex = 0, pClearEndIndex = 0;
|
||
//
|
||
// // if (pInsert > pSrc) // C++ pointer compare
|
||
// if (pInsertIndex > pSrcIndex) // C# index compare
|
||
// {
|
||
// pClearStart = pSrc;
|
||
// pClearEnd = pInsert;
|
||
// }
|
||
// else
|
||
// {
|
||
// // pClearStart = pInsert + ulCount;
|
||
// pClearStartIndex = pInsertIndex + (int)ulCount;
|
||
// // pClearEnd = pSrc + ulCount;
|
||
// pClearEndIndex = pSrcIndex + (int)ulCount;
|
||
// }
|
||
//
|
||
// // while (pClearStart < pClearEnd)
|
||
// while (pClearStartIndex < pClearEndIndex)
|
||
// {
|
||
// pClearStart.m_ulTemplAddr = 0;
|
||
// pClearStart.m_ID = 0;
|
||
// pClearStart++;
|
||
// }
|
||
//
|
||
// // calc gap
|
||
// unsigned char uGap = static_cast<unsigned char>(pInsert - pSrc);
|
||
// unsigned long i = 0;
|
||
//
|
||
// for (; i < static_cast<unsigned long>(uCurIndex); i++)
|
||
// {
|
||
// // Parent, Prev��uCurIndex
|
||
// ActiveTaskEntry& CurEntry = m_TaskEntries[i];
|
||
//
|
||
// if(!CurEntry.m_ID)
|
||
// continue;
|
||
//
|
||
// if (CurEntry.m_ChildIndex != 0xff && CurEntry.m_ChildIndex >= uCurIndex)
|
||
// CurEntry.m_ChildIndex += uGap;
|
||
// if (CurEntry.m_NextSblIndex != 0xff && CurEntry.m_NextSblIndex >= uCurIndex)
|
||
// CurEntry.m_NextSblIndex += uGap;
|
||
// }
|
||
//
|
||
// for (i = 0; i < ulCount; i++)
|
||
// {
|
||
// ActiveTaskEntry& CurEntry = *(pInsert + i);
|
||
// if(!CurEntry.m_ID)
|
||
// continue;
|
||
//
|
||
// if (CurEntry.m_ParentIndex != 0xff && CurEntry.m_ParentIndex >= uCurIndex)
|
||
// CurEntry.m_ParentIndex += uGap;
|
||
// if (CurEntry.m_PrevSblIndex != 0xff && CurEntry.m_PrevSblIndex >= uCurIndex)
|
||
// CurEntry.m_PrevSblIndex += uGap;
|
||
// if (CurEntry.m_ChildIndex != 0xff)
|
||
// CurEntry.m_ChildIndex += uGap;
|
||
// if (CurEntry.m_NextSblIndex != 0xff)
|
||
// CurEntry.m_NextSblIndex += uGap;
|
||
// }
|
||
}
|
||
public void ClearTask(TaskInterface pTask, ActiveTaskEntry pEntry, bool bRemoveItem)
|
||
{
|
||
RecursiveClearTask(pTask, pEntry, bRemoveItem, true, true);
|
||
RealignTask(pEntry, 0);
|
||
}
|
||
|
||
void RecursiveClearTask(
|
||
TaskInterface pTask,
|
||
ActiveTaskEntry pEntry,
|
||
bool bRemoveItem,
|
||
bool bRemoveAcquired,
|
||
bool bClearTask)
|
||
{
|
||
while (pEntry.m_ChildIndex != 0xff)
|
||
{
|
||
RecursiveClearTask(
|
||
pTask,
|
||
m_TaskEntries[pEntry.m_ChildIndex],
|
||
bRemoveItem,
|
||
bRemoveAcquired,
|
||
bClearTask);
|
||
}
|
||
|
||
ATaskTempl pTempl = pEntry.GetTempl();
|
||
|
||
// ȥ����õ���Ʒ
|
||
#if _TASK_CLIENT
|
||
if (bRemoveItem && pTempl != null)
|
||
{
|
||
if (bRemoveAcquired || pTempl.m_FixedData.m_bClearAcquired) pTempl.RemoveAcquiredItem(pTask, bClearTask, false);
|
||
pTempl.TakeAwayGivenItems(pTask);
|
||
}
|
||
#endif
|
||
|
||
ushort uTaskId = pEntry.m_ID;
|
||
|
||
pEntry.m_ulTemplAddr = 0;
|
||
pEntry.m_ID = 0;
|
||
|
||
if (m_uTaskCount > 0)
|
||
m_uTaskCount--;
|
||
else
|
||
// TaskInterface::WriteLog(pTask->GetPlayerId(), uTaskId, 0, "ClearTask, TaskCount == 0");
|
||
|
||
if (pEntry.m_ParentIndex != 0xff)
|
||
{
|
||
if (pEntry.m_PrevSblIndex != 0xff)
|
||
m_TaskEntries[pEntry.m_PrevSblIndex].m_NextSblIndex = pEntry.m_NextSblIndex;
|
||
else
|
||
m_TaskEntries[pEntry.m_ParentIndex].m_ChildIndex = pEntry.m_NextSblIndex;
|
||
if (pEntry.m_NextSblIndex != 0xff) m_TaskEntries[pEntry.m_NextSblIndex].m_PrevSblIndex = pEntry.m_PrevSblIndex;
|
||
}
|
||
else
|
||
{
|
||
if (pTempl != null)
|
||
{
|
||
if (pTempl.m_FixedData.m_bHidden)
|
||
{
|
||
if (m_uTopHideTaskCount > 0)
|
||
m_uTopHideTaskCount--;
|
||
}
|
||
else if(pTempl.m_FixedData.m_bDisplayInTitleTaskUI)
|
||
{
|
||
if (m_uTitleTaskCount > 0)
|
||
m_uTitleTaskCount--;
|
||
}
|
||
else
|
||
{
|
||
if (m_uTopShowTaskCount > 0)
|
||
m_uTopShowTaskCount--;
|
||
}
|
||
|
||
if (m_uUsedCount >= pTempl.m_uDepth)
|
||
m_uUsedCount -= pTempl.m_uDepth;
|
||
else
|
||
{
|
||
// TaskInterface::WriteLog(pTask->GetPlayerId(), uTaskId, 0, "ClearTask, No Enough Used Count");
|
||
m_uUsedCount = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public ActiveTaskEntry GetEntry(uint ulId)
|
||
{
|
||
for (int i = 0; i < m_uTaskCount; i++)
|
||
if (m_TaskEntries[i].m_ID == ulId)
|
||
return m_TaskEntries[i];
|
||
|
||
return null;
|
||
}
|
||
// void ClearChildrenOf(TaskInterface* pTask, ActiveTaskEntry* pParent, bool bRemoveItem = true);
|
||
// ActiveTaskEntry* GetEntry(unsigned long ulId)
|
||
// {
|
||
// for (unsigned char i = 0; i < m_uTaskCount; i++)
|
||
// if (m_TaskEntries[i].m_ID == ulId)
|
||
// return &m_TaskEntries[i];
|
||
//
|
||
// return NULL;
|
||
// }
|
||
// void RemoveAll()
|
||
// {
|
||
// unsigned short ver = m_Version;
|
||
// memset(this, 0, sizeof(*this));
|
||
// m_Version = ver;
|
||
// }
|
||
// bool IsValid() const { return m_uTaskCount <= TASK_ACTIVE_LIST_MAX_LEN; }
|
||
// bool IsTimeMarkUpdate() const { return (m_uListState & TLIST_STATE_UPDATE_TIME_MARK) != 0; }
|
||
// void SetTimeMarkUpdate() { m_uListState |= TLIST_STATE_UPDATE_TIME_MARK; }
|
||
// void ClearTimeMarkUpdate() { m_uListState &= ~TLIST_STATE_UPDATE_TIME_MARK; }
|
||
// int GetMaxSimultaneousCount() {return m_uMaxSimultaneousCount ? TASK_MAX_SIMULTANEOUS_COUT : TASK_DEFAULT_MAX_SIMULTANEOUS_COUT;}
|
||
public void ExpandMaxSimultaneousCount()
|
||
{
|
||
m_uMaxSimultaneousCount = true;
|
||
}
|
||
};
|
||
} |