improve spawn callback; more robust deletion of actors
This commit is contained in:
644
scripts/base.js
644
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 {}
|
||||
|
||||
@@ -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("");
|
||||
};
|
||||
|
||||
@@ -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(" ");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
85
scripts/draw2d.js
Normal file
85
scripts/draw2d.js
Normal file
@@ -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
|
||||
});
|
||||
};
|
||||
@@ -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")
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
22
scripts/path.js
Normal file
22
scripts/path.js
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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?.()
|
||||
|
||||
102
scripts/util.js
Normal file
102
scripts/util.js
Normal file
@@ -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
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user