• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

PreemptiveMultitasking

Status
Not open for further replies.
Level 1
Joined
Jul 13, 2012
Messages
6
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:
8192 should be 8191 (there are 8192 indexes available, but the index range is 0-8191).

You should include an example on how this would be useful (I have a vague idea of what you could do with this, but it is easier to visualize with an example). Also, I don't believe this is the correct forum. For JASS submissions, we have a JASS resource forum.
 
Status
Not open for further replies.
Top