Skip to content

Commit

Permalink
Fixed more leaks. Faster build reloading.
Browse files Browse the repository at this point in the history
  • Loading branch information
dsrw committed Sep 16, 2023
1 parent fd05b7f commit 82e7f75
Show file tree
Hide file tree
Showing 15 changed files with 82 additions and 61 deletions.
2 changes: 1 addition & 1 deletion enu.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ else:

requires "nim >= 1.6.10",
"https://github.com/dsrw/godot-nim#892c482",
"https://github.com/dsrw/model_citizen 0.17.6",
"https://github.com/dsrw/model_citizen 0.17.7",
"https://github.com/dsrw/nanoid.nim 0.2.1",
"cligen 1.6.0",
"https://github.com/treeform/pretty",
Expand Down
6 changes: 3 additions & 3 deletions src/controllers/node_controllers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import core, models, nodes / [bot_node, build_node, sign_node, player_node]

proc remove_from_scene(unit: Unit) =
debug "removing unit", unit = unit.id
assert ?unit.node
ensure ?unit.node
if unit == previous_build: previous_build = nil
if unit == current_build: current_build = nil

Expand Down Expand Up @@ -44,7 +44,7 @@ proc add_to_scene(unit: Unit) =
node.model = unit
node.transform = unit.transform
if node.owner != nil:
raise_assert \"{T.name} node shouldn't be owned. unit = {unit.id}"
fail \"{T.name} node shouldn't be owned. unit = {unit.id}"
unit.node.visible = Visible in unit.global_flags and
ScriptInitializing notin unit.global_flags

Expand Down Expand Up @@ -72,7 +72,7 @@ proc add_to_scene(unit: Unit) =
player.start_transform = player.transform
player.add(BotNode, state.nodes.data)
else:
raise_assert "unknown unit type for " & unit.id
fail "unknown unit type for " & unit.id

for child in unit.units:
child.parent = unit
Expand Down
14 changes: 7 additions & 7 deletions src/controllers/script_controllers/host_bridge.nim
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,23 @@ proc get_unit(self: Worker, a: VmArgs, pos: int): Unit {.gcsafe.} =

proc get_bot(self: Worker, a: VmArgs, pos: int): Bot =
let unit = self.get_unit(a, pos)
assert not unit.is_nil and unit of Bot
ensure not unit.is_nil and unit of Bot
Bot(unit)

proc get_build(self: Worker, a: VmArgs, pos: int): Build =
let unit = self.get_unit(a, pos)
assert not unit.is_nil and unit of Build
ensure not unit.is_nil and unit of Build
Build(unit)

proc get_sign(self: Worker, a: VmArgs, pos: int): Sign =
let unit = self.get_unit(a, pos)
assert not unit.is_nil and unit of Sign
ensure not unit.is_nil and unit of Sign
Sign(unit)

proc to_node(self: Worker, unit: Unit): PNode =
if ?unit:
if unit notin self.node_map:
raise_assert \"unit `{unit.id}` not in node_map"
fail \"unit `{unit.id}` not in node_map"
self.node_map[unit]
else:
ast.new_node(nkNilLit)
Expand All @@ -81,15 +81,15 @@ proc press_action(self: Worker, name: string) =
state.queued_action = name

proc register_active(self: Worker, pnode: PNode) =
assert not self.active_unit.is_nil
ensure not self.active_unit.is_nil
self.map_unit(self.active_unit, pnode)

proc new_instance(self: Worker, src: Unit, dest: PNode) =
let id = src.id & "_" & self.active_unit.id & "_instance_" &
$(self.active_unit.units.len + 1)

var clone = src.clone(self.active_unit, id)
assert not clone.is_nil
ensure not clone.is_nil
clone.script_ctx = ScriptCtx.init(owner = clone, clone_of = src,
interpreter = self.interpreter)

Expand Down Expand Up @@ -118,7 +118,7 @@ proc pause_script(self: Worker) =
proc begin_turn(self: Worker, unit: Unit, direction: Vector3, degrees: float,
lean: bool, move_mode: int): string =

assert not degrees.is_nan
ensure not degrees.is_nan
var degrees = floor_mod(degrees, 360)
let ctx = self.active_unit.script_ctx
ctx.callback = unit.on_begin_turn(direction, degrees, lean, move_mode)
Expand Down
6 changes: 3 additions & 3 deletions src/controllers/script_controllers/scripting.nim
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ proc init_interpreter*[T](self: Worker, _: T) {.gcsafe.} =
raise (ref VMQuit)(info: info, msg: msg, location: loc)

interpreter.enter_hook = proc(c: PCtx, pc: int, tos: PStackFrame, instr: TInstr) =
assert ?controller
assert ?controller.active_unit
assert ?controller.active_unit.script_ctx
ensure ?controller
ensure ?controller.active_unit
ensure ?controller.active_unit.script_ctx

let ctx = controller.active_unit.script_ctx
let info = c.debug[pc]
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/script_controllers/worker.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ proc advance_unit(self: Worker, unit: Unit, timeout: MonoTime): bool =
let unit = Build(unit)
unit.voxels_remaining_this_frame += unit.voxels_per_frame
try:
assert self.active_unit.is_nil
ensure self.active_unit.is_nil
var task_state = NextTask

let now = get_mono_time()
Expand Down Expand Up @@ -88,7 +88,7 @@ proc change_code(self: Worker, unit: Unit, code: Code) =
else:
# We load the player before we init the interpreter to get to an
# interactive state quicker. Otherwise this shouldn't ever be nil.
assert unit.id == state.player.id
ensure unit.id == state.player.id
else:
self.load_script(unit)

Expand Down
8 changes: 4 additions & 4 deletions src/game.nim
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ world: {state.config.world}
state.nodes.game = self

var uc = initial_user_config
assert not state.is_nil
ensure not state.is_nil

let env_listen_address = get_env("ENU_LISTEN_ADDRESS")
randomize()
Expand Down Expand Up @@ -208,12 +208,12 @@ world: {state.config.world}

method ready* =
state.nodes.data = state.nodes.game.find_node("Level").get_node("data")
assert not state.nodes.data.is_nil
ensure not state.nodes.data.is_nil
self.scaled_viewport =
self.get_node("ViewportContainer/Viewport") as Viewport

self.bind_signals(self.get_viewport(), "size_changed")
assert not self.scaled_viewport.is_nil
ensure not self.scaled_viewport.is_nil
if state.config.mega_pixels >= 1.0:
self.scaled_viewport.get_texture.flags = FLAG_FILTER

Expand Down Expand Up @@ -340,7 +340,7 @@ world: {state.config.world}

method on_meta_clicked(url: string) =
if url.starts_with("nim://"):
assert ?state.open_sign
ensure ?state.open_sign

state.open_sign.owner.eval = url[6..^1]

Expand Down
6 changes: 3 additions & 3 deletions src/libs/interpreters.nim
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ proc get_var*(self: ScriptCtx, var_name: string, module_name: string): PNode =
self.interpreter.get_global_value(sym)

proc resume*(self: ScriptCtx): bool =
assert not self.ctx.is_nil
assert self.pc > 0
assert not self.tos.is_nil
ensure not self.ctx.is_nil
ensure self.pc > 0
ensure not self.tos.is_nil

trace "resuming", script = self.file_name, module = self.module_name
result = try:
Expand Down
18 changes: 9 additions & 9 deletions src/models/builds.nim
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ proc del_voxel(self: Build, position: Vector3) =
proc restore_edits*(self: Build) =
if self.id in self.shared.edits:
for loc, info in self.shared.edits[self.id]:
assert info.kind in [Manual, Hole]
ensure info.kind in [Manual, Hole]
if info.kind != Hole:
self.add_voxel(loc, info)
else:
Expand Down Expand Up @@ -324,19 +324,19 @@ method reset*(self: Build) =
self.color = self.start_color
self.speed = 1
self.scale = 1

self.global_flags += Resetting
self.global_flags += Visible
self.reset_state()

let chunks = self.chunks.value
for chunk_id, chunk in chunks:
for vec, info in chunk.value:
if info.kind == Computed:
self.chunks[chunk_id].del(vec)
if self.chunks[chunk_id].len == 0:
self.chunks[chunk_id].destroy
self.chunks.del(chunk_id)
self.chunks.del(chunk_id)
chunk.destroy

self.units.clear()
self.global_flags -= Resetting
self.restore_edits
self.draw(vec3(), (Computed, self.start_color))

method ensure_visible*(self: Build) =
Expand Down Expand Up @@ -461,9 +461,9 @@ when is_main_module:
var b = Build.init

b.draw vec3(1, 1, 1), (Computed, Color())
check vec3(1, 1, 1) in b.chunks[vec3(0, 0, 0)]
ensure vec3(1, 1, 1) in b.chunks[vec3(0, 0, 0)]
b.draw vec3(17, 17, 17), (Computed, Color())
check vec3(17, 17, 17) in b.chunks[vec3(1, 1, 1)]
ensure vec3(17, 17, 17) in b.chunks[vec3(1, 1, 1)]
var c = Build.init(transform = Transform(origin: vec3(5, 5, 5)))
c.parent = b

Expand Down
4 changes: 2 additions & 2 deletions src/models/serializers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ proc to_json_hook(shared_edits: ZenTable[string, Table[Vector3, VoxelInfo]]):
proc from_json_hook(self: var Table[Vector3, VoxelInfo],
json: JsonNode) {.gcsafe.} =

assert load_chunks
ensure load_chunks
for chunks in json:
for chunk in chunks[1]:
let location = chunk[0].json_to(Vector3)
Expand All @@ -68,7 +68,7 @@ proc from_json_hook(self: var Table[Vector3, VoxelInfo],
proc from_json_hook(self: var ZenTable[string, Table[Vector3, VoxelInfo]],
json: JsonNode) =

assert not load_chunks
ensure not load_chunks
for id, edits in json:
for edit in edits:
if id notin self:
Expand Down
20 changes: 10 additions & 10 deletions src/models/states.nim
Original file line number Diff line number Diff line change
Expand Up @@ -201,31 +201,31 @@ when is_main_module:
state.pop_flag CommandMode

state.push_flag MouseCaptured
check MouseCaptured in state.local_flags
ensure MouseCaptured in state.local_flags

state.open_unit = Unit()
check MouseCaptured notin state.local_flags
ensure MouseCaptured notin state.local_flags

state.push_flag CommandMode
check MouseCaptured in state.local_flags
ensure MouseCaptured in state.local_flags

state.pop_flag MouseCaptured
check MouseCaptured in state.local_flags
ensure MouseCaptured in state.local_flags

state.open_unit = nil
check MouseCaptured in state.local_flags
ensure MouseCaptured in state.local_flags

state.pop_flag CommandMode
check MouseCaptured notin state.local_flags
ensure MouseCaptured notin state.local_flags

state.pop_flag EditorVisible
check MouseCaptured notin state.local_flags
ensure MouseCaptured notin state.local_flags

state.push_flag MouseCaptured
check MouseCaptured in state.local_flags
ensure MouseCaptured in state.local_flags

state.push_flag DocsVisible
check MouseCaptured notin state.local_flags
ensure MouseCaptured notin state.local_flags

state.push_flag CommandMode
check MouseCaptured in state.local_flags
ensure MouseCaptured in state.local_flags
10 changes: 5 additions & 5 deletions src/models/units.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ from pkg / core / godotcoretypes import Basis
import core, models / [states, colors], libs / interpreters

proc init_shared*(self: Unit) =
assert ?self.shared_value
ensure ?self.shared_value
if ?self.parent:
self.shared = self.parent.shared
elif not ?self.shared:
Expand Down Expand Up @@ -82,15 +82,15 @@ method worker_thread_joined*(self: Unit) {.base, gcsafe.} = discard
method on_begin_move*(self: Unit, direction: Vector3, steps: float,
move_mode: int): Callback {.base, gcsafe.} =

raise_assert "override me"
fail "override me"

method on_begin_turn*(self: Unit, direction: Vector3, degrees: float,
lean: bool, move_mode: int): Callback {.base, gcsafe.} =

raise_assert "override me"
fail "override me"

method clone*(self: Unit, clone_to: Unit, id: string): Unit {.base, gcsafe.} =
raise_assert "override me"
fail "override me"

method code_template*(self: Unit, imports: string): string {.base, gcsafe.} =
read_file self.script_ctx.script
Expand Down Expand Up @@ -124,7 +124,7 @@ method off_collision*(self: Model, partner: Model) {.base, gcsafe.} =
discard

proc destroy*[T: Unit](self: T) =
assert ?self
ensure ?self

if self of Sign:
# :( Sign(self) will fail to compile if T is a Build or a Bot.
Expand Down
34 changes: 27 additions & 7 deletions src/nodes/build_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ gdobj BuildNode of VoxelTerrain:
active_chunks: Table[Vector3, ZID]
transform_zid: ZID
default_view_distance: int
chunks_zid: ZID

proc init*() =
self.bind_signals self, "block_loaded", "block_unloaded"
Expand Down Expand Up @@ -94,6 +95,21 @@ gdobj BuildNode of VoxelTerrain:
else:
self.visible = false

proc track_chunks() =
self.chunks_zid = self.model.chunks.watch:
let id = change.item.key
if id in self.active_chunks:
if added:
self.track_chunk(change.item.key)
elif removed:
self.active_chunks[id] = empty_zid

proc untrack_chunks() =
Zen.thread_ctx.untrack(self.chunks_zid)
for chunk_id, zid in self.active_chunks:
Zen.thread_ctx.untrack(zid)
self.active_chunks[chunk_id] = empty_zid

proc track_changes() =
self.model.glow_value.watch:
if added:
Expand All @@ -105,20 +121,24 @@ gdobj BuildNode of VoxelTerrain:
debug "changing bounds", new = change.item
self.bounds = change.item

self.model.chunks.watch:
let id = change.item.key
if id in self.active_chunks:
if added:
self.track_chunk(change.item.key)
elif removed:
self.active_chunks[id] = empty_zid
self.track_chunks()

self.model.global_flags.watch:
if (change.item == Visible and ScriptInitializing notin
self.model.global_flags) or ScriptInitializing.removed:

self.set_visibility

elif Resetting.added:
self.untrack_chunks()
let model = self.model
self.generator = nil
self.stream = nil

elif Resetting.removed:
self.generator = gdnew[VoxelGeneratorFlat]()
self.track_chunks()

self.model.local_flags.watch:
if Highlight.added:
self.set_glow highlight_glow
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/queries.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import godotapi / [ray_cast]
import core, models / [units]

proc run*(query: var SightQuery, source: Unit) =
assert not ?query.answer
ensure not ?query.answer
query.answer = some(false)

let ray = source.sight_ray
Expand Down
3 changes: 2 additions & 1 deletion src/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export godotbase except print
export Interpreter

type
EnuError* = object of CatchableError
LocalStateFlags* = enum
CommandMode, EditorVisible, ConsoleVisible,
BlockTargetVisible, ReticleVisible, DocsVisible, MouseCaptured,
Expand All @@ -32,7 +33,7 @@ type
Running, Done, NextTask

GlobalModelFlags* = enum
Global, Visible, Lock, Ready, ScriptInitializing, Dirty
Global, Visible, Lock, Ready, ScriptInitializing, Dirty, Resetting

LocalModelFlags* = enum
Hover, TargetMoved, Highlight, Hide
Expand Down
Loading

0 comments on commit 82e7f75

Please sign in to comment.