Timekeeper Mod v1.3
timekeeper (by sorcerykid)
Timekeeper acts as a centralized dispatcher for all time-sensitive routines, obviating the need for redundant timer implementations within each mod.
Repository:
https://bitbucket.org/sorcerykid/timekeeper
https://github.com/sorcerykid/timekeeper (mirror)
Download Archive (.zip)
Download Archive (.tar.gz)
Dependencies:
None.
Source Code License:
The MIT License (MIT)
Overview:
The Timekeeper class provides a simple and efficient means of executing code at regular intervals. The constructor itself is global, so typically it will be used in conjunction with entities.
- Timekeeper( this )
Instantiates and returns a new timekeeper object, with an optional meta table for use by callbacks (typically this will be a reference to the entity itself). Ideally the Timekeeper constructor will be called as soon as the LuaEntitySAO has been added to the environment.
Code: Select all
on_activate = function (self)
self.timekeeper = Timekeeper(self)
:
end,
- timekeeper.start( period, name, func, delay )
Starts a new timer with the given name and period. The callback will execute no sooner than the next server step. If the callback returns false, then the timer will be cancelled and removed from the queue. An optional delay can be specified to avoid concurrency with other running timers.
timekeeper.start_now( period, name, func )
Identical to timekeeper.start(), except the first iteration of the callback will be executed immediately.
timekeeper.clear( name )
Cancels an existing timer with the given name.
- this - the meta table that was originally passed to the constructor
- cycles - the number of cycles that have accrued, beginning at 1
- period - the interval between each cycle
- elapsed - the elapsed time for all cycles
- overrun - the overrun time from the last cycle
Code: Select all
on_step = function (self, dtime)
local timers = self.timekeeper.on_step(dtime)
:
end,
For convenience, a globaltimer singleton object is available for use by all mods. This can avoid the need to register multiple globalsteps when a simple timer mechanism is all that is required. In this case, the timer names must be prefixed with the mod name and a colon to avoid collisions.
The following method is available, but only at server startup:
- globaltimer.start( period, name, func, delay )
Starts a new global timer with the given name and period (name must be prefixed with the current mod name). The callback will execute no sooner than the first server step. An optional delay can be specified to avoid concurrency with other global timers.
- cycles - the number of cycles that have accrued, beginning at 1
- period - the interval between each cycle
- uptime - the elapsed time since server start
- overrun - the overrun time from the last cycle
Here is an example mod that displays the player's orientation at the bottom of the screen:
Code: Select all
local player_huds = { }
local dir_names = {
["N"] = "north",
["NE"] = "northeast",
["E"] = "east",
["SE"] = "southeast",
["S"] = "south",
["SW"] = "southwest",
["W"] = "west",
["NW"] = "northwest",
["U"] = "up",
["D"] = "down",
}
minetest.register_on_joinplayer( function( player )
local player_name = player:get_player_name( )
player_huds[ player_name ] = player:hud_add( {
hud_elem_type = "text",
text = "",
position = { x = 0.5, y = 1 },
scale = { x = -100, y = -100 },
number = 0xFFFFFF,
alignment = { x = 0, y = 0 },
offset = { x = 0, y = -105 }
} )
end )
minetest.register_on_leaveplayer( function( player )
player_huds[ player:get_player_name( ) ] = nil
end )
local function to_facing( dir )
local dx = math.floor( dir.x + 0.5 )
local dz = math.floor( dir.z + 0.5 )
if dx == 0 and dz == 0 then
return dir.y > 0 and "U" or "D"
else
return ( { [1] = "N", [0] = "", [-1] = "S" } )[ dz ] .. ( { [1] = "E", [0] = "", [-1] = "W" } )[ dx ]
end
end
globaltimer.start( 2.5, "sample_mod:update_hud", function ( cycles )
for _, player in ipairs( minetest.get_connected_players( ) ) do
local cur_dir = to_facing( player:get_look_dir( ) )
local player_name = player:get_player_name( )
player:hud_change( player_huds[ player_name ], "text", string.format( "You are facing %s", dir_names[ cur_dir ] ) )
end
end )