mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 03:25:23 +09:00
Add startable legacy code
This commit is contained in:
@@ -12,16 +12,16 @@ end
|
||||
local setAdminAsync = Async.register(setAdmin)
|
||||
setAdminAsync(game.players[1], true)
|
||||
|
||||
@usage-- Functions stored in global table
|
||||
@usage-- Functions stored in storage table
|
||||
-- This can be used to create run time configurable callbacks, although this is not recommended
|
||||
global.myCallback = Async.register(function()
|
||||
storage.myCallback = Async.register(function()
|
||||
game.print("I got called!")
|
||||
end)
|
||||
|
||||
-- The function can be called just like any other function
|
||||
global.myCallback()
|
||||
storage.myCallback()
|
||||
|
||||
@usage-- Creating singleton tasks (best used with global data)
|
||||
@usage-- Creating singleton tasks (best used with storage data)
|
||||
-- This allows you to split large tasks across multiple ticks to prevent lag
|
||||
local myTask = Async.register(function(remainingWork)
|
||||
game.print("Working... " .. remainingWork)
|
||||
@@ -68,7 +68,7 @@ fillTableAsync({}, "foo", 10) -- Puts 10 lots of foo into the table
|
||||
]]
|
||||
|
||||
local Clustorio = require("modules/clusterio/api")
|
||||
local ExpUtil = require("modules.exp_util.common") --- @dep exp_util.common
|
||||
local ExpUtil = require("modules/exp_util/common")
|
||||
|
||||
local Async = {
|
||||
status = {}, -- Stores the allowed return types from a async function
|
||||
@@ -286,10 +286,10 @@ local function on_tick()
|
||||
end
|
||||
|
||||
--- On load, check the queue status and update the pressure values
|
||||
local function on_load()
|
||||
if global.exp_async_next == nil then return end
|
||||
async_next = global.exp_async_next
|
||||
async_queue = global.exp_async_queue
|
||||
function Async.on_load()
|
||||
if storage.exp_async_next == nil then return end
|
||||
async_next = storage.exp_async_next
|
||||
async_queue = storage.exp_async_queue
|
||||
for _, pending in ipairs(async_next) do
|
||||
local count = Async._queue_pressure[pending.id]
|
||||
if count == nil then
|
||||
@@ -310,17 +310,15 @@ local function on_load()
|
||||
end
|
||||
end
|
||||
|
||||
--- On server startup initialise the global data
|
||||
local function on_server_startup()
|
||||
if global.exp_async_next == nil then
|
||||
global.exp_async_next = {}
|
||||
global.exp_async_queue = {}
|
||||
--- On server startup initialise the storage data
|
||||
function Async.on_init()
|
||||
if storage.exp_async_next == nil then
|
||||
storage.exp_async_next = {}
|
||||
storage.exp_async_queue = {}
|
||||
end
|
||||
on_load()
|
||||
Async.on_load()
|
||||
end
|
||||
|
||||
Async.on_load = on_load
|
||||
Async.on_init = on_server_startup
|
||||
Async.events[defines.events.on_tick] = on_tick
|
||||
Async.events[Clustorio.events.on_server_startup] = on_server_startup
|
||||
Async.events[Clustorio.events.on_server_startup] = Async.on_init
|
||||
return Async
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
]]
|
||||
|
||||
local assert = assert
|
||||
--local getlocal = debug.getlocal
|
||||
--local getupvalue = debug.getupvalue
|
||||
local getinfo = debug.getinfo
|
||||
local traceback = debug.traceback
|
||||
local floor = math.floor
|
||||
@@ -14,7 +12,7 @@ local concat = table.concat
|
||||
|
||||
local Common = {
|
||||
--- A large mapping of colour rgb values by their common name
|
||||
color = require 'modules.exp_util.include.color'
|
||||
color = require("modules/exp_util/include/color")
|
||||
}
|
||||
|
||||
--- Raise an error if we are not in runtime
|
||||
@@ -35,40 +33,50 @@ function Common.assert_not_closure(func)
|
||||
end
|
||||
end]]
|
||||
|
||||
--- Check the type of a value, also considers LuaObject.object_name and metatable.__class
|
||||
--- Returns true when the check failed and an error should be raised
|
||||
local function check_type(value, type_name)
|
||||
local value_type = type(value) --[[@as string]]
|
||||
if value_type == "userdata" then
|
||||
if type_name == "userdata" then
|
||||
return false, value_type
|
||||
end
|
||||
value_type = value.object_name
|
||||
elseif value_type == "table" then
|
||||
if type_name == "table" then
|
||||
return false, value_type
|
||||
end
|
||||
local mt = getmetatable(value)
|
||||
if mt and mt.__class then
|
||||
value_type = mt.__class
|
||||
end
|
||||
end
|
||||
return value == nil or value_type ~= type_name, value_type
|
||||
end
|
||||
|
||||
local assert_type_fmt = "%s expected to be of type %s but got %s"
|
||||
--- Raise an error if the type of a value is not as expected
|
||||
-- @param value The value to assert the type of
|
||||
-- @tparam string type_name The name of the type that value is expected to be
|
||||
-- @tparam[opt=Value] string value_name The name of the value being tested, this is included in the error message
|
||||
function Common.assert_type(value, type_name, value_name)
|
||||
if value == nil or type(value) ~= type_name then
|
||||
error(assert_type_fmt:format(value_name or "Value", type_name, type(value)), 2)
|
||||
local failed, actual_type = check_type(value, type_name)
|
||||
if failed then
|
||||
error(assert_type_fmt:format(value_name or "Value", type_name, actual_type), 2)
|
||||
end
|
||||
end
|
||||
|
||||
local assert_argument_fmt = "Bad argument #%d to %s; %s expected to be of type %s but got %s"
|
||||
--[[--- Raise an error if the type of any argument is not as expected, can be costly, for frequent callers see assert_argument_type
|
||||
-- @tparam string ... The type for each argument of the calling function
|
||||
function Common.assert_argument_types(...)
|
||||
local arg_types = {...}
|
||||
local info = getinfo(2, "nu")
|
||||
for arg_index = 1, info.nparams do
|
||||
local arg_name, arg_value = getlocal(2, arg_index)
|
||||
if arg_types[arg_index] and (arg_value == nil or type(arg_value) ~= arg_types[arg_index]) then
|
||||
error(assert_argument_fmt:format(arg_index, info.name or "<anonymous>", arg_name, arg_types[arg_index]), 2)
|
||||
end
|
||||
end
|
||||
end]]
|
||||
|
||||
--- Raise an error if the type of any argument is not as expected, more performant than assert_argument_types, but requires more manual input
|
||||
-- @param arg_value The argument to assert the type of
|
||||
-- @tparam string type_name The name of the type that value is expected to be
|
||||
-- @tparam number arg_index The index of the argument being tested, this is included in the error message
|
||||
-- @tparam[opt=Argument] string arg_name The name of the argument being tested, this is included in the error message
|
||||
function Common.assert_argument_type(arg_value, type_name, arg_index, arg_name)
|
||||
if arg_value == nil or type(arg_value) ~= type_name then
|
||||
local failed, actual_type = check_type(arg_value, type_name)
|
||||
if failed then
|
||||
local func_name = getinfo(2, "n").name or "<anonymous>"
|
||||
error(assert_argument_fmt:format(arg_index, func_name, arg_name or "Argument", type_name), 2)
|
||||
error(assert_argument_fmt:format(arg_index, func_name, arg_name or "Argument", type_name, actual_type), 2)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -110,14 +118,14 @@ end
|
||||
-- @treturn string The relative filepath of the given stack frame
|
||||
function Common.safe_file_path(level)
|
||||
level = level or 1
|
||||
return getinfo(level+1, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5)
|
||||
return getinfo(level+1, 'S').short_src:sub(10, -5)
|
||||
end
|
||||
|
||||
--- Returns the name of your module, this assumes your module is stored within /modules (which it is for clustorio)
|
||||
-- @tparam[opt=1] number level The level of the stack to get the module of, a value of 1 is the caller of this function
|
||||
-- @treturn string The name of the module at the given stack frame
|
||||
function Common.get_module_name(level)
|
||||
local file_within_module = getinfo((level or 1)+1, 'S').source:match('^.+/currently%-playing/modules/(.+)$'):sub(1, -5)
|
||||
local file_within_module = getinfo((level or 1)+1, 'S').short_src:sub(18, -5)
|
||||
local next_slash = file_within_module:find("/")
|
||||
if next_slash then
|
||||
return file_within_module:sub(1, next_slash-1)
|
||||
@@ -132,8 +140,8 @@ end
|
||||
-- @treturn string The name of the function at the given stack frame or provided as an argument
|
||||
function Common.get_function_name(func, raw)
|
||||
local debug_info = getinfo(func, "Sn")
|
||||
local safe_source = debug_info.source:match('^.+/currently%-playing/(.+)$')
|
||||
local file_name = safe_source and safe_source:sub(1, -5) or debug_info.source
|
||||
local safe_source = debug_info.source:find('__level__')
|
||||
local file_name = safe_source == 1 and debug_info.short_src:sub(10, -5) or debug_info.source
|
||||
local func_name = debug_info.name or debug_info.linedefined
|
||||
if raw then return file_name .. ":" .. func_name end
|
||||
return "<" .. file_name .. ":" .. func_name .. ">"
|
||||
|
||||
@@ -25,7 +25,7 @@ end
|
||||
]]
|
||||
|
||||
local FloatingText = {}
|
||||
FloatingText.color = require("modules.exp_util.include.color")
|
||||
FloatingText.color = require("modules/exp_util/include/color")
|
||||
|
||||
--- Print Messages.
|
||||
-- Short lived messages that last at most a few seconds
|
||||
@@ -177,4 +177,4 @@ function FloatingText.create_tag_as_player(player, text, alt_mode)
|
||||
}
|
||||
end
|
||||
|
||||
return FloatingText
|
||||
return FloatingText
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--luacheck:ignore global require
|
||||
|
||||
local package = require 'modules.exp_util.include.package'
|
||||
local package = require("modules/exp_util/include/package")
|
||||
local loaded = package.loaded
|
||||
local _require = require
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"load": [
|
||||
"include/package.lua",
|
||||
"include/require.lua",
|
||||
"global.lua",
|
||||
"storage.lua",
|
||||
"async.lua"
|
||||
],
|
||||
"require": [
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
--[[-- Util Module - Global
|
||||
- Provides a method of using global with the guarantee that keys will not conflict
|
||||
@core Global
|
||||
@alias Global
|
||||
--[[-- Util Module - Storage
|
||||
- Provides a method of using storage with the guarantee that keys will not conflict
|
||||
@core Storage
|
||||
@alias Storage
|
||||
|
||||
@usage--- Drop in boiler plate:
|
||||
-- Below is a drop in boiler plate which ensures your global access will not conflict with other modules
|
||||
local global = {}
|
||||
Global.register(global, function(tbl)
|
||||
global = tbl
|
||||
-- Below is a drop in boiler plate which ensures your storage access will not conflict with other modules
|
||||
local storage = {}
|
||||
Storage.register(storage, function(tbl)
|
||||
storage = tbl
|
||||
end)
|
||||
|
||||
@usage--- Registering new global tables:
|
||||
@usage--- Registering new storage tables:
|
||||
-- The boiler plate above is not recommend because it is not descriptive in its function
|
||||
-- Best practice is to list out all variables you are storing in global and their function
|
||||
-- Best practice is to list out all variables you are storing in storage and their function
|
||||
local MyModule = {
|
||||
public_data = {} -- Stores data which other modules can access
|
||||
}
|
||||
|
||||
local private_data = {} -- Stores data which other modules cant access
|
||||
local more_private_data = {} -- Stores more data which other modules cant access
|
||||
-- You can not store a whole module in global because not all data types are serialisable
|
||||
Global.register({
|
||||
-- You can not store a whole module in storage because not all data types are serialisable
|
||||
Storage.register({
|
||||
MyModule.public_data,
|
||||
private_data,
|
||||
more_private_data
|
||||
}, function(tbl)
|
||||
-- You can also use this callback to set metatable on class instances you have stored in global
|
||||
-- You can also use this callback to set metatable on class instances you have stored in storage
|
||||
MyModule.public_data = tbl[1]
|
||||
private_data = tbl[2]
|
||||
more_private_data = tbl[3]
|
||||
@@ -34,26 +34,26 @@ end)
|
||||
]]
|
||||
|
||||
local Clustorio = require("modules/clusterio/api")
|
||||
local ExpUtil = require("modules.exp_util.common")
|
||||
local ExpUtil = require("modules/exp_util/common")
|
||||
|
||||
local Global = {
|
||||
local Storage = {
|
||||
registered = {}, -- Map of all registered values and their initial values
|
||||
}
|
||||
|
||||
--- Register a new table to be stored in global, can only be called once per file, can not be called during runtime
|
||||
--- Register a new table to be stored in storage, can only be called once per file, can not be called during runtime
|
||||
-- @tparam table tbl The initial value for the table you are registering, this should be a local variable
|
||||
-- @tparam function callback The callback used to replace local references and metatables
|
||||
function Global.register(tbl, callback)
|
||||
function Storage.register(tbl, callback)
|
||||
ExpUtil.assert_not_runtime()
|
||||
ExpUtil.assert_argument_type(tbl, "table", 1, "tbl")
|
||||
ExpUtil.assert_argument_type(callback, "function", 2, "callback")
|
||||
|
||||
local name = ExpUtil.safe_file_path(2)
|
||||
if Global.registered[name] then
|
||||
error("Global.register can only be called once per file", 2)
|
||||
if Storage.registered[name] then
|
||||
error("Storage.register can only be called once per file", 2)
|
||||
end
|
||||
|
||||
Global.registered[name] = {
|
||||
Storage.registered[name] = {
|
||||
init = tbl,
|
||||
callback = callback
|
||||
}
|
||||
@@ -61,41 +61,40 @@ end
|
||||
|
||||
--- Register a metatable which will be automatically restored during on_load
|
||||
-- @tparam string name The name of the metatable to register, must be unique within your module
|
||||
function Global.register_metatable(name, tbl)
|
||||
function Storage.register_metatable(name, tbl)
|
||||
local module_name = ExpUtil.get_module_name(2)
|
||||
script.register_metatable(module_name.."."..name, tbl)
|
||||
end
|
||||
|
||||
--- Restore aliases on load, we do not need to initialise data during this event
|
||||
function Global.on_load()
|
||||
local globals = global.exp_global
|
||||
if globals == nil then return end
|
||||
for name, data in pairs(Global.registered) do
|
||||
if globals[name] ~= nil then
|
||||
data.callback(globals[name])
|
||||
function Storage.on_load()
|
||||
local exp_storage = storage.exp_storage
|
||||
if exp_storage == nil then return end
|
||||
for name, info in pairs(Storage.registered) do
|
||||
if exp_storage[name] ~= nil then
|
||||
info.callback(exp_storage[name])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Event Handler, sets initial values if needed and calls all callbacks
|
||||
local function on_server_startup()
|
||||
local globals = global.exp_global
|
||||
if globals == nil then
|
||||
globals = {}
|
||||
global.exp_global = globals
|
||||
function Storage.on_init()
|
||||
local exp_storage = storage.exp_storage
|
||||
if exp_storage == nil then
|
||||
exp_storage = {}
|
||||
storage.exp_storage = exp_storage
|
||||
end
|
||||
|
||||
for name, data in pairs(Global.registered) do
|
||||
if globals[name] == nil then
|
||||
globals[name] = data.init
|
||||
for name, info in pairs(Storage.registered) do
|
||||
if exp_storage[name] == nil then
|
||||
exp_storage[name] = info.init
|
||||
end
|
||||
data.callback(globals[name])
|
||||
info.callback(exp_storage[name])
|
||||
end
|
||||
end
|
||||
|
||||
Global.on_init = on_server_startup
|
||||
Global.events = {
|
||||
[Clustorio.events.on_server_startup] = on_server_startup
|
||||
Storage.events = {
|
||||
[Clustorio.events.on_server_startup] = Storage.on_init
|
||||
}
|
||||
|
||||
return Global
|
||||
return Storage
|
||||
Reference in New Issue
Block a user