diff --git a/.cell/cell.toml b/.cell/cell.toml index 473031f4..b4abda85 100644 --- a/.cell/cell.toml +++ b/.cell/cell.toml @@ -1,2 +1,8 @@ [dependencies] extramath = "https://gitea.pockle.world/john/extramath@master" + +[system] +ar_timer = 60 # seconds before idle actor reclamation +actor_memory = 0 # MB of memory an actor can use; 0 for unbounded +net_service = 0.1 # seconds per net service pull +reply_timeout = 60 # seconds to hold callback for reply messages; 0 for unbounded \ No newline at end of file diff --git a/prosperon/_sdl_video.ce b/prosperon/_sdl_video.ce index bb509da3..4701d3b0 100644 --- a/prosperon/_sdl_video.ce +++ b/prosperon/_sdl_video.ce @@ -1,6 +1,6 @@ // SDL Video Actor // This actor runs on the main thread and handles all SDL video operations - +log.console("TO HERE") var surface = use('surface') // Default window configuration - documents all available window options @@ -824,12 +824,4 @@ function handle_keyboard(msg) { return {error: "Unknown keyboard operation: " + msg.op}; } } - -// Export resource info for debugging -prosperon.sdl_video = { - resources: resources, - next_id: function() { return next_id; }, - // Export the actor reference for external access - actor: $_ -}; \ No newline at end of file diff --git a/prosperon/dull.ce b/prosperon/dull.ce deleted file mode 100644 index 9545ec4d..00000000 --- a/prosperon/dull.ce +++ /dev/null @@ -1,17 +0,0 @@ -var render = use('render') - -for (var i in render) log.console(i) - -function loop() -{ - prosperon.gpu.draw_color([1,1,1,1]) - prosperon.gpu.clear() - ren.draw_color([0,0,0,1]) - draw.rectangle({x:50,y:50,width:50,height:50}) - prosperon.gpu.present() - $_.delay(loop, 1/60) -} - -loop() - -$_.delay($_.stop, 3) diff --git a/prosperon/examples/chess/main.ce b/prosperon/examples/chess/main.ce index 27ae3e02..cdb644c9 100644 --- a/prosperon/examples/chess/main.ce +++ b/prosperon/examples/chess/main.ce @@ -1,15 +1,15 @@ /* main.js – runs the demo with your prototype-based grid */ var json = use('json') -var draw2d = use('draw2d') +var draw2d = use('prosperon/draw2d') var blob = use('blob') /*──── import our pieces + systems ───────────────────────────────────*/ -var Grid = use('examples/chess/grid'); // your new ctor -var MovementSystem = use('examples/chess/movement').MovementSystem; -var startingPos = use('examples/chess/pieces').startingPosition; -var rules = use('examples/chess/rules'); +var Grid = use('grid'); // your new ctor +var MovementSystem = use('movement').MovementSystem; +var startingPos = use('pieces').startingPosition; +var rules = use('rules'); /*──── build board ───────────────────────────────────────────────────*/ var grid = new Grid(8, 8); @@ -395,6 +395,3 @@ $_.receiver(e => { handleKeyDown(e) } }) - -var parseq = use('parseq', $_.delay) -for (var i in parseq) log.console(i) diff --git a/prosperon/moth.ce b/prosperon/main.ce similarity index 96% rename from prosperon/moth.ce rename to prosperon/main.ce index dc9728e6..4634af24 100644 --- a/prosperon/moth.ce +++ b/prosperon/main.ce @@ -1,8 +1,3 @@ -/** - * Moth Game Framework - * Higher-level game development framework built on top of Prosperon - */ - var os = use('os'); var io = use('io'); var transform = use('transform'); @@ -73,10 +68,13 @@ var camera = { viewport: {x:0,y:0,width:1,height:1}, // viewport it appears on screen ortho:true, anchor:[0.5,0.5],//{x:0.5,y:0.5}, + rotation:[0,0,0,1], surface: undefined } var util = use('util') +log.console(util) +log.console(camera) var cammy = util.camera_globals(camera) var graphics @@ -86,20 +84,13 @@ var render var gameactor -var dir = args[0] - -if (!io.exists(args[0] + '/main.js')) - throw Error(`No main.js found in ${args[0]}`) - -log.spam('Starting game in ' + dir) - -io.mount(dir) +var game = args[0] $_.start(e => { if (gameactor) return gameactor = e.actor loop() -}, args[0] + "/main.js") +}, args[0]) send(video_actor, { kind: "window", diff --git a/scripts/engine.cm b/scripts/engine.cm index f6629792..6c39fe38 100644 --- a/scripts/engine.cm +++ b/scripts/engine.cm @@ -110,8 +110,6 @@ if (!io.exists('.cell')) { os.exit(1); } -io.mount(io.realdir("/") + "/.cell/modules") - var use_cache = {} var BASEPATH = 'scripts/base' + MOD_EXT @@ -129,20 +127,25 @@ globalThis.use = function use(file, ...args) { return use_cache[file] } - // Check for circular dependencies - if (loadingStack.includes(file)) { - let cycleIndex = loadingStack.indexOf(file) - let cyclePath = loadingStack.slice(cycleIndex).concat(file) - - throw new Error( - `Circular dependency detected while loading "${file}".\n` + - `Module chain: ${loadingStack.join(" -> ")}\n` + - `Cycle specifically: ${cyclePath.join(" -> ")}` - ) - } + // We'll check for circular dependencies after we determine the path var path = null - if (io.exists(file + MOD_EXT) && !io.is_directory(file + MOD_EXT)) { + + // First check if we're loading from a script and look in its directory + if (loadingStack.length > 0) { + var currentScript = loadingStack[loadingStack.length - 1] + if (currentScript.includes('/')) { + var currentDir = currentScript.substring(0, currentScript.lastIndexOf('/')) + // Try the file name as-is in the current directory + var localPath = currentDir + '/' + file + MOD_EXT + if (io.exists(localPath) && !io.is_directory(localPath)) { + path = localPath + } + } + } + + // If not found locally, check the normal path + if (!path && io.exists(file + MOD_EXT) && !io.is_directory(file + MOD_EXT)) { path = file + MOD_EXT } @@ -160,18 +163,20 @@ globalThis.use = function use(file, ...args) { return embed_mod } - // If we have a script path, check for circular dependency - if (inProgress[path]) { + // Check for circular dependencies using the resolved path + if (path && loadingStack.includes(path)) { + let cycleIndex = loadingStack.indexOf(path) + let cyclePath = loadingStack.slice(cycleIndex).concat(path) + throw new Error( `Circular dependency detected while loading "${file}".\n` + `Module chain: ${loadingStack.join(" -> ")}\n` + `Cycle specifically: ${cyclePath.join(" -> ")}` ) - } inProgress[path] = true - loadingStack.push(file) + loadingStack.push(path) // Determine the compiled file path in .cell directory var compiledPath = ".cell/build/" + io.realdir(path) + "/" + path + '.o' @@ -232,23 +237,21 @@ globalThis.use = function use(file, ...args) { return ret } -var configPath = '.cell/cell.toml' -if (io.exists(configPath)) { - try { - var toml = use('toml') - var configText = io.slurp(configPath) - var config = toml.decode(configText) - - // Override defaults with config values - if (config.ENETSERVICE !== undefined) - ENETSERVICE = config.ENETSERVICE - if (config.REPLYTIMEOUT !== undefined) - REPLYTIMEOUT = config.REPLYTIMEOUT - } catch (err) { - log.error(`Failed to load config from ${configPath}: ${err}`) - } +var shop = use('shop') +var config = shop.load_config() +var default_config = { + ar_timer: 60, + actor_memory:0, + net_service:0.1, + reply_timeout:60 } +config.system ??= {} +config.system.__proto__ = default_config + +ENETSERVICE = config.system.net_service +REPLYTIMEOUT = config.system.reply_timeout + globalThis.json = use('json') globalThis.text = use('text') var time = use('time') @@ -288,11 +291,6 @@ stone.p = function(object) return Object.isFrozen(object) } -var DOCPATH = 'scripts/doc' + MOD_EXT -var script = io.slurp(DOCPATH) -var fnname = "doc" -script = `(function ${fnname}() { ${script}; })` - /* When handling a message, the message appears like this: { @@ -629,7 +627,7 @@ function turn(msg) send_messages() } -actor_mod.register_actor(cell.id, turn, cell.args.main) +actor_mod.register_actor(cell.id, turn, cell.args.main, config.system) overling = cell.args.overling root = cell.args.root @@ -762,19 +760,21 @@ if (io.exists(progPath + ACTOR_EXT) && !io.is_directory(progPath + ACTOR_EXT)) { if (!prog) throw new Error(cell.args.program + " not found."); -var progDir = io.realdir(prog) + "/" + prog.substring(0, prog.lastIndexOf('/')) -var search = io.searchpath() -//io.unmount(search[1]) +var progDir = io.realdir(prog) + "/" + prog.substring(0, prog.lastIndexOf('/')) io.mount(progDir.replace(/\/+$/, '')) var progContent = io.slurp(prog) + var prog_script = `(function ${cell.args.program.name()}_start($_, arg) { var args = arg; ${progContent} })` + var val = js.eval(cell.args.program, prog_script)($_, cell.args.arg) if (val) throw new Error('Program must not return anything'); +log.console("WAYDOWN") + send_messages() })() \ No newline at end of file diff --git a/source/cell.c b/source/cell.c index 69e96eff..4189ac0a 100644 --- a/source/cell.c +++ b/source/cell.c @@ -365,7 +365,7 @@ cell_rt *get_actor(char *id) return actor; } -const char *register_actor(const char *id, cell_rt *actor, int mainthread) +const char *register_actor(const char *id, cell_rt *actor, int mainthread, JSValue config) { SDL_LockMutex(actors_mutex); if (shgeti(actors, id) != -1) { @@ -448,7 +448,7 @@ void set_actor_state(cell_rt *actor) END: if (actor->state == ACTOR_IDLE && !actor->ar && !has_upcoming) { if (JS_IsUndefined(actor->unneeded)) - actor->ar = SDL_AddTimerNS(SDL_SECONDS_TO_NS(0.1), actor_remove_cb, actor); + actor->ar = SDL_AddTimerNS(SDL_SECONDS_TO_NS(5), actor_remove_cb, actor); else { if (!isinf(actor->unneeded_secs)) actor->ar = SDL_AddTimerNS(SDL_SECONDS_TO_NS(actor->unneeded_secs), actor_remove_cb, actor); @@ -1553,12 +1553,12 @@ int main(int argc, char **argv) char scriptpath[PATH_MAX]; snprintf(scriptpath, sizeof(scriptpath), "%s/scripts", cell_parent_dir); -// char cellpath[PATH_MAX]; -// snprintf(scriptpath, sizeof(scriptpath), "%s/.cell", cell_parent_dir); + char cellpath[PATH_MAX]; + snprintf(cellpath, sizeof(cellpath), "%s/.cell/modules", cell_parent_dir); - PHYSFS_mount(scriptpath, NULL, 1); - PHYSFS_mount(cell_parent_dir, NULL, 0); -// PHYSFS_mount(cellpath, "cell://, 0); + PHYSFS_mount(scriptpath, NULL, 1); + PHYSFS_mount(cellpath, NULL, 0); + PHYSFS_mount(cell_parent_dir, NULL, 0); PHYSFS_setWriteDir(cell_parent_dir); free(cell_parent_dir); diff --git a/source/cell.h b/source/cell.h index d8a60cc1..6503188e 100644 --- a/source/cell.h +++ b/source/cell.h @@ -79,7 +79,7 @@ extern SDL_TLSID prosperon_id; extern cell_rt *root_cell; // first actor in the system cell_rt *create_actor(void *wota, void (*hook)(JSContext*)); -const char *register_actor(const char *id, cell_rt *actor, int mainthread); +const char *register_actor(const char *id, cell_rt *actor, int mainthread, JSValue config); void actor_disrupt(cell_rt *actor); const char *send_message(const char *id, void *msg); diff --git a/source/qjs_actor.c b/source/qjs_actor.c index 6157cb2d..be639f8f 100644 --- a/source/qjs_actor.c +++ b/source/qjs_actor.c @@ -18,7 +18,7 @@ cell_rt *js2actor(JSContext *js, JSValue v) return NULL; cell_rt *crt = JS_GetContextOpaque(js); - JSValue actor_data = JS_GetProperty(js, v, crt->actor_sym); + JSValue actor_data = JS_GetPropertyStr(js, v, "__ACTORDATA__"); if (JS_IsUndefined(actor_data)) { JS_FreeValue(js, actor_data); @@ -68,7 +68,7 @@ JSValue actor2js(JSContext *js, cell_rt *actor) cell_rt *crt = JS_GetContextOpaque(js); - JS_SetProperty(js, actor_obj, crt->actor_sym, actor_data); + JS_SetPropertyStr(js, actor_obj, "__ACTORDATA__", actor_data); return actor_obj; } @@ -100,7 +100,7 @@ JSC_CCALL(os_mailbox_push, JSC_CCALL(os_register_actor, cell_rt *rt = JS_GetContextOpaque(js); const char *id = JS_ToCString(js, argv[0]); - const char *err = register_actor(id, rt, JS_ToBool(js, argv[2])); + const char *err = register_actor(id, rt, JS_ToBool(js, argv[2]), argv[3]); if (err) return JS_ThrowInternalError(js, "Could not register actor: %s", err); rt->message_handle = JS_DupValue(js, argv[1]); rt->context = js; @@ -164,7 +164,7 @@ static const JSCFunctionListEntry js_actor_funcs[] = { MIST_FUNC_DEF(os, mailbox_exist, 1), MIST_FUNC_DEF(actor, delay, 2), MIST_FUNC_DEF(actor, removetimer, 1), - MIST_FUNC_DEF(os, register_actor, 2), + MIST_FUNC_DEF(os, register_actor, 4), MIST_FUNC_DEF(os, unneeded, 2), MIST_FUNC_DEF(os, destroy, 0), MIST_FUNC_DEF(actor, disrupt, 0), diff --git a/source/qjs_sdl_video.c b/source/qjs_sdl_video.c index 07a5d7ae..8c325b1c 100644 --- a/source/qjs_sdl_video.c +++ b/source/qjs_sdl_video.c @@ -1806,7 +1806,7 @@ JSValue js_sdl_video_use(JSContext *js) { JSValue startup = JS_NewObject(js); JS_SetPropertyStr(js,startup, "id", JS_NewStringLen(js,id,64)); - JS_SetPropertyStr(js,startup, "program", JS_NewString(js,"_sdl_video.js")); + JS_SetPropertyStr(js,startup, "program", JS_NewString(js,"prosperon/_sdl_video")); JS_SetPropertyStr(js,startup,"main",JS_NewBool(js,1)); void *wota = value2wota(js,startup, JS_UNDEFINED);