2016-07-19 09:21:45 +02:00
|
|
|
#include "std.h"
|
|
|
|
|
#include "bbsys.h"
|
|
|
|
|
|
|
|
|
|
//how many strings allocated
|
|
|
|
|
static int stringCnt;
|
|
|
|
|
|
|
|
|
|
//how many objects new'd but not deleted
|
|
|
|
|
static int objCnt;
|
|
|
|
|
|
|
|
|
|
//how many objects deleted but not released
|
|
|
|
|
static int unrelObjCnt;
|
|
|
|
|
|
|
|
|
|
//how many objects to alloc per block
|
|
|
|
|
static const int OBJ_NEW_INC = 512;
|
|
|
|
|
|
|
|
|
|
//how many strings to alloc per block
|
|
|
|
|
static const int STR_NEW_INC = 512;
|
|
|
|
|
|
|
|
|
|
//current data ptr
|
|
|
|
|
static BBData *dataPtr;
|
|
|
|
|
|
|
|
|
|
//chunks of mem - WHAT THE FUCK WAS I ON?!?!?!?
|
|
|
|
|
//static list<char*> memBlks;
|
|
|
|
|
|
|
|
|
|
//strings
|
|
|
|
|
static BBStr usedStrs, freeStrs;
|
|
|
|
|
|
|
|
|
|
//object handle number
|
|
|
|
|
static int next_handle;
|
|
|
|
|
|
|
|
|
|
//object<->handle maps
|
|
|
|
|
static map<int, BBObj*> handle_map;
|
|
|
|
|
static map<BBObj*, int> object_map;
|
|
|
|
|
|
|
|
|
|
static BBType _bbIntType(BBTYPE_INT);
|
|
|
|
|
static BBType _bbFltType(BBTYPE_FLT);
|
|
|
|
|
static BBType _bbStrType(BBTYPE_STR);
|
|
|
|
|
static BBType _bbCStrType(BBTYPE_CSTR);
|
|
|
|
|
|
|
|
|
|
static void *bbMalloc(int size) {
|
|
|
|
|
return malloc(size);
|
|
|
|
|
/*
|
2016-10-03 17:11:15 +02:00
|
|
|
char *c=new char[ size ];
|
2016-07-19 09:21:45 +02:00
|
|
|
memBlks.push_back( c );
|
|
|
|
|
return c;
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void bbFree(void *q) {
|
|
|
|
|
free(q);
|
|
|
|
|
/*
|
|
|
|
|
if( !q ) return;
|
|
|
|
|
char *c=(char*)q;
|
|
|
|
|
memBlks.remove( c );
|
|
|
|
|
delete [] c;
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void removeStr(BBStr *str) {
|
|
|
|
|
str->next->prev = str->prev;
|
|
|
|
|
str->prev->next = str->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void insertStr(BBStr *str, BBStr *next) {
|
|
|
|
|
str->next = next;
|
|
|
|
|
str->prev = next->prev;
|
|
|
|
|
str->prev->next = str;
|
|
|
|
|
next->prev = str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *BBStr::operator new(size_t size) {
|
|
|
|
|
if (freeStrs.next == &freeStrs) {
|
|
|
|
|
BBStr *t = (BBStr*)bbMalloc(sizeof(BBStr)*STR_NEW_INC);
|
|
|
|
|
for (int k = 0; k < STR_NEW_INC; ++k) insertStr(t++, &freeStrs);
|
|
|
|
|
}
|
|
|
|
|
BBStr *t = freeStrs.next;
|
|
|
|
|
removeStr(t); insertStr(t, &usedStrs);
|
|
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BBStr::operator delete(void *q) {
|
|
|
|
|
if (!q) return;
|
|
|
|
|
BBStr *t = (BBStr*)q;
|
|
|
|
|
removeStr(t); insertStr(t, &freeStrs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr::BBStr() {
|
|
|
|
|
++stringCnt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr::BBStr(const char *s) :string(s) {
|
|
|
|
|
++stringCnt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr::BBStr(const char *s, int n) : string(s, n) {
|
|
|
|
|
++stringCnt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr::BBStr(const BBStr &s) : string(s) {
|
|
|
|
|
++stringCnt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr::BBStr(const string &s) : string(s) {
|
|
|
|
|
++stringCnt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr &BBStr::operator=(const char *s) {
|
|
|
|
|
string::operator=(s); return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr &BBStr::operator=(const BBStr &s) {
|
|
|
|
|
string::operator=(s); return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr &BBStr::operator=(const string &s) {
|
|
|
|
|
string::operator=(s); return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr::~BBStr() {
|
|
|
|
|
--stringCnt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr *_bbStrLoad(BBStr **var) {
|
2016-10-03 17:11:15 +02:00
|
|
|
return *var ? new BBStr(**var) : new BBStr();
|
2016-07-19 09:21:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbStrRelease(BBStr *str) {
|
|
|
|
|
delete str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbStrStore(BBStr **var, BBStr *str) {
|
|
|
|
|
_bbStrRelease(*var); *var = str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr *_bbStrConcat(BBStr *s1, BBStr *s2) {
|
|
|
|
|
*s1 += *s2; delete s2; return s1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbStrCompare(BBStr *lhs, BBStr *rhs) {
|
|
|
|
|
int n = lhs->compare(*rhs);
|
|
|
|
|
delete lhs; delete rhs; return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbStrToInt(BBStr *s) {
|
|
|
|
|
int n = atoi(*s);
|
|
|
|
|
delete s; return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr *_bbStrFromInt(int n) {
|
2016-10-03 17:11:15 +02:00
|
|
|
return new BBStr(itoa(n));
|
2016-07-19 09:21:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float _bbStrToFloat(BBStr *s) {
|
|
|
|
|
float n = (float)atof(*s);
|
|
|
|
|
delete s; return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr *_bbStrFromFloat(float n) {
|
2016-10-03 17:11:15 +02:00
|
|
|
return new BBStr(ftoa(n));
|
2016-07-19 09:21:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr *_bbStrConst(const char *s) {
|
2016-10-03 17:11:15 +02:00
|
|
|
return new BBStr(s);
|
2016-07-19 09:21:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void * _bbVecAlloc(BBVecType *type) {
|
|
|
|
|
void *vec = bbMalloc(type->size * 4);
|
|
|
|
|
memset(vec, 0, type->size * 4);
|
|
|
|
|
return vec;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbVecFree(void *vec, BBVecType *type) {
|
|
|
|
|
if (type->elementType->type == BBTYPE_STR) {
|
|
|
|
|
BBStr **p = (BBStr**)vec;
|
|
|
|
|
for (int k = 0; k < type->size; ++p, ++k) {
|
|
|
|
|
if (*p) _bbStrRelease(*p);
|
|
|
|
|
}
|
|
|
|
|
} else if (type->elementType->type == BBTYPE_OBJ) {
|
|
|
|
|
BBObj **p = (BBObj**)vec;
|
|
|
|
|
for (int k = 0; k < type->size; ++p, ++k) {
|
|
|
|
|
if (*p) _bbObjRelease(*p);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bbFree(vec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbVecBoundsEx() {
|
|
|
|
|
ThrowRuntimeException("Blitz array index out of bounds");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbUndimArray(BBArray *array) {
|
|
|
|
|
if (void *t = array->data) {
|
|
|
|
|
if (array->elementType == BBTYPE_STR) {
|
|
|
|
|
BBStr **p = (BBStr**)t;
|
|
|
|
|
int size = array->scales[array->dims - 1];
|
|
|
|
|
for (int k = 0; k < size; ++p, ++k) {
|
|
|
|
|
if (*p) _bbStrRelease(*p);
|
|
|
|
|
}
|
|
|
|
|
} else if (array->elementType == BBTYPE_OBJ) {
|
|
|
|
|
BBObj **p = (BBObj**)t;
|
|
|
|
|
int size = array->scales[array->dims - 1];
|
|
|
|
|
for (int k = 0; k < size; ++p, ++k) {
|
|
|
|
|
if (*p) _bbObjRelease(*p);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bbFree(t);
|
|
|
|
|
array->data = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbDimArray(BBArray *array) {
|
|
|
|
|
int k;
|
|
|
|
|
for (k = 0; k < array->dims; ++k) ++array->scales[k];
|
|
|
|
|
for (k = 1; k < array->dims; ++k) {
|
|
|
|
|
array->scales[k] *= array->scales[k - 1];
|
|
|
|
|
}
|
|
|
|
|
int size = array->scales[array->dims - 1];
|
|
|
|
|
array->data = bbMalloc(size * 4);
|
|
|
|
|
memset(array->data, 0, size * 4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbArrayBoundsEx() {
|
|
|
|
|
ThrowRuntimeException("Array index out of bounds");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void unlinkObj(BBObj *obj) {
|
|
|
|
|
obj->next->prev = obj->prev;
|
|
|
|
|
obj->prev->next = obj->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void insertObj(BBObj *obj, BBObj *next) {
|
|
|
|
|
obj->next = next;
|
|
|
|
|
obj->prev = next->prev;
|
|
|
|
|
next->prev->next = obj;
|
|
|
|
|
next->prev = obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBObj *_bbObjNew(BBObjType *type) {
|
|
|
|
|
if (type->free.next == &type->free) {
|
|
|
|
|
int obj_size = sizeof(BBObj) + type->fieldCnt * 4;
|
|
|
|
|
BBObj *o = (BBObj*)bbMalloc(obj_size*OBJ_NEW_INC);
|
|
|
|
|
for (int k = 0; k < OBJ_NEW_INC; ++k) {
|
|
|
|
|
insertObj(o, &type->free);
|
|
|
|
|
o = (BBObj*)((char*)o + obj_size);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
BBObj *o = type->free.next;
|
|
|
|
|
unlinkObj(o);
|
|
|
|
|
o->type = type;
|
|
|
|
|
o->ref_cnt = 1;
|
|
|
|
|
o->fields = (BBField*)(o + 1);
|
|
|
|
|
for (int k = 0; k < type->fieldCnt; ++k) {
|
|
|
|
|
switch (type->fieldTypes[k]->type) {
|
|
|
|
|
case BBTYPE_VEC:
|
|
|
|
|
o->fields[k].VEC = _bbVecAlloc((BBVecType*)type->fieldTypes[k]);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
o->fields[k].INT = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
insertObj(o, &type->used);
|
|
|
|
|
++unrelObjCnt;
|
|
|
|
|
++objCnt;
|
|
|
|
|
return o;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbObjDelete(BBObj *obj) {
|
|
|
|
|
if (!obj) return;
|
|
|
|
|
BBField *fields = obj->fields;
|
|
|
|
|
if (!fields) return;
|
|
|
|
|
BBObjType *type = obj->type;
|
|
|
|
|
for (int k = 0; k < type->fieldCnt; ++k) {
|
|
|
|
|
switch (type->fieldTypes[k]->type) {
|
|
|
|
|
case BBTYPE_STR:
|
|
|
|
|
_bbStrRelease(fields[k].STR);
|
|
|
|
|
break;
|
|
|
|
|
case BBTYPE_OBJ:
|
|
|
|
|
_bbObjRelease(fields[k].OBJ);
|
|
|
|
|
break;
|
|
|
|
|
case BBTYPE_VEC:
|
|
|
|
|
_bbVecFree(fields[k].VEC, (BBVecType*)type->fieldTypes[k]);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
map<BBObj*, int>::iterator it = object_map.find(obj);
|
|
|
|
|
if (it != object_map.end()) {
|
|
|
|
|
handle_map.erase(it->second);
|
|
|
|
|
object_map.erase(it);
|
|
|
|
|
}
|
|
|
|
|
obj->fields = 0;
|
|
|
|
|
_bbObjRelease(obj);
|
|
|
|
|
--objCnt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbObjDeleteEach(BBObjType *type) {
|
|
|
|
|
BBObj *obj = type->used.next;
|
|
|
|
|
while (obj->type) {
|
|
|
|
|
BBObj *next = obj->next;
|
|
|
|
|
if (obj->fields) _bbObjDelete(obj);
|
|
|
|
|
obj = next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern void bbDebugLog(BBStr *t);
|
|
|
|
|
extern void bbStop();
|
|
|
|
|
|
|
|
|
|
void _bbObjRelease(BBObj *obj) {
|
|
|
|
|
if (!obj || --obj->ref_cnt) return;
|
|
|
|
|
unlinkObj(obj);
|
|
|
|
|
insertObj(obj, &obj->type->free);
|
|
|
|
|
--unrelObjCnt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbObjStore(BBObj **var, BBObj *obj) {
|
|
|
|
|
if (obj) ++obj->ref_cnt; //do this first incase of self-assignment
|
|
|
|
|
_bbObjRelease(*var);
|
|
|
|
|
*var = obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbObjCompare(BBObj *o1, BBObj *o2) {
|
|
|
|
|
return (o1 ? o1->fields : 0) != (o2 ? o2->fields : 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBObj *_bbObjNext(BBObj *obj) {
|
|
|
|
|
do {
|
|
|
|
|
obj = obj->next;
|
|
|
|
|
if (!obj->type) return 0;
|
|
|
|
|
} while (!obj->fields);
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBObj *_bbObjPrev(BBObj *obj) {
|
|
|
|
|
do {
|
|
|
|
|
obj = obj->prev;
|
|
|
|
|
if (!obj->type) return 0;
|
|
|
|
|
} while (!obj->fields);
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBObj *_bbObjFirst(BBObjType *type) {
|
|
|
|
|
return _bbObjNext(&type->used);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBObj *_bbObjLast(BBObjType *type) {
|
|
|
|
|
return _bbObjPrev(&type->used);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbObjInsBefore(BBObj *o1, BBObj *o2) {
|
|
|
|
|
if (o1 == o2) return;
|
|
|
|
|
unlinkObj(o1);
|
|
|
|
|
insertObj(o1, o2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbObjInsAfter(BBObj *o1, BBObj *o2) {
|
|
|
|
|
if (o1 == o2) return;
|
|
|
|
|
unlinkObj(o1);
|
|
|
|
|
insertObj(o1, o2->next);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbObjEachFirst(BBObj **var, BBObjType *type) {
|
|
|
|
|
_bbObjStore(var, _bbObjFirst(type));
|
|
|
|
|
return *var != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbObjEachNext(BBObj **var) {
|
|
|
|
|
_bbObjStore(var, _bbObjNext(*var));
|
|
|
|
|
return *var != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbObjEachFirst2(BBObj **var, BBObjType *type) {
|
|
|
|
|
*var = _bbObjFirst(type);
|
|
|
|
|
return *var != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbObjEachNext2(BBObj **var) {
|
|
|
|
|
*var = _bbObjNext(*var);
|
|
|
|
|
return *var != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr *_bbObjToStr(BBObj *obj) {
|
2016-10-03 17:11:15 +02:00
|
|
|
if (!obj || !obj->fields) return new BBStr("[NULL]");
|
2016-07-19 09:21:45 +02:00
|
|
|
|
|
|
|
|
static BBObj *root;
|
|
|
|
|
static int recurs_cnt;
|
|
|
|
|
|
2016-10-03 17:11:15 +02:00
|
|
|
if (obj == root) return new BBStr("[ROOT]");
|
|
|
|
|
if (recurs_cnt == 8) return new BBStr("....");
|
2016-07-19 09:21:45 +02:00
|
|
|
|
|
|
|
|
++recurs_cnt;
|
|
|
|
|
BBObj *oldRoot = root;
|
|
|
|
|
if (!root) root = obj;
|
|
|
|
|
|
|
|
|
|
BBObjType *type = obj->type;
|
|
|
|
|
BBField *fields = obj->fields;
|
2016-10-03 17:11:15 +02:00
|
|
|
BBStr *s = new BBStr("["), *t;
|
2016-07-19 09:21:45 +02:00
|
|
|
for (int k = 0; k < type->fieldCnt; ++k) {
|
|
|
|
|
if (k) *s += ',';
|
|
|
|
|
switch (type->fieldTypes[k]->type) {
|
|
|
|
|
case BBTYPE_INT:
|
|
|
|
|
t = _bbStrFromInt(fields[k].INT); *s += *t; delete t;
|
|
|
|
|
break;
|
|
|
|
|
case BBTYPE_FLT:
|
|
|
|
|
t = _bbStrFromFloat(fields[k].FLT); *s += *t; delete t;
|
|
|
|
|
break;
|
|
|
|
|
case BBTYPE_STR:
|
|
|
|
|
if (fields[k].STR) *s += '\"' + *fields[k].STR + '\"';
|
|
|
|
|
else *s += "\"\"";
|
|
|
|
|
break;
|
|
|
|
|
case BBTYPE_OBJ:
|
|
|
|
|
t = _bbObjToStr(fields[k].OBJ); *s += *t; delete t;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
*s += "???";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*s += ']';
|
|
|
|
|
root = oldRoot;
|
|
|
|
|
--recurs_cnt;
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbObjToHandle(BBObj *obj) {
|
|
|
|
|
if (!obj || !obj->fields) return 0;
|
|
|
|
|
map<BBObj*, int>::const_iterator it = object_map.find(obj);
|
|
|
|
|
if (it != object_map.end()) return it->second;
|
|
|
|
|
++next_handle;
|
|
|
|
|
object_map[obj] = next_handle;
|
|
|
|
|
handle_map[next_handle] = obj;
|
|
|
|
|
return next_handle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBObj *_bbObjFromHandle(int handle, BBObjType *type) {
|
|
|
|
|
map<int, BBObj*>::const_iterator it = handle_map.find(handle);
|
|
|
|
|
if (it == handle_map.end()) return 0;
|
|
|
|
|
BBObj *obj = it->second;
|
|
|
|
|
return obj->type == type ? obj : 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbNullObjEx() {
|
|
|
|
|
ThrowRuntimeException("Object does not exist");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _bbRestore(BBData *data) {
|
|
|
|
|
dataPtr = data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbReadInt() {
|
|
|
|
|
switch (dataPtr->fieldType) {
|
|
|
|
|
case BBTYPE_END:ThrowRuntimeException("Out of data"); return 0;
|
|
|
|
|
case BBTYPE_INT:return dataPtr++->field.INT;
|
|
|
|
|
case BBTYPE_FLT:return dataPtr++->field.FLT;
|
|
|
|
|
case BBTYPE_CSTR:return atoi(dataPtr++->field.CSTR);
|
|
|
|
|
default:ThrowRuntimeException("Bad data type"); return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float _bbReadFloat() {
|
|
|
|
|
switch (dataPtr->fieldType) {
|
|
|
|
|
case BBTYPE_END:ThrowRuntimeException("Out of data"); return 0;
|
|
|
|
|
case BBTYPE_INT:return dataPtr++->field.INT;
|
|
|
|
|
case BBTYPE_FLT:return dataPtr++->field.FLT;
|
|
|
|
|
case BBTYPE_CSTR:return atof(dataPtr++->field.CSTR);
|
|
|
|
|
default:ThrowRuntimeException("Bad data type"); return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BBStr *_bbReadStr() {
|
|
|
|
|
switch (dataPtr->fieldType) {
|
|
|
|
|
case BBTYPE_END:ThrowRuntimeException("Out of data"); return 0;
|
2016-10-03 17:11:15 +02:00
|
|
|
case BBTYPE_INT:return new BBStr(itoa(dataPtr++->field.INT));
|
|
|
|
|
case BBTYPE_FLT:return new BBStr(ftoa(dataPtr++->field.FLT));
|
|
|
|
|
case BBTYPE_CSTR:return new BBStr(dataPtr++->field.CSTR);
|
2016-07-19 09:21:45 +02:00
|
|
|
default:ThrowRuntimeException("Bad data type"); return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbAbs(int n) {
|
|
|
|
|
return n >= 0 ? n : -n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbSgn(int n) {
|
|
|
|
|
return n > 0 ? 1 : (n < 0 ? -1 : 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _bbMod(int x, int y) {
|
|
|
|
|
return x%y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float _bbFAbs(float n) {
|
|
|
|
|
return n >= 0 ? n : -n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float _bbFSgn(float n) {
|
|
|
|
|
return n > 0 ? 1 : (n < 0 ? -1 : 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float _bbFMod(float x, float y) {
|
|
|
|
|
return (float)fmod(x, y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float _bbFPow(float x, float y) {
|
|
|
|
|
return (float)pow(x, y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void bbRuntimeStats() {
|
|
|
|
|
gx_runtime->debugLog(("Active strings :" + itoa(stringCnt)).c_str());
|
|
|
|
|
gx_runtime->debugLog(("Active objects :" + itoa(objCnt)).c_str());
|
|
|
|
|
gx_runtime->debugLog(("Unreleased objs:" + itoa(unrelObjCnt)).c_str());
|
|
|
|
|
/*
|
|
|
|
|
clog<<"Active strings:"<<stringCnt<<endl;
|
|
|
|
|
clog<<"Active objects:"<<objCnt<<endl;
|
|
|
|
|
clog<<"Unreleased Objects:"<<unrelObjCnt<<endl;
|
|
|
|
|
for( BBStr *t=usedStrs.next;t!=&usedStrs;t=t->next ){
|
|
|
|
|
clog<<"string@"<<(void*)t<<endl;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool basic_create() {
|
|
|
|
|
next_handle = 0;
|
|
|
|
|
// memBlks.clear();
|
|
|
|
|
handle_map.clear();
|
|
|
|
|
object_map.clear();
|
|
|
|
|
stringCnt = objCnt = unrelObjCnt = 0;
|
|
|
|
|
usedStrs.next = usedStrs.prev = &usedStrs;
|
|
|
|
|
freeStrs.next = freeStrs.prev = &freeStrs;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool basic_destroy() {
|
|
|
|
|
while (usedStrs.next != &usedStrs) delete usedStrs.next;
|
|
|
|
|
// while( memBlks.size() ) bbFree( memBlks.back() );
|
|
|
|
|
handle_map.clear();
|
|
|
|
|
object_map.clear();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void basic_link(void(*rtSym)(const char *sym, void *pc)) {
|
|
|
|
|
|
|
|
|
|
rtSym("_bbIntType", &_bbIntType);
|
|
|
|
|
rtSym("_bbFltType", &_bbFltType);
|
|
|
|
|
rtSym("_bbStrType", &_bbStrType);
|
|
|
|
|
rtSym("_bbCStrType", &_bbCStrType);
|
|
|
|
|
|
|
|
|
|
rtSym("_bbStrLoad", _bbStrLoad);
|
|
|
|
|
rtSym("_bbStrRelease", _bbStrRelease);
|
|
|
|
|
rtSym("_bbStrStore", _bbStrStore);
|
|
|
|
|
rtSym("_bbStrCompare", _bbStrCompare);
|
|
|
|
|
rtSym("_bbStrConcat", _bbStrConcat);
|
|
|
|
|
rtSym("_bbStrToInt", _bbStrToInt);
|
|
|
|
|
rtSym("_bbStrFromInt", _bbStrFromInt);
|
|
|
|
|
rtSym("_bbStrToFloat", _bbStrToFloat);
|
|
|
|
|
rtSym("_bbStrFromFloat", _bbStrFromFloat);
|
|
|
|
|
rtSym("_bbStrConst", _bbStrConst);
|
|
|
|
|
rtSym("_bbDimArray", _bbDimArray);
|
|
|
|
|
rtSym("_bbUndimArray", _bbUndimArray);
|
|
|
|
|
rtSym("_bbArrayBoundsEx", _bbArrayBoundsEx);
|
|
|
|
|
rtSym("_bbVecAlloc", _bbVecAlloc);
|
|
|
|
|
rtSym("_bbVecFree", _bbVecFree);
|
|
|
|
|
rtSym("_bbVecBoundsEx", _bbVecBoundsEx);
|
|
|
|
|
rtSym("_bbObjNew", _bbObjNew);
|
|
|
|
|
rtSym("_bbObjDelete", _bbObjDelete);
|
|
|
|
|
rtSym("_bbObjDeleteEach", _bbObjDeleteEach);
|
|
|
|
|
rtSym("_bbObjRelease", _bbObjRelease);
|
|
|
|
|
rtSym("_bbObjStore", _bbObjStore);
|
|
|
|
|
rtSym("_bbObjCompare", _bbObjCompare);
|
|
|
|
|
rtSym("_bbObjNext", _bbObjNext);
|
|
|
|
|
rtSym("_bbObjPrev", _bbObjPrev);
|
|
|
|
|
rtSym("_bbObjFirst", _bbObjFirst);
|
|
|
|
|
rtSym("_bbObjLast", _bbObjLast);
|
|
|
|
|
rtSym("_bbObjInsBefore", _bbObjInsBefore);
|
|
|
|
|
rtSym("_bbObjInsAfter", _bbObjInsAfter);
|
|
|
|
|
rtSym("_bbObjEachFirst", _bbObjEachFirst);
|
|
|
|
|
rtSym("_bbObjEachNext", _bbObjEachNext);
|
|
|
|
|
rtSym("_bbObjEachFirst2", _bbObjEachFirst2);
|
|
|
|
|
rtSym("_bbObjEachNext2", _bbObjEachNext2);
|
|
|
|
|
rtSym("_bbObjToStr", _bbObjToStr);
|
|
|
|
|
rtSym("_bbObjToHandle", _bbObjToHandle);
|
|
|
|
|
rtSym("_bbObjFromHandle", _bbObjFromHandle);
|
|
|
|
|
rtSym("_bbNullObjEx", _bbNullObjEx);
|
|
|
|
|
rtSym("_bbRestore", _bbRestore);
|
|
|
|
|
rtSym("_bbReadInt", _bbReadInt);
|
|
|
|
|
rtSym("_bbReadFloat", _bbReadFloat);
|
|
|
|
|
rtSym("_bbReadStr", _bbReadStr);
|
|
|
|
|
rtSym("_bbAbs", _bbAbs);
|
|
|
|
|
rtSym("_bbSgn", _bbSgn);
|
|
|
|
|
rtSym("_bbMod", _bbMod);
|
|
|
|
|
rtSym("_bbFAbs", _bbFAbs);
|
|
|
|
|
rtSym("_bbFSgn", _bbFSgn);
|
|
|
|
|
rtSym("_bbFMod", _bbFMod);
|
|
|
|
|
rtSym("_bbFPow", _bbFPow);
|
|
|
|
|
rtSym("RuntimeStats", bbRuntimeStats);
|
|
|
|
|
}
|