Skip to content

Commit 50e59d9

Browse files
committed
Update editor scripts
1 parent 8d2b8c2 commit 50e59d9

19 files changed

+1117
-279
lines changed
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
--- Module for assigning layers to GUI nodes based on textures and fonts
2+
3+
local defold_parser = require("druid.editor_scripts.defold_parser.defold_parser")
4+
local system = require("druid.editor_scripts.defold_parser.system.system")
5+
6+
local M = {}
7+
8+
9+
---Create a backup of a file
10+
---@param file_path string - The path of the file to backup
11+
---@return string|nil - The backup file path, or nil if backup failed
12+
local function create_backup(file_path)
13+
local backup_path = file_path .. ".backup"
14+
print("Creating backup at:", backup_path)
15+
16+
-- Read and write using system module
17+
local content, err_read = system.read_file(file_path)
18+
if not content then
19+
print("Error reading original file for backup:", err_read)
20+
return nil
21+
end
22+
23+
local success, err_write = system.write_file(backup_path, content)
24+
if not success then
25+
print("Error creating backup file:", err_write)
26+
return nil
27+
end
28+
29+
print("Backup created successfully")
30+
return backup_path
31+
end
32+
33+
34+
---Restore from a backup file
35+
---@param backup_path string - The path of the backup file
36+
---@param original_path string - The path to restore to
37+
---@return boolean - True if restore was successful
38+
local function restore_from_backup(backup_path, original_path)
39+
print("Restoring from backup:", backup_path)
40+
41+
-- Read backup file
42+
local content, err = system.read_file(backup_path)
43+
if not content then
44+
print("Error reading backup file:", err)
45+
return false
46+
end
47+
48+
-- Write to original file
49+
local success, err = system.write_file(original_path, content)
50+
if not success then
51+
print("Error restoring from backup:", err)
52+
return false
53+
end
54+
55+
print("Restored successfully from backup")
56+
return true
57+
end
58+
59+
60+
---Remove a backup file
61+
---@param backup_path string - The path of the backup file to remove
62+
local function remove_backup(backup_path)
63+
print("Removing backup file:", backup_path)
64+
local success, err = os.remove(backup_path)
65+
if not success then
66+
print("Warning: Could not remove backup file:", err)
67+
print("You may want to manually remove it:", backup_path)
68+
else
69+
print("Backup file removed successfully")
70+
end
71+
end
72+
73+
---Assign layers to GUI nodes based on textures and fonts
74+
---@param gui_resource string - The GUI resource to process
75+
---@return table - Editor command to reload the resource
76+
function M.assign_layers(gui_resource)
77+
local gui_path = editor.get(gui_resource, "path")
78+
print("Setting up layers for", gui_path)
79+
80+
-- Get the absolute path to the file
81+
local absolute_project_path = editor.external_file_attributes(".").path
82+
if not absolute_project_path:match("[\\/]$") then
83+
absolute_project_path = absolute_project_path .. "/"
84+
end
85+
local clean_gui_path = gui_path
86+
if clean_gui_path:sub(1, 1) == "/" then
87+
clean_gui_path = clean_gui_path:sub(2)
88+
end
89+
local gui_absolute_path = absolute_project_path .. clean_gui_path
90+
91+
-- Create a backup before modifying the file
92+
local backup_path = create_backup(gui_absolute_path)
93+
if not backup_path then
94+
print("Failed to create backup, aborting...")
95+
return {}
96+
end
97+
98+
-- Parse the GUI file using defold_parser
99+
print("Parsing GUI file...")
100+
local gui_data = defold_parser.load_from_file(gui_absolute_path)
101+
if not gui_data then
102+
print("Error: Failed to parse GUI file")
103+
return {}
104+
end
105+
106+
-- Collect all textures and fonts
107+
print("Collecting all available textures and fonts...")
108+
local all_textures = {}
109+
local all_fonts = {}
110+
111+
-- Get textures
112+
if gui_data.textures then
113+
for _, texture in ipairs(gui_data.textures) do
114+
print("Found texture:", texture.name)
115+
all_textures[texture.name] = true
116+
end
117+
end
118+
119+
-- Get fonts
120+
if gui_data.fonts then
121+
for _, font in ipairs(gui_data.fonts) do
122+
print("Found font:", font.name)
123+
all_fonts[font.name] = true
124+
end
125+
end
126+
127+
-- Track which textures and fonts are actually used by nodes
128+
print("Finding used textures and fonts...")
129+
local used_layers = {}
130+
131+
-- First pass: find all used textures and fonts
132+
if gui_data.nodes then
133+
for _, node in ipairs(gui_data.nodes) do
134+
if node.texture then
135+
local layer_name = node.texture:match("([^/]+)")
136+
if layer_name and all_textures[layer_name] then
137+
used_layers[layer_name] = true
138+
print("Node", node.id, "uses texture:", layer_name)
139+
end
140+
elseif node.font then
141+
local layer_name = node.font
142+
if all_fonts[layer_name] then
143+
used_layers[layer_name] = true
144+
print("Node", node.id, "uses font:", layer_name)
145+
end
146+
end
147+
end
148+
end
149+
150+
-- Create a set of existing layer names for faster lookup
151+
print("Checking existing layers...")
152+
local existing_layers = {}
153+
if gui_data.layers then
154+
for _, layer in ipairs(gui_data.layers) do
155+
if layer.name then
156+
existing_layers[layer.name] = true
157+
print("Found existing layer:", layer.name)
158+
end
159+
end
160+
end
161+
162+
-- Convert set to array of used layers
163+
local layers = {}
164+
for layer_name in pairs(used_layers) do
165+
if not existing_layers[layer_name] then
166+
table.insert(layers, layer_name)
167+
print("Adding new layer:", layer_name)
168+
else
169+
print("Layer already exists:", layer_name)
170+
end
171+
end
172+
173+
-- Sort new layers for consistent output
174+
table.sort(layers)
175+
176+
print("Found", #layers, "new layers to add")
177+
178+
-- Add new layers (preserving existing ones)
179+
print("Adding new layers...")
180+
gui_data.layers = gui_data.layers or {}
181+
for _, layer_name in ipairs(layers) do
182+
table.insert(gui_data.layers, {
183+
name = layer_name,
184+
})
185+
end
186+
187+
-- Create a lookup table for faster matching - include both existing and new layers
188+
local layer_lookup = {}
189+
for layer_name in pairs(existing_layers) do
190+
layer_lookup[layer_name] = true
191+
end
192+
for _, layer_name in ipairs(layers) do
193+
layer_lookup[layer_name] = true
194+
end
195+
196+
-- Update nodes to use the correct layer
197+
print("Updating node layers...")
198+
if gui_data.nodes then
199+
for _, node in ipairs(gui_data.nodes) do
200+
if node.texture then
201+
local layer_name = node.texture:match("([^/]+)")
202+
if layer_name and layer_lookup[layer_name] then
203+
print("Assigning node", node.id, "to layer:", layer_name)
204+
node.layer = layer_name
205+
end
206+
elseif node.font then
207+
local layer_name = node.font
208+
if layer_lookup[layer_name] then
209+
print("Assigning node", node.id, "to layer:", layer_name)
210+
node.layer = layer_name
211+
end
212+
end
213+
end
214+
end
215+
216+
-- Write the updated GUI file
217+
print("Writing updated GUI file...")
218+
local success = defold_parser.save_to_file(gui_absolute_path, gui_data)
219+
220+
if not success then
221+
print("Error: Failed to save GUI file")
222+
print("Attempting to restore from backup...")
223+
local restored = restore_from_backup(backup_path, gui_absolute_path)
224+
if not restored then
225+
print("Critical: Failed to restore from backup. Manual intervention may be required.")
226+
end
227+
return {}
228+
end
229+
230+
-- Everything worked, remove the backup
231+
remove_backup(backup_path)
232+
233+
print("Successfully assigned layers for GUI:", gui_path)
234+
235+
return {}
236+
end
237+
238+
239+
return M

druid/editor_scripts/create_druid_component.py

Lines changed: 0 additions & 132 deletions
This file was deleted.

0 commit comments

Comments
 (0)