Skip to content

Commit

Permalink
Add editor export type
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyjor committed Dec 30, 2024
1 parent 967884f commit af33ee5
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 24 deletions.
6 changes: 6 additions & 0 deletions src/JulGame.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
29 changes: 14 additions & 15 deletions src/editor/JulGameEditor/Components/ComponentInputs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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

Expand Down
10 changes: 5 additions & 5 deletions src/editor/JulGameEditor/Utils/FileContents.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/engine/SceneManagement/SceneBuilder.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions src/engine/SceneManagement/SceneWriter.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module SceneWriterModule
using ...JulGame
using JSON3

export serialize_entities
Expand Down Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions src/utils/Structs.jl
Original file line number Diff line number Diff line change
@@ -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
21 changes: 21 additions & 0 deletions src/utils/Types.jl
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit af33ee5

Please sign in to comment.