mirror of https://github.com/dsrw/enu.git
Server connect/listen support. Doesn't work.
Formatting fixes. Changed {.cast(gcsafe}.} to {.gcsafe.} to keep the jetbrains nim plugin happy
This commit is contained in:
parent
38c271cafb
commit
57be8e5628
|
@ -39,7 +39,8 @@ requires "nim >= 1.6.10",
|
|||
"chroma",
|
||||
"markdown",
|
||||
"chronicles",
|
||||
"zippy"
|
||||
"zippy",
|
||||
"dotenv"
|
||||
|
||||
proc gen: string =
|
||||
if generator_path == "":
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
--define:vm_exec_hooks
|
||||
--threads:on
|
||||
--define:nim_preview_hash_ref
|
||||
--define:nim_type_names
|
||||
--experimental:dynamic_bind_sym
|
||||
--mm:orc
|
||||
--panics:on
|
||||
|
||||
--warning:"LockLevel:off"
|
||||
--warning:"UseBase:off"
|
||||
|
||||
--experimental:"dynamic_bind_sym"
|
||||
|
||||
--define:"vm_exec_hooks"
|
||||
--define:"nim_preview_hash_ref"
|
||||
--define:"nim_type_names"
|
||||
--define:"chronicles_enabled=on"
|
||||
--define:"chronicles_log_level=INFO"
|
||||
--define:"chronicles_disabled_topics=model_citizen,scripting"
|
||||
--define:"chronicles_sinks=textlines[dynamic]"
|
||||
|
||||
# --define:zen_trace
|
||||
# --define:"chronicles_timestamps=None" # disable timestamps for better diffs
|
||||
# --define:"zen_trace"
|
||||
|
||||
if defined(release):
|
||||
--define:"chronicles_colors=None"
|
||||
|
|
|
@ -89,8 +89,6 @@ proc find_nested_changes(parent: Change[Unit]) =
|
|||
|
||||
proc watch*(self: NodeController, state: GameState) =
|
||||
state.units.changes:
|
||||
if ?change.item:
|
||||
debug "Unit added", unit = change.item.id, changes = change.changes
|
||||
if added:
|
||||
change.item.add_to_scene()
|
||||
elif modified:
|
||||
|
|
|
@ -59,7 +59,7 @@ proc link_dependency_impl(self: Worker, dep: Unit) =
|
|||
|
||||
proc write_stack_trace(self: Worker) =
|
||||
let ctx = self.active_unit.script_ctx
|
||||
{.cast(gcsafe).}:
|
||||
{.gcsafe.}:
|
||||
msg_writeln(ctx.ctx.config, "stack trace: (most recent call last)",
|
||||
{msg_no_unit_sep})
|
||||
stack_trace_aux(ctx.ctx, ctx.tos, ctx.pc)
|
||||
|
@ -67,7 +67,7 @@ proc write_stack_trace(self: Worker) =
|
|||
proc get_unit(self: Worker, a: VmArgs, pos: int): Unit {.gcsafe.} =
|
||||
let pnode = a.get_node(pos)
|
||||
assert pnode in self.unit_map
|
||||
{.cast(gcsafe).}:
|
||||
{.gcsafe.}:
|
||||
result = self.unit_map[pnode]
|
||||
|
||||
proc get_bot(self: Worker, a: VmArgs, pos: int): Bot =
|
||||
|
@ -717,6 +717,9 @@ proc launch_worker(params: (ZenContext, GameState)) {.gcsafe.} =
|
|||
|
||||
Zen.thread_ctx = worker_ctx
|
||||
Zen.thread_ctx.subscribe(ctx)
|
||||
let server_address = main_thread_state.config.server_address
|
||||
if not listen and server_address != "":
|
||||
Zen.thread_ctx.subscribe(server_address)
|
||||
|
||||
Zen.thread_ctx.recv
|
||||
assert Zen.thread_ctx.len == ctx.len
|
||||
|
@ -787,8 +790,8 @@ proc launch_worker(params: (ZenContext, GameState)) {.gcsafe.} =
|
|||
|
||||
proc extract_file_info(msg: string): tuple[name: string, info: TLineInfo] =
|
||||
if msg =~ re"unhandled exception: (.*)\((\d+), (\d+)\)":
|
||||
result = (matches[0], TLineInfo(line: matches[1].parse_int.uint16,
|
||||
col: matches[2].parse_int.int16))
|
||||
result = (matches[0], TLineInfo(line: matches[1].parse_int.uint16, col:
|
||||
matches[2].parse_int.int16))
|
||||
|
||||
proc eval*(self: Worker, code: string) =
|
||||
let active = self.active_unit
|
||||
|
|
48
src/game.nim
48
src/game.nim
|
@ -1,10 +1,11 @@
|
|||
import std / [monotimes, os, jsonutils, json, math, locks]
|
||||
import pkg / [godot, zippy / ziparchives]
|
||||
import godotapi / [input, input_event, gd_os, node, scene_tree,
|
||||
packed_scene, sprite, control, viewport, viewport_texture,
|
||||
performance, label, theme, dynamic_font, resource_loader, main_loop,
|
||||
project_settings, input_map, input_event_action, input_event_key, global_constants,
|
||||
scroll_container]
|
||||
from dotenv import nil
|
||||
import godotapi / [input, input_event, gd_os, node, scene_tree, packed_scene,
|
||||
sprite, control, viewport, viewport_texture, performance, label, theme,
|
||||
dynamic_font, resource_loader, main_loop, project_settings, input_map,
|
||||
input_event_action, input_event_key, global_constants, scroll_container]
|
||||
|
||||
import core, types, globals, controllers, models / serializers
|
||||
|
||||
type
|
||||
|
@ -18,8 +19,14 @@ type
|
|||
start_full_screen: Option[bool]
|
||||
semicolon_as_colon: Option[bool]
|
||||
world_prefix: Option[string]
|
||||
listen: Option[bool]
|
||||
server_address: Option[string]
|
||||
|
||||
const auto_save_interval = 30.seconds
|
||||
|
||||
if file_exists(".env"):
|
||||
dotenv.overload()
|
||||
|
||||
Zen.thread_ctx = ZenContext.init(name = "main", chan_size = 1000)
|
||||
state = GameState.init
|
||||
|
||||
|
@ -38,14 +45,15 @@ gdobj Game of Node:
|
|||
script_controller: ScriptController
|
||||
|
||||
method process*(delta: float) =
|
||||
Zen.thread_ctx.recv(duration = (1.0 / 60.0).seconds)
|
||||
Zen.thread_ctx.recv(max_duration = (1.0 / 60.0).seconds)
|
||||
inc state.frame_count
|
||||
let time = get_mono_time()
|
||||
if state.config.show_stats:
|
||||
let fps = get_monitor(TIME_FPS)
|
||||
|
||||
let vram = get_monitor(RENDER_VIDEO_MEM_USED)
|
||||
self.stats.text = &"FPS: {fps}\nscale_factor: {state.scale_factor}\nvram: {vram}"
|
||||
self.stats.text =
|
||||
&"FPS: {fps}\nscale_factor: {state.scale_factor}\nvram: {vram}"
|
||||
|
||||
if time > self.rescale_at:
|
||||
self.rescale_at = MonoTime.high
|
||||
|
@ -64,7 +72,9 @@ gdobj Game of Node:
|
|||
|
||||
proc rescale*() =
|
||||
let vp = self.get_viewport().size
|
||||
state.scale_factor = sqrt(state.config.mega_pixels * 1_000_000.0 / (vp.x * vp.y))
|
||||
state.scale_factor = sqrt(state.config.mega_pixels *
|
||||
1_000_000.0 / (vp.x * vp.y))
|
||||
|
||||
self.scaled_viewport.size = vp * state.scale_factor
|
||||
|
||||
method notification*(what: int) =
|
||||
|
@ -134,6 +144,7 @@ gdobj Game of Node:
|
|||
assert not state.config.is_nil
|
||||
|
||||
state.config.font_size.value = uc.font_size ||= (20 * screen_scale).int
|
||||
let env_listen = get_env("ENU_LISTEN").to_lower() == "true"
|
||||
with state.config:
|
||||
dock_icon_size = uc.dock_icon_size ||= 100 * screen_scale
|
||||
world_prefix = uc.world_prefix ||= "tutorial"
|
||||
|
@ -142,7 +153,10 @@ gdobj Game of Node:
|
|||
mega_pixels = uc.mega_pixels ||= 2.0
|
||||
start_full_screen = uc.start_full_screen ||= true
|
||||
semicolon_as_colon = uc.semicolon_as_colon ||= false
|
||||
lib_dir = join_path(get_executable_path().parent_dir(), "..", "..", "..", "vmlib")
|
||||
lib_dir = join_path(get_executable_path().parent_dir(), "..", "..", "..",
|
||||
"vmlib")
|
||||
server_address = uc.server_address ||= ""
|
||||
listen = env_listen or (uc.listen ||= false)
|
||||
|
||||
state.set_flag(God, uc.god_mode ||= false)
|
||||
|
||||
|
@ -153,7 +167,9 @@ gdobj Game of Node:
|
|||
when defined(dist):
|
||||
let exe_dir = parent_dir get_executable_path()
|
||||
if host_os == "macosx":
|
||||
state.config.lib_dir = join_path(exe_dir.parent_dir, "Resources", "vmlib")
|
||||
state.config.lib_dir = join_path(exe_dir.parent_dir, "Resources",
|
||||
"vmlib")
|
||||
|
||||
elif host_os == "windows":
|
||||
state.config.lib_dir = join_path(exe_dir, "vmlib")
|
||||
elif host_os == "linux":
|
||||
|
@ -186,7 +202,9 @@ gdobj Game of Node:
|
|||
method ready* =
|
||||
state.nodes.data = state.nodes.game.find_node("Level").get_node("data")
|
||||
assert not state.nodes.data.is_nil
|
||||
self.scaled_viewport = self.get_node("ViewportContainer/Viewport") as Viewport
|
||||
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
|
||||
if state.config.mega_pixels >= 1.0:
|
||||
|
@ -253,10 +271,12 @@ gdobj Game of Node:
|
|||
|
||||
if event.is_action_pressed("previous"):
|
||||
state.update_action_index(-1)
|
||||
# NOTE: alt+enter isn't being picked up on windows if the editor is open. Needs investigation.
|
||||
# NOTE: alt+enter isn't being picked up on windows if the editor is
|
||||
# open. Needs investigation.
|
||||
if event.is_action_pressed("toggle_fullscreen") or (host_os == "windows" and
|
||||
CommandMode in state.flags and EditorVisible in state.flags and
|
||||
event of InputEventKey and event.as(InputEventKey).scancode == KEY_ENTER):
|
||||
CommandMode in state.flags and EditorVisible in state.flags and
|
||||
event of InputEventKey and
|
||||
event.as(InputEventKey).scancode == KEY_ENTER):
|
||||
|
||||
set_window_fullscreen not is_window_fullscreen()
|
||||
elif event.is_action_pressed("next_world"):
|
||||
|
|
|
@ -200,7 +200,7 @@ proc select_routine*(i: Interpreter; name: string, module_name: string): PSym =
|
|||
## Selects a declared routine (proc/func/etc) from the main module.
|
||||
## The routine needs to have the export marker ``*``. The only matching
|
||||
## routine is returned and ``nil`` if it is overloaded.
|
||||
{.cast(gcsafe).}:
|
||||
{.gcsafe.}:
|
||||
result = select_unique_symbol(i, name, {sk_template, sk_macro, sk_func,
|
||||
sk_method, sk_proc, sk_converter}, module_name)
|
||||
|
||||
|
@ -225,7 +225,7 @@ proc load_module*(i: Interpreter, file_name, code: string,
|
|||
break
|
||||
|
||||
if module.is_nil:
|
||||
{.cast(gcsafe).}:
|
||||
{.gcsafe.}:
|
||||
module = i.graph.make_module(file_name)
|
||||
|
||||
init_str_tables(i.graph, module)
|
||||
|
@ -236,7 +236,7 @@ proc load_module*(i: Interpreter, file_name, code: string,
|
|||
# which causes "cannot evaluate at compile time" issues with some variables.
|
||||
# Force things back to em_repl.
|
||||
PCtx(i.graph.vm).mode = em_repl
|
||||
{.cast(gcsafe).}:
|
||||
{.gcsafe.}:
|
||||
discard process_module(i.graph, module, i.idgen, stream, a)
|
||||
|
||||
# adapted from
|
||||
|
|
|
@ -16,7 +16,7 @@ private_access ScriptCtx
|
|||
proc init*(_: type Interpreter, script_dir, vmlib: string): Interpreter =
|
||||
let std_paths = STDLIB_PATHS.map_it join_path(vmlib, "stdlib", it)
|
||||
let source_paths = std_paths & join_path(vmlib, "enu") & @[script_dir]
|
||||
{.cast(gcsafe).}:
|
||||
{.gcsafe.}:
|
||||
result = create_interpreter("base_api.nim", source_paths)
|
||||
|
||||
proc pause*(ctx: ScriptCtx) =
|
||||
|
@ -70,7 +70,7 @@ proc call_proc*(self: ScriptCtx, proc_name: string, args: varargs[PNode, `to_nod
|
|||
if foreign_proc == nil:
|
||||
raise new_exception(VMError, &"script does not export a proc of the name: '{proc_name}'")
|
||||
result = try:
|
||||
{.cast(gcsafe).}:
|
||||
{.gcsafe.}:
|
||||
(false, self.interpreter.call_routine(foreign_proc, args))
|
||||
except VMPause:
|
||||
(self.exit_code.is_none, nil)
|
||||
|
@ -90,7 +90,7 @@ proc resume*(self: ScriptCtx): bool =
|
|||
|
||||
debug "resuming", script = self.file_name, module = self.module_name
|
||||
result = try:
|
||||
{.cast(gcsafe).}:
|
||||
{.gcsafe.}:
|
||||
discard exec_from_ctx(self.ctx, self.pc, self.tos)
|
||||
false
|
||||
except VMPause:
|
||||
|
|
|
@ -143,6 +143,8 @@ type
|
|||
start_full_screen*: bool
|
||||
semicolon_as_colon*: bool
|
||||
world_prefix*: string
|
||||
listen*: bool
|
||||
server_address*: string
|
||||
|
||||
ScriptCtx* = ref object
|
||||
script*: string
|
||||
|
|
Loading…
Reference in New Issue