3
0
mirror of https://github.com/britzl/monarch.git synced 2025-11-26 10:50:55 +01:00

rewrite editor script to use editor.transact api (#115)

This commit is contained in:
Jerakin
2025-10-06 13:39:13 +02:00
committed by GitHub
parent d91e44f12d
commit 18a8d1ea06
3 changed files with 196 additions and 89 deletions

View File

@@ -20,10 +20,15 @@ Or point to the ZIP file of a [specific release](https://github.com/britzl/monar
Using Monarch requires that screens are created in a certain way. Once you have one or more screens created you can start navigating between the screens. Using Monarch requires that screens are created in a certain way. Once you have one or more screens created you can start navigating between the screens.
## Editor Script ## Editor Script
Right click in on a`.gui` file in the outline and selected the menu item, it creates a `.collection` and a `.gui_script` with the same name as the `.gui` file. It adds the file with some basic setup done to them, adding the selected gui script to the created gui scene and in turns adds the gui scene to the newly created collection. Right click in on a`.gui`, `.gui_script` or `.collection` file in the outline and selected the menu item, it creates the other two file types with the same name as the selected file. It adds the file with some basic setup done to them, adding the selected gui script to the created gui scene and in turns adds the gui scene to the newly created collection.
You can also right click on directory to get the option to create a monarch scene from it, the directory should be empty (or only contain other monarch scene files).Use the option and it will create all three files inside of the directory.
<img src="/docs/editor_script.gif" width="200px"> <img src="/docs/editor_script.gif" width="200px">
You can use Monarchs editor script with your own custom templates. Create the template files you want, these are normal defold files. Then inside of your game.project file add a path to the files you created.
## Creating screens ## Creating screens
Monarch screens are created in individual collections and either loaded through collection proxies or created through collection factories. Monarch screens are created in individual collections and either loaded through collection proxies or created through collection factories.

View File

@@ -1,8 +1,13 @@
local M = {} local M = {}
local collection_template local collection_template
local gui_script_content local gui_script_template
local gui_file_content local gui_template
local function _log(msg)
io.stdout:write("ERROR:MONARCH: " .. msg .. "\n")
io.stdout:flush()
end
local function ends_with(str, ending) local function ends_with(str, ending)
return ending == "" or str:sub(-#ending) == ending return ending == "" or str:sub(-#ending) == ending
@@ -13,48 +18,143 @@ local function file_exists(name)
if f~=nil then io.close(f) return true else return false end if f~=nil then io.close(f) return true else return false end
end end
local function get_filename(path) local function get_filename(path)
local main, filename, extension = path:match("(.-)([^\\/]-%.?([^%.\\/]*))$") local main, filename, extension = path:match("(.-)([^\\/]-%.?([^%.\\/]*))$")
return main, filename return main, filename
end end
local function create_files(file_path) local function get_template(game_project_path)
-- The input file can be the "compiled" file. If they are they end with "c".
-- If they end with "c" remove the last charater.
local path = editor.get("/game.project", game_project_path)
if path == nil then
return
end
if ends_with(path, "c") then
return path:sub(1, -2)
end
return path
end
local function get_template_content(type_string)
local default_template = {
collection = collection_template,
gui_script = gui_script_template,
gui = gui_template,
}
local custom_template = {
collection = get_template("monarch.collection_template"),
gui_script = get_template("monarch.gui_script_template"),
gui = get_template("monarch.gui_template"),
}
local template = custom_template[type_string]
if template ~= nil then
local file = io.open("." .. template, "rb")
if file == nil then
_log("Could not read " .. type_string .. " template '" .. template .. "'")
return
end
local content = file:read("*a")
file:close()
return content
end
return default_template[type_string]
end
local function add_monarch_go(collection_file, gui_file, name)
return editor.tx.add(collection_file, "children", {
type = "go",
id = "monarch",
components = {
{
type = "component-reference",
id = name,
path = gui_file,
}
}
})
end
local function create_collection(collection_file, gui_file, name)
local _collection_content = get_template_content("collection")
if _collection_content == nil then
_log("Could not create colletion file at " .. gui)
return
end
local collection = io.open("." .. collection_file, "w")
if collection == nil then
_log("Could not create colletion file at " .. collection_file)
return
end
collection:write(_collection_content)
collection:close()
return add_monarch_go(collection_file, gui_file, name)
end
local function create_gui(gui_file, gui_script_file)
local gui_content = get_template_content("gui")
if gui_content == nil then
_log("Could not create gui file at " .. gui)
return
end
local gui = io.open("." .. gui_file, "w")
if gui == nil then
_log("Could not create gui file at " .. gui)
return
end
gui:write(gui_content)
gui:close()
return editor.tx.set(gui_file, "script", gui_script_file)
end
local function create_files(directory, name)
-- Construct paths -- Construct paths
local path = editor.get(file_path, "path") local target_collection_path = directory .. name .. ".collection"
local main, filename = get_filename(path) local target_gui_script_path = directory .. name .. ".gui_script"
local basename = filename:match("(.+)%..+") local target_gui_path = directory .. name .. ".gui"
local target_collection_path = "." .. main .. basename .. ".collection"
local target_gui_script_path = "." .. main .. basename .. ".gui_script"
local target_gui_path = "." .. main .. basename .. ".gui"
-- Create the files if they don't exists if not file_exists("." .. target_gui_script_path) then
if not file_exists(target_collection_path) then local gui_script_template_content = get_template_content("gui_script")
local collection_content = collection_template(path, basename) if gui_script_template_content == nil then
local collection = io.open(target_collection_path, "w") return
collection:write(collection_content) end
collection:close() local gui_script = io.open("." .. target_gui_script_path, "w")
end gui_script:write(gui_script_template_content)
if not file_exists(target_gui_script_path) then
local gui_script = io.open(target_gui_script_path, "w")
gui_script:write(gui_script_content)
gui_script:close() gui_script:close()
-- Put the gui_script path into the gui file
local gui_file = io.open("." .. path, "rb")
local gui_text = gui_file:read("*a")
gui_file:close()
gui_text = string.gsub(gui_text, 'script: "%.*"', [[script: "]] .. main .. basename .. ".gui_script" .. [["]])
gui_file = io.open("." .. path, "w")
gui_file:write(gui_text)
gui_file:close()
end end
if not file_exists(target_gui_path) then local transactions = {}
local gui_content = gui_template(path)
local gui = io.open(target_gui_path, "w") if file_exists("." .. target_gui_path) then
gui:write(gui_content) -- If the gui file exists change the script.
gui:close() table.insert(transactions, editor.tx.set(target_gui_path, "script", target_gui_script_path)
)
else
-- If the gui file doesn't exist create a new one.
local transaction = create_gui(target_gui_path, target_gui_script_path)
if transaction == nil then
return
end
table.insert(transactions, transaction)
end
if file_exists("." .. target_collection_path) then
--- If the collection already exists we will add the monarch go to it.
local transaction = add_monarch_go(target_collection_path, target_gui_path, name)
if transaction == nil then
return
end
table.insert(transactions, transaction)
else
-- If the collection doesn't exists we create a new one.
local transaction = create_collection(target_collection_path, target_gui_path, name)
if transaction == nil then
return
end
table.insert(transactions, transaction)
end
if #transactions > 1 then
editor.transact(transactions)
editor.save()
end end
end end
@@ -68,23 +168,54 @@ function M.get_commands()
}, },
active = function(opts) active = function(opts)
local path = editor.get(opts.selection, "path") local path = editor.get(opts.selection, "path")
return ends_with(path, ".gui") return ends_with(path, ".gui") or ends_with(path, ".gui_script") or ends_with(path, ".collection")
end, end,
run = function(opts) run = function(opts)
create_files(opts.selection) local path = editor.get(opts.selection, "path")
local directory, filename = get_filename(path)
local basename = filename:match("(.+)%..+")
create_files(directory, basename)
end
},
{
label="Create Monarch Scene From Directory",
locations = {"Assets"},
query = {
selection = {type = "resource", cardinality = "one"}
},
active = function(opts)
local _is_directory = editor.resource_attributes(editor.get(opts.selection, "path")).is_directory
if not _is_directory then
return false
end
local _children = editor.get(opts.selection, "children")
if #_children >= 3 then
return false
end
for i = 1, #_children do
local _path = editor.get(_children[i], "path")
if not (ends_with(_path, ".gui") or ends_with(_path, ".collection") or ends_with(_path, ".gui_script")) then
return false
end
end
return true
end,
run = function(opts)
local path = editor.get(opts.selection, "path")
local _, filename = get_filename(path)
create_files(path .. "/", filename)
end end
} }
} }
end end
gui_template = function(gui_script) gui_template = [[
return [[script: "]].. gui_script .. [[" material: "/builtins/materials/gui.material"
material: "/builtins/materials/gui.material" adjust_reference: ADJUST_REFERENCE_PARENT
adjust_reference: ADJUST_REFERENCE_PARENT ]]
]]
end
gui_script_content = [[local monarch = require "monarch.monarch" gui_script_template = [[local monarch = require "monarch.monarch"
function init(self) function init(self)
msg.post(".", "acquire_input_focus") msg.post(".", "acquire_input_focus")
@@ -106,49 +237,10 @@ function on_reload(self)
end end
]] ]]
collection_template = [[
collection_template = function(gui_script, name) name: "m"
return [[name: "]].. name .. [[" scale_along_z: 0
scale_along_z: 0 ]]
embedded_instances {
id: "go"
data: "components {\n"
" id: \"monarch\"\n"
" component: \"]].. gui_script .. [[\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}
]]
end
return M return M

10
monarch/ext.properties Normal file
View File

@@ -0,0 +1,10 @@
[monarch]
collection_template.type = resource
collection_template.filter = collection
gui_script_template.type = resource
gui_script_template.filter = gui_script
gui_template.type = resource
gui_template.filter = gui