From af33ee5d4a1bbac1c8eeed90bf3ffa2f87d1333e Mon Sep 17 00:00:00 2001 From: Kyle Conel Date: Mon, 30 Dec 2024 14:36:16 -0500 Subject: [PATCH] Add editor export type --- src/JulGame.jl | 6 ++++ .../Components/ComponentInputs.jl | 29 +++++++++---------- .../JulGameEditor/Utils/FileContents.jl | 10 +++---- src/engine/SceneManagement/SceneBuilder.jl | 2 +- src/engine/SceneManagement/SceneWriter.jl | 8 +++-- src/utils/Structs.jl | 26 +++++++++++++++++ src/utils/Types.jl | 21 ++++++++++++++ 7 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 src/utils/Structs.jl create mode 100644 src/utils/Types.jl diff --git a/src/JulGame.jl b/src/JulGame.jl index 3b05bead..48029e4f 100644 --- a/src/JulGame.jl +++ b/src/JulGame.jl @@ -16,6 +16,12 @@ module JulGame const SDL2E = SDL2Extension export DELTA_TIME, IS_EDITOR, SDL2, SDL2E, MAIN + include("utils/Structs.jl") + export EditorExport + + include("utils/Types.jl") + export Script + include("utils/Utils.jl") export CallSDLFunction diff --git a/src/editor/JulGameEditor/Components/ComponentInputs.jl b/src/editor/JulGameEditor/Components/ComponentInputs.jl index 07640e17..030f9487 100644 --- a/src/editor/JulGameEditor/Components/ComponentInputs.jl +++ b/src/editor/JulGameEditor/Components/ComponentInputs.jl @@ -573,10 +573,9 @@ function show_script_editor(entity, newScriptText) CImGui.Button("Delete $(i)") && (deleteat!(entity.scripts, i); return;) for field in fieldnames(typeof(entity.scripts[i])) - if field == :parent + if field == :parent || !(fieldtype(typeof(entity.scripts[i]), field) <: EditorExport) continue end - if isdefined(entity.scripts[i], Symbol(field)) display_script_field_input(entity.scripts[i], field) else @@ -592,9 +591,9 @@ function show_script_editor(entity, newScriptText) end function display_script_field_input(script, field) - ftype = fieldtype(typeof(script), field) + ftype = typeof(getproperty(script, field)) if ftype == String - buf = "$(getfield(script, field))"*"\0"^(64) + buf = "$(getproperty(script, field))"*"\0"^(64) CImGui.InputText("$(field)", buf, length(buf)) currentTextInTextBox = "" for characterIndex = eachindex(buf) @@ -605,33 +604,33 @@ function display_script_field_input(script, field) break end end - setfield!(script, field, currentTextInTextBox) + setproperty!(script, field, currentTextInTextBox) elseif ftype == Float64 || ftype == Float32 - x = ftype(getfield(script, field)) + x = ftype(getproperty(script, field)) x = Cfloat(x) @c CImGui.InputFloat("$(field)", &x, 1) - setfield!(script, field, ftype(x)) + setproperty!(script, field, ftype(x)) elseif ftype <: Int64 || ftype <: Int32 || ftype <: Int16 || ftype <: Int8 - x = ftype(getfield(script, field)) + x = ftype(getproperty(script, field)) x = convert(Int32, x) @c CImGui.InputInt("$(field)", &x, 1) x = convert(ftype, x) - setfield!(script, field, x) + setproperty!(script, field, x) elseif ftype == Bool - x = getfield(script, field) + x = getproperty(script, field) @c CImGui.Checkbox("$(field)", &x) - setfield!(script, field, x) + setproperty!(script, field, x) end end function init_undefined_field(script, field) - ftype = fieldtype(typeof(script), field) + ftype = typeof(getproperty(script, field)) if ftype == String - setfield!(script, field, "") + setproperty!(script, field, "") elseif ftype <: Number - setfield!(script, field, 0) + setproperty!(script, field, 0) elseif ftype == Bool - setfield!(script, field, false) + setproperty!(script, field, false) end end diff --git a/src/editor/JulGameEditor/Utils/FileContents.jl b/src/editor/JulGameEditor/Utils/FileContents.jl index e2c86f55..371d7051 100644 --- a/src/editor/JulGameEditor/Utils/FileContents.jl +++ b/src/editor/JulGameEditor/Utils/FileContents.jl @@ -77,12 +77,12 @@ end function newScriptContent(scriptName) return "module $(scriptName)Module using ..JulGame - mutable struct $scriptName - parent # do not remove this line, this is a reference to the entity that this script is attached to - # This is where you define your script's fields - # Example: speed::Float64 + mutable struct $(scriptName) <: Script + parent # do not remove this line, this is a reference to the entity that this script is attached to + # This is where you define your script's fields + # Example: speed::Float64 - function $scriptName() + function $(scriptName)() this = new() # do not remove this line # this is where you initialize your script's fields diff --git a/src/engine/SceneManagement/SceneBuilder.jl b/src/engine/SceneManagement/SceneBuilder.jl index 784fc428..a2c86a0f 100644 --- a/src/engine/SceneManagement/SceneBuilder.jl +++ b/src/engine/SceneManagement/SceneBuilder.jl @@ -243,7 +243,7 @@ module SceneBuilderModule continue end @debug "Overwriting $(key) to $(value) using scene file" - Base.invokelatest(setfield!, newScript, key, value) + Base.invokelatest(setfield!, newScript, key, EditorExport(value)) catch e @warn string(e) end diff --git a/src/engine/SceneManagement/SceneWriter.jl b/src/engine/SceneManagement/SceneWriter.jl index 94b92248..53d56dfa 100644 --- a/src/engine/SceneManagement/SceneWriter.jl +++ b/src/engine/SceneManagement/SceneWriter.jl @@ -1,4 +1,5 @@ module SceneWriterModule + using ...JulGame using JSON3 export serialize_entities @@ -241,11 +242,12 @@ module SceneWriterModule val = nothing if isdefined(script, Symbol(field)) val = getfield(script, field) - if typeof(val) <: AbstractArray - val = nothing + if !isa(val, EditorExport) + continue end + val = val.value else - val = set_undefined_field(script, field) + continue end fields["$(field)"] = val end diff --git a/src/utils/Structs.jl b/src/utils/Structs.jl new file mode 100644 index 00000000..43c7a36f --- /dev/null +++ b/src/utils/Structs.jl @@ -0,0 +1,26 @@ +mutable struct EditorExport{T} + value::T + + # Inner constructor + function EditorExport(value::T) where T + return new{T}(value) # Use `new` to construct the object + end +end + +# Overload `getproperty` to access `value` transparently +function Base.getproperty(editor::EditorExport{T}, sym::Symbol) where T + if sym === :value + return getfield(editor, :value) # Preserve direct access to `value` + else + return editor.value # Redirect other accesses to `value` + end +end + +# Overload `setproperty!` to modify `value` transparently +function Base.setproperty!(editor::EditorExport{T}, sym::Symbol, new_value) where T + if sym === :value + setfield!(editor, :value, new_value) # Directly update `value` + else + editor.value = new_value # Redirect updates to `value` + end +end diff --git a/src/utils/Types.jl b/src/utils/Types.jl new file mode 100644 index 00000000..429e6734 --- /dev/null +++ b/src/utils/Types.jl @@ -0,0 +1,21 @@ +abstract type Script end + +function Base.getproperty(script::Script, property::Symbol) + if isa(getfield(script, property), EditorExport) + return getfield(script, property).value + end + + return getfield(script, property) +end + +function Base.setproperty!(script::Script, property::Symbol, value) + field = findfirst(f->f==property, fieldnames(typeof(script))) + + if fieldtype(typeof(script), field) <: EditorExport + setfield!(script, property, EditorExport(value)) + else + setfield!(script, property, value) + end +end + +# TODO: Add a way to add custom fields to scripts \ No newline at end of file