diff --git a/scripts/base.js b/scripts/base.js index bbd3881a..5c3e6935 100644 --- a/scripts/base.js +++ b/scripts/base.js @@ -1,60 +1,22 @@ -Number.roman = { - M: 1000, - D: 500, - C: 100, - L: 50, - X: 10, - V: 5, - I: 1, -}; +Object.defineProperty(Array.prototype, "dofilter", { + value: function array_dofilter(fn) { + for (let i = 0; i < this.length; i++) { + if (!fn.call(this, this[i], i, this)) { + this.splice(i, 1); + i--; + } + } + return this; + }, +}); -function deep_copy(from) { - return json.decode(json.encode(from)); -} - -Object.methods = function (o) { - var m = []; - Object.keys(o).forEach(function (k) { - if (typeof o[k] === "function") m.push(k); - }); - return m; -}; -Object.methods.doc = "Retun an array of all functions an object has access to."; - -Object.dig = function (obj, path, def = {}) { - var pp = path.split("."); - for (var i = 0; i < pp.length - 1; i++) { - obj = obj[pp[i]] = obj[pp[i]] || {}; +Object.defineProperty(Array.prototype, "delete", { + value: function(item) { + var idx = this.indexOf(item); + if (idx > -1) this.splice(idx,1) + return undefined } - obj[pp[pp.length - 1]] = def; - return def; -}; - -Object.rkeys = function (o) { - var keys = []; - Object.keys(o).forEach(function (key) { - keys.push(key); - if (Object.isObject(o[key])) keys.push(Object.rkeys(o[key])); - }); - return keys; -}; - -Object.readonly = function (o, name, msg) { - var tmp = {}; - var prop = Object.getOwnPropertyDescriptor(o, name); - if (!prop) { - console.error(`Attempted to make property ${name} readonly, but it doesn't exist on ${o}.`); - return; - } - Object.defineProperty(tmp, name, prop); - prop.get = function () { - return tmp[name]; - }; - prop.set = function () { - console.warn(`Attempted to set readonly property ${name}`); - }; - Object.defineProperty(o, name, prop); -}; +}); Object.mixin = function (target, source) { if (typeof source !== "object") return target; @@ -62,155 +24,6 @@ Object.mixin = function (target, source) { return target; }; -Object.mix = function (...objs) { - var n = {}; - for (var o of objs) Object.mixin(n, o); - - return n; -}; - -Object.deepmixin = function (target, source) { - var o = source; - while (o !== Object.prototype) { - Object.mixin(target, o); - o = o.__proto__; - } -}; - -Object.deepfreeze = function (obj) { - for (var key in obj) { - if (typeof obj[key] === "object") Object.deepfreeze(obj[key]); - } - Object.freeze(obj); -}; - -/* Goes through each key and overwrites if it's present */ -Object.dainty_assign = function (target, source) { - Object.keys(source).forEach(function (k) { - if (typeof source[k] === "function") return; - if (!(k in target)) return; - if (Array.isArray(source[k])) target[k] = deep_copy(source[k]); - else if (Object.isObject(source[k])) Object.dainty_assign(target[k], source[k]); - else target[k] = source[k]; - }); -}; - -Object.isObject = function (o) { - return o instanceof Object && !(o instanceof Array); -}; - -Object.setter_assign = function (target, source) { - for (var key in target) if (Object.isAccessor(target, key) && typeof source[key] !== "undefined") target[key] = source[key]; -}; - -Object.containingKey = function (obj, prop) { - if (typeof obj !== "object") return undefined; - if (!(prop in obj)) return undefined; - - var o = obj; - while (o.__proto__ && !Object.hasOwn(o, prop)) o = o.__proto__; - - return o; -}; - -Object.access = function (obj, name) { - var dig = name.split("."); - - for (var i of dig) { - obj = obj[i]; - if (!obj) return undefined; - } - - return obj; -}; - -Object.isAccessor = function (obj, prop) { - var o = Object.containingKey(obj, prop); - if (!o) return false; - - var desc = Object.getOwnPropertyDescriptor(o, prop); - if (!desc) return false; - if (desc.get || desc.set) return true; - return false; -}; - -Object.mergekey = function (o1, o2, k) { - if (!o2) return; - if (typeof o2[k] === "object") { - if (Array.isArray(o2[k])) o1[k] = deep_copy(o2[k]); - else { - if (!o1[k]) o1[k] = {}; - if (typeof o1[k] === "object") Object.merge(o1[k], o2[k]); - else o1[k] = o2[k]; - } - } else o1[k] = o2[k]; -}; - -/* Same as merge from Ruby */ -/* Adds objs key by key to target */ -Object.merge = function (target, ...objs) { - for (var obj of objs) for (var key of Object.keys(obj)) Object.mergekey(target, obj, key); - - return target; -}; - -Object.totalmerge = function (target, ...objs) { - for (var obj of objs) for (var key in obj) Object.mergekey(target, obj, key); - - return target; -}; - -/* Returns a new object with undefined, null, and empty values removed. */ -Object.compact = function (obj) {}; - -Object.totalassign = function (to, from) { - for (var key in from) to[key] = from[key]; -}; - -/* Prototypes out an object and assigns values */ -Object.copy = function (proto, ...objs) { - var c = Object.create(proto); - for (var obj of objs) Object.mixin(c, obj); - return c; -}; - -/* OBJECT DEFININTIONS */ -Object.defHidden = function (obj, prop) { - Object.defineProperty(obj, prop, { enumerable: false, writable: true }); -}; - -Object.hide = function hide(obj, ...props) { - for (var prop of props) { - var p = Object.getOwnPropertyDescriptor(obj, prop); - if (p && p.enumerable) - Object.defineProperty(obj, prop, {...p, enumerable:false}); - } -}; - -Object.enumerable = function (obj, val, ...props) { - for (var prop of props) { - p = Object.getOwnPropertyDescriptor(obj, prop); - if (!p) continue; - p.enumerable = val; - Object.defineProperty(obj, prop, p); - } -}; - -Object.unhide = function (obj, ...props) { - for (var prop of props) { - var p = Object.getOwnPropertyDescriptor(obj, prop); - if (!p) continue; - p.enumerable = true; - Object.defineProperty(obj, prop, p); - } -}; - -Object.defineProperty(Object.prototype, "obscure", { - value: function (name) { - Object.defineProperty(this, name, { enumerable: false }); - }, -}); - Object.defineProperty(Object.prototype, "mixin", { value: function mixin(obj) { if (typeof obj === "string") obj = use(obj); @@ -219,108 +32,27 @@ Object.defineProperty(Object.prototype, "mixin", { }, }); -Object.defineProperty(Object.prototype, "hasOwn", { - value: function (x) { - return this.hasOwnProperty(x); - }, -}); - -Object.defineProperty(Object.prototype, "defn", { - value: function (name, val) { - Object.defineProperty(this, name, { - value: val, - writable: true, - configurable: true, - }); - }, -}); - -Object.defineProperty(Object.prototype, "nulldef", { - value: function (name, val) { - if (!this.hasOwnProperty(name)) this[name] = val; - }, -}); - -Object.defineProperty(Object.prototype, "prop_obj", { - value: function () { - return JSON.parse(JSON.stringify(this)); - }, -}); - -/* defc 'define constant'. Defines a value that is not writable. */ -Object.defineProperty(Object.prototype, "defc", { - value: function (name, val) { - Object.defineProperty(this, name, { - value: val, - writable: false, - enumerable: true, - configurable: false, - }); - }, -}); - -Object.defineProperty(Object.prototype, "stick", { - value: function (prop) { - Object.defineProperty(this, prop, { writable: false }); - }, -}); - -Object.defineProperty(Object.prototype, "harden", { - value: function (prop) { - Object.defineProperty(this, prop, { - writable: false, - configurable: false, - enumerable: false, - }); - }, -}); - -Object.defineProperty(Object.prototype, "deflock", { - value: function (prop) { - Object.defineProperty(this, prop, { configurable: false }); - }, -}); - -Object.defineProperty(Object.prototype, "forEach", { - value: function (fn) { - Object.values(this).forEach(fn); - }, -}); - -Object.empty = function empty(obj) { - return Object.keys(obj).length === 0; -}; - -Object.defineProperty(Object.prototype, "nth", { - value: function (x) { - if (this.empty || x >= Object.keys(this).length) return null; - - return this[Object.keys(this)[x]]; - }, -}); - -Object.defineProperty(Object.prototype, "filter", { - value: function (fn) { - return Object.values(this).filter(fn); - }, -}); - -Object.defineProperty(Object.prototype, "push", { - value: function (val) { - var str = val.toString(); - str = str.replaceAll(".", "_"); - var n = 1; - var t = str; - while (Object.hasOwn(this, t)) { - t = str + n; - n++; - } - this[t] = val; - return t; - }, -}); - /* STRING DEFS */ +Object.defineProperty(String.prototype, "rm", { + value: function (index, endidx = index + 1) { + return this.slice(0, index) + this.slice(endidx); + }, +}); + +Object.defineProperty(String.prototype, "tolast", { + value: function (val) { + var idx = this.lastIndexOf(val); + if (idx === -1) return this.slice(); + return this.slice(0, idx); + }, +}); + +Object.defineProperty(String.prototype, "dir", { + value: function () { + if (!this.includes("/")) return ""; + return this.tolast("/"); + }, +}); Object.defineProperty(String.prototype, "next", { value: function (char, from) { @@ -346,12 +78,10 @@ Object.defineProperty(String.prototype, "next", { }); Object.defineProperty(String.prototype, "prev", { - value: function (char, from, count) { + value: function (char, from, count = 0) { if (from > this.length - 1) return -1; else if (!from) from = this.length - 1; - if (!count) count = 0; - var find = this.slice(0, from).lastIndexOf(char); while (count > 1) { @@ -364,16 +94,6 @@ Object.defineProperty(String.prototype, "prev", { }, }); -Object.defineProperty(String.prototype, "shift", { - value: function (n) { - if (n === 0) return this.slice(); - - if (n > 0) return this.slice(n); - - if (n < 0) return this.slice(0, this.length + n); - }, -}); - Object.defineProperty(String.prototype, "strip_ext", { value: function () { return this.tolast("."); @@ -386,26 +106,6 @@ Object.defineProperty(String.prototype, "ext", { }, }); -Object.defineProperty(String.prototype, 'has_ext', { - value: function() { - var lastdot = this.lastIndexOf('.'); - return lastdot > 0 && lastdot < this.length-1; - } -}); - -Object.defineProperty(String.prototype, "set_ext", { - value: function (val) { - return this.strip_ext() + val; - }, -}); - -Object.defineProperty(String.prototype, "folder_same_name", { - value: function () { - var dirs = this.dir().split("/"); - return dirs.last() === this.name(); - }, -}); - Object.defineProperty(String.prototype, "up_path", { value: function () { var base = this.base(); @@ -460,18 +160,6 @@ Object.defineProperty(String.prototype, "base", { }, }); -Object.defineProperty(String.prototype, "splice", { - value: function (index, str) { - return this.slice(0, index) + str + this.slice(index); - }, -}); - -Object.defineProperty(String.prototype, "sub", { - value: function (index, str) { - return this.slice(0, index) + str + this.slice(index + str.length); - }, -}); - Object.defineProperty(String.prototype, "updir", { value: function () { if (this.lastIndexOf("/") === this.length - 1) return this.slice(0, this.length - 1); @@ -481,17 +169,6 @@ Object.defineProperty(String.prototype, "updir", { }, }); -Object.defineProperty(String.prototype, "uc", { - value: function () { - return this.toUpperCase(); - }, -}); -Object.defineProperty(String.prototype, "lc", { - value: function () { - return this.toLowerCase(); - }, -}); - /* ARRAY DEFS */ Object.defineProperty(Array.prototype, "copy", { value: function () { @@ -505,42 +182,6 @@ Object.defineProperty(Array.prototype, "copy", { }, }); -Object.defineProperty(Array.prototype, "forFrom", { - value: function (n, fn) { - for (var i = n; i < this.length; i++) fn(this[i]); - }, -}); - -Object.defineProperty(Array.prototype, "forTo", { - value: function (n, fn) { - for (var i = 0; i < n; i++) fn(this[i]); - }, -}); - -Object.defineProperty(Array.prototype, "dofilter", { - value: function array_dofilter(fn) { - for (let i = 0; i < this.length; i++) { - if (!fn.call(this, this[i], i, this)) { - this.splice(i, 1); - i--; - } - } - return this; - }, -}); - -Object.defineProperty(Array.prototype, "reversed", { - value: function array_reversed() { - var c = this.slice(); - return c.reverse(); - }, -}); - -Array.random = function random(arr) { - if (!Array.isArray(arr)) return; - return arr[Math.floor(Math.random()*arr.length)]; -} - function make_swizz() { function setelem(n) { return { @@ -673,62 +314,12 @@ function make_swizz() { } make_swizz(); -Object.defineProperty(Array.prototype, "newfirst", { - value: function (i) { - var c = this.slice(); - if (i >= c.length) return c; - - do { - c.push(c.shift()); - i--; - } while (i > 0); - - return c; - }, -}); - -Object.defineProperty(Array.prototype, "doubleup", { - value: function (n) { - var c = []; - this.forEach(function (x) { - for (var i = 0; i < n; i++) c.push(x); - }); - - return c; - }, -}); - -Object.defineProperty(Array.prototype, "mult", { - value: function (arr) { - var c = []; - for (var i = 0; i < this.length; i++) { - c[i] = this[i] * arr[i]; - } - return c; - }, -}); - -Object.defineProperty(Array.prototype, "apply", { - value: function fnapply(fn) { - this.forEach(function (x) { - x[fn].apply(x); - }); - }, -}); - -Object.defineProperty(Array.prototype, "sorted", { - value: function sorted() { - return this.toSorted(); - }, -}); - Object.defineProperty(Array.prototype, "equal", { value: function equal(b) { if (this.length !== b.length) return false; if (b == null) return false; if (this === b) return true; - - return JSON.stringify(this.sorted()) === JSON.stringify(b.sorted()); + return JSON.stringify(this) === JSON.stringify(b) for (var i = 0; i < this.length; i++) { if (!this[i] === b[i]) return false; @@ -738,122 +329,6 @@ Object.defineProperty(Array.prototype, "equal", { }, }); -Object.defineProperty(Array.prototype, "mapc", { - value: function (fn) { - return this.map(x => fn(x)); - }, -}); - -Object.defineProperty(Array.prototype, "mapvec", { - value: function (fn, b) { - return this.map((x, i) => fn(x, b[i])); - }, -}); - -Object.defineProperty(Array.prototype, "remove", { - value: function remove(b) { - var idx = this.indexOf(b); - - if (idx === -1) return false; - - this.splice(idx, 1); - - return true; - }, -}); - -Object.defineProperty(Array.prototype, "delete", { - value: function remove(b) { - var idx = this.indexOf(b); - - if (idx === -1) return false; - - this.splice(idx, 1); - - return true; - }, -}); - -Object.defineProperty(Array.prototype, "set", { - value: function set(b) { - if (this.length !== b.length) return; - - b.forEach(function (val, i) { - this[i] = val; - }, this); - }, -}); - -Object.defineProperty(Array.prototype, "flat", { - value: function flat() { - return [].concat.apply([], this); - }, -}); - -/* Return true if array contains x */ -Object.defineProperty(Array.prototype, "empty", { - get: function empty() { - return this.length === 0; - }, -}); - -Object.defineProperty(Array.prototype, "push_unique", { - value: function (x) { - var inc = !this.includes(x); - if (inc) this.push(x); - return inc; - }, -}); - -Object.defineProperty(Array.prototype, "unique", { - value: function () { - var c = []; - this.forEach(function (x) { - c.push_unique(x); - }); - return c; - }, -}); - -Object.defineProperty(Array.prototype, "unduped", { - value: function () { - return [...new Set(this)]; - }, -}); - -Object.defineProperty(Array.prototype, "findIndex", { - value: function (fn) { - var idx = -1; - this.every(function (x, i) { - if (fn(x)) { - idx = i; - return false; - } - - return true; - }); - - return idx; - }, -}); - -Object.defineProperty(Array.prototype, "find", { - value: function (fn) { - var ret; - - this.every(function (x) { - if (fn(x)) { - ret = x; - return false; - } - - return true; - }); - - return ret; - }, -}); - Object.defineProperty(Array.prototype, "search", { value: function (val) { for (var i = 0; i < this.length; i++) if (this[i] === val) return i; @@ -903,44 +378,3 @@ Object.defineProperty(Array.prototype, "mirrored", { return c; }, }); - -Object.defineProperty(Array.prototype, "forEachRight", { - value: function(fn) { - for (var i = this.length-1; i >= 0; i--) - fn(this[i], i); - } -}); - -Number.hex = function (n) { - var s = Math.floor(n).toString(16); - if (s.length === 1) s = "0" + s; - return s.uc(); -}; - -Object.defineProperty(Object.prototype, "lerp", { - value: function (to, t) { - var self = this; - var obj = {}; - - Object.keys(self).forEach(function (key) { - obj[key] = self[key].lerp(to[key], t); - }); - - return obj; - }, -}); - -/* POINT ASSISTANCE */ -function points2cm(points) { - var x = 0; - var y = 0; - var n = points.length; - points.forEach(function (p) { - x = x + p[0]; - y = y + p[1]; - }); - - return [x / n, y / n]; -} - -return {} diff --git a/scripts/color.js b/scripts/color.js index 01d04c76..9a60e4ff 100644 --- a/scripts/color.js +++ b/scripts/color.js @@ -1,3 +1,9 @@ +function tohex(n) { + var s = Math.floor(n).toString(16); + if (s.length === 1) s = "0" + s; + return s.toUpperCase(); +}; + var Color = { white: [255, 255, 255], black: [0, 0, 0], @@ -17,7 +23,7 @@ Color.editor.ur = Color.green; Color.tohtml = function (v) { var html = v.map(function (n) { - return Number.hex(n * 255); + return tohex(n * 255); }); return "#" + html.join(""); }; diff --git a/scripts/convert.js b/scripts/convert.js index 3eac3e94..ddf99e58 100644 --- a/scripts/convert.js +++ b/scripts/convert.js @@ -35,6 +35,16 @@ convert.deromanize = function (str) { return num; }; +convert.roman = { + M: 1000, + D: 500, + C: 100, + L: 50, + X: 10, + V: 5, + I: 1, +} + convert.buf2hex = function (buffer) { // buffer is an ArrayBuffer return [...new Uint8Array(buffer)].map(x => x.toString(16).padStart(2, "0")).join(" "); diff --git a/scripts/debug.js b/scripts/debug.js index 1d2b5ad8..543d0567 100644 --- a/scripts/debug.js +++ b/scripts/debug.js @@ -1,5 +1,6 @@ var render = use('render') var debug = os.use('debug') +var util = use('util') debug.build = function (fn) { if (!debug.show) return; @@ -192,7 +193,7 @@ debug.api.print_doc = function (name) { obj = eval(name); - if (!Object.isObject(obj)) { + if (!util.isObject(obj)) { console.warn("Cannot print the API of something that isn't an object."); return undefined; } diff --git a/scripts/diff.js b/scripts/diff.js index c36af29d..815c4a56 100644 --- a/scripts/diff.js +++ b/scripts/diff.js @@ -1,3 +1,4 @@ +var util = use('util') var diff = {} function deep_copy(from) { @@ -41,14 +42,14 @@ diff.ediff = function ediff(from, to) { } var diff = ediff(from[key], to[key]); - if (diff && !Object.empty(diff)) ret[key] = Object.values(ediff(v, [])); + if (diff && !util.isEmpty(diff)) ret[key] = Object.values(ediff(v, [])); return; } if (typeof v === "object" && v !== null) { var diff = ediff(v, to[key]); - if (diff && !Object.empty(diff)) ret[key] = diff; + if (diff && !util.isEmpty(diff)) ret[key] = diff; return; } @@ -60,7 +61,7 @@ diff.ediff = function ediff(from, to) { if (!to || v !== to[key]) ret[key] = v; }); - if (Object.empty(ret)) return undefined; + if (util.isEmpty(ret)) return undefined; return ret; } @@ -75,7 +76,7 @@ diff.samediff = function samediff(from, to) { return same; } Object.keys(from).forEach(function (k) { - if (Object.isObject(from[k])) { + if (util.isObject(from[k])) { samediff(from[k], to[k]); return; } diff --git a/scripts/draw2d.js b/scripts/draw2d.js new file mode 100644 index 00000000..bd4a0e94 --- /dev/null +++ b/scripts/draw2d.js @@ -0,0 +1,85 @@ +var render = use('render') +var vector = use('vector') + +var draw = {} + +draw.line = function render_line(points, color = Color.white, thickness = 1, pipeline = rect_pipeline) { + var mesh = os.make_line_prim(points,thickness, 0,0,color); + render.current_queue.push({ + type: 'geometry', + mesh, + pipeline, + first_index:0, + num_indices:mesh.num_indices + }); +}; + +draw.cross = function render_cross(pos, size, color = Color.red, thickness = 1, pipe = sprite_pipeline) { + var a = [pos.add([0, size]), pos.add([0, -size])]; + var b = [pos.add([size, 0]), pos.add([-size, 0])]; + draw.line(a, color, thickness); + draw.line(b, color, thickness); +}; + +draw.arrow = function render_arrow(start, end, color = Color.red, wingspan = 4, wingangle = 10, pipe = sprite_pipeline) { + var dir = vector.norm(end.sub(start)) + var wing1 = [vector.rotate(dir, wingangle).scale(wingspan).add(end), end]; + var wing2 = [vector.rotate(dir, -wingangle).scale(wingspan).add(end), end]; + render.line([start, end], color); + render.line(wing1, color); + render.line(wing2, color); +}; + +draw.rectangle = function render_rectangle(rect, color = Color.white, pipeline = rect_pipeline) { + var T = os.make_transform(); + T.rect(rect); + render.current_queue.push({ + type:'sprite', + transform:T, + color, + pipeline + }); +}; + +var tile_def = {repeat_x:true, repeat_y:true}; +draw.tile = function(image, rect, color = Color.white, tile = tile_def, pipeline = sprite_pipeline) +{ + if (!image) throw Error ('Need an image to render.') + if (typeof image === "string") + image = graphics.texture(image); + + var mesh = render._main.tile(image.texture, {x:0,y:0,width:image.texture.width,height:image.texture.height}, rect, tile); + current_queue.push({ + type:'geometry', + mesh, + image, + pipeline, + first_index:0, + num_indices:mesh.num_indices + }); +} + +// slice is given in pixels +var slice9_info = { + tile_top:true, + tile_bottom:true, + tile_left:true, + tile_right:true, + tile_center_x:true, + tile_center_right:true +}; +draw.slice9 = function slice9(image, rect = [0,0], slice = 0, color = Color.white, info = slice9_info, pipeline = sprite_pipeline) { + if (!image) throw Error ('Need an image to render.') + if (typeof image === "string") + image = graphics.texture(image); + + var mesh = render._main.slice9(image.texture, rect, gizmo.normalizeSpacing(slice), info); + current_queue.push({ + type: 'geometry', + mesh, + image, + pipeline, + first_index:0, + num_indices:mesh.num_indices + }); +}; diff --git a/scripts/engine.js b/scripts/engine.js index bc5011fa..f7dae30e 100644 --- a/scripts/engine.js +++ b/scripts/engine.js @@ -1,47 +1,11 @@ globalThis.console = os.use('console') globalThis.prosperon = os.use('prosperon') -globalThis.game = os.use('game') var io = os.use('io') -Object.defineProperty(Object.prototype, "object_id", { - value: function() { - return os.value_id(this); - } -}); - os.mem_limit.doc = "Set the memory limit of the runtime in bytes."; os.gc_threshold.doc = "Set the threshold before a GC pass is triggered in bytes. This is set to malloc_size + malloc_size>>1 after a GC pass."; os.max_stacksize.doc = "Set the max stack size in bytes."; -Object.defineProperty(String.prototype, "rm", { - value: function (index, endidx = index + 1) { - return this.slice(0, index) + this.slice(endidx); - }, -}); - -Object.defineProperty(String.prototype, "tolast", { - value: function (val) { - var idx = this.lastIndexOf(val); - if (idx === -1) return this.slice(); - return this.slice(0, idx); - }, -}); - -Object.defineProperty(String.prototype, "dir", { - value: function () { - if (!this.includes("/")) return ""; - return this.tolast("/"); - }, -}); - -Object.defineProperty(String.prototype, "folder", { - value: function () { - var dir = this.dir(); - if (!dir) return ""; - else return dir + "/"; - }, -}); - globalThis.Resources = {}; Resources.rm_fn = function rm_fn(fn, text) { @@ -241,12 +205,11 @@ io.slurpbytes = function(path) var ignore = io.slurp('.prosperonignore').split('\n'); var allpaths; -var tmpglob = io.glob; io.glob = function glob(pat) { if (!allpaths) allpaths = io.globfs(ignore); - return allpaths.filter(str => game.glob(pat,str)).sort(); + return allpaths.filter(str => io.match(pat,str)).sort(); } io.invalidate = function() @@ -352,69 +315,10 @@ console.doc = { clear: "Clear console.", }; -globalThis.global = globalThis; - var script = io.slurp("core/scripts/base.js") var fnname = "base" script = `(function ${fnname}() { ${script}; })` -Object.assign(globalThis,os.eval("core/scripts/base.js",script)()) - -function splitPath(path) { - return path.split('/').filter(part => part.length > 0); -} - -function splitPattern(pattern) { - return pattern.split('/').filter(part => part.length > 0); -} - -function matchPath(pathParts, patternParts) { - let pathIndex = 0; - let patternIndex = 0; - let starPatternIndex = -1; - let starPathIndex = -1; - - while (pathIndex < pathParts.length) { - if (patternIndex < patternParts.length) { - if (patternParts[patternIndex] === '**') { - // Record the position of '**' in the pattern - starPatternIndex = patternIndex; - // Record the current position in the path - starPathIndex = pathIndex; - // Move to the next pattern component - patternIndex++; - continue; - } else if ( - patternParts[patternIndex] === '*' || - patternParts[patternIndex] === pathParts[pathIndex] - ) { - // If the pattern is '*' or exact match, move to the next component - patternIndex++; - pathIndex++; - continue; - } - } - - if (starPatternIndex !== -1) { - // If there was a previous '**', backtrack - patternIndex = starPatternIndex + 1; - starPathIndex++; - pathIndex = starPathIndex; - continue; - } - - // No match and no '**' to backtrack to - return false; - } - - // Check for remaining '**' in the pattern - while (patternIndex < patternParts.length && patternParts[patternIndex] === '**') { - patternIndex++; - } - - return patternIndex === patternParts.length; -} - - +os.eval('core/scripts/base.js', script)() prosperon.SIGABRT = function() { @@ -433,6 +337,7 @@ function add_timer(obj, fn, seconds) var timers = obj.timers; var stop = function () { + if (!timer) return timers.delete(stop); timer.fn = undefined; timer = undefined; @@ -548,7 +453,7 @@ var script_fn = function script_fn(path) { var module_name = file.name() if (parsed.module) { - var mod_script = `(function setup_${module_name}_module(){ var self = this; var $ = this; ${parsed.module}})`; + var mod_script = `(function setup_${module_name}_module(){ var self = this; var $ = this; var exports = {}; var module = {exports:exports}; var define = undefined; ${parsed.module}})`; var module_fn = os.eval(file, mod_script) var module_ret = module_fn.call(); if (module_ret === undefined || module_ret === null) @@ -688,7 +593,7 @@ var Register = { fns.splice(left, 0, dofn); return function () { - fns.remove(dofn); + fns.delete(dofn) }; }; @@ -764,19 +669,24 @@ Register.add_cb("imgui"); Register.add_cb("app"); Register.add_cb("prerender"); +function cant_kill() +{ + throw Error("Can't kill an object in its spawning code. Move the kill command to awake."); +} + actor.toString = function() { return this.__file } actor.spawn = function spawn(script, config, callback) { + if (this.__dead__) throw Error("Attempting to spawn on a dead actor") var prog if (!script) { - prog = Object.create(actor) - if (callback) callback(prog) - return prog + 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`) } - 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); @@ -786,10 +696,16 @@ actor.spawn = function spawn(script, config, callback) { underling.timers = [] underling.underlings = new Set() - if (callback) callback(underling) + if (callback) callback(underling, { + message:"created" + }) + try{ prog.prog_fn.call(underling) } catch(e) {throw e} + if (underling.__dead__) + return undefined + if (typeof config === 'object') Object.assign(underling,config); if (!underling.__reggies) @@ -803,6 +719,12 @@ try{ if (underling.tag) search.tag_add(underling.tag, underling) + Object.defineProperty(underling, 'garbage', { + configurable: false, + writable: false, + value: underling.garbage + }) + return underling; }; @@ -821,7 +743,7 @@ var input = use('input') actor.kill = function kill() { if (this.__dead__) return; this.__dead__ = true; - this.timers.forEachRight(t => t()) + this.timers.slice().forEach(t => t()) // slice in case something is removed from timers while running delete this.timers input.do_uncontrol(this); Event.rm_obj(this); @@ -853,29 +775,9 @@ actor.interval = function interval(fn, seconds) { return stop; }; -actor.underlings = new Set() - -globalThis.app = actor.spawn() -app.garbage = function () { - os.exit(0); -}; - -globalThis.world = app; - var search = use('search') -/* MATH EXTENSIONS */ -Object.defineProperty(Number.prototype, "lerp", { - value: function (to, t) { - return Math.lerp(this, to, t); - }, -}); +actor.underlings = new Set() -Object.defineProperty(Number.prototype, "clamp", { - value: function (from, to) { - return Math.clamp(this, from, to); - }, -}); - -global.mixin("color"); -global.mixin("std") +globalThis.mixin("color"); +globalThis.mixin("std") diff --git a/scripts/graphics.js b/scripts/graphics.js index c18d97b1..4da0b970 100644 --- a/scripts/graphics.js +++ b/scripts/graphics.js @@ -159,6 +159,24 @@ function make_spritesheet(paths, width, height) sheet.load_gpu(); } +var fontcache = {}; +var datas= []; +graphics.get_font = function get_font(path,size) +{ + var parts = path.split('.'); + if (!isNaN(parts[1])) { + path = parts[0]; + size = Number(parts[1]); + } + path = Resources.find_font(path); + var fontstr = `${path}.${size}`; + if (fontcache[fontstr]) return fontcache[fontstr]; + + var data = io.slurpbytes(path); + fontcache[fontstr] = os.make_font(data,size); + fontcache[fontstr].texture = prosperon.gpu.load_texture(fontcache[fontstr].surface); + return fontcache[fontstr]; +} graphics.semver = {}; graphics.semver.valid = function (v, range) { diff --git a/scripts/input.js b/scripts/input.js index 204f6aa3..159c5568 100644 --- a/scripts/input.js +++ b/scripts/input.js @@ -1,4 +1,5 @@ var input = os.use('input') +var util = use('util') var downkeys = {}; @@ -110,7 +111,7 @@ input.mouse.normal.doc = "Set the mouse to show again after hiding."; input.keyboard = {}; input.keyboard.down = function (code) { if (typeof code === "number") return downkeys[code]; - if (typeof code === "string") return downkeys[code.uc().charCodeAt()] || downkeys[code.lc().charCodeAt()]; + if (typeof code === "string") return downkeys[code.toUpperCase().charCodeAt()] || downkeys[code.toLowerCase().charCodeAt()]; return undefined; }; @@ -176,9 +177,7 @@ input.action = { input.tabcomplete = function tabcomplete(val, list) { if (!val) return val; - list.dofilter(function (x) { - return x.startsWith(val); - }); + list = filter(x => x.startsWith(val)) if (list.length === 1) { return list[0]; @@ -186,7 +185,7 @@ input.tabcomplete = function tabcomplete(val, list) { var ret = undefined; var i = val.length; - while (!ret && !Object.empty(list)) { + while (!ret && list.length !== 0) { var char = list[0][i]; if ( !list.every(function (x) { @@ -196,9 +195,7 @@ input.tabcomplete = function tabcomplete(val, list) { ret = list[0].slice(0, i); else { i++; - list.dofilter(function (x) { - return x.length - 1 > i; - }); + list = list.filter(x => x.length-1 > i) } } @@ -218,7 +215,7 @@ var Player = { }, mouse_input(type, ...args) { - for (var pawn of this.pawns.reversed()) { + for (var pawn of [...this.pawns].reverse()) { if (typeof pawn.inputs?.mouse?.[type] === "function") { pawn.inputs.mouse[type].call(pawn, ...args); pawn.inputs.post?.call(pawn); @@ -228,7 +225,7 @@ var Player = { }, char_input(c) { - for (var pawn of this.pawns.reversed()) { + for (var pawn of [...this.pawns].reverse()) { if (typeof pawn.inputs?.char === "function") { pawn.inputs.char.call(pawn, c); pawn.inputs.post?.call(pawn); @@ -238,7 +235,7 @@ var Player = { }, joy_input(name, joystick) { - for (var pawn of this.pawns.reversed()) { + for (var pawn of [...this.pawns].reverse()) { if (!pawn.inputs) return; if (!pawn.inputs.joystick) return; if (!pawn.inputs.joystick[name]) return; @@ -255,8 +252,7 @@ var Player = { }, raw_input(cmd, state, ...args) { - this.pawns = this.pawns.filter(x => x.inputs); - for (var pawn of this.pawns.reversed()) { + for (var pawn of [...this.pawns].reverse()) { var inputs = pawn.inputs; if (!inputs[cmd]) { @@ -294,27 +290,25 @@ var Player = { obj_controlled(obj) { for (var p in Player.players) { - if (p.pawns.contains(obj)) return true; + if (p.pawns.has(obj)) return true; } return false; }, print_pawns() { - for (var pawn of this.pawns.reversed()) console.log(pawn.toString()); + [...this.pawns].reverse().forEach(x => console.log(x)) }, create() { var n = Object.create(this); - n.pawns = []; + n.pawns = new Set() n.gamepads = []; this.players.push(n); this[this.players.length - 1] = n; return n; }, - pawns: [], - control(pawn) { if (!pawn) return @@ -322,18 +316,18 @@ var Player = { if (!pawn.inputs) throw new Error("attempted to control a pawn without any input object."); - this.pawns.push_unique(pawn); + this.pawns.add(pawn); }, uncontrol(pawn) { - this.pawns = this.pawns.filter(x => x !== pawn); + this.pawns.delete(pawn) }, }; input.do_uncontrol = function input_do_uncontrol(pawn) { -// if (!pawn.inputs) return; + if (!pawn.inputs) return; Player.players.forEach(function (p) { - p.pawns = p.pawns.filter(x => x !== pawn) + p.pawns.delete(pawn) }); }; diff --git a/scripts/lodash.js b/scripts/lodash.js deleted file mode 100644 index 7ea09417..00000000 --- a/scripts/lodash.js +++ /dev/null @@ -1,10 +0,0 @@ -var lodash = {}; -lodash.get = function (obj, path, defValue) { - if (!path) return undefined; - // Check if path is string or array. Regex : ensure that we do not have '.' and brackets. - var pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g); - var result = pathArray.reduce((prevObj, key) => prevObj && prevObj[key], obj); - return result === undefined ? defValue : result; -} - -return lodash diff --git a/scripts/path.js b/scripts/path.js new file mode 100644 index 00000000..3930b662 --- /dev/null +++ b/scripts/path.js @@ -0,0 +1,22 @@ +var path = {} + +path.name = function name(str) +{ + var idx = str.indexOf("/"); + if (idx === -1) return str.tolast("."); + return str.fromlast("/").tolast("."); +} + +path.dir = function (str) { + if (!str.includes("/")) return ""; + var idx = str.lastIndexOf(s + return str.tolast("/"); +} + +path.folder = function(str) { + var dir = this.dir(); + if (!dir) return ""; + else return dir + "/"; +} + +return path diff --git a/scripts/pmath.js b/scripts/pmath.js index 616558ad..4100bedd 100644 --- a/scripts/pmath.js +++ b/scripts/pmath.js @@ -60,4 +60,17 @@ pmath.sign = function (n) { return n >= 0 ? 1 : -1; }; +pmath.points2cm = function(points) +{ + var x = 0; + var y = 0; + var n = points.length; + points.forEach(function (p) { + x = x + p[0]; + y = y + p[1]; + }); + + return [x / n, y / n]; +} + return pmath diff --git a/scripts/render.js b/scripts/render.js index 80e8cdc0..65b5dfb7 100644 --- a/scripts/render.js +++ b/scripts/render.js @@ -5,9 +5,7 @@ var gizmo = use('gizmos') var vector = use('vector') var search = use('search') -game.timescale = 1 - -prosperon.window = game.engine_start(config); +prosperon.window = os.engine_start(config); var driver = "vulkan" switch(os.sys()) { @@ -831,16 +829,6 @@ render.line = function render_line(points, color = Color.white, thickness = 1, p }); }; -render.dbg_line = function(points, color = Color.white) -{ - -} - -render.dbg_point = function(points, color = Color.white) -{ - -} - /* All draw in screen space */ render.point = function (pos, size, color = Color.blue) { render._main.point(pos,color); @@ -896,9 +884,11 @@ render.particles = function render_particles(emitter, pipeline = sprite_pipeline }); } -render.text = function text(text, rect, font = prosperon.font, size = 0, color = Color.white, wrap = 0, pipeline = sprite_pipeline) { +var sysfont = graphics.get_font('fonts/c64.ttf', 8); + +render.text = function text(text, rect, font = sysfont, size = 0, color = Color.white, wrap = 0, pipeline = sprite_pipeline) { if (typeof font === 'string') - font = render.get_font(font) + font = graphics.get_font(font) var mesh = os.make_text_buffer(text, rect, 0, color, wrap, font); // full_upload(mesh) @@ -915,7 +905,7 @@ render.text = function text(text, rect, font = prosperon.font, size = 0, color = return; if (typeof font === 'string') - font = render.get_font(font); + font = graphics.get_font(font); if (!font) return; var pos = [rect.x,rect.y]; @@ -928,7 +918,7 @@ render.text = function text(text, rect, font = prosperon.font, size = 0, color = render.text_size = function(str, font, ...args) { if (typeof font === 'string') - font = render.get_font(font); + font = graphics.get_font(font); return font.text_size(str, ...args); } @@ -996,32 +986,6 @@ render.mask = function mask(image, pos, scale, rotation = 0, ref = 1) render.draw(shape.quad); } -function calc_image_size(img) -{ - return [img.texture.width*img.rect.width, img.texture.height*img.rect.height]; -} - - -function tile(image, rect = [0,0], color = Color.white, repeat = {}) -{ - if (!image) throw Error ('Need an image to render.') - if (typeof image === "string") - image = graphics.texture(image); - - render._main.tile(image, rect, undefined, 1); - return; - - var tex = image.texture; - if (!tex) return; - - var image_size = calc_image_size(image); //image.size; - - var size = [rect.width ? rect.width : image_size.x, rect.height ? rect.height : image_size.y]; - - render._main.tile(image.texture, rect, image.rect, 1); - return; -} - var std_sprite_cmd = { type: 'sprite', pipeline: sprite_pipeline, @@ -1130,34 +1094,11 @@ render.slice9 = function slice9(image, rect = [0,0], slice = 0, color = Color.wh var textssbos = []; var tdraw = 0; -var fontcache = {}; -var datas= []; -render.get_font = function get_font(path,size) -{ - var parts = path.split('.'); - if (!isNaN(parts[1])) { - path = parts[0]; - size = Number(parts[1]); - } - path = Resources.find_font(path); - var fontstr = `${path}.${size}`; - if (fontcache[fontstr]) return fontcache[fontstr]; - - var data = io.slurpbytes(path); - fontcache[fontstr] = os.make_font(data,size); - fontcache[fontstr].texture = render._main.load_texture(fontcache[fontstr].surface); - return fontcache[fontstr]; -} - render.doc = "Draw shapes in screen space."; render.cross.doc = "Draw a cross centered at pos, with arm length size."; render.arrow.doc = "Draw an arrow from start to end, with wings of length wingspan at angle wingangle."; render.rectangle.doc = "Draw a rectangle, with its corners at lowerleft and upperright."; -render.draw = function render_draw(mesh, material, pipeline) { - -}; - render.viewport = function(rect) { render._main.viewport(rect); @@ -1217,7 +1158,8 @@ function screen2hud(pos) */ prosperon.make_camera = function make_camera() { - var cam = world.spawn(); + return; +/* var cam = world.spawn(); cam.near = 1; cam.far = -1000; cam.ortho = true; // True if this is a 2d camera @@ -1228,7 +1170,7 @@ prosperon.make_camera = function make_camera() { cam.screen2cam = screen2cam; cam.screen2hud = screen2hud; cam.zoom = 1; // the "scale factor" this camera demonstrates - return cam; + return cam;*/ }; var screencolor; @@ -1367,6 +1309,7 @@ var last_frame_time = 0; var frame_t = 0; // Ran once per frame var fpses = []; +var timescale = 1 render.process = function process() { var now = profile.now(); var dt = now - last_frame_time; @@ -1379,7 +1322,7 @@ render.process = function process() { frame_t = last_frame_time; - game.engine_input(e => { + os.engine_input(e => { prosperon[e.type]?.(e); }); @@ -1388,9 +1331,9 @@ render.process = function process() { prosperon.appupdate(dt) input.procdown() - emitters.update(dt * game.timescale) - os.update_timers(dt * game.timescale) - prosperon.update(dt*game.timescale) + emitters.update(dt * timescale) + os.update_timers(dt * timescale) + prosperon.update(dt*timescale) if (sim.mode === "step") sim.pause(); if (sim.mode === "play" || sim.mode === "step") { @@ -1399,8 +1342,8 @@ render.process = function process() { while (physlag > physics.delta) { physlag -= physics.delta; - prosperon.phys2d_step(physics.delta * game.timescale); - prosperon.physupdate(physics.delta * game.timescale); + prosperon.phys2d_step(physics.delta * timescale); + prosperon.physupdate(physics.delta * timescale); } */ } @@ -1419,7 +1362,7 @@ render.process = function process() { // Some initialization shader_type = render._main.shader_format()[0]; -prosperon.font = render.get_font('fonts/c64.ttf', 8); + std_sampler = render._main.make_sampler({ min_filter: "nearest", diff --git a/scripts/std.js b/scripts/std.js index dbd65c71..07eb5f7e 100644 --- a/scripts/std.js +++ b/scripts/std.js @@ -5,6 +5,7 @@ else os.user = os.env("USER"); var sim = use('sim') var io = use('io') +var util = use('util') /*var ignore; if (ignore = io.slurp('.prosperonignore')) { @@ -212,8 +213,20 @@ Cmdline.register_order( function (argv) { if (argv[0]) io.chdir(argv[0]); - if (io.exists("main.js")) app.spawn("main.js") - else app.spawn("nogame.js"); + var app + if (io.exists("main.js")) + app = actor.spawn("main.js", {}, function(underling, msg) { + if (msg.message !== "created") return; + Object.defineProperty(underling, 'then', { + configurable:false, + writable:false, + value:function() { + os.exit(0); + } + }); + }) + else + app = actor.spawn("nogame.js"); var ren = use('render') @@ -355,7 +368,7 @@ Cmdline.register_order( var obj = json.decode(io.slurp(file)); var nn = nota.encode(obj); - io.slurpwrite(file.set_ext(".nota"), nn); + io.slurpwrite(file.strip_ext() + ".nota", nn); } }, "Create a nota file from a json.", @@ -372,7 +385,7 @@ Cmdline.register_order( say(file.ext()); var obj = nota.decode(io.slurp(file)); var nn = json.encode(obj); - io.slurpwrite(file.set_ext(".json", nn)); + io.slurpwrite(file.strip_ext() + ".json", nn); } }, "Create a JSON from a nota.", @@ -435,7 +448,7 @@ Cmdline.print_order = function (fn) { Cmdline.register_order( "help", function (order) { - if (!Object.empty(order)) { + if (!util.isEmpty(order)) { var orfn = Cmdline.orders[order]; if (!orfn) { diff --git a/scripts/tween.js b/scripts/tween.js index 1e105646..db65b0ca 100644 --- a/scripts/tween.js +++ b/scripts/tween.js @@ -1,4 +1,5 @@ var profile = use('profile') +var util = use('util') /* Take numbers from 0 to 1 and remap them to easing functions */ var Ease = { @@ -127,7 +128,7 @@ var tween = function (from, to, time, fn, cb) { var update = function tween_update(dt) { var elapsed = profile.now() - start; - fn(from.lerp(to, elapsed / time)); + fn(util.obj_lerp(from,to,elapsed/time)); if (elapsed >= time) { fn(to) cb?.() diff --git a/scripts/util.js b/scripts/util.js new file mode 100644 index 00000000..57eddf92 --- /dev/null +++ b/scripts/util.js @@ -0,0 +1,102 @@ +var util = {} + +util.deepfreeze = function (obj) { + for (var key in obj) { + if (typeof obj[key] === "object") Object.deepfreeze(obj[key]); + } + Object.freeze(obj); +}; + +util.dainty_assign = function (target, source) { + Object.keys(source).forEach(function (k) { + if (typeof source[k] === "function") return; + if (!(k in target)) return; + if (Array.isArray(source[k])) target[k] = deep_copy(source[k]); + else if (Object.isObject(source[k])) Object.dainty_assign(target[k], source[k]); + else target[k] = source[k]; + }); +}; + +util.get = function (obj, path, defValue) { + if (!path) return undefined; + // Check if path is string or array. Regex : ensure that we do not have '.' and brackets. + var pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g); + var result = pathArray.reduce((prevObj, key) => prevObj && prevObj[key], obj); + return result === undefined ? defValue : result; +} + +util.isObject = function (o) { + return o instanceof Object && !(o instanceof Array); +}; + +util.isEmpty = function(o) { + return Object.keys(obj).length === 0; +} + +util.dig = function (obj, path, def = {}) { + var pp = path.split("."); + for (var i = 0; i < pp.length - 1; i++) { + obj = obj[pp[i]] = obj[pp[i]] || {}; + } + obj[pp[pp.length - 1]] = def; + return def; +}; + +util.access = function (obj, name) { + var dig = name.split("."); + + for (var i of dig) { + obj = obj[i]; + if (!obj) return undefined; + } + + return obj; +}; + +function deep_copy(from) { + return json.decode(json.encode(from)); +} + + + +util.mergekey = function (o1, o2, k) { + if (!o2) return; + if (typeof o2[k] === "object") { + if (Array.isArray(o2[k])) o1[k] = deep_copy(o2[k]); + else { + if (!o1[k]) o1[k] = {}; + if (typeof o1[k] === "object") util.merge(o1[k], o2[k]); + else o1[k] = o2[k]; + } + } else o1[k] = o2[k]; +}; + +/* Same as merge from Ruby */ +/* Adds objs key by key to target */ +util.merge = function (target, ...objs) { + for (var obj of objs) for (var key of Object.keys(obj)) util.mergekey(target, obj, key); + + return target; +}; + +util.copy = function (proto, ...objs) { + var c = Object.create(proto); + for (var obj of objs) Object.mixin(c, obj); + return c; +}; + +util.obj_lerp = function(a,b,t) +{ + if (a.lerp) + return a.lerp(b,t); + + var obj = {}; + + Object.keys(a).forEach(function (key) { + obj[key] = a[key].lerp(b[key], t); + }); + + return obj; +} + +return util diff --git a/source/jsffi.c b/source/jsffi.c index 4b9a6a68..981cdd7d 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -29,6 +29,8 @@ #include "cgltf.h" #include "physfs.h" +#include "wildmatch.h" + #include "freelist.h" #include "sprite.h" @@ -261,13 +263,6 @@ int JS_GETBOOL(JSContext *js, JSValue v, const char *prop) return r; } -JSValue js_getpropertystr(JSContext *js, JSValue v, const char *str) -{ - JSValue ret = JS_GetPropertyStr(js, v, str); - JS_FreeValue(js,ret); - return ret; -} - JSValue js_getproperty(JSContext *js, JSValue v, JSAtom atom) { JSValue ret = JS_GetProperty(js, v, atom); @@ -2226,6 +2221,17 @@ static const JSCFunctionListEntry js_array_funcs[] = { PROTO_FUNC_DEF(array, lerp, 2) }; +JSC_CCALL(number_lerp, + double a = js2number(js,self); + double b = js2number(js,argv[0]); + double t = js2number(js,argv[1]); + return number2js(js, (b-a)*t+a); +) + +static const JSCFunctionListEntry js_number_funcs[] = { + PROTO_FUNC_DEF(number, lerp, 2), +}; + #define JS_SDL_PROP(JS, VAL, SDLPROP, PROP) \ { \ JSValue v = JS_GetPropertyStr(JS,VAL,#PROP); \ @@ -2235,7 +2241,7 @@ JS_FreeCString(JS,str); \ JS_FreeValue(js,v); \ } \ -JSC_SCALL(game_engine_start, +JSC_SCALL(os_engine_start, JSValue p = argv[0]; JS_SDL_PROP(js, p, SDL_PROP_APP_METADATA_NAME_STRING, name) JS_SDL_PROP(js, p, SDL_PROP_APP_METADATA_VERSION_STRING, version) @@ -2629,7 +2635,7 @@ static JSValue event2js(JSContext *js, SDL_Event event) void gui_input(SDL_Event *e); // Polls and handles all input events -JSC_CCALL(game_engine_input, +JSC_CCALL(os_engine_input, SDL_Event event; while (SDL_PollEvent(&event)) { #ifndef NEDITOR @@ -2640,19 +2646,6 @@ JSC_CCALL(game_engine_input, uncaught_exception(js,ret); } ) -#include "wildmatch.h" -JSC_SSCALL(game_glob, - if (wildmatch(str, str2, WM_PATHNAME | WM_PERIOD | WM_WILDSTAR) == WM_MATCH) - ret = JS_NewBool(js,1); - else - ret = JS_NewBool(js, 0); -) - -static const JSCFunctionListEntry js_game_funcs[] = { - MIST_FUNC_DEF(game, engine_start, 1), - MIST_FUNC_DEF(game, engine_input,1), - MIST_FUNC_DEF(game, glob, 2), -}; JSC_CCALL(camera_list, int num; @@ -5694,6 +5687,14 @@ int globfs_cb(struct globdata *data, char *dir, char *file) return 1; } + +JSC_SSCALL(io_match, + if (wildmatch(str, str2, WM_PATHNAME | WM_PERIOD | WM_WILDSTAR) == WM_MATCH) + ret = JS_NewBool(js,1); + else + ret = JS_NewBool(js, 0); +) + JSC_CCALL(io_globfs, ret = JS_NewArray(js); struct globdata data; @@ -5730,6 +5731,7 @@ static const JSCFunctionListEntry js_io_funcs[] = { MIST_FUNC_DEF(io, mkdir, 1), MIST_FUNC_DEF(io,stat,1), MIST_FUNC_DEF(io, globfs, 1), + MIST_FUNC_DEF(io, match, 2), MIST_FUNC_DEF(io, exists, 1), MIST_FUNC_DEF(io, mount, 1), MIST_FUNC_DEF(io,unmount,1), @@ -7190,7 +7192,6 @@ typedef struct { #define MISTLINE(NAME) { #NAME, js_##NAME##_funcs, countof(js_##NAME##_funcs) } static ModuleEntry module_registry[] = { - MISTLINE(game), MISTLINE(io), MISTLINE(input), MISTLINE(prosperon), @@ -7207,8 +7208,6 @@ static ModuleEntry module_registry[] = { JSC_SCALL(os_use, SDL_SharedObject *ptr; - printf("str %s found? %d\n", str, access(str,F_OK)); - printf("obj? %p\n", SDL_LoadObject(str)); if (access(str, F_OK) != 0 || !(ptr = SDL_LoadObject(str))) { for (int i = 0; i < sizeof(module_registry)/sizeof(module_registry[0]); i++) { if (strcmp(str,module_registry[i].name) == 0) { @@ -7232,7 +7231,8 @@ JSC_SCALL(os_use, ) JSC_SSCALL(os_trimchr, - int len = js2number(js,js_getpropertystr(js,argv[0], "length")); + int len; + JS_GETPROP(js,len,argv[0],length,number) const char *start = str; while (*start == *str2) @@ -7246,6 +7246,8 @@ JSC_SSCALL(os_trimchr, ) static const JSCFunctionListEntry js_os_funcs[] = { + MIST_FUNC_DEF(os, engine_start, 1), + MIST_FUNC_DEF(os, engine_input, 1), MIST_FUNC_DEF(os, turbulence, 4), MIST_FUNC_DEF(os, model_buffer, 1), MIST_FUNC_DEF(os, clean_transforms, 0), @@ -7634,9 +7636,17 @@ void ffi_load(JSContext *js) { QJSGLOBALCLASS(os); - JSValue array_proto = js_getpropertystr(js,globalThis, "Array"); - array_proto = js_getpropertystr(js,array_proto, "prototype"); + JSValue jsarray = JS_GetPropertyStr(js,globalThis, "Array"); + JSValue array_proto = JS_GetPropertyStr(js,jsarray, "prototype"); JS_SetPropertyFunctionList(js, array_proto, js_array_funcs, countof(js_array_funcs)); + JS_FreeValue(js,jsarray); + JS_FreeValue(js,array_proto); + + JSValue jsnumber = JS_GetPropertyStr(js,globalThis, "Number"); + JSValue number_proto = JS_GetPropertyStr(js,jsnumber, "prototype"); + JS_SetPropertyFunctionList(js, number_proto, js_number_funcs, countof(js_number_funcs)); + JS_FreeValue(js,jsnumber); + JS_FreeValue(js,number_proto); JS_SetPropertyStr(js, globalThis, "layout", js_layout_use(js)); JS_SetPropertyStr(js, globalThis, "soloud", js_soloud_use(js));