Page 1 of 1

[mod] Scheduler [scheduler]

Posted: Sat Aug 09, 2014 18:27
by aldobr
Small untested code for scheduler functions

Code: Select all

-- Copyright (C) AldoBr - WTFPL
-- Usefull routines for scheduling repetitive tasks

-- Scheduler object
function createscheduler()
	return {

		-- Number of ticks since game started
		timerticks = 0,

		-- Table containning the events
		events = { },

		-- Last Id used
		lastschedulerentryid = -1,

		-- Get a new ID for the event	
		createnewschedulerentryid = function(pThis)
			lastschedulerentryid = lastschedulerentryid + 1
			return lastschedulerentryid
		end,

		-- Scheduler entry object
		-- pTime is the time that the event will take place first (in number of timer ticks since server started)
		-- pRepeatTimes is the number of times the event should be repeated (-1 to repeat indefinitely)
		-- pRepeatInterval is the interval in timer ticks between each repetition 
		-- pFunction is the function that should be called when the event takes place
		createevent = function(pThis, pTime, pRepeatTimes, pRepeatInterval, pFunction)
			local id = createnewschedulerentryid()
			pThis.events[id] = {
				eventtime = pTime,
				eventrepeat = pRepeatTimes,
				eventinterval = pRepeatInterval,
				eventfunction = pFunction,
				processevent = function(aThis)
					if eventrepeat > 0 then	-- repeat is a positive integer, number of repetitions
						aThis:eventfunction()
						aThis.eventrepeat = aThis.eventrepeat - 1
						aThis.eventtime = aThis.eventtime + aThis.eventinterval
					elseif eventrepeat < 0 then -- repeat is a negative integer, repeat indefinitely
						aThis:eventfunction()
					elseif eventrepeat = 0 then -- repeat reached 0, remove event
						pThis.events[id] = nil
					end
				end
			}
			return id
		end,

		-- Deletes the event pointed to by pID
		deleteevent = function(pThis, pID)
			pThis.events[pID] = nil
		end

		-- Check events
		checkevents = function(pThis)
			for _, value in pairs(pThis.events) do
				if pThis.timerticks >= value.eventtime then
					value:processevent()
				end
			end
		end 

	}
end

-- Timer tick ammount of seconds
defaultschedulertimerticks = 60 -- tick each minute

-- Creates a default scheduler
defaultscheduler = createscheduler()

-- Function to activate the default scheduler in a minetest.after event
defaultschedulerfunction = function()
	defaultscheduler.timerticks = timerticks + 1
	defaultscheduler:checkevents()
	minetest.after(defaultschedulertimerticks, defaultschedulerfunction)
end

-- Setup the default scheduler
minetest.after(defaultschedulertimerticks, defaultschedulerfunction)
to use :

-- this will trigger a event five minutes later and keep repeating indefinitely each 5 minutes (-1 repeat means repeat indefinitely)
defaultscheduler:createevent(defaultscheduler.timerticks + 5, -1, 5, function print('5 minutes') end)

Code is untested. License is WTFPL.

Re: [mod] Scheduler [scheduler]

Posted: Sat Aug 09, 2014 18:30
by Krock
What's exatly the difference to globalsteps?

Re: [mod] Scheduler [scheduler]

Posted: Sat Aug 09, 2014 18:39
by aldobr
What global steps ? :P

Edit: ah that global step

http://dev.minetest.net/minetest.register_globalstep

well, its called by timertick (by default each timer ticks in 1 minute). can be repeated indefinitely or by a set ammount of times.

basically, its more flexible and imposes less load on the server (dont need to be called every server step).

Re: [mod] Scheduler [scheduler]

Posted: Sat Aug 09, 2014 19:44
by kaeza
While the intention is good, there are several alternatives already:
  • Global step callbacks.
  • `minetest.after'
  • Node timers (if your processing is based on nodes).
  • The first two coupled with coroutines (to keep state, e.g. to incrementally process something, see my fork of MAPP mod for an example).
TBH, GPL also detracts from projects like this; it doesn't allow it to be included in e.g. LGPL- or BSD-/MIT- licensed code, effectively limiting your user base for no reason.

Re: [mod] Scheduler [scheduler]

Posted: Sat Aug 09, 2014 20:02
by stu
To add to kaeza's suggested alternatives, there is also the builtin core.handle_async()
Personally, I prefer to handle these things in my own code for greater control but it is a nice idea all the same.

Re: [mod] Scheduler [scheduler]

Posted: Sat Aug 09, 2014 20:33
by aldobr
kaeza wrote:While the intention is good, there are several alternatives already:
  • Global step callbacks.
Cannot be stoped in a simple manner. You cannot say "repeat 10 times, with 5 minutes waiting in between, then forget about it".
[*]`minetest.after'[/*]
Does not auto-repeat neither keep track of how many times it repeated. This scheduler is actually a generalization of this approach.
[*]Node timers (if your processing is based on nodes).[/*]
Cannot be stoped in a simple manner.
[*]The first two coupled with coroutines (to keep state, e.g. to incrementally process something, see my fork of MAPP mod for an example).[/*]
[/list]
I dont see why we would need global step to implement a scheduler. If i understood correctly, gobal step is called every single game loop in the engine. This is costly.
TBH, GPL also detracts from projects like this; it doesn't allow it to be included in e.g. LGPL- or BSD-/MIT- licensed code, effectively limiting your user base for no reason.
I can use other license.