forked from Mirrors/openclonk
Script: Initial proplists are readonly at runtime
That way, recreating them from game data during savegame load won't suddenly revert changes, because there aren't any changes.floating-point
parent
1a3f8fe80b
commit
bf9137149c
|
@ -1432,6 +1432,7 @@ void C4DefList::CallEveryDefinition()
|
|||
{
|
||||
C4AulParSet Pars(C4VPropList(it->second));
|
||||
it->second->Script.Call(PSF_Definition, 0, &Pars, true);
|
||||
it->second->Freeze();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1021,6 +1021,8 @@ static C4Value FnSetProperty_C4V(C4AulContext *cthr, C4Value * key_C4V, C4Value
|
|||
if (!pObj) return C4VFalse;
|
||||
C4String * key = key_C4V->_getStr();
|
||||
if (!key) return C4VFalse;
|
||||
if (pObj->IsFrozen())
|
||||
throw new C4AulExecError(cthr->Obj, "proplist write: proplist is readonly");
|
||||
pObj->SetProperty(key, *to);
|
||||
return C4VTrue;
|
||||
}
|
||||
|
|
|
@ -141,10 +141,12 @@ typedef ptrdiff_t ssize_t;
|
|||
#define GNUC_FORMAT_ATTRIBUTE __attribute__ ((format (printf, 1, 2)))
|
||||
#define GNUC_FORMAT_ATTRIBUTE_O __attribute__ ((format (printf, 2, 3)))
|
||||
#define ALWAYS_INLINE inline __attribute__ ((always_inline))
|
||||
#define NORETURN __attribute__ ((noreturn))
|
||||
#else
|
||||
#define GNUC_FORMAT_ATTRIBUTE
|
||||
#define GNUC_FORMAT_ATTRIBUTE_O
|
||||
#define ALWAYS_INLINE __forceinline
|
||||
#define NORETURN
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -247,6 +247,8 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
|
|||
C4Value *pPropList = pCurVal - 1;
|
||||
if (!(pPropList->ConvertTo(C4V_PropList) && pPropList->_getPropList()))
|
||||
throw new C4AulExecError(pCurCtx->Obj, FormatString("proplist write: proplist expected, got %s", pPropList->GetTypeName()).getData());
|
||||
if (pPropList->_getPropList()->IsFrozen())
|
||||
throw new C4AulExecError(pCurCtx->Obj, "proplist write: proplist is readonly");
|
||||
pPropList->_getPropList()->SetProperty(pCPos->Par.s, pCurVal[0]);
|
||||
pPropList->Set(pCurVal[0]);
|
||||
PopValue();
|
||||
|
@ -492,6 +494,8 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
|
|||
{
|
||||
assert(pStruct->GetType() == C4V_PropList || pStruct->GetType() == C4V_C4Object);
|
||||
C4PropList *pPropList = pStruct->_getPropList();
|
||||
if (pPropList->IsFrozen())
|
||||
throw new C4AulExecError(pCurCtx->Obj, "proplist write: proplist is readonly");
|
||||
pPropList->SetProperty(pIndex->_getStr(), *pValue);
|
||||
}
|
||||
// Set result, remove array and index from stack
|
||||
|
|
|
@ -175,7 +175,7 @@ public:
|
|||
|
||||
void Shift(HoldStringsPolicy HoldStrings = Hold, bool bOperator = true);
|
||||
void Match(C4AulTokenType TokenType, const char * Message = NULL);
|
||||
void UnexpectedToken(const char * Expected);
|
||||
void UnexpectedToken(const char * Expected) NORETURN;
|
||||
const char * GetTokenName(C4AulTokenType TokenType);
|
||||
|
||||
void Warn(const char *pMsg, const char *pIdtf=0);
|
||||
|
@ -3003,6 +3003,7 @@ C4Value C4AulParseState::Parse_ConstExpression()
|
|||
else if (TokenType != ATT_BLCLOSE)
|
||||
UnexpectedToken("'}' or ','");
|
||||
}
|
||||
r._getPropList()->Freeze();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -97,7 +97,7 @@ C4PropListNumbered::~C4PropListNumbered()
|
|||
|
||||
C4PropList::C4PropList(C4PropList * prototype):
|
||||
Status(1),
|
||||
FirstRef(NULL), prototype(prototype)
|
||||
FirstRef(NULL), prototype(prototype), constant(false)
|
||||
{
|
||||
if (prototype)
|
||||
SetProperty(Strings.P[P_Prototype], C4VPropList(prototype));
|
||||
|
@ -318,6 +318,7 @@ int32_t C4PropList::GetPropertyInt(C4PropertyName n)
|
|||
|
||||
void C4PropList::SetProperty(C4String * k, const C4Value & to)
|
||||
{
|
||||
assert(!constant);
|
||||
assert(Strings.Set.Has(k));
|
||||
if (k == Strings.P[P_Prototype] && to.GetType() == C4V_PropList)
|
||||
{
|
||||
|
|
|
@ -63,10 +63,17 @@ public:
|
|||
bool GetPropertyVal(C4PropertyName k, C4Value *pResult) { return GetPropertyVal(Strings.P[k], pResult); }
|
||||
C4String * GetPropertyStr(C4PropertyName k);
|
||||
int32_t GetPropertyInt(C4PropertyName k);
|
||||
// not allowed on frozen proplists
|
||||
void SetProperty(C4String * k, const C4Value & to);
|
||||
void ResetProperty(C4String * k);
|
||||
|
||||
static C4PropList * New(C4PropList * prototype = 0);
|
||||
static C4PropList * NewAnon(C4PropList * prototype = 0);
|
||||
|
||||
// only freeze proplists which are not going to be modified
|
||||
void Freeze() { constant = true; }
|
||||
bool IsFrozen() { return constant; }
|
||||
|
||||
virtual void DenumeratePointers();
|
||||
virtual ~C4PropList();
|
||||
|
||||
|
@ -79,7 +86,7 @@ protected:
|
|||
|
||||
private:
|
||||
C4Value *FirstRef; // No-Save
|
||||
bool constant; // if true, this proplist is neither saved nor changeable FIXME: implement
|
||||
bool constant; // if true, this proplist is not changeable
|
||||
|
||||
C4PropList * prototype;
|
||||
friend void CompileNewFunc<C4PropList>(C4PropList *&pStruct, StdCompiler *pComp);
|
||||
|
|
Loading…
Reference in New Issue