• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!
  • New resources must be posted under Resources tab. A discussion thread will be created automatically, you can't open threads manually anymore.

[Lib] Function Queue using Edited Snake's Thread.

tarjei

Necronian Engineer
Joined
May 25, 2008
Messages
505
Reaction score
126
Location
Poland
Hi everyone, I decided to post it,( probably noone will use it anyway) but people that comes here to lear shall have some examples that I have when I was starting coming here. So Its time for a payback. :)

Function Queue: Its simple, sometimes we want to execute few functions in specific order with delays. its syntax may look ugly like:

Code:
function action1(arg)
   --dosmoehting
end
function action2(arg)
   --dosmoehting
end
function action3(arg)
   --dosmoehting
end
function action4(arg)
   --dosmoehting
end
addEvent(action1,1000,arg)
addEvent(action2,1000,arg)
addEvent(action3,1000,arg)
addEvent(action4,1000,arg)
arg - arguments passed to function.

Belive me, when you want to make your code more complexed (whatever it is starting from simplme looped messageing ending at complexed events) it starting to be a big mess.

So I decided to make library using Snake's Thread lib that he agreed to post in my thread about metamethods - I will repost it here. But first a sample.

I want my code to broadcast few messages in some period of time. But not just once. I want to call this queue whenever I want to without using addEvent stuff everytime I need It.

Code:
	local function broadcast(text) doBroadcastMessage(text, MESSAGE_STATUS_WARNING) end
	local BroadcastQueue = FuncQueue:new()
	for i = 0, 4 do
		BroadcastQueue:addFunction(broadcast,i*2*1000*60, "Event starts in |TIME| minutes.")
	end	
	BroadCastQueue:start()
So whenever we call :start method it launch this specific function queue we defined. I find it usefull especially when Im creating more complexed queues that should be called few times or until event is running.

Now the libraries.

Thread.lua: --> Creadits go to Snake.
Code:
Thread = {}
Thread.__index = Thread
 
 
function Thread:new()
	local thread =
	{
		id 		= 0,
		cid		= 0,
 
		delay 		= 0,
		callback	= {},
		loop = false
	}
	setmetatable(thread, Thread)
	self.__index = self
	return thread
end
 
 
function Thread:start()
	if (not self.callback) then
		error('[Thread:start] Could not start thread.')
	end
 
	self.id = addEvent(self:work(), self.delay)
end
 
function Thread:setCallback(func,delay, ...)
		self.callback = {func = func, arg = arg, delay = delay}
end
function Thread:setDelay(d)
	self.callback.delay = d
end
function Thread:enableLoop(enable)
	self.loop = enable
end
function Thread:stop()
	if (self.id <= 0) then
		error('[Thread:stop] Could not stop thread.')
	end
	stopEvent(self.id)
	self.id = 0
end
 
 
function Thread:work()
	return function() 
		if (self.cid > 0 and not isCreature(self.cid)) then
			self:stop()
		else
			if not(self.loop) then
			self.callback.func(unpack(self.callback.arg))
			else
			self.callback.func(unpack(self.callback.arg))
			self.id = addEvent(self:work(),self.callback.delay)
			end
		end
	end
end
FuncQueue.lua:
Code:
FuncQueue = {

}

function FuncQueue:new()
	local obj = {}
	obj.funcs = {}
	obj.currentId = 0
	
	obj.isPaused = false;
	obj.runningId = 0
	self.__index = self
	
	setmetatable(obj, self)
	return obj
end

function FuncQueue:addFunction( func,delay, ...)
	self.funcs[self.currentId + 1] = Thread:new()
	self.funcs[self.currentId + 1]:setCallback(func,delay,...)
	self.currentId = self.currentId + 1
end

function FuncQueue:run()
	return function()
	self.runningId = self.runningId + 1
	print(self.runningId.." ID")
	if self.funcs[self.runningId] == nil or self.isPaused then
		return 
	end
	local func, arg = nil, nil
	
	
	self.funcs[self.runningId]:work()()
	local nextcallback = self.funcs[self.runningId + 1]
	if nextcallback == nil then
	 return 
	end
	addEvent(self:run(), nextcallback.callback.delay)
	end
end
function FuncQueue:start()
	self:run()()
end
function FuncQueue:restart()
	self.runningId = 0
	self:start()
end
function FuncQueue:pause()
	self.isPaused = true
end
function FuncQueue:continue()
	self.isPaused = false
	self:start()
end
 
Back
Top