forked from Mirrors/openclonk
Completely removed references from the engine, changed array semantics to not copy automatically, implemented postfix ++/-- correctly
parent
efb5925129
commit
edb4a4a0b2
|
@ -686,13 +686,13 @@ void C4Def::Draw(C4Facet &cgo, bool fSelected, DWORD iColor, C4Object *pObj, int
|
|||
if (pObj)
|
||||
{
|
||||
instance = pObj->pMeshInstance;
|
||||
pObj->GetPropertyVal(P_PictureTransformation, value);
|
||||
pObj->GetPropertyVal(P_PictureTransformation, &value);
|
||||
}
|
||||
else
|
||||
{
|
||||
dummy.reset(new StdMeshInstance(*graphics->Mesh));
|
||||
instance = dummy.get();
|
||||
GetPropertyVal(P_PictureTransformation, value);
|
||||
GetPropertyVal(P_PictureTransformation, &value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1394,9 +1394,9 @@ C4PropList *C4Def::GetActionByName(C4String *actname)
|
|||
// If we get the null string or ActIdle by name, return NULL action
|
||||
if (!actname || actname == Strings.P[P_Idle]) return NULL;
|
||||
// otherwise, query actmap
|
||||
C4Value ActMap; GetPropertyVal(P_ActMap, ActMap);
|
||||
C4Value ActMap; GetPropertyVal(P_ActMap, &ActMap);
|
||||
if (!ActMap.getPropList()) return false;
|
||||
C4Value Action; ActMap.getPropList()->GetPropertyVal(actname, Action);
|
||||
C4Value Action; ActMap.getPropList()->GetPropertyVal(actname, &Action);
|
||||
if (!Action.getPropList()) return false;
|
||||
return Action.getPropList();
|
||||
}
|
||||
|
|
|
@ -733,12 +733,12 @@ void C4GraphicsOverlay::UpdateFacet()
|
|||
return;
|
||||
|
||||
C4Value v;
|
||||
pDef->GetPropertyVal(P_ActMap, v);
|
||||
pDef->GetPropertyVal(P_ActMap, &v);
|
||||
C4PropList *actmap = v.getPropList();
|
||||
if (!actmap)
|
||||
return;
|
||||
|
||||
actmap->GetPropertyVal(::Strings.RegString(Action), v);
|
||||
actmap->GetPropertyVal(::Strings.RegString(Action), &v);
|
||||
C4PropList *action = v.getPropList();
|
||||
if (!action)
|
||||
return;
|
||||
|
@ -1093,7 +1093,7 @@ void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByP
|
|||
}
|
||||
|
||||
C4Value value;
|
||||
pDef->GetPropertyVal(P_PictureTransformation, value);
|
||||
pDef->GetPropertyVal(P_PictureTransformation, &value);
|
||||
StdMeshMatrix matrix;
|
||||
if (C4ValueToMatrix(value, &matrix))
|
||||
lpDDraw->SetMeshTransform(&matrix);
|
||||
|
@ -1170,7 +1170,7 @@ void C4GraphicsOverlay::DrawPicture(C4Facet &cgo, C4Object *pForObj)
|
|||
C4Def *pDef = pSourceGfx->pDef;
|
||||
|
||||
C4Value value;
|
||||
pDef->GetPropertyVal(P_PictureTransformation, value);
|
||||
pDef->GetPropertyVal(P_PictureTransformation, &value);
|
||||
StdMeshMatrix matrix;
|
||||
if (C4ValueToMatrix(value, &matrix))
|
||||
lpDDraw->SetMeshTransform(&matrix);
|
||||
|
|
|
@ -212,10 +212,10 @@ void C4PhysicalInfo::PromotionUpdate(int32_t iRank, bool fUpdateTrainablePhysica
|
|||
for (int32_t iPhysIdx=0; (szPhysName = GetNameByIndex(iPhysIdx, &PhysOff)); ++iPhysIdx)
|
||||
{
|
||||
C4Value PhysVal(this->*PhysOff);
|
||||
C4AulParSet Pars(C4VString(szPhysName), C4VInt(iRank), C4VRef(&PhysVal));
|
||||
if (!!pTrainDef->Script.Call(PSF_GetFairCrewPhysical, 0, &Pars))
|
||||
C4AulParSet Pars(C4VString(szPhysName), C4VInt(iRank), PhysVal);
|
||||
if (C4Value NewVal = pTrainDef->Script.Call(PSF_GetFairCrewPhysical, 0, &Pars))
|
||||
{
|
||||
this->*PhysOff = PhysVal.getInt();
|
||||
this->*PhysOff = NewVal.getInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -555,7 +555,7 @@ void C4Object::DrawFaceImpl(C4TargetFacet &cgo, bool action, float fx, float fy,
|
|||
break;
|
||||
case C4DefGraphics::TYPE_Mesh:
|
||||
C4Value value;
|
||||
GetPropertyVal(P_MeshTransformation, value);
|
||||
GetPropertyVal(P_MeshTransformation, &value);
|
||||
StdMeshMatrix matrix;
|
||||
if (C4ValueToMatrix(value, &matrix))
|
||||
lpDDraw->SetMeshTransform(&matrix);
|
||||
|
@ -2671,7 +2671,7 @@ void C4Object::DrawLine(C4TargetFacet &cgo)
|
|||
// additive mode?
|
||||
PrepareDrawing();
|
||||
// Draw line segments
|
||||
C4Value colorsV; GetPropertyVal(P_LineColors, colorsV);
|
||||
C4Value colorsV; GetPropertyVal(P_LineColors, &colorsV);
|
||||
C4ValueArray *colors = colorsV.getArray();
|
||||
int32_t color0 = 0xFFFF00FF, color1 = 0xFFFF00FF; // use bright colors so author notices
|
||||
if (colors)
|
||||
|
@ -3343,7 +3343,7 @@ void C4Object::Resort()
|
|||
C4PropList* C4Object::GetAction()
|
||||
{
|
||||
C4Value value;
|
||||
GetPropertyVal(P_Action, value);
|
||||
GetPropertyVal(P_Action, &value);
|
||||
return value.getPropList();
|
||||
}
|
||||
|
||||
|
@ -3474,9 +3474,9 @@ bool C4Object::SetActionByName(C4String *ActName,
|
|||
// If we get the null string or ActIdle by name, set ActIdle
|
||||
if (!ActName || ActName == Strings.P[P_Idle])
|
||||
return SetAction(0,0,0,iCalls,fForce);
|
||||
C4Value ActMap; GetPropertyVal(P_ActMap, ActMap);
|
||||
C4Value ActMap; GetPropertyVal(P_ActMap, &ActMap);
|
||||
if (!ActMap.getPropList()) return false;
|
||||
C4Value Action; ActMap.getPropList()->GetPropertyVal(ActName, Action);
|
||||
C4Value Action; ActMap.getPropList()->GetPropertyVal(ActName, &Action);
|
||||
if (!Action.getPropList()) return false;
|
||||
return SetAction(Action.getPropList(),pTarget,pTarget2,iCalls,fForce);
|
||||
}
|
||||
|
@ -4595,7 +4595,7 @@ void C4Object::ExecAction()
|
|||
int32_t attachVertex0,attachVertex1;
|
||||
attachVertex0=attachVertex1=0;
|
||||
{
|
||||
C4Value lineAttachV; GetPropertyVal(P_LineAttach, lineAttachV);
|
||||
C4Value lineAttachV; GetPropertyVal(P_LineAttach, &lineAttachV);
|
||||
C4ValueArray *lineAttach = lineAttachV.getArray();
|
||||
if (lineAttach)
|
||||
{
|
||||
|
@ -4839,7 +4839,7 @@ bool C4Object::IsVisible(int32_t iForPlr, bool fAsOverlay)
|
|||
{
|
||||
bool fDraw;
|
||||
C4Value vis;
|
||||
if (!GetPropertyVal(P_Visibility, vis))
|
||||
if (!GetPropertyVal(P_Visibility, &vis))
|
||||
return true;
|
||||
|
||||
int32_t Visibility;
|
||||
|
@ -5064,7 +5064,7 @@ void C4Object::GetParallaxity(int32_t *parX, int32_t *parY)
|
|||
assert(parX); assert(parY);
|
||||
*parX = 100; *parY = 100;
|
||||
if (!(Category & C4D_Parallax)) return;
|
||||
C4Value parV; GetPropertyVal(P_Parallaxity, parV);
|
||||
C4Value parV; GetPropertyVal(P_Parallaxity, &parV);
|
||||
C4ValueArray *par = parV.getArray();
|
||||
if (!par) return;
|
||||
*parX = par->GetItem(0).getInt();
|
||||
|
@ -5074,7 +5074,7 @@ void C4Object::GetParallaxity(int32_t *parX, int32_t *parY)
|
|||
bool C4Object::GetDragImage(C4Object **drag_object, C4ID *drag_id)
|
||||
{
|
||||
// drag is possible if MouseDragImage is assigned
|
||||
C4Value parV; GetPropertyVal(P_MouseDragImage, parV);
|
||||
C4Value parV; GetPropertyVal(P_MouseDragImage, &parV);
|
||||
if (!parV) return false;
|
||||
// determine drag object/id
|
||||
C4Object *obj=NULL; C4ID id;
|
||||
|
|
|
@ -638,7 +638,7 @@ bool C4FindObjectActionTarget::Check(C4Object *pObj)
|
|||
bool C4FindObjectProcedure::Check(C4Object *pObj)
|
||||
{
|
||||
C4Value v;
|
||||
pObj->GetAction()->GetPropertyVal(P_Procedure, v);
|
||||
pObj->GetAction()->GetPropertyVal(P_Procedure, &v);
|
||||
return v != C4VNull && v.getInt() == procedure;
|
||||
}
|
||||
|
||||
|
|
|
@ -194,7 +194,6 @@ typedef bool t_bool;
|
|||
typedef C4ID t_id;
|
||||
typedef C4Object *t_object;
|
||||
typedef C4String *t_string;
|
||||
typedef C4Value &t_ref;
|
||||
typedef C4Value t_any;
|
||||
typedef C4ValueArray *t_array;
|
||||
|
||||
|
@ -203,8 +202,7 @@ inline t_bool getPar_bool(C4Value *pVal) { return pVal->getBool(); }
|
|||
inline t_id getPar_id(C4Value *pVal) { return pVal->getC4ID(); }
|
||||
inline t_object getPar_object(C4Value *pVal) { return pVal->getObj(); }
|
||||
inline t_string getPar_string(C4Value *pVal) { return pVal->getStr(); }
|
||||
//inline t_ref getPar_ref(C4Value *pVal) { return pVal->GetRefVal(); }
|
||||
inline t_any getPar_any(C4Value *pVal) { return pVal->GetRefValConst(); }
|
||||
inline t_any getPar_any(C4Value *pVal) { return *pVal; }
|
||||
inline t_array getPar_array(C4Value *pVal) { return pVal->getArray(); }
|
||||
|
||||
#define PAR(type, name) t_##type name = getPar_##type(pPars++)
|
||||
|
@ -1011,7 +1009,7 @@ static C4Value FnGetProperty_C4V(C4AulContext *cthr, C4Value * key_C4V, C4Value
|
|||
C4String * key = key_C4V->_getStr();
|
||||
if (!key) return C4VNull;
|
||||
C4Value r;
|
||||
pObj->GetPropertyRef(key, r);
|
||||
pObj->GetPropertyVal(key, &r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -1924,26 +1922,25 @@ static C4Object *FnComposeContents(C4AulObjectContext *cthr, C4ID c_id)
|
|||
return cthr->Obj->ComposeContents(c_id);
|
||||
}
|
||||
|
||||
static bool FnFindConstructionSite(C4AulContext *cthr, C4PropList * PropList, C4Value * VarX, C4Value * VarY)
|
||||
static C4ValueArray *FnFindConstructionSite(C4AulContext *cthr, C4PropList * PropList, int32_t v1, int32_t v2)
|
||||
{
|
||||
// Get def Old-style implementation (fixed)...
|
||||
// Get def
|
||||
C4Def *pDef;
|
||||
if (!(pDef=PropList->GetDef())) return false;
|
||||
// Get thread vars
|
||||
if (!cthr->Caller) return false;
|
||||
C4Value V1 = VarX->GetRefValConst();
|
||||
C4Value V2 = VarY->GetRefValConst();
|
||||
// Construction check at starting position
|
||||
if (ConstructionCheck(PropList,V1.getInt(),V2.getInt()))
|
||||
return true;
|
||||
if (ConstructionCheck(PropList,v1,v2))
|
||||
return NULL;
|
||||
// Search for real
|
||||
int32_t v1 = V1.getInt(), v2 = V2.getInt();
|
||||
bool result = !!FindConSiteSpot(v1, v2,
|
||||
pDef->Shape.Wdt,pDef->Shape.Hgt,
|
||||
pDef->Category,
|
||||
20);
|
||||
*VarX = C4VInt(v1); *VarY = C4VInt(v2);
|
||||
return result;
|
||||
C4ValueArray *pArray = new C4ValueArray(2);
|
||||
pArray->SetItem(0, C4VInt(v1));
|
||||
pArray->SetItem(1, C4VInt(v2));
|
||||
return pArray;
|
||||
}
|
||||
|
||||
C4FindObject *CreateCriterionsFromPars(C4Value *pPars, C4FindObject **pFOs, C4SortObject **pSOs)
|
||||
|
@ -2919,18 +2916,19 @@ static bool FnPathFree(C4AulContext *cthr, long X1, long Y1, long X2, long Y2)
|
|||
return !!PathFree(X1, Y1, X2, Y2);
|
||||
}
|
||||
|
||||
static C4Value FnPathFree2_C4V(C4AulContext *cthr, C4Value * X1, C4Value * Y1, C4Value * X2, C4Value * Y2)
|
||||
static C4Value FnPathFree2(C4AulContext *cthr, int32_t x1, int32_t y1, int32_t x2, int32_t y2)
|
||||
{
|
||||
int32_t x = -1, y = -1;
|
||||
C4Value x1 = X1->GetRefValConst(), y1 = Y1->GetRefValConst();
|
||||
// Do not use getInt on the references, because it destroys them.
|
||||
bool r = !!PathFree(x1.getInt(), y1.getInt(), X2->getInt(), Y2->getInt(), &x, &y);
|
||||
bool r = !!PathFree(x1, y1, x2, y2, &x, &y);
|
||||
if (!r)
|
||||
{
|
||||
*X1 = C4VInt(x);
|
||||
*Y1 = C4VInt(y);
|
||||
C4ValueArray *pArray = new C4ValueArray(2);
|
||||
pArray->SetItem(0, C4VInt(x));
|
||||
pArray->SetItem(1, C4VInt(y));
|
||||
return C4VArray(pArray);
|
||||
}
|
||||
return C4VBool(r);
|
||||
return C4VBool(true);
|
||||
}
|
||||
|
||||
static long FnSetTransferZone(C4AulObjectContext *cthr, long iX, long iY, long iWdt, long iHgt)
|
||||
|
@ -3353,11 +3351,6 @@ static C4String *FnGetProcedure(C4AulObjectContext *cthr)
|
|||
return String(ProcedureName[iProc]);
|
||||
}
|
||||
|
||||
static C4Value FnIsRef(C4AulContext *cthr, C4Value* Value)
|
||||
{
|
||||
return C4VBool(Value->IsRef());
|
||||
}
|
||||
|
||||
static C4Value FnGetType(C4AulContext *cthr, C4Value* Value)
|
||||
{
|
||||
return C4VInt(Value->GetType());
|
||||
|
@ -3403,14 +3396,14 @@ static C4Value FnGetIndexOf(C4AulContext *cthr, C4Value *pPars)
|
|||
return C4VInt(-1);
|
||||
}
|
||||
|
||||
static C4Void FnSetLength(C4AulContext *cthr, C4Value *pArrayRef, int iNewSize)
|
||||
static C4Void FnSetLength(C4AulContext *cthr, C4ValueArray *pArray, int iNewSize)
|
||||
{
|
||||
// safety
|
||||
if (iNewSize<0 || iNewSize > C4ValueArray::MaxSize)
|
||||
throw new C4AulExecError(cthr->Obj, FormatString("SetLength: invalid array size (%d)", iNewSize).getData());
|
||||
|
||||
// set new size
|
||||
pArrayRef->SetArrayLength(iNewSize, cthr);
|
||||
pArray->SetSize(iNewSize);
|
||||
return C4VNull;
|
||||
}
|
||||
|
||||
|
@ -4025,8 +4018,8 @@ static C4Value FnVarN(C4AulContext *cthr, C4Value *strName_C4V)
|
|||
if (iID < 0)
|
||||
return C4VNull;
|
||||
|
||||
// return reference on variable
|
||||
return cthr->Caller->Vars[iID].GetRef();
|
||||
// return variable value
|
||||
return cthr->Caller->Vars[iID];
|
||||
}
|
||||
|
||||
static C4Value FnLocalN(C4AulContext* cthr, C4Value* strName_C4V)
|
||||
|
@ -4037,10 +4030,9 @@ static C4Value FnLocalN(C4AulContext* cthr, C4Value* strName_C4V)
|
|||
C4String * key = strName_C4V->getStr();
|
||||
if (!key) return C4VNull;
|
||||
|
||||
// get reference on variable
|
||||
// get variable
|
||||
C4Value r;
|
||||
cthr->Obj->GetPropertyRef(key, r);
|
||||
|
||||
cthr->Obj->GetPropertyVal(key, &r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -4053,8 +4045,8 @@ static C4Value FnGlobalN(C4AulContext* cthr, C4Value* strName_C4V)
|
|||
|
||||
if (!pVarN) return C4Value();
|
||||
|
||||
// return reference on variable
|
||||
return pVarN->GetRef();
|
||||
// return variable value
|
||||
return *pVarN;
|
||||
}
|
||||
|
||||
static bool FnSetSkyAdjust(C4AulContext* cthr, long dwAdjust, long dwBackClr)
|
||||
|
@ -4724,11 +4716,13 @@ static C4Value FnSimFlight(C4AulContext *ctx, C4Value *pvrX, C4Value *pvrY, C4Va
|
|||
if (!SimFlight(x, y, xdir, ydir, iDensityMin, iDensityMax, iIter))
|
||||
return C4VFalse;
|
||||
|
||||
// write results back
|
||||
*pvrX = C4VInt(fixtoi(x)); *pvrY = C4VInt(fixtoi(y));
|
||||
*pvrXDir = C4VInt(fixtoi(xdir * iPrec)); *pvrYDir = C4VInt(fixtoi(ydir * iPrec));
|
||||
|
||||
return C4VTrue;
|
||||
// write results to array
|
||||
C4ValueArray *pResults = new C4ValueArray(4);
|
||||
pResults->SetItem(0, C4VInt(fixtoi(x)));
|
||||
pResults->SetItem(1, C4VInt(fixtoi(y)));
|
||||
pResults->SetItem(2, C4VInt(fixtoi(xdir * iPrec)));
|
||||
pResults->SetItem(3, C4VInt(fixtoi(ydir * iPrec)));
|
||||
return C4VArray(pResults);
|
||||
}
|
||||
#undef COPY_C4V_PAR
|
||||
static bool FnSetPortrait(C4AulObjectContext *ctx, C4String *pstrPortrait, C4ID idSourceDef, bool fPermanent, bool fCopyGfx)
|
||||
|
@ -6382,6 +6376,7 @@ void InitFunctionMap(C4AulScriptEngine *pEngine)
|
|||
AddFunc(pEngine, "ExecuteCommand", FnExecuteCommand);
|
||||
AddFunc(pEngine, "LocateFunc", FnLocateFunc);
|
||||
AddFunc(pEngine, "PathFree", FnPathFree);
|
||||
AddFunc(pEngine, "PathFree2", FnPathFree2);
|
||||
AddFunc(pEngine, "SetNextMission", FnSetNextMission);
|
||||
AddFunc(pEngine, "GetPlayerControlState", FnGetPlayerControlState);
|
||||
AddFunc(pEngine, "SetPlayerControlEnabled", FnSetPlayerControlEnabled);
|
||||
|
@ -6791,7 +6786,6 @@ C4ScriptFnDef C4ScriptFnMap[]=
|
|||
{ "AddCommand", 1 ,C4V_Bool ,{ C4V_String ,C4V_C4Object,C4V_Any ,C4V_Int ,C4V_C4Object,C4V_Int ,C4V_Any ,C4V_Int ,C4V_Int ,C4V_Any} ,0 , FnAddCommand },
|
||||
{ "AppendCommand", 1 ,C4V_Bool ,{ C4V_String ,C4V_C4Object,C4V_Any ,C4V_Int ,C4V_C4Object,C4V_Int ,C4V_Any ,C4V_Int ,C4V_Int ,C4V_Any} ,0 , FnAppendCommand },
|
||||
{ "GetCommand", 1 ,C4V_Any ,{ C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,0 , FnGetCommand },
|
||||
{ "PathFree2", 1 ,C4V_Bool ,{ C4V_Ref ,C4V_Ref ,C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnPathFree2_C4V , 0 },
|
||||
{ "FindObject", 1 ,C4V_C4Object ,{ C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,0 , FnFindObject },
|
||||
{ "FindObjects", 1 ,C4V_Array ,{ C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,0 , FnFindObjects },
|
||||
{ "ObjectCount", 1 ,C4V_Int ,{ C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,0 , FnObjectCount },
|
||||
|
@ -6816,7 +6810,6 @@ C4ScriptFnDef C4ScriptFnMap[]=
|
|||
{ "GetHomebaseMaterial", 1 ,C4V_Int ,{ C4V_Int ,C4V_PropList,C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetHomebaseMaterial_C4V , 0 },
|
||||
{ "GetHomebaseProduction",1 ,C4V_Int ,{ C4V_Int ,C4V_PropList,C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetHomebaseProduction_C4V , 0 },
|
||||
|
||||
{ "IsRef", 1 ,C4V_Bool ,{ C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnIsRef, 0 },
|
||||
{ "GetType", 1 ,C4V_Int ,{ C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetType, 0 },
|
||||
|
||||
{ "CreateArray", 1 ,C4V_Array ,{ C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,0, FnCreateArray },
|
||||
|
@ -6835,7 +6828,7 @@ C4ScriptFnDef C4ScriptFnMap[]=
|
|||
{ "GetPlrExtraData", 1 ,C4V_Any ,{ C4V_Int ,C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetPlrExtraData, 0 },
|
||||
{ "SetCrewExtraData", 1 ,C4V_Any ,{ C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnSetCrewExtraData, 0 },
|
||||
{ "GetCrewExtraData", 1 ,C4V_Any ,{ C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetCrewExtraData, 0 },
|
||||
{ "SimFlight", 1 ,C4V_Bool ,{ C4V_Ref ,C4V_Ref ,C4V_Ref ,C4V_Ref ,C4V_Int ,C4V_Int ,C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any} ,MkFnC4V FnSimFlight, 0 },
|
||||
{ "SimFlight", 1 ,C4V_Bool ,{ C4V_Int ,C4V_Int ,C4V_Int ,C4V_Int ,C4V_Int ,C4V_Int ,C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any} ,MkFnC4V FnSimFlight, 0 },
|
||||
{ "GetPortrait", 1 ,C4V_Any ,{ C4V_C4Object,C4V_Bool ,C4V_Bool ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetPortrait, 0 },
|
||||
{ "AddEffect", 1 ,C4V_Int ,{ C4V_String ,C4V_C4Object,C4V_Int ,C4V_Int ,C4V_C4Object,C4V_PropList,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnAddEffect_C4V, 0 },
|
||||
{ "GetEffect", 1 ,C4V_Any ,{ C4V_String ,C4V_C4Object,C4V_Int ,C4V_Int ,C4V_Int ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any} ,MkFnC4V FnGetEffect_C4V, 0 },
|
||||
|
|
|
@ -29,8 +29,8 @@ class C4AulScriptEngine;
|
|||
class StdMeshMatrix;
|
||||
|
||||
const int C4SCR_Access_Public = 0,
|
||||
C4SCR_Access_Protected = 1,
|
||||
C4SCR_Access_Private = 2;
|
||||
C4SCR_Access_Protected = 1,
|
||||
C4SCR_Access_Private = 2;
|
||||
|
||||
#define C4SCR_Public "public"
|
||||
#define C4SCR_Protected "protected"
|
||||
|
@ -57,7 +57,7 @@ struct C4ScriptFnDef
|
|||
bool Public;
|
||||
C4V_Type RetType; // type returned. ignored when C4V
|
||||
C4V_Type ParType[10];// type of the parameters. error when wrong parameter type.
|
||||
C4Value (*FunctionC4V)(C4AulContext *cthr, C4Value*, C4Value*, C4Value*, C4Value*, C4Value*,
|
||||
C4Value (*FunctionC4V)(struct C4AulContext *cthr, C4Value*, C4Value*, C4Value*, C4Value*, C4Value*,
|
||||
C4Value*, C4Value*, C4Value*, C4Value*, C4Value*);
|
||||
C4Value (*FunctionC4V2)(struct C4AulContext *, C4Value *);
|
||||
};
|
||||
|
|
|
@ -413,7 +413,6 @@ void C4AulScriptFunc::CopyBody(C4AulScriptFunc &FromFunc)
|
|||
Script = FromFunc.Script;
|
||||
VarNamed = FromFunc.VarNamed;
|
||||
ParNamed = FromFunc.ParNamed;
|
||||
bReturnRef = FromFunc.bReturnRef;
|
||||
pOrgScript = FromFunc.pOrgScript;
|
||||
for (int i = 0; i < C4AUL_MAX_Par; i++)
|
||||
ParType[i] = FromFunc.ParType[i];
|
||||
|
|
|
@ -206,6 +206,7 @@ struct C4ScriptOpDef
|
|||
unsigned short Priority;
|
||||
const char* Identifier;
|
||||
C4AulBCCType Code;
|
||||
C4AulBCCType ResultModifier; // code to apply to result after it was calculated
|
||||
bool Postfix;
|
||||
bool Changer; // changes first operand to result, rewrite to "a = a (op) b"
|
||||
bool NoSecondStatement; // no second statement expected (++/-- postfix)
|
||||
|
@ -316,12 +317,11 @@ public:
|
|||
C4ValueMapNames VarNamed; // list of named vars in this function
|
||||
C4ValueMapNames ParNamed; // list of named pars in this function
|
||||
C4V_Type ParType[C4AUL_MAX_Par]; // parameter types
|
||||
bool bReturnRef; // return reference
|
||||
C4AulScript *pOrgScript; // the orginal script (!= Owner if included or appended)
|
||||
|
||||
C4AulScriptFunc(C4AulScript *pOwner, const char *pName, bool bAtEnd = true) : C4AulFunc(pOwner, pName, bAtEnd),
|
||||
OwnerOverloaded(NULL), idImage (C4ID::None), iImagePhase(0), Condition(NULL), ControlMethod(C4AUL_ControlMethod_All),
|
||||
bReturnRef(false), tProfileTime(0)
|
||||
tProfileTime(0)
|
||||
{
|
||||
for (int i = 0; i < C4AUL_MAX_Par; i++) ParType[i] = C4V_Any;
|
||||
} // constructor
|
||||
|
@ -330,7 +330,7 @@ public:
|
|||
|
||||
virtual bool GetPublic() { return true; }
|
||||
virtual C4V_Type *GetParType() { return ParType; }
|
||||
virtual C4V_Type GetRetType() { return bReturnRef ? C4V_Ref : C4V_Any; }
|
||||
virtual C4V_Type GetRetType() { return C4V_Any; }
|
||||
virtual C4Value Exec(C4AulContext *pCallerCtx, C4Value pPars[], bool fPassErrors=false); // execute func (script call, should not happen)
|
||||
virtual C4Value Exec(C4Object *pObj=NULL, C4AulParSet *pPars = NULL, bool fPassErrors=false); // execute func (engine call)
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
|
|||
if (!pCurCtx->Obj)
|
||||
throw new C4AulExecError(pCurCtx->Obj, "can't access local variables in a definition call!");
|
||||
PushNullVals(1);
|
||||
pCurCtx->Obj->GetPropertyVal(pCPos->Par.s, pCurVal[0]);
|
||||
pCurCtx->Obj->GetPropertyVal(pCPos->Par.s, pCurVal);
|
||||
break;
|
||||
case AB_LOCALN_SET:
|
||||
if (!pCurCtx->Obj)
|
||||
|
@ -439,13 +439,13 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
|
|||
// Typcheck to determine whether it's an array or a proplist
|
||||
if(CheckArrayAccess(pStruct, pIndex) == C4V_Array)
|
||||
{
|
||||
pStruct->GetArrayElement(pIndex->_getInt(), *pResult, pCurCtx, true);
|
||||
*pResult = pStruct->_getArray()->GetItem(pIndex->_getInt());
|
||||
}
|
||||
else
|
||||
{
|
||||
C4PropList *pPropList = pStruct->getPropList();
|
||||
assert(pPropList);
|
||||
if (!pPropList->GetPropertyVal(pIndex->_getStr(), *pResult))
|
||||
assert(pStruct->GetType() == C4V_PropList || pStruct->GetType() == C4V_C4Object);
|
||||
C4PropList *pPropList = pStruct->_getPropList();
|
||||
if (!pPropList->GetPropertyVal(pIndex->_getStr(), pResult))
|
||||
pResult->Set0();
|
||||
}
|
||||
// Remove index
|
||||
|
@ -458,15 +458,12 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
|
|||
// Typcheck to determine whether it's an array or a proplist
|
||||
if(CheckArrayAccess(pStruct, pIndex) == C4V_Array)
|
||||
{
|
||||
// TODO: Does not work, because array gets copied here!
|
||||
C4Value Ref;
|
||||
pStruct->GetArrayElement(pIndex->_getInt(), Ref, pCurCtx, false);
|
||||
Ref.getRef()->Set(*pValue);
|
||||
pStruct->_getArray()->SetItem(pIndex->_getInt(), *pValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
C4PropList *pPropList = pStruct->getPropList();
|
||||
assert(pPropList);
|
||||
assert(pStruct->GetType() == C4V_PropList || pStruct->GetType() == C4V_C4Object);
|
||||
C4PropList *pPropList = pStruct->_getPropList();
|
||||
pPropList->SetProperty(pIndex->_getStr(), *pValue);
|
||||
}
|
||||
// Set result, remove array and index from stack
|
||||
|
@ -551,10 +548,6 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
|
|||
|
||||
case AB_RETURN:
|
||||
{
|
||||
// Resolve reference
|
||||
if (!pCurCtx->Func->SFunc()->bReturnRef)
|
||||
pCurVal->Deref();
|
||||
|
||||
// Trace
|
||||
if (iTraceStart >= 0)
|
||||
{
|
||||
|
|
|
@ -73,12 +73,6 @@ private:
|
|||
(++pCurVal)->Set(rVal);
|
||||
}
|
||||
|
||||
void PushValueRef(C4Value &rVal)
|
||||
{
|
||||
CheckOverflow(1);
|
||||
(++pCurVal)->SetRef(&rVal);
|
||||
}
|
||||
|
||||
void PushNullVals(int iCnt)
|
||||
{
|
||||
CheckOverflow(iCnt);
|
||||
|
|
|
@ -419,54 +419,54 @@ bool C4AulParseState::AdvanceSpaces()
|
|||
|
||||
C4ScriptOpDef C4ScriptOpMap[] =
|
||||
{
|
||||
// priority postfix
|
||||
// | identifier | changer
|
||||
// | | Bytecode | | no second id
|
||||
// | | | | | | RetType ParType1 ParType2
|
||||
// priority postfix
|
||||
// | identifier | changer
|
||||
// | | Bytecode Result | | no second id
|
||||
// | | | Modifier | | | RetType ParType1 ParType2
|
||||
// prefix
|
||||
{ 15, "++", AB_Inc, 0, 1, 0, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 15, "--", AB_Dec, 0, 1, 0, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 15, "~", AB_BitNot, 0, 0, 0, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 15, "!", AB_Not, 0, 0, 0, C4V_Bool, C4V_Bool, C4V_Any},
|
||||
{ 15, "+", AB_ERR, 0, 0, 0, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 15, "-", AB_Neg, 0, 0, 0, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 15, "++", AB_Inc, AB_ERR, 0, 1, 0, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 15, "--", AB_Dec, AB_ERR, 0, 1, 0, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 15, "~", AB_BitNot, AB_ERR, 0, 0, 0, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 15, "!", AB_Not, AB_ERR, 0, 0, 0, C4V_Bool, C4V_Bool, C4V_Any},
|
||||
{ 15, "+", AB_ERR, AB_ERR, 0, 0, 0, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 15, "-", AB_Neg, AB_ERR, 0, 0, 0, C4V_Int, C4V_Int, C4V_Any},
|
||||
|
||||
// postfix (whithout second statement)
|
||||
{ 16, "++", AB_Inc, 1, 1, 1, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 16, "--", AB_Dec, 1, 1, 1, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 16, "++", AB_Inc, AB_Dec, 1, 1, 1, C4V_Int, C4V_Int, C4V_Any},
|
||||
{ 16, "--", AB_Dec, AB_Inc, 1, 1, 1, C4V_Int, C4V_Int, C4V_Any},
|
||||
|
||||
// postfix
|
||||
{ 14, "**", AB_Pow, AB_ERR, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 13, "/", AB_Div, AB_ERR, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 13, "*", AB_Mul, AB_ERR, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 13, "%", AB_Mod, AB_ERR, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 12, "-", AB_Sub, AB_ERR, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 12, "+", AB_Sum, AB_ERR, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 11, "<<", AB_LeftShift, AB_ERR, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 11, ">>", AB_RightShift, AB_ERR, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 10, "<", AB_LessThan, AB_ERR, 1, 0, 0, C4V_Bool, C4V_Int, C4V_Int},
|
||||
{ 10, "<=", AB_LessThanEqual, AB_ERR, 1, 0, 0, C4V_Bool, C4V_Int, C4V_Int},
|
||||
{ 10, ">", AB_GreaterThan, AB_ERR, 1, 0, 0, C4V_Bool, C4V_Int, C4V_Int},
|
||||
{ 10, ">=", AB_GreaterThanEqual,AB_ERR, 1, 0, 0, C4V_Bool, C4V_Int, C4V_Int},
|
||||
{ 9, "==", AB_Equal, AB_ERR, 1, 0, 0, C4V_Bool, C4V_Any, C4V_Any},
|
||||
{ 9, "!=", AB_NotEqual, AB_ERR, 1, 0, 0, C4V_Bool, C4V_Any, C4V_Any},
|
||||
{ 8, "&", AB_BitAnd, AB_ERR, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 6, "^", AB_BitXOr, AB_ERR, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 6, "|", AB_BitOr, AB_ERR, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 5, "&&", AB_JUMPAND, AB_ERR, 1, 0, 0, C4V_Bool, C4V_Bool, C4V_Bool},
|
||||
{ 4, "||", AB_JUMPOR, AB_ERR, 1, 0, 0, C4V_Bool, C4V_Bool, C4V_Bool},
|
||||
|
||||
// postfix
|
||||
{ 14, "**", AB_Pow, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 13, "/", AB_Div, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 13, "*", AB_Mul, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 13, "%", AB_Mod, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 12, "-", AB_Sub, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 12, "+", AB_Sum, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 11, "<<", AB_LeftShift, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 11, ">>", AB_RightShift, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 10, "<", AB_LessThan, 1, 0, 0, C4V_Bool, C4V_Int, C4V_Int},
|
||||
{ 10, "<=", AB_LessThanEqual, 1, 0, 0, C4V_Bool, C4V_Int, C4V_Int},
|
||||
{ 10, ">", AB_GreaterThan, 1, 0, 0, C4V_Bool, C4V_Int, C4V_Int},
|
||||
{ 10, ">=", AB_GreaterThanEqual,1, 0, 0, C4V_Bool, C4V_Int, C4V_Int},
|
||||
{ 9, "==", AB_Equal, 1, 0, 0, C4V_Bool, C4V_Any, C4V_Any},
|
||||
{ 9, "!=", AB_NotEqual, 1, 0, 0, C4V_Bool, C4V_Any, C4V_Any},
|
||||
{ 8, "&", AB_BitAnd, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 6, "^", AB_BitXOr, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 6, "|", AB_BitOr, 1, 0, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 5, "&&", AB_JUMPAND, 1, 0, 0, C4V_Bool, C4V_Bool, C4V_Bool},
|
||||
{ 4, "||", AB_JUMPOR, 1, 0, 0, C4V_Bool, C4V_Bool, C4V_Bool},
|
||||
|
||||
// changers
|
||||
{ 2, "*=", AB_Mul, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "/=", AB_Div, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "%=", AB_Mod, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "+=", AB_Sum, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "-=", AB_Sub, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "&=", AB_BitAnd, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "|=", AB_BitOr, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "^=", AB_BitXOr, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
|
||||
{ 0, NULL, AB_ERR, 0, 0, 0, C4V_Any, C4V_Any, C4V_Any}
|
||||
{ 2, "*=", AB_Mul, AB_ERR, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "/=", AB_Div, AB_ERR, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "%=", AB_Mod, AB_ERR, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "+=", AB_Sum, AB_ERR, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "-=", AB_Sub, AB_ERR, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "&=", AB_BitAnd, AB_ERR, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "|=", AB_BitOr, AB_ERR, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
{ 2, "^=", AB_BitXOr, AB_ERR, 1, 1, 0, C4V_Int, C4V_Int, C4V_Int},
|
||||
|
||||
{ 0, NULL, AB_ERR, AB_ERR, 0, 0, 0, C4V_Any, C4V_Any, C4V_Any}
|
||||
};
|
||||
|
||||
int C4AulParseState::GetOperator(const char* pScript)
|
||||
|
@ -1128,6 +1128,22 @@ void C4AulParseState::AddBCC(C4AulBCCType eType, intptr_t X)
|
|||
return;
|
||||
}
|
||||
|
||||
// Prune unneeded Incs / Decs
|
||||
if(eType == AB_STACK && X < 0 && (pCPos1->bccType == AB_Inc || pCPos1->bccType == AB_Dec))
|
||||
if(C4ScriptOpMap[pCPos1->Par.i].ResultModifier != pCPos1->bccType)
|
||||
{
|
||||
pCPos1->bccType = eType;
|
||||
pCPos1->Par.i = X;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it was a result modifier, we can safely remove it knowing that it was neither
|
||||
// the first chunk nor a jump target. We can therefore apply additional optimizations.
|
||||
a->RemoveLastBCC();
|
||||
pCPos1--;
|
||||
}
|
||||
|
||||
// Join VARN_SET + STACK -1 to IVARN (equivalent)
|
||||
if(eType == AB_STACK && X == -1 && pCPos1->bccType == AB_VARN_SET)
|
||||
{
|
||||
|
@ -1544,13 +1560,7 @@ void C4AulParseState::Parse_FuncHead()
|
|||
if (SEqual(Idtf, C4AUL_Func))
|
||||
{
|
||||
Shift(Discard, false);
|
||||
bool bReturnRef = false;
|
||||
// get next token, must be func name or "&"
|
||||
if (TokenType == ATT_AMP)
|
||||
{
|
||||
bReturnRef = true;
|
||||
Shift(Discard, false);
|
||||
}
|
||||
// get next token, must be func name
|
||||
if (TokenType != ATT_IDTF)
|
||||
UnexpectedToken("function name");
|
||||
// check: symbol already in use?
|
||||
|
@ -1587,7 +1597,6 @@ void C4AulParseState::Parse_FuncHead()
|
|||
// set up func (in the case we got an error)
|
||||
Fn->Script = SPos; // temporary
|
||||
Fn->Access = Acc; Fn->pOrgScript = a;
|
||||
Fn->bReturnRef = bReturnRef;
|
||||
Shift(Discard,false);
|
||||
// expect an opening bracket now
|
||||
if (TokenType != ATT_BOPEN)
|
||||
|
@ -1623,7 +1632,6 @@ void C4AulParseState::Parse_FuncHead()
|
|||
else if (SEqual(Idtf, C4AUL_TypeString)) { Fn->ParType[cpar] = C4V_String; Shift(Discard,false); }
|
||||
else if (SEqual(Idtf, C4AUL_TypeArray)) { Fn->ParType[cpar] = C4V_Array; Shift(Discard,false); }
|
||||
// ampersand?
|
||||
if (TokenType == ATT_AMP) { Fn->ParType[cpar] = C4V_Ref; Shift(Discard,false); }
|
||||
if (TokenType != ATT_IDTF)
|
||||
{
|
||||
UnexpectedToken("parameter name");
|
||||
|
@ -2654,9 +2662,13 @@ void C4AulParseState::Parse_Expression2(int iParentPrio)
|
|||
Parse_Expression(C4ScriptOpMap[OpID].Priority);
|
||||
// write byte code
|
||||
AddBCC(C4ScriptOpMap[OpID].Code, OpID);
|
||||
// write setter
|
||||
// write setter and mofidier
|
||||
if (C4ScriptOpMap[OpID].Changer)
|
||||
{
|
||||
AddBCC(Setter.bccType, Setter.Par.i);
|
||||
if(C4ScriptOpMap[OpID].ResultModifier != AB_ERR)
|
||||
AddBCC(C4ScriptOpMap[OpID].ResultModifier, OpID);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -42,19 +42,6 @@ void C4PropList::DelRef(const C4Value * pRef, C4Value * pNextRef)
|
|||
pVal->NextRef = pNextRef;
|
||||
}
|
||||
if (FirstRef) return;
|
||||
if (iElementReferences) return;
|
||||
// These classes have their own memory management
|
||||
if (dynamic_cast<C4Object *>(this)) return;
|
||||
if (dynamic_cast<C4Def *>(this)) return;
|
||||
delete this;
|
||||
}
|
||||
|
||||
void C4PropList::DecElementRef()
|
||||
{
|
||||
assert(iElementReferences > 0);
|
||||
--iElementReferences;
|
||||
if (iElementReferences) return;
|
||||
if (FirstRef) return;
|
||||
// These classes have their own memory management
|
||||
if (dynamic_cast<C4Object *>(this)) return;
|
||||
if (dynamic_cast<C4Def *>(this)) return;
|
||||
|
@ -110,7 +97,7 @@ C4PropListNumbered::~C4PropListNumbered()
|
|||
|
||||
C4PropList::C4PropList(C4PropList * prototype):
|
||||
Status(1),
|
||||
FirstRef(NULL), iElementReferences(0), prototype(prototype)
|
||||
FirstRef(NULL), prototype(prototype)
|
||||
{
|
||||
if (prototype)
|
||||
SetProperty(Strings.P[P_Prototype], C4VPropList(prototype));
|
||||
|
@ -125,8 +112,8 @@ void C4PropList::DenumeratePointers()
|
|||
p = Properties.Next(p);
|
||||
}
|
||||
C4Value v;
|
||||
GetPropertyVal(Strings.P[P_Prototype], v);
|
||||
prototype = v.getPropList();
|
||||
if(GetPropertyVal(Strings.P[P_Prototype], &v))
|
||||
prototype = v.getPropList();
|
||||
}
|
||||
|
||||
C4PropList::~C4PropList()
|
||||
|
@ -139,7 +126,6 @@ C4PropList::~C4PropList()
|
|||
FirstRef = FirstRef->NextRef;
|
||||
ref->NextRef = NULL;
|
||||
}
|
||||
assert(!iElementReferences);
|
||||
assert(!::Objects.ObjectNumber(this));
|
||||
}
|
||||
|
||||
|
@ -288,67 +274,17 @@ bool C4PropList::HasProperty(C4String * k) const
|
|||
return false;
|
||||
}
|
||||
|
||||
void C4PropList::GetPropertyRef(C4String * k, C4Value & to)
|
||||
{
|
||||
// The prototype is special
|
||||
if (k == Strings.P[P_Prototype])
|
||||
{
|
||||
to.SetPropList(prototype);
|
||||
return;
|
||||
}
|
||||
to.SetPropListRef(this, k);
|
||||
}
|
||||
|
||||
C4Value * C4PropList::GetRefToProperty(C4String * k)
|
||||
{
|
||||
// The prototype is special
|
||||
if (k == Strings.P[P_Prototype])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (Properties.Has(k))
|
||||
{
|
||||
return &Properties.Get(k).Value;
|
||||
}
|
||||
if (prototype)
|
||||
{
|
||||
C4Property p(k, *(prototype->GetRefToProperty(k)));
|
||||
return &(Properties.Add(p)->Value);
|
||||
}
|
||||
C4Property p(k, C4VNull);
|
||||
return &(Properties.Add(p)->Value);
|
||||
}
|
||||
|
||||
const C4Value * C4PropList::GetRefToPropertyConst(C4String * k) const
|
||||
{
|
||||
// The prototype is special
|
||||
if (k == Strings.P[P_Prototype])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (Properties.Has(k))
|
||||
{
|
||||
return &Properties.Get(k).Value;
|
||||
}
|
||||
if (prototype)
|
||||
{
|
||||
return prototype->GetRefToPropertyConst(k);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool C4PropList::GetPropertyVal(C4String * k, C4Value & to)
|
||||
bool C4PropList::GetPropertyVal(C4String * k, C4Value *pResult)
|
||||
{
|
||||
if (Properties.Has(k))
|
||||
{
|
||||
to.Set(Properties.Get(k).Value);
|
||||
*pResult = Properties.Get(k).Value;
|
||||
return true;
|
||||
}
|
||||
if (prototype)
|
||||
{
|
||||
return prototype->GetPropertyVal(k, to);
|
||||
}
|
||||
return false;
|
||||
else if(prototype)
|
||||
return prototype->GetPropertyVal(k, pResult);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
C4String * C4PropList::GetPropertyStr(C4PropertyName n)
|
||||
|
@ -403,8 +339,6 @@ void C4PropList::ResetProperty(C4String * k)
|
|||
Properties.Remove(k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<> template<>
|
||||
unsigned int C4Set<C4PropListNumbered *>::Hash<int>(int e)
|
||||
{
|
||||
|
|
|
@ -49,8 +49,6 @@ public:
|
|||
int32_t Status;
|
||||
void AddRef(C4Value *pRef);
|
||||
void DelRef(const C4Value *pRef, C4Value * pNextRef);
|
||||
void IncElementRef() { ++iElementReferences; }
|
||||
void DecElementRef();
|
||||
void AssignRemoval();
|
||||
const char *GetName();
|
||||
virtual void SetName (const char *NewName = 0);
|
||||
|
@ -60,12 +58,9 @@ public:
|
|||
virtual C4PropListNumbered * GetPropListNumbered();
|
||||
C4PropList * GetPrototype() { return prototype; }
|
||||
|
||||
void GetPropertyRef(C4String * k, C4Value & to);
|
||||
bool HasProperty(C4String * k) const;
|
||||
C4Value * GetRefToProperty(C4String * k);
|
||||
const C4Value * GetRefToPropertyConst(C4String * k) const;
|
||||
bool GetPropertyVal(C4String * k, C4Value & to);
|
||||
bool GetPropertyVal(C4PropertyName k, C4Value & to) { return GetPropertyVal(Strings.P[k], to); }
|
||||
bool GetPropertyVal(C4String *k, C4Value *pResult);
|
||||
bool GetPropertyVal(C4PropertyName k, C4Value *pResult) { return GetPropertyVal(Strings.P[k], pResult); }
|
||||
C4String * GetPropertyStr(C4PropertyName k);
|
||||
int32_t GetPropertyInt(C4PropertyName k);
|
||||
void SetProperty(C4String * k, const C4Value & to);
|
||||
|
@ -85,7 +80,6 @@ protected:
|
|||
private:
|
||||
C4Value *FirstRef; // No-Save
|
||||
bool constant; // if true, this proplist is neither saved nor changeable FIXME: implement
|
||||
unsigned int iElementReferences;
|
||||
|
||||
C4PropList * prototype;
|
||||
friend void CompileNewFunc<C4PropList>(C4PropList *&pStruct, StdCompiler *pComp);
|
||||
|
|
|
@ -33,32 +33,12 @@ const C4NullValue C4VNull = C4NullValue();
|
|||
const C4Value C4VTrue = C4VBool(true);
|
||||
const C4Value C4VFalse = C4VBool(false);
|
||||
|
||||
C4Value::~C4Value()
|
||||
{
|
||||
// resolve all C4Values referencing this Value
|
||||
while (FirstRef)
|
||||
FirstRef->Set(*this);
|
||||
|
||||
// delete contents
|
||||
DelDataRef(Data, Type, GetNextRef(), GetBaseArray(), Type == C4V_PropListRef ? PropListRefKey : NULL);
|
||||
}
|
||||
|
||||
C4Value &C4Value::operator = (const C4Value &nValue)
|
||||
{
|
||||
// set referenced value
|
||||
GetRefVal().Set(nValue.GetRefVal());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void C4Value::AddDataRef()
|
||||
{
|
||||
assert(Type != C4V_Any || !Data);
|
||||
switch (Type)
|
||||
{
|
||||
case C4V_Ref: Data.Ref->AddRef(this); break;
|
||||
case C4V_PropListRef: Data.PropList->IncElementRef(); PropListRefKey->IncRef(); break;
|
||||
case C4V_Array: Data.Array = Data.Array->IncRef(); break;
|
||||
case C4V_Array: Data.Array->IncRef(); break;
|
||||
case C4V_String: Data.Str->IncRef(); break;
|
||||
case C4V_C4Object:
|
||||
case C4V_PropList:
|
||||
|
@ -75,17 +55,11 @@ void C4Value::AddDataRef()
|
|||
}
|
||||
}
|
||||
|
||||
void C4Value::DelDataRef(C4V_Data Data, C4V_Type Type, C4Value * pNextRef, C4ValueArray * pBaseArray, C4String * Key)
|
||||
void C4Value::DelDataRef(C4V_Data Data, C4V_Type Type, C4Value *pNextRef)
|
||||
{
|
||||
// clean up
|
||||
switch (Type)
|
||||
{
|
||||
case C4V_Ref:
|
||||
// Save because AddDataRef does not set this flag
|
||||
HasBaseArray = false;
|
||||
Data.Ref->DelRef(this, pNextRef, pBaseArray);
|
||||
break;
|
||||
case C4V_PropListRef: Data.PropList->DecElementRef(); Key->DecRef(); break;
|
||||
case C4V_C4Object: case C4V_PropList: Data.PropList->DelRef(this, pNextRef); break;
|
||||
case C4V_Array: Data.Array->DecRef(); break;
|
||||
case C4V_String: Data.Str->DecRef(); break;
|
||||
|
@ -93,33 +67,23 @@ void C4Value::DelDataRef(C4V_Data Data, C4V_Type Type, C4Value * pNextRef, C4Val
|
|||
}
|
||||
}
|
||||
|
||||
void C4Value::Set(C4V_Data nData, C4V_Type nType, C4String * nPropListRefKey)
|
||||
void C4Value::Set(C4V_Data nData, C4V_Type nType)
|
||||
{
|
||||
assert(nType != C4V_Any || !nData);
|
||||
assert(nType != C4V_PropListRef || nPropListRefKey);
|
||||
// Do not add this to the same linked list twice.
|
||||
if (Data == nData && Type == nType) return;
|
||||
|
||||
C4V_Data oData = Data;
|
||||
C4V_Type oType = Type;
|
||||
C4Value * oNextRef = NextRef;
|
||||
C4ValueArray * oBaseArray = BaseArray;
|
||||
C4String * oKey = PropListRefKey;
|
||||
bool oHasBaseArray = HasBaseArray;
|
||||
|
||||
// change
|
||||
PropListRefKey = nPropListRefKey; // This will be overwritten if the union is needed for something else
|
||||
Data = nData;
|
||||
Type = nData || IsNullableType(nType) ? nType : C4V_Any;
|
||||
|
||||
// hold
|
||||
// hold new data & clean up old
|
||||
AddDataRef();
|
||||
|
||||
// clean up
|
||||
DelDataRef(oData, oType,
|
||||
oHasBaseArray ? NULL : oNextRef,
|
||||
oHasBaseArray ? oBaseArray : NULL,
|
||||
oType == C4V_PropListRef ? oKey : NULL);
|
||||
DelDataRef(oData, oType, oNextRef);
|
||||
}
|
||||
|
||||
void C4Value::Set0()
|
||||
|
@ -128,152 +92,11 @@ void C4Value::Set0()
|
|||
C4V_Type oType = Type;
|
||||
|
||||
// change
|
||||
Data = 0;
|
||||
Data.Obj = 0;
|
||||
Type = C4V_Any;
|
||||
|
||||
// clean up (save even if Data was 0 before)
|
||||
DelDataRef(oData, oType,
|
||||
HasBaseArray ? NULL : NextRef,
|
||||
HasBaseArray ? BaseArray : NULL,
|
||||
oType == C4V_PropListRef ? PropListRefKey : NULL);
|
||||
}
|
||||
|
||||
void C4Value::SetPropListRef(C4PropList * PropList, C4String * Key)
|
||||
{
|
||||
assert(PropList);
|
||||
assert(Key);
|
||||
C4V_Data d; d.PropList = PropList;
|
||||
Set(d, C4V_PropListRef, Key);
|
||||
}
|
||||
|
||||
void C4Value::Move(C4Value *nValue)
|
||||
{
|
||||
nValue->Set(*this);
|
||||
|
||||
// change references
|
||||
for (C4Value *pVal = FirstRef; pVal; pVal = pVal->GetNextRef())
|
||||
pVal->Data.Ref = nValue;
|
||||
|
||||
// copy ref list
|
||||
assert(!nValue->FirstRef);
|
||||
nValue->FirstRef = FirstRef;
|
||||
|
||||
// delete usself
|
||||
FirstRef = NULL;
|
||||
Set0();
|
||||
}
|
||||
|
||||
void C4Value::GetArrayElement(int32_t Index, C4Value & target, C4AulContext *pctx, bool noref)
|
||||
{
|
||||
if (noref)
|
||||
{
|
||||
const C4Value & Ref = GetRefValConst();
|
||||
// No array (and no nullpointer because Data==0 => Type==any)
|
||||
if (Ref.Type != C4V_Array)
|
||||
throw new C4AulExecError(pctx->Obj, "Array access: array expected");
|
||||
// Get the item, but do not resize the array - it might be used more than once
|
||||
if (Index < Ref.Data.Array->GetSize())
|
||||
target.Set(Ref.Data.Array->GetItem(Index));
|
||||
else
|
||||
target.Set0();
|
||||
}
|
||||
else
|
||||
{
|
||||
C4Value & Ref = GetRefVal();
|
||||
// No array (and no nullpointer because Data==0 => Type==any)
|
||||
if (Ref.Type != C4V_Array)
|
||||
throw new C4AulExecError(pctx->Obj, "Array access: array expected");
|
||||
// Is target the first ref?
|
||||
if (Index >= Ref.Data.Array->GetSize() || !Ref.Data.Array->GetItem(Index).FirstRef)
|
||||
{
|
||||
Ref.Data.Array = Ref.Data.Array->IncElementRef();
|
||||
target.SetRef(&Ref.Data.Array->GetItem(Index));
|
||||
if (target.Type == C4V_Ref)
|
||||
{
|
||||
assert(!target.NextRef);
|
||||
target.BaseArray = Ref.Data.Array;
|
||||
target.HasBaseArray = true;
|
||||
}
|
||||
// else target apparently owned the last reference to the array
|
||||
}
|
||||
else
|
||||
{
|
||||
target.SetRef(&Ref.Data.Array->GetItem(Index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C4Value::SetArrayLength(int32_t size, C4AulContext *cthr)
|
||||
{
|
||||
C4Value & Ref = GetRefVal();
|
||||
// No array
|
||||
if (Ref.Type != C4V_Array)
|
||||
throw new C4AulExecError(cthr->Obj, "SetLength: array expected");
|
||||
Ref.Data.Array = Ref.Data.Array->SetLength(size);
|
||||
}
|
||||
|
||||
const C4Value & C4Value::GetRefVal() const
|
||||
{
|
||||
const C4Value* pVal = this;
|
||||
while (1)
|
||||
{
|
||||
if (pVal->Type == C4V_Ref)
|
||||
pVal = pVal->Data.Ref;
|
||||
else if (pVal->Type == C4V_PropListRef)
|
||||
{
|
||||
pVal = pVal->Data.PropList->GetRefToPropertyConst(pVal->PropListRefKey);
|
||||
if (!pVal) return C4VNull;
|
||||
}
|
||||
else
|
||||
return *pVal;
|
||||
}
|
||||
}
|
||||
|
||||
C4Value &C4Value::GetRefVal()
|
||||
{
|
||||
C4Value* pVal = this;
|
||||
while (1)
|
||||
{
|
||||
if (pVal->Type == C4V_Ref)
|
||||
pVal = pVal->Data.Ref;
|
||||
else if (pVal->Type == C4V_PropListRef)
|
||||
pVal = pVal->Data.PropList->GetRefToProperty(pVal->PropListRefKey);
|
||||
else
|
||||
return *pVal;
|
||||
}
|
||||
}
|
||||
|
||||
void C4Value::AddRef(C4Value *pRef)
|
||||
{
|
||||
pRef->NextRef = FirstRef;
|
||||
FirstRef = pRef;
|
||||
}
|
||||
|
||||
void C4Value::DelRef(const C4Value *pRef, C4Value * pNextRef, C4ValueArray * pBaseArray)
|
||||
{
|
||||
if (pRef == FirstRef)
|
||||
FirstRef = pNextRef;
|
||||
else
|
||||
{
|
||||
C4Value* pVal = FirstRef;
|
||||
while (pVal->NextRef != pRef)
|
||||
{
|
||||
// assert that pRef really was in the list
|
||||
assert(pVal->NextRef && !pVal->HasBaseArray);
|
||||
pVal = pVal->NextRef;
|
||||
}
|
||||
pVal->NextRef = pNextRef;
|
||||
if (pBaseArray)
|
||||
{
|
||||
pVal->HasBaseArray = true;
|
||||
pVal->BaseArray = pBaseArray;
|
||||
}
|
||||
}
|
||||
// Was pRef the last ref to an array element?
|
||||
if (pBaseArray && !FirstRef)
|
||||
{
|
||||
pBaseArray->DecElementRef();
|
||||
}
|
||||
DelDataRef(oData, oType, NextRef);
|
||||
}
|
||||
|
||||
const char* GetC4VName(const C4V_Type Type)
|
||||
|
@ -294,8 +117,6 @@ const char* GetC4VName(const C4V_Type Type)
|
|||
return "array";
|
||||
case C4V_PropList:
|
||||
return "proplist";
|
||||
case C4V_Ref:
|
||||
return "&";
|
||||
default:
|
||||
return "!Fehler!";
|
||||
}
|
||||
|
@ -324,7 +145,6 @@ char GetC4VID(const C4V_Type Type)
|
|||
case C4V_PropList:
|
||||
return 'p';
|
||||
default:
|
||||
assert(Type != C4V_Ref && Type != C4V_PropListRef);
|
||||
assert(false);
|
||||
}
|
||||
return ' ';
|
||||
|
@ -344,8 +164,6 @@ C4V_Type GetC4VFromID(const char C4VID)
|
|||
return C4V_C4Object;
|
||||
case 's':
|
||||
return C4V_String;
|
||||
case 'V':
|
||||
return C4V_Ref;
|
||||
case 'O':
|
||||
return C4V_C4ObjectEnum;
|
||||
case 'D':
|
||||
|
@ -371,22 +189,6 @@ static bool FnCnvError(C4Value *Val, C4V_Type toType)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool FnCnvDeref(C4Value *Val, C4V_Type toType)
|
||||
{
|
||||
// resolve reference of Value
|
||||
Val->Deref();
|
||||
// retry to check convert
|
||||
return Val->ConvertTo(toType);
|
||||
}
|
||||
|
||||
bool C4Value::FnCnvPLR(C4Value *Val, C4V_Type toType)
|
||||
{
|
||||
// resolve reference of Value
|
||||
Val->SetRef(Val->Data.PropList->GetRefToProperty(Val->PropListRefKey));
|
||||
// retry to check convert
|
||||
return Val->ConvertTo(toType);
|
||||
}
|
||||
|
||||
static bool FnOk0(C4Value *Val, C4V_Type toType)
|
||||
{
|
||||
// 0 can be treated as nil, but every other integer can't
|
||||
|
@ -404,8 +206,6 @@ bool C4Value::FnCnvObject(C4Value *Val, C4V_Type toType)
|
|||
#define CnvOK 0, false // allow conversion by same value
|
||||
#define CnvOK0 FnOk0, true
|
||||
#define CnvError FnCnvError, true
|
||||
#define CnvDeref FnCnvDeref, false
|
||||
#define CnvPLR FnCnvPLR, false
|
||||
#define CnvObject FnCnvObject, false
|
||||
|
||||
C4VCnvFn C4Value::C4ScriptCnvMap[C4V_Last+1][C4V_Last+1] =
|
||||
|
@ -418,8 +218,6 @@ C4VCnvFn C4Value::C4ScriptCnvMap[C4V_Last+1][C4V_Last+1] =
|
|||
{ CnvOK }, // C4Object
|
||||
{ CnvOK }, // String
|
||||
{ CnvOK }, // Array
|
||||
{ CnvError }, // Ref
|
||||
{ CnvError }, // PropListRef
|
||||
},
|
||||
{ // C4V_Int
|
||||
{ CnvOK }, // any
|
||||
|
@ -429,8 +227,6 @@ C4VCnvFn C4Value::C4ScriptCnvMap[C4V_Last+1][C4V_Last+1] =
|
|||
{ CnvOK0 }, // C4Object only if 0
|
||||
{ CnvOK0 }, // String only if 0
|
||||
{ CnvOK0 }, // Array only if 0
|
||||
{ CnvError }, // Ref
|
||||
{ CnvError }, // PropListRef
|
||||
},
|
||||
{ // C4V_Bool
|
||||
{ CnvOK }, // any
|
||||
|
@ -440,8 +236,6 @@ C4VCnvFn C4Value::C4ScriptCnvMap[C4V_Last+1][C4V_Last+1] =
|
|||
{ CnvError }, // C4Object NEVER!
|
||||
{ CnvError }, // String NEVER!
|
||||
{ CnvError }, // Array NEVER!
|
||||
{ CnvError }, // Ref
|
||||
{ CnvError }, // PropListRef
|
||||
},
|
||||
{ // C4V_PropList
|
||||
{ CnvOK }, // any
|
||||
|
@ -451,8 +245,6 @@ C4VCnvFn C4Value::C4ScriptCnvMap[C4V_Last+1][C4V_Last+1] =
|
|||
{ CnvObject }, // C4Object
|
||||
{ CnvError }, // String NEVER!
|
||||
{ CnvError }, // Array NEVER!
|
||||
{ CnvError }, // Ref NEVER!
|
||||
{ CnvError }, // PropListRef
|
||||
},
|
||||
{ // C4V_Object
|
||||
{ CnvOK }, // any
|
||||
|
@ -462,8 +254,6 @@ C4VCnvFn C4Value::C4ScriptCnvMap[C4V_Last+1][C4V_Last+1] =
|
|||
{ CnvOK }, // C4Object same
|
||||
{ CnvError }, // String NEVER!
|
||||
{ CnvError }, // Array NEVER!
|
||||
{ CnvError }, // Ref NEVER!
|
||||
{ CnvError }, // PropListRef
|
||||
},
|
||||
{ // C4V_String
|
||||
{ CnvOK }, // any
|
||||
|
@ -473,8 +263,6 @@ C4VCnvFn C4Value::C4ScriptCnvMap[C4V_Last+1][C4V_Last+1] =
|
|||
{ CnvError }, // C4Object NEVER!
|
||||
{ CnvOK }, // String same
|
||||
{ CnvError }, // Array NEVER!
|
||||
{ CnvError }, // Ref NEVER!
|
||||
{ CnvError }, // PropListRef
|
||||
},
|
||||
{ // C4V_Array
|
||||
{ CnvOK }, // any
|
||||
|
@ -484,45 +272,17 @@ C4VCnvFn C4Value::C4ScriptCnvMap[C4V_Last+1][C4V_Last+1] =
|
|||
{ CnvError }, // C4Object NEVER!
|
||||
{ CnvError }, // String NEVER!
|
||||
{ CnvOK }, // Array same
|
||||
{ CnvError }, // Ref NEVER!
|
||||
{ CnvError }, // PropListRef
|
||||
},
|
||||
{ // C4V_Ref - resolve reference and retry type check
|
||||
{ CnvDeref }, // any
|
||||
{ CnvDeref }, // int
|
||||
{ CnvDeref }, // Bool
|
||||
{ CnvDeref }, // PropList
|
||||
{ CnvDeref }, // C4Object
|
||||
{ CnvDeref }, // String
|
||||
{ CnvDeref }, // Array
|
||||
{ CnvOK }, // Ref same
|
||||
{ CnvError }, // PropListRef
|
||||
},
|
||||
{ // C4V_Ref - resolve reference and retry type check
|
||||
{ CnvPLR }, // any
|
||||
{ CnvPLR }, // int
|
||||
{ CnvPLR }, // Bool
|
||||
{ CnvPLR }, // PropList
|
||||
{ CnvPLR }, // C4Object
|
||||
{ CnvPLR }, // String
|
||||
{ CnvPLR }, // Array
|
||||
{ CnvPLR }, // Ref
|
||||
{ CnvOK }, // PropListRef same
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
#undef CnvOK
|
||||
#undef CnvOK0
|
||||
#undef CnvError
|
||||
#undef CnvDeref
|
||||
#undef CnvPLR
|
||||
#undef CnvObject
|
||||
|
||||
// Humanreadable debug output
|
||||
StdStrBuf C4Value::GetDataString()
|
||||
{
|
||||
if (Type == C4V_Ref)
|
||||
return GetRefVal().GetDataString() + "*";
|
||||
|
||||
// ouput by type info
|
||||
switch (GetType())
|
||||
|
@ -736,7 +496,7 @@ void C4Value::CompileFunc(StdCompiler *pComp)
|
|||
case C4V_Array:
|
||||
pComp->Separator(StdCompiler::SEP_START2);
|
||||
pComp->Value(mkPtrAdapt(Data.Array, false));
|
||||
if (fCompiler) Data.Array = Data.Array->IncRef();
|
||||
if (fCompiler) Data.Array->IncRef();
|
||||
pComp->Separator(StdCompiler::SEP_END2);
|
||||
break;
|
||||
|
||||
|
@ -746,7 +506,6 @@ void C4Value::CompileFunc(StdCompiler *pComp)
|
|||
break;
|
||||
|
||||
// shouldn't happen
|
||||
case C4V_Ref:
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
|
@ -785,7 +544,6 @@ bool C4Value::operator == (const C4Value& Value2) const
|
|||
case C4V_Array:
|
||||
return Type == Value2.Type && *(Data.Array) == *(Value2.Data.Array);
|
||||
default:
|
||||
// C4AulExec should have dereferenced both values, no need to implement comparison here
|
||||
return Data == Value2.Data;
|
||||
}
|
||||
return GetData() == Value2.GetData();
|
||||
|
|
|
@ -39,14 +39,12 @@ enum C4V_Type
|
|||
C4V_C4Object=4,
|
||||
C4V_String=5,
|
||||
C4V_Array=6,
|
||||
C4V_Ref=7, // reference to a value (variable)
|
||||
C4V_PropListRef=8, // reference to an entry in a proplist
|
||||
|
||||
C4V_C4ObjectEnum=9, // enumerated object
|
||||
C4V_C4DefEnum=10 // enumerated object
|
||||
};
|
||||
|
||||
#define C4V_Last (int) C4V_PropListRef
|
||||
#define C4V_Last (int) C4V_Array
|
||||
|
||||
const char* GetC4VName(const C4V_Type Type);
|
||||
char GetC4VID(const C4V_Type Type);
|
||||
|
@ -58,13 +56,12 @@ union C4V_Data
|
|||
C4Object * Obj;
|
||||
C4PropList * PropList;
|
||||
C4String * Str;
|
||||
C4Value * Ref;
|
||||
C4ValueArray * Array;
|
||||
// cheat a little - assume that all members have the same length
|
||||
operator void * () { return Ref; }
|
||||
operator const void * () const { return Ref; }
|
||||
bool operator== (C4V_Data b) { return Ref == b.Ref; }
|
||||
C4V_Data& operator= (C4Value * p) { Ref = p; return *this; }
|
||||
operator void * () { return Obj; }
|
||||
operator const void * () const { return Obj; }
|
||||
bool operator== (C4V_Data b) { return Obj == b.Obj; }
|
||||
C4V_Data &operator = (void *p) { Obj = reinterpret_cast<C4Object *>(p); return *this; }
|
||||
};
|
||||
|
||||
// converter function, used in converter table
|
||||
|
@ -80,29 +77,27 @@ class C4Value
|
|||
{
|
||||
public:
|
||||
|
||||
C4Value() : NextRef(NULL), FirstRef(NULL), Type(C4V_Any), HasBaseArray(false) { Data.Ref = 0; }
|
||||
C4Value() : NextRef(NULL), Type(C4V_Any) { Data.Obj = 0; }
|
||||
|
||||
C4Value(const C4Value &nValue) : Data(nValue.Data), PropListRefKey(nValue.PropListRefKey), FirstRef(NULL), Type(nValue.Type), HasBaseArray(false)
|
||||
C4Value(const C4Value &nValue) : Data(nValue.Data), NextRef(NULL), Type(nValue.Type)
|
||||
{ AddDataRef(); }
|
||||
|
||||
explicit C4Value(bool data): NextRef(NULL), FirstRef(NULL), Type(C4V_Bool), HasBaseArray(false)
|
||||
{ Data.Int = data; AddDataRef(); }
|
||||
explicit C4Value(int32_t data): NextRef(NULL), FirstRef(NULL), Type(C4V_Int), HasBaseArray(false)
|
||||
{ Data.Int = data; AddDataRef(); }
|
||||
explicit C4Value(C4Object *pObj): NextRef(NULL), FirstRef(NULL), Type(pObj ? C4V_C4Object : C4V_Any), HasBaseArray(false)
|
||||
explicit C4Value(bool data): NextRef(NULL), Type(C4V_Bool)
|
||||
{ Data.Int = data; }
|
||||
explicit C4Value(int32_t data): NextRef(NULL), Type(C4V_Int)
|
||||
{ Data.Int = data; }
|
||||
explicit C4Value(C4Object *pObj): NextRef(NULL), Type(pObj ? C4V_C4Object : C4V_Any)
|
||||
{ Data.Obj = pObj; AddDataRef(); }
|
||||
explicit C4Value(C4String *pStr): NextRef(NULL), FirstRef(NULL), Type(pStr ? C4V_String : C4V_Any), HasBaseArray(false)
|
||||
explicit C4Value(C4String *pStr): NextRef(NULL), Type(pStr ? C4V_String : C4V_Any)
|
||||
{ Data.Str = pStr; AddDataRef(); }
|
||||
explicit C4Value(C4ValueArray *pArray): NextRef(NULL), FirstRef(NULL), Type(pArray ? C4V_Array : C4V_Any), HasBaseArray(false)
|
||||
explicit C4Value(C4ValueArray *pArray): NextRef(NULL), Type(pArray ? C4V_Array : C4V_Any)
|
||||
{ Data.Array = pArray; AddDataRef(); }
|
||||
explicit C4Value(C4PropList *p): NextRef(NULL), FirstRef(NULL), Type(p ? C4V_PropList : C4V_Any), HasBaseArray(false)
|
||||
explicit C4Value(C4PropList *p): NextRef(NULL), Type(p ? C4V_PropList : C4V_Any)
|
||||
{ Data.PropList = p; AddDataRef(); }
|
||||
explicit C4Value(C4Value *pVal): NextRef(NULL), FirstRef(NULL), Type(pVal ? C4V_Ref : C4V_Any), HasBaseArray(false)
|
||||
{ Data.Ref = pVal; AddDataRef(); }
|
||||
|
||||
C4Value& operator = (const C4Value& nValue);
|
||||
C4Value& operator = (const C4Value& nValue) { Set(nValue); return *this; }
|
||||
|
||||
~C4Value();
|
||||
~C4Value() { DelDataRef(Data, Type, NextRef); }
|
||||
|
||||
// Checked getters
|
||||
int32_t getInt() { return ConvertTo(C4V_Int) ? Data.Int : 0; }
|
||||
|
@ -112,7 +107,6 @@ public:
|
|||
C4PropList * getPropList() { return ConvertTo(C4V_PropList) ? Data.PropList : NULL; }
|
||||
C4String * getStr() { return ConvertTo(C4V_String) ? Data.Str : NULL; }
|
||||
C4ValueArray * getArray() { return ConvertTo(C4V_Array) ? Data.Array : NULL; }
|
||||
C4Value * getRef() { return ConvertTo(C4V_Ref) ? Data.Ref : NULL; }
|
||||
|
||||
// Unchecked getters
|
||||
int32_t _getInt() const { return Data.Int; }
|
||||
|
@ -121,7 +115,6 @@ public:
|
|||
C4String *_getStr() const { return Data.Str; }
|
||||
C4ValueArray *_getArray() const { return Data.Array; }
|
||||
C4PropList *_getPropList() const { return Data.PropList; }
|
||||
C4Value *_getRef() { return Data.Ref; }
|
||||
|
||||
// Template versions
|
||||
template <typename T> inline T Get() { return C4ValueConv<T>::FromC4V(*this); }
|
||||
|
@ -130,68 +123,37 @@ public:
|
|||
bool operator ! () const { return !GetData(); }
|
||||
inline operator const void* () const { return GetData()?this:0; } // To allow use of C4Value in conditions
|
||||
|
||||
void Set(const C4Value &nValue) { if (this != &nValue) Set(nValue.Data, nValue.Type, nValue.PropListRefKey); }
|
||||
void Set(const C4Value &nValue) { if (this != &nValue) Set(nValue.Data, nValue.Type); }
|
||||
|
||||
void SetInt(int i) { C4V_Data d; d.Int = i; Set(d, C4V_Int); }
|
||||
|
||||
void SetBool(bool b) { C4V_Data d; d.Int = b; Set(d, C4V_Bool); }
|
||||
|
||||
void SetObject(C4Object * Obj) { C4V_Data d; d.Obj = Obj; Set(d, C4V_C4Object); }
|
||||
|
||||
void SetString(C4String * Str) { C4V_Data d; d.Str = Str; Set(d, C4V_String); }
|
||||
|
||||
void SetArray(C4ValueArray * Array) { C4V_Data d; d.Array = Array; Set(d, C4V_Array); }
|
||||
|
||||
void SetPropList(C4PropList * PropList) { C4V_Data d; d.PropList = PropList; Set(d, C4V_PropList); }
|
||||
|
||||
void SetRef(C4Value* nValue) { C4V_Data d; d.Ref = nValue; Set(d, C4V_Ref); }
|
||||
|
||||
void SetPropListRef(C4PropList * PropList, C4String * Key);
|
||||
|
||||
void Set0();
|
||||
|
||||
bool operator == (const C4Value& Value2) const;
|
||||
bool operator != (const C4Value& Value2) const;
|
||||
|
||||
// Change and set Type to int in case it was any before (avoids GuessType())
|
||||
C4Value & operator += (int32_t by) { GetData().Int += by; GetRefVal().Type=C4V_Int; return *this; }
|
||||
C4Value & operator -= (int32_t by) { GetData().Int -= by; GetRefVal().Type=C4V_Int; return *this; }
|
||||
C4Value & operator *= (int32_t by) { GetData().Int *= by; GetRefVal().Type=C4V_Int; return *this; }
|
||||
C4Value & operator /= (int32_t by) { GetData().Int /= by; GetRefVal().Type=C4V_Int; return *this; }
|
||||
C4Value & operator %= (int32_t by) { GetData().Int %= by; GetRefVal().Type=C4V_Int; return *this; }
|
||||
C4Value & operator &= (int32_t by) { GetData().Int &= by; GetRefVal().Type=C4V_Int; return *this; }
|
||||
C4Value & operator ^= (int32_t by) { GetData().Int ^= by; GetRefVal().Type=C4V_Int; return *this; }
|
||||
C4Value & operator |= (int32_t by) { GetData().Int |= by; GetRefVal().Type=C4V_Int; return *this; }
|
||||
C4Value & operator ++ () { GetData().Int ++; GetRefVal().Type=C4V_Int; return *this; }
|
||||
C4Value operator ++ (int) { C4Value alt = GetRefValConst(); GetData().Int ++; GetRefVal().Type=C4V_Int; return alt; }
|
||||
C4Value & operator -- () { GetData().Int --; GetRefVal().Type=C4V_Int; return *this; }
|
||||
C4Value operator -- (int) { C4Value alt = GetRefValConst(); GetData().Int --; GetRefVal().Type=C4V_Int; return alt; }
|
||||
C4Value & operator += (int32_t by) { Data.Int += by; Type=C4V_Int; return *this; }
|
||||
C4Value & operator -= (int32_t by) { Data.Int -= by; Type=C4V_Int; return *this; }
|
||||
C4Value & operator *= (int32_t by) { Data.Int *= by; Type=C4V_Int; return *this; }
|
||||
C4Value & operator /= (int32_t by) { Data.Int /= by; Type=C4V_Int; return *this; }
|
||||
C4Value & operator %= (int32_t by) { Data.Int %= by; Type=C4V_Int; return *this; }
|
||||
C4Value & operator &= (int32_t by) { Data.Int &= by; Type=C4V_Int; return *this; }
|
||||
C4Value & operator ^= (int32_t by) { Data.Int ^= by; Type=C4V_Int; return *this; }
|
||||
C4Value & operator |= (int32_t by) { Data.Int |= by; Type=C4V_Int; return *this; }
|
||||
C4Value & operator ++ () { Data.Int++; Type=C4V_Int; return *this; }
|
||||
C4Value operator ++ (int) { C4Value old = *this; ++(*this); return old; }
|
||||
C4Value & operator -- () { Data.Int--; Type=C4V_Int; return *this; }
|
||||
C4Value operator -- (int) { C4Value old = *this; --(*this); return old; }
|
||||
|
||||
void Move(C4Value *nValue);
|
||||
|
||||
C4Value GetRef() { return C4Value(this); }
|
||||
void Deref() { Set(GetRefValConst()); }
|
||||
bool IsRef() { return Type == C4V_Ref; }
|
||||
|
||||
// get data of referenced value
|
||||
C4V_Data GetData() const { return GetRefVal().Data; }
|
||||
C4V_Data & GetData() { return GetRefVal().Data; }
|
||||
|
||||
// get type of referenced value
|
||||
C4V_Type GetType() const { return GetRefVal().Type; }
|
||||
|
||||
// return referenced value
|
||||
const C4Value & GetRefVal() const;
|
||||
const C4Value & GetRefValConst() const { return GetRefVal(); }
|
||||
protected:
|
||||
// This also creates a new entry in a proplist if the referenced value was previously only in the prototype
|
||||
C4Value & GetRefVal();
|
||||
|
||||
public:
|
||||
// Get the Value at the index. Throws C4AulExecError if not an array
|
||||
void GetArrayElement(int32_t index, C4Value & to, struct C4AulContext *pctx, bool noref);
|
||||
// Set the length of the array. Throws C4AulExecError if not an array
|
||||
void SetArrayLength(int32_t size, C4AulContext *cthr);
|
||||
// getters
|
||||
C4V_Data GetData() const { return Data; }
|
||||
C4V_Data & GetData() { return Data; }
|
||||
C4V_Type GetType() const { return Type; }
|
||||
|
||||
const char *GetTypeName() const { return GetC4VName(GetType()); }
|
||||
const char *GetTypeInfo();
|
||||
|
@ -222,40 +184,19 @@ protected:
|
|||
// data
|
||||
C4V_Data Data;
|
||||
|
||||
// reference-list
|
||||
union
|
||||
{
|
||||
C4Value * NextRef;
|
||||
C4ValueArray * BaseArray;
|
||||
C4String * PropListRefKey;
|
||||
};
|
||||
C4Value * FirstRef;
|
||||
|
||||
// data type
|
||||
C4V_Type Type:8;
|
||||
bool HasBaseArray:8;
|
||||
// All referenzes to a C4Value form a linked list, so that they can be updated if the C4Value
|
||||
// has to move, (array is resized), or goes out of scope (func & f() { var r; return r; })
|
||||
// If the reference is in an array, the last c4value in the list has HasBaseArray set, and
|
||||
// BaseArray points to the array. This is used to count the references to elements that an
|
||||
// array has, and maintain the invariant that an array can only have multiple references to
|
||||
// the array OR its elements, but not both. For example, a[0] = a; has to copy the entire
|
||||
// old array into its first element. But a[0]=42; GetLength(a); should not copy the array,
|
||||
// so the element reference count has to be reset after a[0] is removed from the stack.
|
||||
C4V_Type Type;
|
||||
|
||||
C4Value * GetNextRef() { if (HasBaseArray) return 0; else return NextRef; }
|
||||
C4ValueArray * GetBaseArray() { if (HasBaseArray) return BaseArray; else return 0; }
|
||||
// proplist reference list
|
||||
C4Value * NextRef;
|
||||
|
||||
C4Value(C4V_Data nData, C4V_Type nType): Data(nData), NextRef(NULL), FirstRef(NULL), HasBaseArray(false)
|
||||
{ Type = nData || IsNullableType(nType) ? nType : C4V_Any; AddDataRef(); }
|
||||
C4Value(C4V_Data nData, C4V_Type nType): Data(nData), NextRef(NULL)
|
||||
{ Type = (nData || IsNullableType(nType) ? nType : C4V_Any); AddDataRef(); }
|
||||
|
||||
void Set(C4V_Data nData, C4V_Type nType, C4String * PropListRefKey = 0);
|
||||
|
||||
void AddRef(C4Value *pRef);
|
||||
void DelRef(const C4Value *pRef, C4Value * pNextRef, C4ValueArray * pBaseArray);
|
||||
void Set(C4V_Data nData, C4V_Type nType);
|
||||
|
||||
void AddDataRef();
|
||||
void DelDataRef(C4V_Data Data, C4V_Type Type, C4Value * pNextRef, C4ValueArray * pBaseArray, C4String * Key);
|
||||
void DelDataRef(C4V_Data Data, C4V_Type Type, C4Value *pNextRef);
|
||||
|
||||
static C4VCnvFn C4ScriptCnvMap[C4V_Last+1][C4V_Last+1];
|
||||
static bool FnCnvObject(C4Value *Val, C4V_Type toType);
|
||||
|
@ -276,7 +217,6 @@ inline C4Value C4VObj(C4Object *pObj) { return C4Value(pObj); }
|
|||
inline C4Value C4VPropList(C4PropList * p) { return C4Value(p); }
|
||||
inline C4Value C4VString(C4String *pStr) { return C4Value(pStr); }
|
||||
inline C4Value C4VArray(C4ValueArray *pArray) { return C4Value(pArray); }
|
||||
inline C4Value C4VRef(C4Value *pVal) { return pVal->GetRef(); }
|
||||
|
||||
C4Value C4VString(StdStrBuf strString);
|
||||
C4Value C4VString(const char *strString);
|
||||
|
@ -331,13 +271,6 @@ template <> struct C4ValueConv<C4PropList *>
|
|||
inline static C4PropList *_FromC4V(C4Value &v) { return v._getPropList(); }
|
||||
inline static C4Value ToC4V(C4PropList *v) { return C4VPropList(v); }
|
||||
};
|
||||
template <> struct C4ValueConv<C4Value *>
|
||||
{
|
||||
inline static C4V_Type Type() { return C4V_Ref; }
|
||||
inline static C4Value *FromC4V(C4Value &v) { return v.getRef(); }
|
||||
inline static C4Value *_FromC4V(C4Value &v) { return v._getRef(); }
|
||||
inline static C4Value ToC4V(C4Value *v) { return C4VRef(v); }
|
||||
};
|
||||
template <> struct C4ValueConv<const C4Value &>
|
||||
{
|
||||
inline static C4V_Type Type() { return C4V_Any; }
|
||||
|
|
|
@ -109,23 +109,23 @@ C4Value &C4ValueList::GetItem(int32_t iElem)
|
|||
else if (iElem < 0)
|
||||
iElem = iSize + iElem;
|
||||
else if (iElem >= iSize && iElem < MaxSize) this->SetSize(iElem + 1);
|
||||
// out-of-memory? This might not be catched, but it's better than a segfault
|
||||
// out-of-memory? This might not get caught, but it's better than a segfault
|
||||
if (iElem >= iSize)
|
||||
throw new C4AulExecError(NULL,"out of memory");
|
||||
// return
|
||||
return pData[iElem];
|
||||
}
|
||||
|
||||
void C4ValueList::SetItem(int32_t iElemNr, C4Value iValue)
|
||||
void C4ValueList::SetItem(int32_t iElemNr, const C4Value &Value)
|
||||
{
|
||||
// enlarge
|
||||
if (iElemNr < 0) iElemNr = 0;
|
||||
if (iElemNr >= iSize && iElemNr < MaxSize) this->SetSize(iElemNr + 1);
|
||||
// out-of-memory? This might not be catched, but it's better than a segfault
|
||||
// out-of-memory? This might not get caught, but it's better than a segfault
|
||||
if (iElemNr >= iSize)
|
||||
throw new C4AulExecError(NULL,"out of memory");
|
||||
// set
|
||||
pData[iElemNr]=iValue;
|
||||
pData[iElemNr]=Value;
|
||||
}
|
||||
|
||||
void C4ValueList::SetSize(int32_t inSize)
|
||||
|
@ -142,14 +142,14 @@ void C4ValueList::SetSize(int32_t inSize)
|
|||
// bounds check
|
||||
if (inSize > MaxSize) return;
|
||||
|
||||
// create new array (initialises)
|
||||
// create new array
|
||||
C4Value* pnData = new C4Value [inSize];
|
||||
if (!pnData) return;
|
||||
|
||||
// move existing values
|
||||
int32_t i;
|
||||
for (i=0; i<iSize; i++)
|
||||
pData[i].Move(&pnData[i]);
|
||||
pnData[i] = pData[i];
|
||||
|
||||
// replace
|
||||
delete[] pData;
|
||||
|
@ -195,17 +195,12 @@ void C4ValueList::CompileFunc(class StdCompiler *pComp)
|
|||
}
|
||||
|
||||
C4ValueArray::C4ValueArray()
|
||||
: C4ValueList(), iRefCnt(0), iElementReferences(0)
|
||||
: C4ValueList(), iRefCnt(0)
|
||||
{
|
||||
}
|
||||
|
||||
C4ValueArray::C4ValueArray(int32_t inSize)
|
||||
: C4ValueList(inSize), iRefCnt(0), iElementReferences(0)
|
||||
{
|
||||
}
|
||||
|
||||
C4ValueArray::C4ValueArray(const C4ValueArray &Array2)
|
||||
: C4ValueList(Array2), iRefCnt(1), iElementReferences(0)
|
||||
: C4ValueList(inSize), iRefCnt(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -215,44 +210,6 @@ C4ValueArray::~C4ValueArray()
|
|||
|
||||
enum { C4VALUEARRAY_DEBUG = 0 };
|
||||
|
||||
C4ValueArray * C4ValueArray::IncElementRef()
|
||||
{
|
||||
if (iRefCnt > 1)
|
||||
{
|
||||
C4ValueArray * pNew = new C4ValueArray(*this);
|
||||
pNew->iElementReferences = 1;
|
||||
if (C4VALUEARRAY_DEBUG) printf("%p IncElementRef at %d, %d - Copying %p\n", static_cast<void*>(this), iRefCnt, iElementReferences, static_cast<void*>(pNew));
|
||||
--iRefCnt;
|
||||
return pNew;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (C4VALUEARRAY_DEBUG) printf("%p IncElementRef at %d, %d\n", static_cast<void*>(this), iRefCnt, iElementReferences);
|
||||
++iElementReferences;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
void C4ValueArray::DecElementRef()
|
||||
{
|
||||
if (C4VALUEARRAY_DEBUG) printf("%p DecElementRef at %d, %d\n", static_cast<void*>(this), iRefCnt, iElementReferences);
|
||||
assert(iElementReferences > 0);
|
||||
--iElementReferences;
|
||||
}
|
||||
|
||||
C4ValueArray * C4ValueArray::IncRef()
|
||||
{
|
||||
if (iRefCnt >= 1 && iElementReferences)
|
||||
{
|
||||
C4ValueArray * pNew = new C4ValueArray(*this);
|
||||
if (C4VALUEARRAY_DEBUG) printf("%p IncRef from %d, %d - Copying %p\n", static_cast<void*>(this), iRefCnt, iElementReferences, static_cast<void*>(pNew));
|
||||
return pNew;
|
||||
}
|
||||
if (C4VALUEARRAY_DEBUG) printf("%p IncRef from %d, %d\n", static_cast<void*>(this), iRefCnt, iElementReferences);
|
||||
iRefCnt++;
|
||||
return this;
|
||||
}
|
||||
|
||||
C4ValueArray * C4ValueArray::GetSlice(int32_t startIndex, int32_t endIndex)
|
||||
{
|
||||
// adjust indices so that the default end index works and that negative numbers count backwards from the end of the string
|
||||
|
@ -265,9 +222,7 @@ C4ValueArray * C4ValueArray::GetSlice(int32_t startIndex, int32_t endIndex)
|
|||
else if (endIndex < 0) endIndex += iSize;
|
||||
|
||||
if (startIndex == 0 && endIndex == iSize)
|
||||
{
|
||||
return IncRef();
|
||||
}
|
||||
return this;
|
||||
else
|
||||
{
|
||||
C4ValueArray* NewArray = new C4ValueArray(std::max(0, endIndex - startIndex));
|
||||
|
@ -277,31 +232,3 @@ C4ValueArray * C4ValueArray::GetSlice(int32_t startIndex, int32_t endIndex)
|
|||
}
|
||||
}
|
||||
|
||||
C4ValueArray * C4ValueArray::SetLength(int32_t size)
|
||||
{
|
||||
if (iRefCnt > 1)
|
||||
{
|
||||
C4ValueArray * pNew = (new C4ValueArray(size))->IncRef();
|
||||
for (int32_t i = 0; i < size; i++)
|
||||
pNew->pData[i].Set(pData[i]);
|
||||
if (C4VALUEARRAY_DEBUG) printf("%p SetLength at %d, %d - Copying %p\n", static_cast<void*>(this), iRefCnt, iElementReferences, static_cast<void*>(pNew));
|
||||
--iRefCnt;
|
||||
return pNew;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (C4VALUEARRAY_DEBUG) printf("%p SetLength at %d, %d\n", static_cast<void*>(this), iRefCnt, iElementReferences);
|
||||
SetSize(size);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
void C4ValueArray::DecRef()
|
||||
{
|
||||
if (C4VALUEARRAY_DEBUG) printf("%p DecRef from %d, %d%s\n", static_cast<void*>(this), iRefCnt, iElementReferences, iRefCnt == 1 ? " - Deleting" : "");
|
||||
assert(iRefCnt);
|
||||
if (!--iRefCnt)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
C4Value &operator[](int32_t iElem) { return GetItem(iElem); }
|
||||
|
||||
void Reset();
|
||||
void SetItem(int32_t iElemNr, C4Value iValue);
|
||||
void SetItem(int32_t iElemNr, const C4Value &Value);
|
||||
void SetSize(int32_t inSize); // (enlarge only!)
|
||||
|
||||
void DenumeratePointers();
|
||||
|
@ -78,23 +78,20 @@ public:
|
|||
|
||||
~C4ValueArray();
|
||||
|
||||
// Add Reference, return self or new copy if necessary
|
||||
C4ValueArray * IncRef();
|
||||
C4ValueArray * IncElementRef();
|
||||
// Add/Remove Reference
|
||||
void IncRef() { iRefCnt++; }
|
||||
void DecRef() { if (!--iRefCnt) delete this; }
|
||||
|
||||
// Return sub-array [startIndex, endIndex), or reference for [0, iSize)
|
||||
C4ValueArray * GetSlice(int32_t startIndex, int32_t endIndex);
|
||||
// Change length, return self or new copy if necessary
|
||||
C4ValueArray * SetLength(int32_t size);
|
||||
void DecRef();
|
||||
void DecElementRef();
|
||||
// Change length
|
||||
void SetLength(int32_t size);
|
||||
|
||||
void Sort(class C4SortObject &rSort);
|
||||
|
||||
private:
|
||||
// Only for IncRef/AddElementRef
|
||||
C4ValueArray(const C4ValueArray &Array2);
|
||||
// Reference counter
|
||||
unsigned int iRefCnt;
|
||||
unsigned int iElementReferences;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -211,16 +211,16 @@ void C4ValueMapData::OnNameListChanged(const char **pOldNames, int32_t iOldSize)
|
|||
//FIXME: This optimization is ugly.
|
||||
if (i < pNames->iSize && SEqual(pNames->pNames[i], pOldNames[i]))
|
||||
{
|
||||
pOldData[i].Move(&pData[i]);
|
||||
pData[i] = pOldData[i];
|
||||
}
|
||||
else for (j = 0; j < pNames->iSize; j++)
|
||||
{
|
||||
if (SEqual(pNames->pNames[j], pOldNames[i]))
|
||||
{
|
||||
if (SEqual(pNames->pNames[j], pOldNames[i]))
|
||||
{
|
||||
pOldData[i].Move(&pData[j]);
|
||||
break;
|
||||
}
|
||||
pData[j] = pOldData[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// delete old data array
|
||||
delete[] pOldData;
|
||||
|
|
Loading…
Reference in New Issue