2024-02-29 13:54:33 -06:00
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-05 15:26:18 -05:00
if ( callback ) callback ( padawan ) ;
2024-02-29 13:54:33 -06:00
if ( typeof config === 'object' )
Object . merge ( padawan , config ) ;
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 ) ;
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 ) ;
2024-02-29 13:54:33 -06:00
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 ; }
2024-03-04 15:18:11 -06:00
check _registers ( padawan ) ;
2024-02-29 13:54:33 -06:00
this . padawans . push ( padawan ) ;
2024-08-06 16:05:24 -05:00
if ( padawan . awake ) padawan . awake ( ) ;
2024-02-29 13:54:33 -06:00
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 ;
}
2024-02-29 13:54:33 -06:00
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'. ` ;
2024-03-04 11:15:55 -06:00
actor . rm _pawn = function ( pawn )
{
this . padawans . remove ( pawn ) ;
}
2024-02-29 13:54:33 -06:00
actor . timers = [ ] ;
actor . kill = function ( ) {
if ( this . _ _dead _ _ ) return ;
2024-03-04 15:18:11 -06:00
this . timers . forEach ( t => t ( ) ) ;
2024-04-03 08:37:29 -05:00
input . do _uncontrol ( this ) ;
2024-03-04 15:18:11 -06:00
Event . rm _obj ( this ) ;
2024-03-04 11:15:55 -06:00
if ( this . master ) this . master . rm _pawn ( this ) ;
2024-02-29 13:54:33 -06:00
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 ) ;
2024-02-29 13:54:33 -06:00
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 ( ) ;
2024-02-29 13:54:33 -06:00
} ;
actor . kill . doc = ` Remove this actor and all its padawans from existence. ` ;
actor . delay = function ( fn , seconds ) {
2024-04-02 07:41:46 -05:00
var timers = this . timers ;
2024-03-19 17:00:49 -05:00
var stop = function ( ) {
2024-04-02 07:41:46 -05:00
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 ) ;
2024-04-02 07:41:46 -05:00
timers . push ( stop ) ;
2024-03-19 17:00:49 -05:00
return stop ;
2024-02-29 13:54:33 -06:00
} ;
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 ;
}
2024-02-29 13:54:33 -06:00
actor . padawans = [ ] ;
global . app = Object . create ( actor ) ;
2024-03-15 11:21:36 -05:00
app . die = function ( ) { os . quit ( ) ; }
2024-02-29 13:54:33 -06:00
return { actor , app } ;