1
0
Fork 0
mirror of https://github.com/Reuh/anselme.git synced 2025-10-28 17:19:31 +00:00

Define injections from a game config.ans

This commit is contained in:
Étienne Fildadut 2022-01-15 02:48:53 +01:00
parent a56e159a7d
commit 6a5595ca04
2 changed files with 39 additions and 22 deletions

View file

@ -6,11 +6,11 @@ local anselme = {
-- api is incremented a each update which may break Lua API compatibility -- api is incremented a each update which may break Lua API compatibility
versions = { versions = {
save = 1, save = 1,
language = 21, language = 22,
api = 4 api = 5
}, },
--- version is incremented at each update --- version is incremented at each update
version = 22, version = 23,
--- currently running interpreter --- currently running interpreter
running = nil running = nil
} }
@ -226,6 +226,8 @@ local vm_mt = {
-- will load in path, in order: -- will load in path, in order:
-- * config.ans, which will be executed in the "config" namespace and may contains various optional configuration options: -- * config.ans, which will be executed in the "config" namespace and may contains various optional configuration options:
-- * language: string, built-in language file to load -- * language: string, built-in language file to load
-- * inject directory: string, directory that may contain "function start.ans", "checkpoint end.ans", etc. which content will be used to setup
-- the custom code injection methods like vm:injectfunctionstart
-- * anselme version: number, version of the anselme language this game was made for -- * anselme version: number, version of the anselme language this game was made for
-- * game version: any, version information of the game. Can be used to perform eventual migration of save with an old version in the main file. -- * game version: any, version information of the game. Can be used to perform eventual migration of save with an old version in the main file.
-- Always included in saved variables. -- Always included in saved variables.
@ -246,6 +248,7 @@ local vm_mt = {
-- get config -- get config
self.game = { self.game = {
language = self:eval("config.language"), language = self:eval("config.language"),
inject_directory = self:eval("config.inject directory"),
anselme_version = self:eval("config.anselme version"), anselme_version = self:eval("config.anselme version"),
game_version = self:eval("config.game version"), game_version = self:eval("config.game version"),
main_file = self:eval("config.main file"), main_file = self:eval("config.main file"),
@ -260,6 +263,16 @@ local vm_mt = {
local s, e = self:loadlanguage(self.game.language) local s, e = self:loadlanguage(self.game.language)
if not s then return s, e end if not s then return s, e end
end end
-- load injections
if self.game.inject_directory then
for _, inject in ipairs{"function start", "function end", "checkpoint start", "checkpoint end"} do
local f = io.open(path.."/"..self.game.inject_directory.."/"..inject..".ans", "r")
if f then
self.state.inject[inject:gsub(" ", "_")] = f:read("*a")
f:close()
end
end
end
-- load main file -- load main file
if self.game.main_file then if self.game.main_file then
local s, e = self:loadfile(path.."/"..self.game.main_file..".ans") local s, e = self:loadfile(path.."/"..self.game.main_file..".ans")
@ -268,7 +281,11 @@ local vm_mt = {
end end
-- load other files -- load other files
for _, item in ipairs(list_directory(path)) do for _, item in ipairs(list_directory(path)) do
if item:match("[^%.]") and item ~= "config.ans" and item ~= self.game.main_file..".ans" then if item:match("[^%.]") and
item ~= "config.ans" and
(self.game.main_file == nil or item ~= self.game.main_file..".ans") and
item ~= self.game.inject_directory
then
local p = path.."/"..item local p = path.."/"..item
local s, e local s, e
if is_directory(p) then if is_directory(p) then
@ -356,28 +373,28 @@ local vm_mt = {
-- can typically be used to define variables for every function like 👁️ -- can typically be used to define variables for every function like 👁️
-- return self -- return self
injectfunctionstart = function(self, code) injectfunctionstart = function(self, code)
self.state.inject.functionstart = code self.state.inject.function_start = code
return self return self
end, end,
--- same as injectfunctionstart, but inject code at the start of every checkpoint --- same as injectfunctionstart, but inject code at the start of every checkpoint
-- nil to disable -- nil to disable
-- return self -- return self
injectcheckpointstart = function(self, code) injectcheckpointstart = function(self, code)
self.state.inject.checkpointstart = code self.state.inject.checkpoint_start = code
return self return self
end, end,
--- same as injectfunctionstart, but inject code at the end of every function --- same as injectfunctionstart, but inject code at the end of every function
-- nil to disable -- nil to disable
-- return self -- return self
injectfunctionend = function(self, code) injectfunctionend = function(self, code)
self.state.inject.functionend = code self.state.inject.function_end = code
return self return self
end, end,
--- same as injectfunctionend, but inject code at the end of every checkpoint --- same as injectfunctionend, but inject code at the end of every checkpoint
-- nil to disable -- nil to disable
-- return self -- return self
injectcheckpointend = function(self, code) injectcheckpointend = function(self, code)
self.state.inject.checkpointend = code self.state.inject.checkpoint_end = code
return self return self
end, end,
@ -575,8 +592,8 @@ return setmetatable(anselme, {
-- global state -- global state
local state = { local state = {
inject = { inject = {
functionstart = nil, functionend = nil, function_start = nil, function_end = nil,
checkpointstart = nil, checkpointend = nil checkpoint_start = nil, checkpoint_end = nil
}, },
feature_flags = { feature_flags = {
["strip trailing spaces"] = true, ["strip trailing spaces"] = true,

View file

@ -199,13 +199,13 @@ local function parse_line(line, state, namespace)
table.insert(line.children, 1, { content = ":🔖=()", source = line.source }) table.insert(line.children, 1, { content = ":🔖=()", source = line.source })
end end
-- custom code injection -- custom code injection
if state.inject.functionstart then if state.inject.function_start then
for i, ll in ipairs(state.inject.functionstart) do for i, ll in ipairs(state.inject.function_start) do
table.insert(line.children, 1+i, ll) table.insert(line.children, 1+i, ll)
end end
end end
if state.inject.functionend then if state.inject.function_end then
for _, ll in ipairs(state.inject.functionend) do for _, ll in ipairs(state.inject.function_end) do
table.insert(line.children, ll) table.insert(line.children, ll)
end end
end end
@ -218,13 +218,13 @@ local function parse_line(line, state, namespace)
table.insert(line.children, 1, { content = ":🏁=0", source = line.source }) table.insert(line.children, 1, { content = ":🏁=0", source = line.source })
end end
-- custom code injection -- custom code injection
if state.inject.checkpointstart then if state.inject.checkpoint_start then
for i, ll in ipairs(state.inject.checkpointstart) do for i, ll in ipairs(state.inject.checkpoint_start) do
table.insert(line.children, 1+i, ll) table.insert(line.children, 1+i, ll)
end end
end end
if state.inject.checkpointend then if state.inject.checkpoint_end then
for _, ll in ipairs(state.inject.checkpointend) do for _, ll in ipairs(state.inject.checkpoint_end) do
table.insert(line.children, ll) table.insert(line.children, ll)
end end
end end
@ -458,8 +458,8 @@ local function parse(state, s, name, source)
-- build state proxy -- build state proxy
local state_proxy = { local state_proxy = {
inject = { inject = {
functionstart = nil, functionend = nil, function_start = nil, function_end = nil,
checkpointstart = nil, checkpointend = nil checkpoint_start = nil, checkpoint_end = nil
}, },
aliases = setmetatable({}, { __index = state.aliases }), aliases = setmetatable({}, { __index = state.aliases }),
variables = setmetatable({}, { __index = state.aliases }), variables = setmetatable({}, { __index = state.aliases }),
@ -480,9 +480,9 @@ local function parse(state, s, name, source)
global_state = state global_state = state
} }
-- parse injects -- parse injects
for _, inject in ipairs{"functionstart", "functionend", "checkpointstart", "checkpointend"} do for _, inject in ipairs{"function_start", "function_end", "checkpoint_start", "checkpoint_end"} do
if state.inject[inject] then if state.inject[inject] then
local inject_indented, err = parse_indented(state.inject[inject], nil, "injected "..inject) local inject_indented, err = parse_indented(state.inject[inject], nil, "injected "..inject:gsub("_", " "))
if not inject_indented then return nil, err end if not inject_indented then return nil, err end
state_proxy.inject[inject] = inject_indented state_proxy.inject[inject] = inject_indented
end end