2023-04-22 16:44:26 -05:00
var Debug = {
2023-12-13 19:53:09 -06:00
fn _break ( fn , obj ) {
if ( typeof fn !== 'function' ) return ;
obj ? ? = globalThis ;
var newfn = function ( ) {
console . log ( "broke" ) ;
fn ( ) ;
} ;
obj [ fn . name ] = newfn ;
} ,
2023-05-16 13:31:19 -05:00
draw _grid ( width , span , color ) {
color = color ? color : Color . green ;
cmd ( 47 , width , span , color ) ;
2023-04-22 16:44:26 -05:00
} ,
2023-12-15 12:45:09 -06:00
coordinate ( pos , size , color ) { GUI . text ( JSON . stringify ( pos . map ( p => Math . round ( p ) ) ) , pos , size , color ) ; } ,
2023-06-06 15:49:55 -05:00
boundingbox ( bb , color ) {
2023-08-14 17:20:30 -05:00
color ? ? = Color . white ;
2024-02-27 10:09:15 -06:00
cmd _points ( 0 , bbox . topoints ( bb ) , color ) ;
2023-06-06 15:49:55 -05:00
} ,
2023-04-22 16:44:26 -05:00
2023-12-18 06:45:27 -06:00
numbered _point ( pos , n , color ) {
color ? ? = Color . white ;
2024-02-25 17:31:48 -06:00
render . point ( pos , 3 , color ) ;
2023-12-18 06:45:27 -06:00
GUI . text ( n , pos . add ( [ 0 , 4 ] ) , 1 , color ) ;
2023-04-22 16:44:26 -05:00
} ,
phys _drawing : false ,
draw _phys ( on ) {
this . phys _drawing = on ;
cmd ( 4 , this . phys _drawing ) ;
} ,
draw _obj _phys ( obj ) {
cmd ( 82 , obj . body ) ;
} ,
2023-12-18 06:45:27 -06:00
gameobject ( go ) { cmd ( 15 , go . body ) ; } ,
2023-08-17 20:13:17 -05:00
draw _bb : false ,
draw _gizmos : false ,
draw _names : false ,
draw ( ) {
if ( this . draw _bb )
2023-11-29 12:40:13 -06:00
Game . all _objects ( function ( x ) { Debug . boundingbox ( x . boundingbox ( ) , Color . Debug . boundingbox . alpha ( 0.05 ) ) ; } ) ;
2023-08-17 20:13:17 -05:00
2024-03-15 11:21:36 -05:00
if ( sim . paused ( ) ) GUI . text ( "PAUSED" , [ 0 , 0 ] , 1 ) ;
2023-08-17 20:13:17 -05:00
if ( this . draw _gizmos )
2023-11-29 12:40:13 -06:00
Game . all _objects ( function ( x ) {
2023-08-17 20:13:17 -05:00
if ( ! x . icon ) return ;
2024-02-25 17:31:48 -06:00
GUI . image ( x . icon , Window . world2screen ( x . pos ) ) ;
2023-08-17 20:13:17 -05:00
} ) ;
if ( this . draw _names )
2023-11-29 12:40:13 -06:00
Game . all _objects ( function ( x ) {
2024-02-25 17:31:48 -06:00
GUI . text ( x , Window . world2screen ( x . pos ) . add ( [ 0 , 32 ] ) , 1 , Color . Debug . names ) ;
2023-08-17 20:13:17 -05:00
} ) ;
2023-08-24 16:22:52 -05:00
2023-09-12 12:45:54 -05:00
if ( Debug . Options . gif . rec ) {
2023-10-26 11:48:02 -05:00
GUI . text ( "REC" , [ 0 , 40 ] , 1 ) ;
2024-03-14 14:10:06 -05:00
GUI . text ( time . timecode ( time . timenow ( ) - Debug . Options . gif . start _time , Debug . Options . gif . fps ) , [ 0 , 30 ] , 1 ) ;
2023-09-12 12:45:54 -05:00
}
2023-09-12 00:02:57 -05:00
2024-03-15 11:21:36 -05:00
GUI . text ( sim . playing ( ) ? "PLAYING"
: sim . stepping ( ) ?
2023-08-27 21:57:19 -05:00
"STEP" :
2024-03-15 11:21:36 -05:00
sim . paused ( ) ?
2023-08-28 17:00:53 -05:00
"PAUSED; EDITING" :
"EDIT" , [ 0 , 0 ] , 1 ) ;
2023-08-17 20:13:17 -05:00
} ,
} ;
2024-03-11 15:11:39 -05:00
function assert ( op , str )
2023-12-18 17:12:05 -06:00
{
2024-03-11 15:11:39 -05:00
str ? ? = ` assertion failed [value ' ${ op } '] ` ;
2024-03-13 16:30:55 -05:00
if ( ! op ) {
console . error ( ` Assertion failed: ${ str } ` ) ;
2024-03-15 11:21:36 -05:00
os . quit ( ) ;
2024-03-13 16:30:55 -05:00
}
2023-12-18 17:12:05 -06:00
}
2023-08-17 20:13:17 -05:00
Debug . Options = { } ;
Debug . Options . Color = {
2024-03-15 10:51:04 -05:00
//set trigger(x) { cmd(17,x); },
//set debug(x) { cmd(16, x); },
2023-04-22 16:44:26 -05:00
} ;
var Gizmos = {
pick _gameobject _points ( worldpos , gameobject , points ) {
2023-11-29 17:31:41 -06:00
var idx = Math . grab _from _points ( worldpos , points . map ( gameobject . this2world , gameobject ) , 25 ) ;
2023-12-18 06:45:27 -06:00
if ( idx === - 1 ) return undefined ;
return idx ;
2023-04-22 16:44:26 -05:00
} ,
} ;
2024-03-14 14:10:06 -05:00
Object . assign ( profile , {
best _t ( t ) {
2023-12-18 06:45:27 -06:00
var qq = 'ns' ;
2024-03-14 14:10:06 -05:00
if ( t > 1000 ) {
t /= 1000 ;
2023-12-18 06:45:27 -06:00
qq = 'us' ;
2024-03-14 14:10:06 -05:00
if ( t > 1000 ) {
t /= 1000 ;
2023-12-18 06:45:27 -06:00
qq = 'ms' ;
}
}
2024-03-14 14:10:06 -05:00
return ` ${ t . toPrecision ( 4 ) } ${ qq } ` ;
2023-12-18 06:45:27 -06:00
} ,
2023-09-11 02:46:12 -05:00
cpu ( fn , times , q ) {
2023-06-07 08:41:09 -05:00
times ? ? = 1 ;
2023-12-18 06:45:27 -06:00
q ? ? = "unnamed" ;
2024-03-14 14:10:06 -05:00
var start = profile . now ( ) ;
2023-06-07 08:41:09 -05:00
for ( var i = 0 ; i < times ; i ++ )
fn ( ) ;
2023-12-18 06:45:27 -06:00
2024-03-14 14:10:06 -05:00
var elapsed = profile . now ( ) - start ;
var avgt = profile . best _t ( elapsed / times ) ;
var totalt = profile . best _t ( elapsed ) ;
say ( ` profile [ ${ q } ]: ${ profile . best _t ( avgt ) } average [ ${ profile . best _t ( totalt ) } for ${ times } loops] ` ) ;
} ,
2023-12-18 06:45:27 -06:00
2024-03-14 14:10:06 -05:00
time ( fn ) {
var start = profile . now ( ) ;
fn ( ) ;
return profile . lap ( start ) ;
2023-06-07 08:41:09 -05:00
} ,
2023-08-17 20:13:17 -05:00
2024-03-14 14:10:06 -05:00
lap ( t ) {
return profile . best _t ( profile . now ( ) - t ) ;
} ,
2024-03-01 11:45:06 -06:00
measure ( fn , str ) {
str ? ? = 'unnamed' ;
2024-03-14 14:10:06 -05:00
var start = profile . now ( ) ;
2024-03-01 11:45:06 -06:00
fn ( ) ;
2024-03-14 14:10:06 -05:00
say ( ` profile [ ${ str } ]: ${ profile . lap ( start ) } ` ) ;
2024-03-01 11:45:06 -06:00
} ,
2024-03-15 11:21:36 -05:00
secs ( ) { return this . now ( ) / 1000000000 ; } ,
2024-02-25 17:31:48 -06:00
} ) ;
2023-04-22 16:44:26 -05:00
2024-03-14 14:10:06 -05:00
2024-03-02 00:00:35 -06:00
2024-03-01 11:45:06 -06:00
performance . test = {
barecall ( ) { performance ( 0 ) ; } ,
unpack _num ( n ) { performance ( 1 , n ) ; } ,
unpack _array ( n ) { performance ( 2 , n ) ; } ,
pack _num ( ) { performance ( 3 ) ; } ,
pack _string ( ) { performance ( 6 ) ; } ,
unpack _string ( s ) { performance ( 4 , s ) ; } ,
unpack _32farr ( a ) { performance ( 5 , a ) ; } ,
call _fn _n ( fn1 , n ) { performance ( 7 , fn1 , n , fn2 ) ; } ,
2023-12-18 06:45:27 -06:00
} ;
2024-03-01 11:45:06 -06:00
performance . test . call _fn _n . doc = "Calls fn1 n times, and then fn2." ;
2024-01-14 10:24:31 -06:00
2024-03-14 14:10:06 -05:00
//performance.cpu.doc = `Output the time it takes to do a given function n number of times. Provide 'q' as "ns", "us", or "ms" to output the time taken in the requested resolution.`;
2023-10-23 08:08:11 -05:00
2023-08-28 17:00:53 -05:00
/* These controls are available during editing, and during play of debug builds */
2024-03-05 22:23:38 -06:00
Debug . inputs = { } ;
Debug . inputs . f1 = function ( ) { Debug . draw _phys ( ! Debug . phys _drawing ) ; } ;
Debug . inputs . f1 . doc = "Draw physics debugging aids." ;
//Debug.inputs.f3 = function() { Debug.draw_bb = !Debug.draw_bb; };
//Debug.inputs.f3.doc = "Toggle drawing bounding boxes.";
Debug . inputs . f4 = function ( ) {
Debug . draw _names = ! Debug . draw _names ;
Debug . draw _gizmos = ! Debug . draw _gizmos ;
2023-08-24 16:22:52 -05:00
} ;
2024-03-05 22:23:38 -06:00
Debug . inputs . f4 . doc = "Toggle drawing gizmos and names of objects." ;
2023-09-12 00:02:57 -05:00
Debug . Options . gif = {
2023-09-12 12:45:54 -05:00
w : 640 , /* Max width */
h : 480 , /* Max height */
stretch : false , /* True if you want to stretch */
2023-09-13 07:31:00 -05:00
cpf : 4 ,
2023-09-14 12:49:29 -05:00
depth : 16 ,
2023-09-12 00:02:57 -05:00
file : "out.gif" ,
rec : false ,
2023-09-12 12:45:54 -05:00
secs : 6 ,
start _time : 0 ,
fps : 0 ,
start ( ) {
var w = this . w ;
var h = this . h ;
if ( ! this . stretch ) {
var win = Window . height / Window . width ;
var gif = h / w ;
if ( gif > win )
h = w * win ;
else
w = h / win ;
}
cmd ( 131 , w , h , this . cpf , this . depth ) ;
this . rec = true ;
this . fps = ( 1 / this . cpf ) * 100 ;
2024-03-14 14:10:06 -05:00
this . start _time = time . now ( ) ;
2023-09-12 12:45:54 -05:00
2023-09-13 07:31:00 -05:00
timer . oneshot ( this . stop . bind ( this ) , this . secs , this , true ) ;
2023-09-12 12:45:54 -05:00
} ,
stop ( ) {
if ( ! this . rec ) return ;
cmd ( 132 , this . file ) ;
this . rec = false ;
} ,
2023-09-12 00:02:57 -05:00
} ;
2023-09-12 12:45:54 -05:00
2024-03-05 22:23:38 -06:00
Debug . inputs . f8 = function ( ) {
2023-09-25 12:29:04 -05:00
var now = new Date ( ) ;
Debug . Options . gif . file = now . toISOString ( ) + ".gif" ;
Debug . Options . gif . start ( ) ;
} ;
2024-03-05 22:23:38 -06:00
Debug . inputs . f9 = function ( ) {
2023-09-25 12:29:04 -05:00
Debug . Options . gif . stop ( ) ;
}
2023-09-12 00:02:57 -05:00
2024-03-15 10:51:04 -05:00
Debug . inputs . f10 = function ( ) { time . timescale = 0.1 ; } ;
2024-03-05 22:23:38 -06:00
Debug . inputs . f10 . doc = "Toggle timescale to 1/10." ;
2024-03-15 10:51:04 -05:00
Debug . inputs . f10 . released = function ( ) { time . timescale = 1.0 ; } ;
2024-03-05 22:23:38 -06:00
Debug . inputs . f12 = function ( ) { GUI . defaults . debug = ! GUI . defaults . debug ; console . warn ( "GUI toggle debug" ) ; } ;
Debug . inputs . f12 . doc = "Toggle drawing GUI debugging aids." ;
2023-08-24 16:22:52 -05:00
2024-03-05 22:23:38 -06:00
Debug . inputs [ 'M-1' ] = render . normal ;
Debug . inputs [ 'M-2' ] = render . wireframe ;
2023-08-17 20:13:17 -05:00
2024-03-05 22:23:38 -06:00
Debug . inputs [ 'C-M-f' ] = function ( ) { } ;
Debug . inputs [ 'C-M-f' ] . doc = "Enter camera fly mode." ;
2023-08-28 17:00:53 -05:00
2024-02-25 17:31:48 -06:00
Debug . api = { } ;
Debug . api . doc _entry = function ( obj , key )
2023-10-23 08:08:11 -05:00
{
2024-02-23 16:05:30 -06:00
if ( typeof key !== 'string' ) {
console . warn ( "Cannot print a key that isn't a string." ) ;
return undefined ;
}
2023-10-23 08:08:11 -05:00
var title = key ;
var o = obj [ key ] ;
if ( typeof o === 'undefined' && obj . impl && typeof obj . impl [ key ] !== 'undefined' )
o = obj . impl [ key ] ;
var t = typeof o ;
2024-02-23 16:05:30 -06:00
if ( Array . isArray ( o ) ) t = "array" ;
else if ( t === 'function' ) {
2023-10-23 08:08:11 -05:00
title = o . toString ( ) . tofirst ( ')' ) + ")" ;
2024-02-23 16:05:30 -06:00
title = title . fromfirst ( '(' ) ;
title = key + "(" + title ;
2023-10-23 08:08:11 -05:00
if ( o . doc ) doc = o . doc ;
t = "" ;
2024-02-23 16:05:30 -06:00
} else if ( t === 'undefined' ) t = "" ;
2023-10-23 08:08:11 -05:00
2024-02-23 16:05:30 -06:00
if ( t ) t = "**" + t + "**\n" ;
2023-10-23 08:08:11 -05:00
2024-02-23 16:05:30 -06:00
var doc = "" ;
if ( o . doc ) doc = o . doc ;
else if ( obj . doc && obj . doc [ key ] ) doc = obj . doc [ key ] ;
else if ( Array . isArray ( o ) ) doc = json . encode ( o ) ;
2023-10-23 08:08:11 -05:00
2024-02-23 16:05:30 -06:00
return ` ## ${ title }
2023-10-23 08:08:11 -05:00
$ { t }
$ { doc }
` ;
}
2024-02-25 17:31:48 -06:00
Debug . api . print _doc = function ( name )
2023-10-23 08:08:11 -05:00
{
2024-02-23 16:05:30 -06:00
var obj = name ;
if ( typeof name === 'string' ) {
obj = eval ( name ) ;
if ( ! obj ) {
console . warn ( ` Cannot print the API of ' ${ name } ', as it was not found. ` ) ;
return undefined ;
}
obj = globalThis [ name ] ;
}
obj = eval ( name ) ;
if ( ! Object . isObject ( obj ) ) {
console . warn ( "Cannot print the API of something that isn't an object." ) ;
return undefined ;
2023-10-23 08:08:11 -05:00
}
2024-02-23 16:05:30 -06:00
if ( ! obj ) {
console . warn ( ` Object ' ${ name } ' does not exist. ` ) ;
return ;
}
var mdoc = "# " + name + "\n" ;
2023-10-23 08:08:11 -05:00
if ( obj . doc ? . doc ) mdoc += obj . doc . doc + "\n" ;
else if ( typeof obj . doc === 'string' ) mdoc += obj . doc + "\n" ;
2024-02-23 16:05:30 -06:00
2023-10-23 08:08:11 -05:00
for ( var key in obj ) {
if ( key === 'doc' ) continue ;
2023-10-26 11:48:02 -05:00
if ( key === 'toString' ) continue ;
2024-02-23 16:05:30 -06:00
2024-02-25 17:31:48 -06:00
mdoc += Debug . api . doc _entry ( obj , key ) + "\n" ;
2023-10-23 08:08:11 -05:00
}
return mdoc ;
}
2024-02-27 10:09:15 -06:00
return {
Debug ,
2024-03-01 11:45:06 -06:00
Gizmos ,
2024-03-11 15:11:39 -05:00
assert
2024-02-27 10:09:15 -06:00
}