basic.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. #include "std.h"
  2. #include "bbsys.h"
  3. //how many strings allocated
  4. static int stringCnt;
  5. //how many objects new'd but not deleted
  6. static int objCnt;
  7. //how many objects deleted but not released
  8. static int unrelObjCnt;
  9. //how many objects to alloc per block
  10. static const int OBJ_NEW_INC=512;
  11. //how many strings to alloc per block
  12. static const int STR_NEW_INC=512;
  13. //current data ptr
  14. static BBData *dataPtr;
  15. //chunks of mem - WHAT THE FUCK WAS I ON?!?!?!?
  16. //static list<char*> memBlks;
  17. //strings
  18. static BBStr usedStrs,freeStrs;
  19. //object handle number
  20. static int next_handle;
  21. //object<->handle maps
  22. static map<int,BBObj*> handle_map;
  23. static map<BBObj*,int> object_map;
  24. static BBType _bbIntType( BBTYPE_INT );
  25. static BBType _bbFltType( BBTYPE_FLT );
  26. static BBType _bbStrType( BBTYPE_STR );
  27. static BBType _bbCStrType( BBTYPE_CSTR );
  28. static void *bbMalloc( int size ){
  29. return malloc(size);
  30. /*
  31. char *c=d_new char[ size ];
  32. memBlks.push_back( c );
  33. return c;
  34. */
  35. }
  36. static void bbFree( void *q ){
  37. free(q);
  38. /*
  39. if( !q ) return;
  40. char *c=(char*)q;
  41. memBlks.remove( c );
  42. delete [] c;
  43. */
  44. }
  45. static void removeStr( BBStr *str ){
  46. str->next->prev=str->prev;
  47. str->prev->next=str->next;
  48. }
  49. static void insertStr( BBStr *str,BBStr *next ){
  50. str->next=next;
  51. str->prev=next->prev;
  52. str->prev->next=str;
  53. next->prev=str;
  54. }
  55. void *BBStr::operator new( size_t size ){
  56. if( freeStrs.next==&freeStrs ){
  57. BBStr *t=(BBStr*)bbMalloc( sizeof(BBStr)*STR_NEW_INC );
  58. for( int k=0;k<STR_NEW_INC;++k ) insertStr( t++,&freeStrs );
  59. }
  60. BBStr *t=freeStrs.next;
  61. removeStr( t );insertStr( t,&usedStrs );
  62. return t;
  63. }
  64. void BBStr::operator delete( void *q ){
  65. if( !q ) return;
  66. BBStr *t=(BBStr*)q;
  67. removeStr( t );insertStr( t,&freeStrs );
  68. }
  69. BBStr::BBStr(){
  70. ++stringCnt;
  71. }
  72. BBStr::BBStr( const char *s ):string(s){
  73. ++stringCnt;
  74. }
  75. BBStr::BBStr( const char *s,int n ):string(s,n){
  76. ++stringCnt;
  77. }
  78. BBStr::BBStr( const BBStr &s ):string(s){
  79. ++stringCnt;
  80. }
  81. BBStr::BBStr( const string &s ):string(s){
  82. ++stringCnt;
  83. }
  84. BBStr &BBStr::operator=( const char *s ){
  85. string::operator=( s );return *this;
  86. }
  87. BBStr &BBStr::operator=( const BBStr &s ){
  88. string::operator=( s );return *this;
  89. }
  90. BBStr &BBStr::operator=( const string &s ){
  91. string::operator=( s );return *this;
  92. }
  93. BBStr::~BBStr(){
  94. --stringCnt;
  95. }
  96. BBStr *_bbStrLoad( BBStr **var ){
  97. return *var ? d_new BBStr( **var ) : d_new BBStr();
  98. }
  99. void _bbStrRelease( BBStr *str ){
  100. delete str;
  101. }
  102. void _bbStrStore( BBStr **var,BBStr *str ){
  103. _bbStrRelease( *var );*var=str;
  104. }
  105. BBStr *_bbStrConcat( BBStr *s1,BBStr *s2 ){
  106. *s1+=*s2;delete s2;return s1;
  107. }
  108. int _bbStrCompare( BBStr *lhs,BBStr *rhs ){
  109. int n=lhs->compare( *rhs );
  110. delete lhs;delete rhs;return n;
  111. }
  112. int _bbStrToInt( BBStr *s ){
  113. int n=atoi( *s );
  114. delete s;return n;
  115. }
  116. BBStr *_bbStrFromInt( int n ){
  117. return d_new BBStr( itoa( n ) );
  118. }
  119. float _bbStrToFloat( BBStr *s ){
  120. float n=(float)atof( *s );
  121. delete s;return n;
  122. }
  123. BBStr *_bbStrFromFloat( float n ){
  124. return d_new BBStr( ftoa( n ) );
  125. }
  126. BBStr *_bbStrConst( const char *s ){
  127. return d_new BBStr( s );
  128. }
  129. void * _bbVecAlloc( BBVecType *type ){
  130. void *vec=bbMalloc( type->size*4 );
  131. memset( vec,0,type->size*4 );
  132. return vec;
  133. }
  134. void _bbVecFree( void *vec,BBVecType *type ){
  135. if( type->elementType->type==BBTYPE_STR ){
  136. BBStr **p=(BBStr**)vec;
  137. for( int k=0;k<type->size;++p,++k ){
  138. if( *p ) _bbStrRelease( *p );
  139. }
  140. }else if( type->elementType->type==BBTYPE_OBJ ){
  141. BBObj **p=(BBObj**)vec;
  142. for( int k=0;k<type->size;++p,++k ){
  143. if( *p ) _bbObjRelease( *p );
  144. }
  145. }
  146. bbFree( vec );
  147. }
  148. void _bbVecBoundsEx(){
  149. RTEX( "Blitz array index out of bounds" );
  150. }
  151. void _bbUndimArray( BBArray *array ){
  152. if( void *t=array->data ){
  153. if( array->elementType==BBTYPE_STR ){
  154. BBStr **p=(BBStr**)t;
  155. int size=array->scales[array->dims-1];
  156. for( int k=0;k<size;++p,++k ){
  157. if( *p ) _bbStrRelease( *p );
  158. }
  159. }else if( array->elementType==BBTYPE_OBJ ){
  160. BBObj **p=(BBObj**)t;
  161. int size=array->scales[array->dims-1];
  162. for( int k=0;k<size;++p,++k ){
  163. if( *p ) _bbObjRelease( *p );
  164. }
  165. }
  166. bbFree( t );
  167. array->data=0;
  168. }
  169. }
  170. void _bbDimArray( BBArray *array ){
  171. int k;
  172. for( k=0;k<array->dims;++k ) ++array->scales[k];
  173. for( k=1;k<array->dims;++k ){
  174. array->scales[k]*=array->scales[k-1];
  175. }
  176. int size=array->scales[array->dims-1];
  177. array->data=bbMalloc( size*4 );
  178. memset( array->data,0,size*4 );
  179. }
  180. void _bbArrayBoundsEx(){
  181. RTEX( "Array index out of bounds" );
  182. }
  183. static void unlinkObj( BBObj *obj ){
  184. obj->next->prev=obj->prev;
  185. obj->prev->next=obj->next;
  186. }
  187. static void insertObj( BBObj *obj,BBObj *next ){
  188. obj->next=next;
  189. obj->prev=next->prev;
  190. next->prev->next=obj;
  191. next->prev=obj;
  192. }
  193. BBObj *_bbObjNew( BBObjType *type ){
  194. if( type->free.next==&type->free ){
  195. int obj_size=sizeof(BBObj)+type->fieldCnt*4;
  196. BBObj *o=(BBObj*)bbMalloc( obj_size*OBJ_NEW_INC );
  197. for( int k=0;k<OBJ_NEW_INC;++k ){
  198. insertObj( o,&type->free );
  199. o=(BBObj*)( (char*)o+obj_size );
  200. }
  201. }
  202. BBObj *o=type->free.next;
  203. unlinkObj( o );
  204. o->type=type;
  205. o->ref_cnt=1;
  206. o->fields=(BBField*)(o+1);
  207. for( int k=0;k<type->fieldCnt;++k ){
  208. switch( type->fieldTypes[k]->type ){
  209. case BBTYPE_VEC:
  210. o->fields[k].VEC=_bbVecAlloc( (BBVecType*)type->fieldTypes[k] );
  211. break;
  212. default:
  213. o->fields[k].INT=0;
  214. }
  215. }
  216. insertObj( o,&type->used );
  217. ++unrelObjCnt;
  218. ++objCnt;
  219. return o;
  220. }
  221. void _bbObjDelete( BBObj *obj ){
  222. if( !obj ) return;
  223. BBField *fields=obj->fields;
  224. if( !fields ) return;
  225. BBObjType *type=obj->type;
  226. for( int k=0;k<type->fieldCnt;++k ){
  227. switch( type->fieldTypes[k]->type ){
  228. case BBTYPE_STR:
  229. _bbStrRelease( fields[k].STR );
  230. break;
  231. case BBTYPE_OBJ:
  232. _bbObjRelease( fields[k].OBJ );
  233. break;
  234. case BBTYPE_VEC:
  235. _bbVecFree( fields[k].VEC,(BBVecType*)type->fieldTypes[k] );
  236. break;
  237. }
  238. }
  239. map<BBObj*,int>::iterator it=object_map.find( obj );
  240. if( it!=object_map.end() ){
  241. handle_map.erase( it->second );
  242. object_map.erase( it );
  243. }
  244. obj->fields=0;
  245. _bbObjRelease( obj );
  246. --objCnt;
  247. }
  248. void _bbObjDeleteEach( BBObjType *type ){
  249. BBObj *obj=type->used.next;
  250. while( obj->type ){
  251. BBObj *next=obj->next;
  252. if( obj->fields ) _bbObjDelete( obj );
  253. obj=next;
  254. }
  255. }
  256. extern void bbDebugLog( BBStr *t );
  257. extern void bbStop( );
  258. void _bbObjRelease( BBObj *obj ){
  259. if( !obj || --obj->ref_cnt ) return;
  260. unlinkObj( obj );
  261. insertObj( obj,&obj->type->free );
  262. --unrelObjCnt;
  263. }
  264. void _bbObjStore( BBObj **var,BBObj *obj ){
  265. if( obj ) ++obj->ref_cnt; //do this first incase of self-assignment
  266. _bbObjRelease( *var );
  267. *var=obj;
  268. }
  269. int _bbObjCompare( BBObj *o1,BBObj *o2 ){
  270. return (o1 ? o1->fields : 0)!=(o2 ? o2->fields : 0);
  271. }
  272. BBObj *_bbObjNext( BBObj *obj ){
  273. do{
  274. obj=obj->next;
  275. if( !obj->type ) return 0;
  276. }while( !obj->fields );
  277. return obj;
  278. }
  279. BBObj *_bbObjPrev( BBObj *obj ){
  280. do{
  281. obj=obj->prev;
  282. if( !obj->type ) return 0;
  283. }while( !obj->fields );
  284. return obj;
  285. }
  286. BBObj *_bbObjFirst( BBObjType *type ){
  287. return _bbObjNext( &type->used );
  288. }
  289. BBObj *_bbObjLast( BBObjType *type ){
  290. return _bbObjPrev( &type->used );
  291. }
  292. void _bbObjInsBefore( BBObj *o1,BBObj *o2 ){
  293. if( o1==o2 ) return;
  294. unlinkObj( o1 );
  295. insertObj( o1,o2 );
  296. }
  297. void _bbObjInsAfter( BBObj *o1,BBObj *o2 ){
  298. if( o1==o2 ) return;
  299. unlinkObj( o1 );
  300. insertObj( o1,o2->next );
  301. }
  302. int _bbObjEachFirst( BBObj **var,BBObjType *type ){
  303. _bbObjStore( var,_bbObjFirst( type ) );
  304. return *var!=0;
  305. }
  306. int _bbObjEachNext( BBObj **var ){
  307. _bbObjStore( var,_bbObjNext( *var ) );
  308. return *var!=0;
  309. }
  310. int _bbObjEachFirst2( BBObj **var,BBObjType *type ){
  311. *var=_bbObjFirst( type );
  312. return *var!=0;
  313. }
  314. int _bbObjEachNext2( BBObj **var ){
  315. *var=_bbObjNext( *var );
  316. return *var!=0;
  317. }
  318. BBStr *_bbObjToStr( BBObj *obj ){
  319. if( !obj || !obj->fields ) return d_new BBStr( "[NULL]" );
  320. static BBObj *root;
  321. static int recurs_cnt;
  322. if( obj==root ) return d_new BBStr( "[ROOT]" );
  323. if( recurs_cnt==8 ) return d_new BBStr( "...." );
  324. ++recurs_cnt;
  325. BBObj *oldRoot=root;
  326. if( !root ) root=obj;
  327. BBObjType *type=obj->type;
  328. BBField *fields=obj->fields;
  329. BBStr *s=d_new BBStr("["),*t;
  330. for( int k=0;k<type->fieldCnt;++k ){
  331. if( k ) *s+=',';
  332. switch( type->fieldTypes[k]->type ){
  333. case BBTYPE_INT:
  334. t=_bbStrFromInt( fields[k].INT );*s+=*t;delete t;
  335. break;
  336. case BBTYPE_FLT:
  337. t=_bbStrFromFloat( fields[k].FLT );*s+=*t;delete t;
  338. break;
  339. case BBTYPE_STR:
  340. if( fields[k].STR ) *s+='\"'+*fields[k].STR+'\"';
  341. else *s+="\"\"";
  342. break;
  343. case BBTYPE_OBJ:
  344. t=_bbObjToStr( fields[k].OBJ );*s+=*t;delete t;
  345. break;
  346. default:
  347. *s+="???";
  348. }
  349. }
  350. *s+=']';
  351. root=oldRoot;
  352. --recurs_cnt;
  353. return s;
  354. }
  355. int _bbObjToHandle( BBObj *obj ){
  356. if( !obj || !obj->fields ) return 0;
  357. map<BBObj*,int>::const_iterator it=object_map.find( obj );
  358. if( it!=object_map.end() ) return it->second;
  359. ++next_handle;
  360. object_map[obj]=next_handle;
  361. handle_map[next_handle]=obj;
  362. return next_handle;
  363. }
  364. BBObj *_bbObjFromHandle( int handle,BBObjType *type ){
  365. map<int,BBObj*>::const_iterator it=handle_map.find( handle );
  366. if( it==handle_map.end() ) return 0;
  367. BBObj *obj=it->second;
  368. return obj->type==type ? obj : 0;
  369. }
  370. void _bbNullObjEx(){
  371. RTEX( "Object does not exist" );
  372. }
  373. void _bbRestore( BBData *data ){
  374. dataPtr=data;
  375. }
  376. int _bbReadInt(){
  377. switch( dataPtr->fieldType ){
  378. case BBTYPE_END:RTEX( "Out of data" );return 0;
  379. case BBTYPE_INT:return dataPtr++->field.INT;
  380. case BBTYPE_FLT:return dataPtr++->field.FLT;
  381. case BBTYPE_CSTR:return atoi( dataPtr++->field.CSTR );
  382. default:RTEX( "Bad data type" );return 0;
  383. }
  384. }
  385. float _bbReadFloat(){
  386. switch( dataPtr->fieldType ){
  387. case BBTYPE_END:RTEX( "Out of data" );return 0;
  388. case BBTYPE_INT:return dataPtr++->field.INT;
  389. case BBTYPE_FLT:return dataPtr++->field.FLT;
  390. case BBTYPE_CSTR:return atof( dataPtr++->field.CSTR );
  391. default:RTEX( "Bad data type" );return 0;
  392. }
  393. }
  394. BBStr *_bbReadStr(){
  395. switch( dataPtr->fieldType ){
  396. case BBTYPE_END:RTEX( "Out of data" );return 0;
  397. case BBTYPE_INT:return d_new BBStr( itoa( dataPtr++->field.INT ) );
  398. case BBTYPE_FLT:return d_new BBStr( ftoa( dataPtr++->field.FLT ) );
  399. case BBTYPE_CSTR:return d_new BBStr( dataPtr++->field.CSTR );
  400. default:RTEX( "Bad data type" );return 0;
  401. }
  402. }
  403. int _bbAbs( int n ){
  404. return n>=0 ? n : -n;
  405. }
  406. int _bbSgn( int n ){
  407. return n>0 ? 1 : (n<0 ? -1 : 0);
  408. }
  409. int _bbMod( int x,int y ){
  410. return x%y;
  411. }
  412. float _bbFAbs( float n ){
  413. return n>=0 ? n : -n;
  414. }
  415. float _bbFSgn( float n ){
  416. return n>0 ? 1 : (n<0 ? -1 : 0);
  417. }
  418. float _bbFMod( float x,float y ){
  419. return (float)fmod( x,y );
  420. }
  421. float _bbFPow( float x,float y ){
  422. return (float)pow( x,y );
  423. }
  424. void bbRuntimeStats(){
  425. gx_runtime->debugLog( ("Active strings :"+itoa(stringCnt)).c_str() );
  426. gx_runtime->debugLog( ("Active objects :"+itoa(objCnt)).c_str() );
  427. gx_runtime->debugLog( ("Unreleased objs:"+itoa(unrelObjCnt)).c_str() );
  428. /*
  429. clog<<"Active strings:"<<stringCnt<<endl;
  430. clog<<"Active objects:"<<objCnt<<endl;
  431. clog<<"Unreleased Objects:"<<unrelObjCnt<<endl;
  432. for( BBStr *t=usedStrs.next;t!=&usedStrs;t=t->next ){
  433. clog<<"string@"<<(void*)t<<endl;
  434. }
  435. */
  436. }
  437. bool basic_create(){
  438. next_handle=0;
  439. // memBlks.clear();
  440. handle_map.clear();
  441. object_map.clear();
  442. stringCnt=objCnt=unrelObjCnt=0;
  443. usedStrs.next=usedStrs.prev=&usedStrs;
  444. freeStrs.next=freeStrs.prev=&freeStrs;
  445. return true;
  446. }
  447. bool basic_destroy(){
  448. while( usedStrs.next!=&usedStrs ) delete usedStrs.next;
  449. // while( memBlks.size() ) bbFree( memBlks.back() );
  450. handle_map.clear();
  451. object_map.clear();
  452. return true;
  453. }
  454. void basic_link( void (*rtSym)( const char *sym,void *pc ) ){
  455. rtSym( "_bbIntType",&_bbIntType );
  456. rtSym( "_bbFltType",&_bbFltType );
  457. rtSym( "_bbStrType",&_bbStrType );
  458. rtSym( "_bbCStrType",&_bbCStrType );
  459. rtSym( "_bbStrLoad",_bbStrLoad );
  460. rtSym( "_bbStrRelease",_bbStrRelease );
  461. rtSym( "_bbStrStore",_bbStrStore );
  462. rtSym( "_bbStrCompare",_bbStrCompare );
  463. rtSym( "_bbStrConcat",_bbStrConcat );
  464. rtSym( "_bbStrToInt",_bbStrToInt );
  465. rtSym( "_bbStrFromInt",_bbStrFromInt );
  466. rtSym( "_bbStrToFloat",_bbStrToFloat );
  467. rtSym( "_bbStrFromFloat",_bbStrFromFloat );
  468. rtSym( "_bbStrConst",_bbStrConst );
  469. rtSym( "_bbDimArray",_bbDimArray );
  470. rtSym( "_bbUndimArray",_bbUndimArray );
  471. rtSym( "_bbArrayBoundsEx",_bbArrayBoundsEx );
  472. rtSym( "_bbVecAlloc",_bbVecAlloc );
  473. rtSym( "_bbVecFree",_bbVecFree );
  474. rtSym( "_bbVecBoundsEx",_bbVecBoundsEx );
  475. rtSym( "_bbObjNew",_bbObjNew );
  476. rtSym( "_bbObjDelete",_bbObjDelete );
  477. rtSym( "_bbObjDeleteEach",_bbObjDeleteEach );
  478. rtSym( "_bbObjRelease",_bbObjRelease );
  479. rtSym( "_bbObjStore",_bbObjStore );
  480. rtSym( "_bbObjCompare",_bbObjCompare );
  481. rtSym( "_bbObjNext",_bbObjNext );
  482. rtSym( "_bbObjPrev",_bbObjPrev );
  483. rtSym( "_bbObjFirst",_bbObjFirst );
  484. rtSym( "_bbObjLast",_bbObjLast );
  485. rtSym( "_bbObjInsBefore",_bbObjInsBefore );
  486. rtSym( "_bbObjInsAfter",_bbObjInsAfter );
  487. rtSym( "_bbObjEachFirst",_bbObjEachFirst );
  488. rtSym( "_bbObjEachNext",_bbObjEachNext );
  489. rtSym( "_bbObjEachFirst2",_bbObjEachFirst2 );
  490. rtSym( "_bbObjEachNext2",_bbObjEachNext2 );
  491. rtSym( "_bbObjToStr",_bbObjToStr );
  492. rtSym( "_bbObjToHandle",_bbObjToHandle );
  493. rtSym( "_bbObjFromHandle",_bbObjFromHandle );
  494. rtSym( "_bbNullObjEx",_bbNullObjEx );
  495. rtSym( "_bbRestore",_bbRestore );
  496. rtSym( "_bbReadInt",_bbReadInt );
  497. rtSym( "_bbReadFloat",_bbReadFloat );
  498. rtSym( "_bbReadStr",_bbReadStr );
  499. rtSym( "_bbAbs",_bbAbs );
  500. rtSym( "_bbSgn",_bbSgn );
  501. rtSym( "_bbMod",_bbMod );
  502. rtSym( "_bbFAbs",_bbFAbs );
  503. rtSym( "_bbFSgn",_bbFSgn );
  504. rtSym( "_bbFMod",_bbFMod );
  505. rtSym( "_bbFPow",_bbFPow );
  506. rtSym( "RuntimeStats",bbRuntimeStats );
  507. }