JASS:
scope FreeIndex
{
private int count = 0;
private int slotCount = 0;
private int array buffSlots;
public int Get()
{
if (slotCount > 0)
{
slotCount--;
return buffSlots[slotCount+1];
}
else
{
count++;
return count;
}
}
public void Release(int id)
{
slotCount++;
buffSlots[slotCount] = id;
}
}
JASS:
library PreemptiveMultitasking
{
#include "TFreeIndex.j"
//SYS
private timer Timer = null;
private int TickCounter = 0;
private float Tick = 0.10;
public int DataId = 0;
private constant int TASK_STACK_MAX = 50;
private constant int TASK_MAX = 8191;
private string array Tasks[TASK_MAX][TASK_STACK_MAX]
private int array TasksDataId[TASK_MAX][TASK_STACK_MAX]
private int array TasksStackCounter;
private int TaskCounter = 0;
private hashtable hashmap = InitHashtable();
public void AddTask(float delay, string funcName, int funcDataId)
{
if(Timer == null)
{
Timer = CreateTimer();
TimerStart(Timer, Tick, true, lambda void(){
TickCounter++;
int id = LoadInteger(hashmap, 0, TickCounter);
if(id > 0)
{
RemoveSavedInteger(hashmap, 0, id);
FreeIndex_Release(id);
for(int i = 0; i < TasksStackCounter[id]; i++)
{
DataId = TasksDataId[id][i];
ExecuteFunc(Tasks[id][i]);
}
TaskCounter-=TasksStackCounter[id];
if(TaskCounter == 0)
{
PauseTimer(Timer);
DestroyTimer(Timer);
}
}
})
}
int taskId = LoadInteger(hashmap, 0, R2I(TickCounter + (delay / Tick)));
if(taskId == 0)
{
taskId = FreeIndex_Get();
SaveInteger(hashmap, 0, R2I(TickCounter + (delay / Tick)), taskId);
}
if(taskId < TASK_MAX)
{
if(TasksStackCounter[taskId] < TASK_STACK_MAX)
{
Tasks[taskId][TasksStackCounter[taskId]] = funcName;
TasksDataId[taskId][TasksStackCounter[taskId]] = funcDataId;
TasksStackCounter[taskId]++;
TaskCounter++;
}
else
{
BJDebugMsg("Reach the limit of number of task stack! \nTasksStackCounter: " + I2S(TasksStackCounter[taskId]));
}
}
else
{
FreeIndex_Release(taskId);
BJDebugMsg("Reach the limit of number of tasks! \ntaskId: " + I2S(taskId));
}
}
}
library PreemptiveMultitaskingTest uses PreemptiveMultitasking
{
private string array TestData
public void TestFunc()
{
BJDebugMsg(TestData[PreemptiveMultitasking_DataId]);
}
private int index = 0;
callback onInit()
{
TriggerSleepAction(1.0)
TimerStart(CreateTimer(), 1.0, true, lambda void(){
for(int i = 0; i < 400; i++)
{
TestData[i] = I2S(i);
PreemptiveMultitasking_AddTask(I2R(i), "PreemptiveMultitaskingTest_TestFunc", i);
}
index++;
BJDebugMsg("test round: " + I2S(index))
if (index == 50)
{
DestroyTimer(GetExpiredTimer());
}
});
}
}
Last edited: