2009-07-22 14:15:18 +00:00
|
|
|
/*
|
2010-12-23 00:01:24 +00:00
|
|
|
* OpenClonk, http://www.openclonk.org
|
|
|
|
*
|
2013-01-09 23:23:06 +00:00
|
|
|
* Copyright (c) 2009-2012 Günther Brammer
|
2010-12-23 00:01:24 +00:00
|
|
|
* Copyright (c) 2009 Nicolas Hake
|
|
|
|
* Copyright (c) 2010 Benjamin Herr
|
2009-07-22 14:15:18 +00:00
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
*
|
|
|
|
* "Clonk" is a registered trademark of Matthes Bender.
|
|
|
|
*/
|
|
|
|
|
2009-05-19 22:12:11 +00:00
|
|
|
/* Property lists */
|
|
|
|
|
|
|
|
#include "C4Value.h"
|
|
|
|
#include "C4StringTable.h"
|
|
|
|
|
2011-01-08 16:04:20 +00:00
|
|
|
#ifndef C4PROPLIST_H
|
|
|
|
#define C4PROPLIST_H
|
|
|
|
|
2009-10-25 23:09:34 +00:00
|
|
|
|
2010-03-28 17:58:21 +00:00
|
|
|
class C4Property
|
|
|
|
{
|
|
|
|
public:
|
2009-07-26 20:31:45 +00:00
|
|
|
C4Property() : Key(0) {}
|
|
|
|
C4Property(C4String *Key, const C4Value &Value) : Key(Key), Value(Value)
|
2010-12-06 15:24:41 +00:00
|
|
|
{ assert(Key); Key->IncRef(); /*assert(Strings.Set.Has(Key));*/ }
|
2010-03-28 17:58:21 +00:00
|
|
|
C4Property(const C4Property &o) : Key(o.Key), Value(o.Value) { if (Key) Key->IncRef(); }
|
2009-07-26 20:31:45 +00:00
|
|
|
C4Property & operator = (const C4Property &o)
|
2012-10-14 12:39:22 +00:00
|
|
|
{ if(o.Key) o.Key->IncRef(); if (Key) Key->DecRef(); Key = o.Key; Value = o.Value; return *this; }
|
2012-07-25 23:21:15 +00:00
|
|
|
#ifdef HAVE_RVALUE_REF
|
|
|
|
C4Property(C4Property && o) : Key(o.Key), Value(std::move(o.Value)) { o.Key = 0; }
|
|
|
|
C4Property & operator = (C4Property && o)
|
2012-10-14 12:39:22 +00:00
|
|
|
{ if (Key) Key->DecRef(); Key = o.Key; o.Key = 0; Value = std::move(o.Value); return *this; }
|
2012-07-25 23:21:15 +00:00
|
|
|
#endif
|
2010-03-28 17:58:21 +00:00
|
|
|
~C4Property() { if (Key) Key->DecRef(); }
|
2011-03-26 22:59:35 +00:00
|
|
|
void CompileFunc(StdCompiler *pComp, C4ValueNumbers *);
|
2009-05-19 22:12:11 +00:00
|
|
|
C4String * Key;
|
|
|
|
C4Value Value;
|
2010-03-21 23:40:03 +00:00
|
|
|
operator const void * () const { return Key; }
|
2010-12-06 15:19:15 +00:00
|
|
|
C4Property & operator = (void * p)
|
|
|
|
{ assert(!p); if (Key) Key->DecRef(); Key = 0; Value.Set0(); return *this; }
|
2012-10-14 12:39:22 +00:00
|
|
|
bool operator < (const C4Property &cmp) const { return strcmp(GetSafeKey(), cmp.GetSafeKey())<0; }
|
|
|
|
const char *GetSafeKey() const { if (Key && Key->GetCStr()) return Key->GetCStr(); return ""; } // get key as C string; return "" if undefined. never return NULL
|
2009-05-19 22:12:11 +00:00
|
|
|
};
|
2010-03-21 23:40:03 +00:00
|
|
|
class C4PropListNumbered;
|
2010-03-28 17:58:21 +00:00
|
|
|
class C4PropList
|
|
|
|
{
|
|
|
|
public:
|
2009-05-19 22:12:11 +00:00
|
|
|
void AddRef(C4Value *pRef);
|
|
|
|
void DelRef(const C4Value *pRef, C4Value * pNextRef);
|
2010-09-22 01:33:57 +00:00
|
|
|
void Clear() { constant = false; Properties.Clear(); prototype = 0; }
|
2011-01-12 22:43:05 +00:00
|
|
|
const char *GetName() const;
|
2009-04-03 19:06:29 +00:00
|
|
|
virtual void SetName (const char *NewName = 0);
|
2009-05-19 22:12:11 +00:00
|
|
|
|
2010-09-10 21:01:30 +00:00
|
|
|
virtual C4Def const * GetDef() const;
|
2009-04-12 12:04:28 +00:00
|
|
|
virtual C4Def * GetDef();
|
2009-04-18 00:46:19 +00:00
|
|
|
virtual C4Object * GetObject();
|
2010-12-19 23:13:56 +00:00
|
|
|
virtual C4Effect * GetEffect();
|
2010-03-21 23:40:03 +00:00
|
|
|
virtual C4PropListNumbered * GetPropListNumbered();
|
2010-09-10 21:01:30 +00:00
|
|
|
C4PropList * GetPrototype() const { return prototype; }
|
2009-04-12 12:04:28 +00:00
|
|
|
|
2012-06-01 15:27:59 +00:00
|
|
|
// saved as a reference to a global constant?
|
|
|
|
virtual class C4PropListStatic * IsStatic() { return NULL; }
|
|
|
|
// saved as a reference to separately saved objects?
|
2011-03-27 16:14:41 +00:00
|
|
|
virtual bool IsNumbered() const { return false; }
|
2012-06-01 15:27:59 +00:00
|
|
|
// some proplists have references that are not reference-counted
|
|
|
|
virtual bool Delete() { return false; }
|
2010-09-08 18:09:27 +00:00
|
|
|
|
2012-05-25 23:32:43 +00:00
|
|
|
// These four operate on properties as seen by script, which can be dynamic
|
2010-12-24 14:10:39 +00:00
|
|
|
// or reflect C++ variables
|
|
|
|
virtual bool GetPropertyByS(C4String *k, C4Value *pResult) const;
|
2012-05-25 23:32:43 +00:00
|
|
|
virtual C4ValueArray * GetProperties() const;
|
2010-12-24 14:10:39 +00:00
|
|
|
// not allowed on frozen proplists
|
|
|
|
virtual void SetPropertyByS(C4String * k, const C4Value & to);
|
|
|
|
virtual void ResetProperty(C4String * k);
|
|
|
|
|
|
|
|
// helper functions to get dynamic properties from other parts of the engine
|
2010-12-06 15:19:15 +00:00
|
|
|
bool GetProperty(C4PropertyName k, C4Value *pResult) const
|
2010-12-06 15:24:41 +00:00
|
|
|
{ return GetPropertyByS(&Strings.P[k], pResult); }
|
2010-09-10 21:01:30 +00:00
|
|
|
C4String * GetPropertyStr(C4PropertyName k) const;
|
2011-10-04 21:04:06 +00:00
|
|
|
C4AulFunc * GetFunc(C4PropertyName k) const
|
|
|
|
{ return GetFunc(&Strings.P[k]); }
|
|
|
|
C4AulFunc * GetFunc(C4String * k) const;
|
|
|
|
C4AulFunc * GetFunc(const char * k) const;
|
2012-05-27 22:50:13 +00:00
|
|
|
C4String * EnumerateOwnFuncs(C4String * prev = 0) const;
|
2012-08-19 19:29:43 +00:00
|
|
|
C4Value Call(C4PropertyName k, C4AulParSet *pPars=0, bool fPassErrors=false)
|
|
|
|
{ return Call(&Strings.P[k], pPars, fPassErrors); }
|
|
|
|
C4Value Call(C4String * k, C4AulParSet *pPars=0, bool fPassErrors=false);
|
|
|
|
C4Value Call(const char * k, C4AulParSet *pPars=0, bool fPassErrors=false);
|
2010-12-08 22:17:00 +00:00
|
|
|
C4PropertyName GetPropertyP(C4PropertyName k) const;
|
2010-09-10 21:01:30 +00:00
|
|
|
int32_t GetPropertyInt(C4PropertyName k) const;
|
2010-12-24 14:10:39 +00:00
|
|
|
bool HasProperty(C4String * k) { return Properties.Has(k); }
|
2010-09-08 12:54:39 +00:00
|
|
|
// not allowed on frozen proplists
|
2010-12-06 15:19:15 +00:00
|
|
|
void SetProperty(C4PropertyName k, const C4Value & to)
|
2010-12-06 15:24:41 +00:00
|
|
|
{ SetPropertyByS(&Strings.P[k], to); }
|
2009-04-03 19:06:29 +00:00
|
|
|
|
2010-03-21 23:40:03 +00:00
|
|
|
static C4PropList * New(C4PropList * prototype = 0);
|
2012-08-15 17:43:02 +00:00
|
|
|
static C4PropListStatic * NewStatic(C4PropList * prototype, const C4PropListStatic * parent, C4String * key);
|
2010-09-08 12:54:39 +00:00
|
|
|
|
|
|
|
// only freeze proplists which are not going to be modified
|
2012-06-01 15:27:59 +00:00
|
|
|
// FIXME: Only C4PropListStatic get frozen. Optimize accordingly.
|
2010-09-08 12:54:39 +00:00
|
|
|
void Freeze() { constant = true; }
|
2011-10-14 23:38:59 +00:00
|
|
|
void Thaw() { constant = false; }
|
2010-09-10 21:01:30 +00:00
|
|
|
bool IsFrozen() const { return constant; }
|
2010-09-08 12:54:39 +00:00
|
|
|
|
2011-03-26 22:59:35 +00:00
|
|
|
virtual void Denumerate(C4ValueNumbers *);
|
2009-05-19 22:12:11 +00:00
|
|
|
virtual ~C4PropList();
|
2009-04-03 19:06:29 +00:00
|
|
|
|
2011-03-26 22:59:35 +00:00
|
|
|
void CompileFunc(StdCompiler *pComp, C4ValueNumbers *);
|
2011-05-09 21:19:31 +00:00
|
|
|
void AppendDataString(StdStrBuf * out, const char * delim, int depth = 3);
|
2009-05-19 22:12:11 +00:00
|
|
|
|
2010-09-10 21:01:30 +00:00
|
|
|
bool operator==(const C4PropList &b) const;
|
2011-02-06 21:30:31 +00:00
|
|
|
#ifdef _DEBUG
|
|
|
|
static C4Set<C4PropList *> PropLists;
|
|
|
|
#endif
|
2010-09-10 21:01:30 +00:00
|
|
|
|
2010-03-28 17:58:21 +00:00
|
|
|
protected:
|
2010-03-21 23:40:03 +00:00
|
|
|
C4PropList(C4PropList * prototype = 0);
|
2011-03-31 20:53:07 +00:00
|
|
|
C4Value *FirstRef; // No-Save
|
2010-03-21 23:40:03 +00:00
|
|
|
|
2010-03-28 17:58:21 +00:00
|
|
|
private:
|
2010-10-17 20:13:12 +00:00
|
|
|
C4Set<C4Property> Properties;
|
2010-12-06 18:04:32 +00:00
|
|
|
C4PropList * prototype;
|
2010-09-08 12:54:39 +00:00
|
|
|
bool constant; // if true, this proplist is not changeable
|
2012-05-27 22:31:55 +00:00
|
|
|
friend class C4ScriptHost;
|
2010-12-06 18:04:32 +00:00
|
|
|
public:
|
|
|
|
int32_t Status;
|
2009-05-19 22:12:11 +00:00
|
|
|
};
|
|
|
|
|
2011-03-26 22:59:35 +00:00
|
|
|
void CompileNewFunc(C4PropList *&pStruct, StdCompiler *pComp, C4ValueNumbers * const & rPar);
|
|
|
|
|
2011-03-05 02:32:51 +00:00
|
|
|
// Proplists that are created during a game and get saved in a savegame
|
2012-06-01 15:27:59 +00:00
|
|
|
// Examples: Objects, Effects
|
2010-03-28 17:58:21 +00:00
|
|
|
class C4PropListNumbered: public C4PropList
|
|
|
|
{
|
|
|
|
public:
|
2010-03-21 23:40:03 +00:00
|
|
|
int32_t Number;
|
|
|
|
~C4PropListNumbered();
|
2011-03-27 16:14:41 +00:00
|
|
|
void CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers);
|
2010-03-21 23:40:03 +00:00
|
|
|
virtual C4PropListNumbered * GetPropListNumbered();
|
|
|
|
void AcquireNumber();
|
2011-03-27 16:14:41 +00:00
|
|
|
virtual bool IsNumbered() const { return true; }
|
2011-03-05 02:32:51 +00:00
|
|
|
|
|
|
|
static C4PropList * GetByNumber(int32_t iNumber); // pointer by number
|
2011-02-06 00:59:49 +00:00
|
|
|
static bool CheckPropList(C4PropList *); // sanity check: true when the proplist is in the list and not a stale pointer
|
2011-03-27 16:14:41 +00:00
|
|
|
static void SetEnumerationIndex(int32_t iMaxObjectNumber);
|
2011-03-05 02:32:51 +00:00
|
|
|
static int32_t GetEnumerationIndex() { return EnumerationIndex; }
|
|
|
|
static void ResetEnumerationIndex();
|
2010-12-19 23:13:56 +00:00
|
|
|
protected:
|
|
|
|
C4PropListNumbered(C4PropList * prototype = 0);
|
2011-03-05 02:32:51 +00:00
|
|
|
|
|
|
|
static C4Set<C4PropListNumbered *> PropLists;
|
|
|
|
static int32_t EnumerationIndex;
|
|
|
|
friend class C4GameObjects;
|
|
|
|
friend class C4Game;
|
2010-12-19 23:13:56 +00:00
|
|
|
};
|
|
|
|
|
2011-03-05 02:32:51 +00:00
|
|
|
// Proplists created by script at runtime
|
2011-03-27 16:14:41 +00:00
|
|
|
class C4PropListScript: public C4PropList
|
2010-12-19 23:13:56 +00:00
|
|
|
{
|
|
|
|
public:
|
2011-03-27 16:14:41 +00:00
|
|
|
C4PropListScript(C4PropList * prototype = 0): C4PropList(prototype) { }
|
2012-06-01 15:27:59 +00:00
|
|
|
bool Delete() { return true; }
|
2010-03-21 23:40:03 +00:00
|
|
|
};
|
|
|
|
|
2012-06-01 15:27:59 +00:00
|
|
|
// PropLists declared in the game data
|
|
|
|
// examples: Definitions, local variable initializers
|
|
|
|
class C4PropListStatic: public C4PropList
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
C4PropListStatic(C4PropList * prototype, const C4PropListStatic * parent, C4String * key):
|
|
|
|
C4PropList(prototype), Parent(parent), ParentKeyName(key) { }
|
|
|
|
virtual ~C4PropListStatic() { }
|
|
|
|
bool Delete() { return true; }
|
|
|
|
virtual C4PropListStatic * IsStatic() { return this; }
|
|
|
|
void RefCompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers) const;
|
2012-05-08 00:24:43 +00:00
|
|
|
StdStrBuf GetDataString() const;
|
2012-05-27 16:00:45 +00:00
|
|
|
const C4PropListStatic * GetParent() { return Parent; }
|
|
|
|
const C4String * GetParentKeyName() { return ParentKeyName; }
|
2012-06-01 15:27:59 +00:00
|
|
|
protected:
|
|
|
|
const C4PropListStatic * Parent;
|
|
|
|
C4RefCntPointer<C4String> ParentKeyName; // property in parent this proplist was created in
|
|
|
|
};
|
2010-03-21 23:40:03 +00:00
|
|
|
|
2009-05-19 22:12:11 +00:00
|
|
|
#endif // C4PROPLIST_H
|