/* import * as THREE from "three"; */
const STATE_NULL = 0;
const STATE_STOP = 2;
const STATE_RUN = 3;
const STATE_PAUSE = 4;
const CALL_OVERFLOW = 4096 ;
const MONO_FONT = "sometype" ;
var µB = null ;
var µX = null ;
var µj = 0;
var µsync = false;
var µret = 0;
var µs = 0 ;
let µl = 0 ;
var µI = null ;
var µV = null ;
var µA = null ;
class Runtime
{
$state = STATE_NULL ;
CONFIG = null;
task_node = null ;
runtime_start_time = 0;
cpu_max_usage = .5 ;
jpf = 1 ;
wait = 1 ;
waited = 0 ;
request_frame = null;
$Config = null;
$Math = new module_Math();
$Basic = null;
$D2 = null ;
$D3 = null ;
$Sprite = null ;
$Data = null ;
$Craft = null ;
FPS = null ;
CALL = null ;
STRUCT = null ;
constructor()
{
Log( "RUNTIME()" );
this.Speed(7);
}
Reset()
{
this.Stop();
µX = null ;
}
RuntimeError( message )
{
var html = "<label>Runtime Error</label><p>"+message+"</p><p>Line "+µs+"</p>" ;
var C = { 'html':html, 'style':"error" } ;
Guru( "RT ERROR="+message ) ;
µsync = true ;
General.Pause();
}
async Load( C )
{
this.Stop() ;
this.CONFIG = C ;
if( C.url == µX?.url )
{
Log("Module reuse");
this.$state = STATE_STOP ;
General.Run();
}
else
{
Log( "import="+C.url + " vs " + µX?.url );
µX = null;
try
{
await import(C.url).then( (module)=>
{
if( module )
{ Log("Module loaded");
this.$state = STATE_STOP ;
µX = new module.default();
µX.url = this.CONFIG.url;
General.Boot();
General.Run();
}
else
{
}
} );
}
catch($e)
{
this.RuntimeError( "Invalid code. Try gain." );
CatchError($e);
}
}
}
Speed($speed)
{
let $X = [.5,1,2,4,8,15,30,60];
if( $speed < 0 )
{ this.jpf = 1;
this.wait = $X[-$speed];
}
else
{
this.jpf = ($X[$speed]/60) * (1000/60) * this.cpu_max_usage;
this.wait = 0;
}
}
RunInit()
{
this.runtime_start_time = new Date().getTime() / 1000.0 ;
Log( "RunInit new config" );
this.$Config = new module_Config();
this.$Basic?.Dispose();
this.$Basic = new module_Basic();
this.$D2?.Dispose();
this.$D2 = new module_D2;
this.$D3?.Dispose();
this.$D3 = new module_D3;
this.$Sprite?.Dispose();
this.$Sprite = new module_Sprite;
this.$Data?.Dispose();
this.$Data = new module_Data ;
this.$Craft?.Dispose();
this.$Craft = new module_Craft ;
General.RefitWindow();
µj = 1 ;
µI = [] ;
µA = [] ;
µV = new Array(µX.vars).fill(0);
this.FPS = { frame:0, count:0, dt:0, last_frame:0, average:0 } ;
this.CALL = [] ;
this.STRUCT = {};
Log( "RunInit() done" );
}
Run()
{
this.task_node = Rain.GetTaskNode("runtime") ;
if( this.$state == STATE_NULL )
{
alert("state_null");
return false;
}
else if( this.$state == STATE_RUN )
{
return true ;
}
else if( this.$state == STATE_PAUSE )
{
this.$state = STATE_RUN;
return true ;
}
else if( this.$state == STATE_STOP )
{
this.RunInit();
this.$state = STATE_RUN ;
this.Runtime();
return true ;
}
else
{
Log("--"+this.$state);
return false;
}
}
Stop()
{
µj = 0 ;
cancelAnimationFrame( this.request_frame );
if( this.$state == STATE_STOP || this.$state == STATE_NULL )
{
return false ;
}
else
{
this.$state = STATE_STOP ;
var $dt = (new Date().getTime() / 1000.0) - this.runtime_start_time;
return true ;
}
}
Pause()
{
if( this.$state == STATE_RUN )
{ this.$state = STATE_PAUSE;
return true;
}
else if( this.$state == STATE_PAUSE )
{ return true ;
}
else
{ return false;
}
}
Runtime()
{
if( this.FPS.last_frame )
{
let dt = performance.now() - this.FPS.last_frame ;
this.FPS.frame ++ ;
this.FPS.count ++ ;
this.FPS.dt += dt ;
if( this.FPS.dt > 1000 )
{ this.FPS.average = this.FPS.average ? (this.FPS.average*5+this.FPS.count)/6 : this.FPS.count ;
this.FPS.count = 0 ;
this.FPS.dt = 0 ;
}
}
this.FPS.last_frame = performance.now();
if( ! µB || ! µX )
{
Log( "! Runtime *BREAK*" );
return false;
}
else if( this.$state == STATE_STOP || this.$state == STATE_NULL )
{
return;
}
else if( this.$state == STATE_PAUSE )
{
}
else if( this.waited > 0 )
{
this.waited -- ;
}
else
{
this.Jumps();
µB.$D3?.Update();
this.waited = this.wait ;
}
if( µj != 0 )
{ this.request_frame = requestAnimationFrame( this.Runtime.bind(µB) );
}
else
{ this.Stop();
}
}
Jumps()
{
let $jumps = this.jpf ;
let $loop_time = performance.now();
let $dt = 0 ;
µsync = false ;
while( $jumps>0 && µj !=0 )
{
try
{
µX["Seg_"+µj]();
}
catch($e)
{
CatchError( $e );
this.Stop();
break;
}
if( µsync == true )
{
break;
}
else if( this.wait != 0 )
{ $jumps --;
}
else
{
$dt = performance.now() - $loop_time;
if( $dt > this.jpf )
{
break;
}
}
}
}
Jmp(to, back)
{
if( µX["Seg_"+to] === undefined )
{
this.RuntimeError( "Gosub Label not found" );
}
else if( this.CALL.length > CALL_OVERFLOW )
{
this.RuntimeError( "Gosub loop / Call stack overflow" );
}
else
{ this.CALL.push(back);
µj = to ;
}
}
Ret()
{
µj = this.CALL.pop() ;
}
Stg()
{
let ARG = Array.prototype.slice.call(arguments);
let id = ARG.join() ;
let value = this.STRUCT[id]??0 ;
return value ;
}
Sts()
{
let ARG = Array.prototype.slice.call(arguments);
let value = ARG.shift();
let id = ARG.join() ;
this.STRUCT[id] = value ;
}
LayerScreenshot( task_id )
{
let merge = document.createElement("CANVAS");
merge.width = 1920 ;
merge.height = 1080 ;
let format = this.$Config.GetBestFormat(16/9, this.$Config.width, this.$Config.$height) ;
let ox = (this.$Config.width-format.width)/2 ;
let oy = (this.$Config.height-format.height)/2 ;
let ctx = merge.getContext("2d",{willReadFrequently:true});
ctx.fillStyle = this.$Config.background_rgba ;
ctx.fillRect(ox, oy, format.width, format.height);
let SCREENS = [] ;
for( let id in µB.$D2.SCREEN )
{ SCREENS.push(µB.$D2.SCREEN[id]);
}
SCREENS.push( µB.$Basic.Screen );
SCREENS.push( { canvas:µB.$D3.canvas, alpha:1 } ) ;
let count = SCREENS.length ;
while( count > 0 )
{
let min = 1000 ;
let next_index = null ;
for( let index in SCREENS )
{
if( SCREENS[index] )
{ let z = SCREENS[index].canvas.style.zIndex ;
if( z < min )
{ min = z ;
next_index = index ;
}
}
}
if( next_index === null )
{ break;
}
else
{
Log( "Merge SS z="+min +","+ SCREENS[next_index].canvas.className ) ;
ctx.globalAlpha = SCREENS[next_index].alpha ;
ctx.drawImage(SCREENS[next_index].canvas,ox,oy,format.width,format.height,0,0,merge.width,merge.height);
SCREENS[next_index] = false ;
count -- ;
}
}
SCREENS = null ;
let image = merge.toDataURL('image/jpeg',0.95);
merge.remove();
return image ;
}
};