diff --git a/prosperon/scenetree.cm b/prosperon/scenetree.cm deleted file mode 100644 index 061a1b55..00000000 --- a/prosperon/scenetree.cm +++ /dev/null @@ -1,397 +0,0 @@ -var ex = this - -var input = use('input') - -var DEAD = Symbol() -var GARBAGE = Symbol() -var FILE = Symbol() -var TIMERS = Symbol() -var REGGIES = Symbol() -var UNDERLINGS = Symbol() -var OVERLING = Symbol() - -function add_timer(obj, fn, seconds) { - var timers = obj[TIMERS] - - var stop = function () { - if (!timer) return - timers.delete(stop) - timer.fn = null - timer = null - } - - function execute() { - if (fn) timer.remain = fn(stop.seconds) - if (!timer) return - if (!timer.remain) stop() - else stop.seconds = timer.remain - } - -// var timer = os.make_timer(execute) - timer.remain = seconds - - stop.remain = seconds - stop.seconds = seconds - - timers.push(stop) - return stop -} - -globalThis.Register = { - registries: [], - - add_cb(name) { - var n = {} - var fns = [] - - n.register = function (fn, oname) { - if (typeof fn != 'function') return - - var dofn = function (...args) { - fn(...args) - } - Object.defineProperty(dofn, 'name', {value:`do_${oname}`}) - - var left = 0 - var right = fns.length - 1 - dofn.layer = fn.layer - dofn.layer ??= 0 - - while (left <= right) { - var mid = Math.floor((left + right) / 2) - if (fns[mid] == dofn.layer) { - left = mid - break - } else if (fns[mid].layer < dofn.layer) left = mid + 1 - else right = mid - 1 - } - - fns.splice(left, 0, dofn) - return function () { - fns.delete(dofn) - } - } - - prosperon[name] = function (...args) { - fns.forEach(fn => { - fn(...args) - }) - } - Object.defineProperty(prosperon[name], 'name', {value:name}) - prosperon[name].fns = fns - - n.clear = function () { - fns = [] - } - - Register[name] = n - Register.registries[name] = n - return n - }, -} - -Register.pull_registers = function pull_registers(obj) { - var reggies = [] - for (var reg in Register.registries) { - if (typeof obj[reg] == "function") - reggies.push(reg) - } - return reggies -} - -Register.register_obj = function register_obj(obj, reg) { - var fn = obj[reg].bind(obj) - fn.layer = obj[reg].layer - var name = obj.ur ? obj.ur.name : obj.toString() - obj[TIMERS].push(Register.registries[reg].register(fn, name)) - if (!obj[reg].name) Object.defineProperty(obj[reg], 'name', {value:`${obj._file}_${reg}`}) -} - -Register.check_registers = function check_registers(obj) { - if (obj[REGGIES]) { - if (obj[REGGIES].length == 0) return - for (var reg of obj[REGGIES]) - Register.register_obj(obj,reg) - return - } - for (var reg in Register.registries) { - if (typeof obj[reg] == "function") - Register.register_obj(obj,reg) - } -} - -Register.add_cb("appupdate") -Register.add_cb("update").doc = "Called once per frame." -Register.add_cb("physupdate") -Register.add_cb("gui") -Register.add_cb("hud") -Register.add_cb("draw") -Register.add_cb("imgui") -Register.add_cb("app") - - -var actor = {} - -actor.toString = function() { return this[FILE] } - -actor.spawn = function spawn(script, config, actor_context) { - if (this[DEAD]) throw new Error("Attempting to spawn on a dead actor") - var prog - if (!script) { - prog = {} - prog.module_ret = {} - prog.prog_fn = function() {} - } else { - prog = script_fn(script) - if (!prog.prog_fn) throw new Error(`Script ${script} is not an actor script or has no actor component`) - } - - var underling - prog.module_ret.__proto__ = actor - underling = Object.create(prog.module_ret) - underling[OVERLING] = this - underling[FILE] = script - underling[TIMERS] = [] - underling[UNDERLINGS] = new Set() - - // Make $_ available to the actor (either passed context or the engine's $_) - var actor_dollar = actor_context || $_ - Object.defineProperty(underling, '$_', { - value: actor_dollar, - writable:false, - enumerable:false, - configurable:false - }) - - Object.defineProperty(underling, 'overling', { - get() { return this[OVERLING] }, - enumerable:true, - configurable:false - }) - - Object.defineProperty(underling, 'underlings', { - get() { return new Set(this[UNDERLINGS]) }, - enumerable:true, - configurable:false - }) - - Object.defineProperty(underling, 'spawn', { - value: function(script, config) { - return actor.spawn.call(this, script, config, actor_dollar) - }, - writable:false, - enumerable:true, - configurable:false - }) - - Object.defineProperty(underling, 'kill', { - value: actor.kill, - writable:false, - enumerable:true, - configurable:false - }) - - Object.defineProperty(underling, 'delay', { - value: actor.delay, - writable:false, - enumerable:true, - configurable:false - }) - - try { - // Pass $_ as a parameter to actor scripts - prog.prog_fn.call(underling, actor_dollar) - } catch(e) { throw e; } - - if (underling[DEAD]) return null; - - if (typeof config == 'object') Object.assign(underling, config) - - if (!underling[REGGIES]) - underling.__proto__[REGGIES] = Register.pull_registers(underling) - - Register.check_registers(underling) - if (underling.awake) underling.awake() - - this[UNDERLINGS].add(underling) - if (underling.tag) act.tag_add(underling.tag, underling) - - underling[GARBAGE] = underling.garbage - return underling -} - -actor.clear = function actor_clear() { - this[UNDERLINGS].forEach(p => { - p.kill() - }) - this[UNDERLINGS].clear() -} - -actor.kill = function kill() { - if (this[DEAD]) return - this[DEAD] = true - this[TIMERS].slice().forEach(t => t()) - delete this[TIMERS] - input.do_uncontrol(this) - - this.clear() - this[OVERLING][UNDERLINGS].delete(this) - delete this[UNDERLINGS] - - if (typeof this.garbage == "function") this.garbage() - if (typeof this.then == "function") this.then() - - act.tag_clear_guid(this) -} -actor.kill.doc = `Remove this actor and all its underlings from existence.` - -actor.delay = function(fn, seconds) { - if (this[DEAD]) return - add_timer(this, fn, seconds) -} -actor.delay.doc = `Call 'fn' after 'seconds' with 'this' set to the actor.` - -actor[UNDERLINGS] = new Set() - - -ex[cell.DOC] = ` -A set of utilities for iterating over a hierarchy of actor-like objects, as well -as managing tag-based lookups. Objects are assumed to have a "objects" property, -pointing to children or sub-objects, forming a tree. -` - -function eachobj(obj, fn) { - var val = fn(obj) - if (val) return val - for (var o in obj.objects) { - if (obj.objects[o] == obj) log.error(`Object ${obj.toString()} is referenced by itself.`) - val = eachobj(obj.objects[o], fn) - if (val) return val - } -} - -ex.all_objects = function (fn, startobj = world) { - return eachobj(startobj, fn) -} -ex.all_objects[cell.DOC] = ` -:param fn: A callback function that receives each object. If it returns a truthy value, iteration stops and that value is returned. -:param startobj: The root object at which iteration begins, default is the global "world". -:return: The first truthy value returned by fn, or null if none. -Iterate over each object (and its sub-objects) in the hierarchy, calling fn for each one. -` - -ex.find_object = function (fn, startobj = world) {} -ex.find_object[cell.DOC] = ` -:param fn: A callback or criteria to locate a particular object. -:param startobj: The root object at which search begins, default "world". -:return: Not yet implemented. -Intended to find a matching object within the hierarchy. -` - -var gtags = {} - -ex.tag_add = function (tag, obj) { - gtags[tag] ??= new Set() - gtags[tag].add(obj) -} -ex.tag_add[cell.DOC] = ` -:param tag: A string tag to associate with the object. -:param obj: The object to add under this tag. -:return: None -Associate the given object with the specified tag. Creates a new tag set if it does not exist. -` - -ex.tag_rm = function (tag, obj) { - delete gtags[tag].delete(obj) -} -ex.tag_rm[cell.DOC] = ` -:param tag: The tag to remove the object from. -:param obj: The object to remove from the tag set. -:return: None -Remove the given object from the specified tag’s set, if it exists. -` - -ex.tag_clear_guid = function (obj) { - for (var tag in gtags) gtags[tag].delete(obj) -} -ex.tag_clear_guid[cell.DOC] = ` -:param obj: The object whose tags should be cleared. -:return: None -Remove the object from all tag sets. -` - -ex.objects_with_tag = function (tag) { - if (!gtags[tag]) return [] - return Array.from(gtags[tag]) -} -ex.objects_with_tag[cell.DOC] = ` -:param tag: A string tag to look up. -:return: An array of objects associated with the given tag. -Retrieve all objects currently tagged with the specified tag. -` - -function parse_file(content, file) { - if (!content) return {} - if (content.match() - if (!/^\s*---\s*$/m.test(content)) { - var part = content.trim() - if (part.match(/return\s+[^;]+;?\s*$/)) { - return { module: part } - } - return { program: part } - } - var parts = content.split(/\n\s*---\s*\n/) - var module = parts[0] - if (!/\breturn\b/.test(module)) - throw new Error(`Malformed file: ${file}. Module section must end with a return statement.`) - - try { - new Function(module)() - } catch (e) { - throw new Error(`Malformed file: ${file}. Module section must end with a return statement.\n` + e.message) - } - - var pad = '\n'.repeat(module.split('\n').length + 4) - return { - module, - program: pad + parts[1] - } -} - -// path is the path of a module or script to resolve -var script_fn = function script_fn(path, args) { - var parsed = {} - var file = resources.find_script(path) - - if (!file) { - parsed.module_ret = bare_load(path) - if (!parsed.module_ret) throw new Error(`Module ${path} could not be created`) - return parsed - } - - var content = io.slurp(file) - var parsed = parse_file(content, file) - var module_name = file.name() - parsed.module_ret = bare_load(path) - parsed.module_ret ??= {} - - if (parsed.module) { - // Create a context object with args - var context = Object.create(parsed.module_ret) - context.__args__ = args || [] - var mod_script = `(function setup_${module_name}_module(){ var self = this; var $ = this; var exports = {}; var module = {exports: exports}; var define = null; var arg = this.__args__; ${parsed.module}})` - var module_fn = js.eval(file, mod_script) - parsed.module_ret = module_fn.call(context) - if (parsed.module_ret == null || parsed.module_ret == null) - throw new Error(`Module ${module_name} must return a value`) - parsed.module_fn = module_fn - } - - parsed.program ??= "" - var prog_script = `(function use_${module_name}($_) { var self = this; var $ = this.__proto__; ${parsed.program}})` - parsed.prog_fn = js.eval(file, prog_script) - - return parsed -}.hashify() - -return ex diff --git a/source/qjs_sdl_input.c b/source/qjs_sdl_input.c index 18475109..d6f966b0 100644 --- a/source/qjs_sdl_input.c +++ b/source/qjs_sdl_input.c @@ -505,7 +505,7 @@ static void event2wota_write(WotaBuffer *wb, const SDL_Event *e, int c) { wota_write_text(wb, "scancode"); wota_write_number(wb, (double)e->key.scancode); wota_write_text(wb, "mod"); - wota_write_number(wb, 0); + wota_write_number(wb, (double)e->key.mod); break; case SDL_EVENT_FINGER_MOTION: case SDL_EVENT_FINGER_DOWN: