prosperon/scripts/actor.js

176 lines
3.9 KiB
JavaScript
Raw Normal View History

var actor = {};
2024-08-05 15:26:18 -05:00
var actor_urs = {};
2024-08-06 16:05:24 -05:00
var script_times = {};
var actor_spawns = {};
2024-08-05 15:26:18 -05:00
globalThis.class_use = function(script, config, base, callback)
{
2024-08-06 16:05:24 -05:00
var file = Resources.find_script(script);
if (!file) {
var ret = Object.create(base);
if (callback) callback(ret);
return ret;
}
if (!actor_urs[file]) {
2024-08-05 15:26:18 -05:00
var newur = Object.create(base);
2024-08-06 16:05:24 -05:00
actor_urs[file] = newur;
script_times[file] = io.mod(file);
actor_spawns[file] = [];
2024-08-05 15:26:18 -05:00
}
2024-08-06 16:05:24 -05:00
var padawan = Object.create(actor_urs[file]);
actor_spawns[file].push(padawan);
padawan._file = file;
2024-08-27 13:57:38 -05:00
padawan._root = file.dir();
2024-08-05 15:26:18 -05:00
if (callback) callback(padawan);
2024-08-05 15:26:18 -05:00
var script = Resources.replstrs(file);
script = `(function() {
var self = this;
var $ = this.__proto__;
${script};
})`;
var fn = os.eval(file,script);
fn.call(padawan);
2024-09-06 18:51:09 -05:00
if (typeof config === 'object')
Object.merge(padawan,config);
2024-08-05 15:26:18 -05:00
return padawan;
}
2024-08-06 16:05:24 -05:00
actor.hotreload = function()
{
profile.cache("hotreload", "check");
for (var i in script_times) {
if (io.mod(i) > script_times[i]) {
say(`HOT RELAODING ${i}`);
script_times[i] = io.mod(i);
var script = Resources.replstrs(i);
script = `(function() {
var self = this;
var $ = this.__proto__;
${script};
})`;
var fn = os.eval(i,script);
for (var obj of actor_spawns[i]) {
var a = obj;
for (var t of a.timers)
t();
a.timers = [];
var save = json.decode(json.encode(a));
fn.call(a);
Object.merge(a,save);
check_registers(a);
}
}
}
profile.endcache();
}
2024-08-05 15:26:18 -05:00
actor.spawn = function(script, config){
if (typeof script !== 'string') return undefined;
var padawan = class_use(script, config, actor);
padawan.padawans = [];
padawan.timers = [];
padawan.master = this;
2024-08-06 16:05:24 -05:00
Object.hide(padawan, "master","padawans");
2024-07-24 14:17:32 -05:00
padawan.toString = function() { return script; }
check_registers(padawan);
this.padawans.push(padawan);
2024-08-06 16:05:24 -05:00
if (padawan.awake) padawan.awake();
return padawan;
};
2024-07-18 12:39:58 -05:00
actor.tween = function(from,to,time,fn) {
var stop = tween(from,to,time,fn);
this.timers.push(stop);
return stop;
}
actor.spawn.doc = `Create a new actor, using this actor as the master, initializing it with 'script' and with data (as a JSON or Nota file) from 'config'.`;
actor.rm_pawn = function(pawn)
{
this.padawans.remove(pawn);
}
actor.timers = [];
actor.kill = function(){
if (this.__dead__) return;
this.timers.forEach(t => t());
2024-04-03 08:37:29 -05:00
input.do_uncontrol(this);
Event.rm_obj(this);
if (this.master) this.master.rm_pawn(this);
this.padawans.forEach(p => p.kill());
this.padawans = [];
this.__dead__ = true;
2024-08-06 16:05:24 -05:00
actor_spawns[this._file].remove(this);
if (typeof this.die === 'function') this.die();
if (typeof this.stop === 'function') this.stop();
2024-07-18 12:39:58 -05:00
if (typeof this.garbage === 'function') this.garbage();
};
actor.kill.doc = `Remove this actor and all its padawans from existence.`;
actor.delay = function(fn, seconds) {
var timers = this.timers;
2024-03-19 17:00:49 -05:00
var stop = function() {
timers.remove(stop);
2024-08-06 14:23:21 -05:00
stop = undefined;
2024-03-19 17:00:49 -05:00
rm();
}
function execute() {
2024-07-18 12:39:58 -05:00
if (fn) fn();
2024-08-06 16:05:24 -05:00
if (stop && stop.then) stop.then();
2024-03-19 17:00:49 -05:00
stop();
}
stop.remain = seconds;
stop.seconds = seconds;
2024-04-14 14:53:41 -05:00
stop.pct = function() { return 1-(stop.remain / stop.seconds); };
2024-03-19 23:01:31 -05:00
2024-03-19 17:00:49 -05:00
function update(dt) {
2024-08-04 15:20:11 -05:00
profile.frame("timer");
2024-03-19 17:00:49 -05:00
stop.remain -= dt;
2024-08-04 15:20:11 -05:00
if (stop.remain <= 0) execute();
profile.endframe();
2024-03-19 17:00:49 -05:00
}
var rm = Register.appupdate.register(update);
timers.push(stop);
2024-03-19 17:00:49 -05:00
return stop;
};
actor.delay.doc = `Call 'fn' after 'seconds' with 'this' set to the actor.`;
2024-08-06 14:23:21 -05:00
actor.interval = function(fn, seconds)
{
var self = this;
var stop;
var usefn = function() {
fn();
stop = self.delay(usefn, seconds);
}
stop = self.delay(usefn, seconds);
return stop;
}
actor.padawans = [];
global.app = Object.create(actor);
2024-03-15 11:21:36 -05:00
app.die = function() { os.quit(); }
return {actor, app};