X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fnasal%2Fvector.c;h=df20c1385584e3ddbef2f8080f74eeba0740ab12;hb=a1bb62f43c2f68a5ce4424f4d99f785b6d88bafe;hp=db98b3e45793c51e38c542a1cd9fa0482d4f2019;hpb=1786692406214447db12b9d5af5364582af23d3b;p=simgear.git diff --git a/simgear/nasal/vector.c b/simgear/nasal/vector.c index db98b3e4..df20c138 100644 --- a/simgear/nasal/vector.c +++ b/simgear/nasal/vector.c @@ -1,71 +1,97 @@ #include "nasal.h" #include "data.h" -static void realloc(struct naVec* v) +static struct VecRec* newvecrec(struct VecRec* old) { - int i, newsz = 1 + ((v->size*3)>>1); - naRef* na = naAlloc(sizeof(naRef) * newsz); - v->alloced = newsz; - for(i=0; isize; i++) - na[i] = v->array[i]; - naFree(v->array); - v->array = na; + int i, oldsz = old ? old->size : 0, newsz = 1 + ((oldsz*3)>>1); + struct VecRec* vr = naAlloc(sizeof(struct VecRec) + sizeof(naRef) * newsz); + if(oldsz > newsz) oldsz = newsz; // race protection + vr->alloced = newsz; + vr->size = oldsz; + for(i=0; iarray[i] = old->array[i]; + return vr; } -void naVec_init(naRef vec) +static void resize(struct naVec* v) { - struct naVec* v = vec.ref.ptr.vec; - v->array = 0; - v->size = 0; - v->alloced = 0; + struct VecRec* vr = newvecrec(v->rec); + naGC_swapfree((void*)&(v->rec), vr); } void naVec_gcclean(struct naVec* v) { - naFree(v->array); - v->size = 0; - v->alloced = 0; - v->array = 0; + naFree(v->rec); + v->rec = 0; } naRef naVec_get(naRef v, int i) { - if(!IS_VEC(v)) return naNil(); - if(i >= v.ref.ptr.vec->size) return naNil(); - return v.ref.ptr.vec->array[i]; + if(IS_VEC(v)) { + struct VecRec* r = PTR(v).vec->rec; + if(r) { + if(i < 0) i += r->size; + if(i >= 0 && i < r->size) return r->array[i]; + } + } + return naNil(); } void naVec_set(naRef vec, int i, naRef o) { - struct naVec* v = vec.ref.ptr.vec; - if(!IS_VEC(vec) || i >= v->size) return; - v->array[i] = o; + if(IS_VEC(vec)) { + struct VecRec* r = PTR(vec).vec->rec; + if(r && i >= r->size) return; + r->array[i] = o; + } } int naVec_size(naRef v) { - if(!IS_VEC(v)) return 0; - return v.ref.ptr.vec->size; + if(IS_VEC(v)) { + struct VecRec* r = PTR(v).vec->rec; + return r ? r->size : 0; + } + return 0; } int naVec_append(naRef vec, naRef o) { - struct naVec* v = vec.ref.ptr.vec; - if(!IS_VEC(vec)) return 0; - if(v->size >= v->alloced) - realloc(v); - v->array[v->size] = o; - return v->size++; + if(IS_VEC(vec)) { + struct VecRec* r = PTR(vec).vec->rec; + while(!r || r->size >= r->alloced) { + resize(PTR(vec).vec); + r = PTR(vec).vec->rec; + } + r->array[r->size] = o; + return r->size++; + } + return 0; +} + +void naVec_setsize(naRef vec, int sz) +{ + int i; + struct VecRec* v = PTR(vec).vec->rec; + struct VecRec* nv = naAlloc(sizeof(struct VecRec) + sizeof(naRef) * sz); + nv->size = sz; + nv->alloced = sz; + for(i=0; iarray[i] = (v && i < v->size) ? v->array[i] : naNil(); + naGC_swapfree((void*)&(PTR(vec).vec->rec), nv); } naRef naVec_removelast(naRef vec) { naRef o; - struct naVec* v = vec.ref.ptr.vec; - if(!IS_VEC(vec) || v->size == 0) return naNil(); - o = v->array[v->size - 1]; - v->size--; - if(v->size < (v->alloced >> 1)) - realloc(v); - return o; + if(IS_VEC(vec)) { + struct VecRec* v = PTR(vec).vec->rec; + if(!v || v->size == 0) return naNil(); + o = v->array[v->size - 1]; + v->size--; + if(v->size < (v->alloced >> 1)) + resize(PTR(vec).vec); + return o; + } + return naNil(); }