2009-07-22 14:15:18 +00:00
|
|
|
/*
|
2010-12-23 00:01:24 +00:00
|
|
|
* OpenClonk, http://www.openclonk.org
|
|
|
|
*
|
|
|
|
* Copyright (c) 2004 Peter Wortmann
|
|
|
|
* Copyright (c) 2007, 2009-2010 Günther Brammer
|
|
|
|
* Copyright (c) 2009 Nicolas Hake
|
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
|
|
|
#include <C4Include.h>
|
|
|
|
#include <C4PropList.h>
|
2009-07-21 14:46:39 +00:00
|
|
|
#include <C4GameObjects.h>
|
2009-05-19 22:12:11 +00:00
|
|
|
#include <C4Game.h>
|
2009-05-19 22:37:14 +00:00
|
|
|
#include <C4Object.h>
|
2009-05-19 22:12:11 +00:00
|
|
|
|
|
|
|
void C4PropList::AddRef(C4Value *pRef)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2011-03-31 20:53:07 +00:00
|
|
|
#ifdef _DEBUG
|
|
|
|
C4Value * pVal = FirstRef;
|
|
|
|
while (pVal)
|
|
|
|
{
|
|
|
|
assert(pVal != pRef);
|
|
|
|
pVal = pVal->NextRef;
|
|
|
|
}
|
|
|
|
#endif
|
2009-05-19 22:12:11 +00:00
|
|
|
pRef->NextRef = FirstRef;
|
|
|
|
FirstRef = pRef;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-05-19 22:12:11 +00:00
|
|
|
|
|
|
|
void C4PropList::DelRef(const C4Value * pRef, C4Value * pNextRef)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2011-03-31 20:53:07 +00:00
|
|
|
assert(FirstRef);
|
2009-05-19 22:12:11 +00:00
|
|
|
// References to objects never have HasBaseArray set
|
2010-03-28 18:58:01 +00:00
|
|
|
if (pRef == FirstRef)
|
2011-03-31 20:53:07 +00:00
|
|
|
{
|
2009-05-19 22:12:11 +00:00
|
|
|
FirstRef = pNextRef;
|
2011-03-31 20:53:07 +00:00
|
|
|
if (pNextRef) return;
|
|
|
|
}
|
2009-05-19 22:12:11 +00:00
|
|
|
else
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2011-03-31 20:53:07 +00:00
|
|
|
C4Value *pPrev = FirstRef;
|
|
|
|
while (pPrev->NextRef != pRef)
|
|
|
|
{
|
|
|
|
pPrev = pPrev->NextRef;
|
|
|
|
assert(pPrev);
|
|
|
|
}
|
|
|
|
pPrev->NextRef = pNextRef;
|
|
|
|
return;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-12-19 23:13:56 +00:00
|
|
|
// Only pure script proplists are garbage collected here, host proplists
|
|
|
|
// like definitions and effects have their own memory management.
|
|
|
|
if (IsScriptPropList()) delete this;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-05-19 22:12:11 +00:00
|
|
|
|
2010-03-21 23:40:03 +00:00
|
|
|
C4PropList * C4PropList::New(C4PropList * prototype)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2011-03-27 16:14:41 +00:00
|
|
|
C4PropList * r = new C4PropListScript(prototype);
|
2010-03-21 23:40:03 +00:00
|
|
|
return r;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
|
2010-09-08 18:09:27 +00:00
|
|
|
C4PropList * C4PropList::NewAnon(C4PropList * prototype)
|
|
|
|
{
|
2011-03-27 16:14:41 +00:00
|
|
|
C4PropList * r = new C4PropListScript(prototype);
|
2010-09-08 18:09:27 +00:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2011-03-05 02:32:51 +00:00
|
|
|
C4Set<C4PropListNumbered *> C4PropListNumbered::PropLists;
|
|
|
|
int32_t C4PropListNumbered::EnumerationIndex = 0;
|
|
|
|
|
|
|
|
C4PropList *C4PropListNumbered::GetByNumber(int32_t iNumber)
|
|
|
|
{
|
|
|
|
return PropLists.Get(iNumber);
|
|
|
|
}
|
|
|
|
|
2011-02-06 00:59:49 +00:00
|
|
|
bool C4PropListNumbered::CheckPropList(C4PropList *pObj)
|
|
|
|
{
|
|
|
|
if (!pObj) return false;
|
|
|
|
C4PropListNumbered * const * p = PropLists.First();
|
|
|
|
while (p)
|
|
|
|
{
|
|
|
|
if (*p == pObj)
|
|
|
|
return true;
|
|
|
|
p = PropLists.Next(p);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-03-27 16:14:41 +00:00
|
|
|
void C4PropListNumbered::SetEnumerationIndex(int32_t iMaxObjectNumber)
|
2011-03-05 02:32:51 +00:00
|
|
|
{
|
|
|
|
// update object enumeration index now, because calls like UpdateTransferZone might create objects
|
|
|
|
EnumerationIndex = Max(EnumerationIndex, iMaxObjectNumber);
|
|
|
|
}
|
|
|
|
|
|
|
|
void C4PropListNumbered::ResetEnumerationIndex()
|
|
|
|
{
|
|
|
|
assert(!PropLists.GetSize());
|
|
|
|
EnumerationIndex = 0;
|
|
|
|
}
|
|
|
|
|
2010-03-21 23:40:03 +00:00
|
|
|
C4PropListNumbered::C4PropListNumbered(C4PropList * prototype): C4PropList(prototype), Number(-1)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
|
|
|
}
|
2010-03-19 00:21:54 +00:00
|
|
|
|
2010-03-21 23:40:03 +00:00
|
|
|
void C4PropListNumbered::AcquireNumber()
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-19 21:33:42 +00:00
|
|
|
// Enumerate object
|
|
|
|
do
|
2011-03-05 02:32:51 +00:00
|
|
|
Number = ++EnumerationIndex;
|
|
|
|
while (PropLists.Get(Number));
|
|
|
|
PropLists.Add(this);
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-05-19 22:32:01 +00:00
|
|
|
|
2010-03-21 23:40:03 +00:00
|
|
|
C4PropListNumbered* C4PropListNumbered::GetPropListNumbered()
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
return this;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
|
2011-03-26 22:59:35 +00:00
|
|
|
void C4PropListNumbered::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers)
|
2010-12-19 23:13:56 +00:00
|
|
|
{
|
|
|
|
pComp->Value(Number);
|
2011-03-27 16:14:41 +00:00
|
|
|
pComp->Separator(StdCompiler::SEP_SEP2);
|
|
|
|
C4PropList::CompileFunc(pComp, numbers);
|
2010-12-19 23:13:56 +00:00
|
|
|
if (pComp->isCompiler())
|
2011-02-05 22:11:02 +00:00
|
|
|
{
|
2011-03-05 02:32:51 +00:00
|
|
|
if (PropLists.Get(Number))
|
2011-02-05 22:11:02 +00:00
|
|
|
{
|
|
|
|
pComp->excCorrupt("multiple PropLists with Number %d", Number);
|
|
|
|
return;
|
|
|
|
}
|
2011-03-05 02:32:51 +00:00
|
|
|
PropLists.Add(this);
|
2011-02-05 22:11:02 +00:00
|
|
|
}
|
2010-12-19 23:13:56 +00:00
|
|
|
}
|
|
|
|
|
2010-03-21 23:40:03 +00:00
|
|
|
C4PropListNumbered::~C4PropListNumbered()
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
|
|
|
if (Number != -1)
|
2011-03-05 02:32:51 +00:00
|
|
|
PropLists.Remove(this);
|
2010-03-21 23:40:03 +00:00
|
|
|
else
|
|
|
|
Log("removing numbered proplist without number");
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
|
2011-02-06 21:30:31 +00:00
|
|
|
#ifdef _DEBUG
|
|
|
|
C4Set<C4PropList *> C4PropList::PropLists;
|
|
|
|
#endif
|
|
|
|
|
2010-03-21 23:40:03 +00:00
|
|
|
C4PropList::C4PropList(C4PropList * prototype):
|
2010-03-28 18:58:01 +00:00
|
|
|
Status(1),
|
2010-09-08 12:54:39 +00:00
|
|
|
FirstRef(NULL), prototype(prototype), constant(false)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
|
|
|
if (prototype)
|
2010-12-06 15:19:15 +00:00
|
|
|
SetProperty(P_Prototype, C4VPropList(prototype));
|
2011-02-06 21:30:31 +00:00
|
|
|
#ifdef _DEBUG
|
|
|
|
PropLists.Add(this);
|
|
|
|
#endif
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
|
2011-03-26 22:59:35 +00:00
|
|
|
void C4PropList::Denumerate(C4ValueNumbers * numbers)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
const C4Property * p = Properties.First();
|
|
|
|
while (p)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2011-03-26 22:59:35 +00:00
|
|
|
const_cast<C4Value &>(p->Value).Denumerate(numbers);
|
2010-03-21 23:40:03 +00:00
|
|
|
p = Properties.Next(p);
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
C4Value v;
|
2010-12-06 15:19:15 +00:00
|
|
|
if(GetProperty(P_Prototype, &v))
|
2010-04-08 00:47:45 +00:00
|
|
|
prototype = v.getPropList();
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
|
2009-05-19 22:12:11 +00:00
|
|
|
C4PropList::~C4PropList()
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-11-25 15:04:32 +00:00
|
|
|
while (FirstRef)
|
|
|
|
{
|
|
|
|
// Manually kill references so DelRef doesn't destroy us again
|
2011-05-09 12:37:28 +00:00
|
|
|
FirstRef->Data = 0; FirstRef->Type = C4V_Nil;
|
2009-11-25 15:04:32 +00:00
|
|
|
C4Value *ref = FirstRef;
|
|
|
|
FirstRef = FirstRef->NextRef;
|
|
|
|
ref->NextRef = NULL;
|
|
|
|
}
|
2011-02-06 21:30:31 +00:00
|
|
|
#ifdef _DEBUG
|
|
|
|
assert(PropLists.Has(this));
|
|
|
|
PropLists.Remove(this);
|
|
|
|
#endif
|
2011-02-06 00:59:49 +00:00
|
|
|
assert(!C4PropListNumbered::CheckPropList(this));
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-05-19 22:12:11 +00:00
|
|
|
|
2010-09-10 21:01:30 +00:00
|
|
|
bool C4PropList::operator==(const C4PropList &b) const
|
|
|
|
{
|
|
|
|
if (Properties.GetSize() != b.Properties.GetSize()) return false;
|
|
|
|
if (GetDef() != b.GetDef()) return false;
|
|
|
|
//if (GetObject() != b.GetObject()) return false;
|
|
|
|
const C4Property * p = Properties.First();
|
|
|
|
while (p)
|
|
|
|
{
|
|
|
|
if (*p != b.Properties.Get(p->Key)) return false;
|
|
|
|
p = Properties.Next(p);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-03-26 22:59:35 +00:00
|
|
|
void C4PropList::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2011-03-27 16:14:41 +00:00
|
|
|
pComp->Value(constant);
|
|
|
|
pComp->Separator(StdCompiler::SEP_SEP2);
|
2011-03-26 22:59:35 +00:00
|
|
|
pComp->Value(mkParAdapt(Properties, numbers));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CompileNewFunc(C4PropList *&pStruct, StdCompiler *pComp, C4ValueNumbers * const & rPar)
|
|
|
|
{
|
|
|
|
std::auto_ptr<C4PropList> temp(C4PropList::New()); // exception-safety
|
|
|
|
pComp->Value(mkParAdapt(*temp, rPar));
|
|
|
|
pStruct = temp.release();
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
|
|
|
|
template<typename T>
|
2011-03-26 22:59:35 +00:00
|
|
|
void C4Set<T>::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
bool fNaming = pComp->hasNaming();
|
|
|
|
if (pComp->isCompiler())
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
// Compiling: Empty previous
|
|
|
|
Clear();
|
|
|
|
// Read size (binary only)
|
|
|
|
uint32_t iSize;
|
2010-03-28 18:58:01 +00:00
|
|
|
if (!pComp->hasNaming()) pComp->Value(iSize);
|
2010-03-21 23:40:03 +00:00
|
|
|
// Read new
|
|
|
|
do
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
// No entries left to read?
|
2010-03-28 18:58:01 +00:00
|
|
|
if (!fNaming && !iSize--)
|
2010-03-21 23:40:03 +00:00
|
|
|
break;
|
|
|
|
// Read entries
|
|
|
|
try
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
T e;
|
2011-03-26 22:59:35 +00:00
|
|
|
// This could use the same technique StdArrayAdapt uses
|
|
|
|
// instead of hardcoding mkParAdapt here
|
|
|
|
pComp->Value(mkParAdapt(e, numbers));
|
2010-03-21 23:40:03 +00:00
|
|
|
Add(e);
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
|
|
|
catch (StdCompiler::NotFoundException *pEx)
|
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
// No value found: Stop reading loop
|
|
|
|
delete pEx;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-03-27 16:14:41 +00:00
|
|
|
while (pComp->Separator(StdCompiler::SEP_SEP));
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
else
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
// Write size (binary only)
|
2010-03-28 18:58:01 +00:00
|
|
|
if (!fNaming)
|
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
int32_t iSize = GetSize();
|
|
|
|
pComp->Value(iSize);
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
// Write all entries
|
|
|
|
const T * p = First();
|
|
|
|
while (p)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2011-03-26 22:59:35 +00:00
|
|
|
pComp->Value(mkParAdapt(*const_cast<T *>(p), numbers));
|
2010-03-21 23:40:03 +00:00
|
|
|
p = Next(p);
|
2011-03-27 16:14:41 +00:00
|
|
|
if (p) pComp->Separator(StdCompiler::SEP_SEP);
|
2010-03-21 23:40:03 +00:00
|
|
|
}
|
|
|
|
}
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
|
2011-03-26 22:59:35 +00:00
|
|
|
void C4Property::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
StdStrBuf s;
|
|
|
|
if (!pComp->isCompiler())
|
|
|
|
s = Key->GetData();
|
|
|
|
pComp->Value(s);
|
|
|
|
if (pComp->isCompiler())
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
if (Key) Key->DecRef();
|
|
|
|
Key = ::Strings.RegString(s);
|
|
|
|
Key->IncRef();
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-04-01 21:08:06 +00:00
|
|
|
pComp->Separator(StdCompiler::SEP_SET);
|
2011-03-26 22:59:35 +00:00
|
|
|
pComp->Value(mkParAdapt(Value, numbers));
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-04-03 19:06:29 +00:00
|
|
|
|
2011-05-05 20:27:22 +00:00
|
|
|
void C4PropList::AppendDataString(StdStrBuf * out, const char * delim, int depth)
|
2011-01-13 16:55:58 +00:00
|
|
|
{
|
|
|
|
StdStrBuf & DataString = *out;
|
2011-05-05 20:27:22 +00:00
|
|
|
if (depth > 2 && Properties.GetSize())
|
|
|
|
{
|
|
|
|
DataString.Append("...");
|
|
|
|
return;
|
|
|
|
}
|
2011-01-13 16:55:58 +00:00
|
|
|
const C4Property * p = Properties.First();
|
|
|
|
while (p)
|
|
|
|
{
|
|
|
|
DataString.Append(p->Key->GetData());
|
|
|
|
DataString.Append(" = ");
|
2011-05-05 20:27:22 +00:00
|
|
|
DataString.Append(p->Value.GetDataString(depth + 1));
|
2011-01-13 16:55:58 +00:00
|
|
|
p = Properties.Next(p);
|
|
|
|
if (p) DataString.Append(delim);
|
|
|
|
}
|
|
|
|
}
|
2009-04-03 19:06:29 +00:00
|
|
|
|
2011-01-12 22:43:05 +00:00
|
|
|
const char * C4PropList::GetName() const
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-03 19:06:29 +00:00
|
|
|
C4String * s = GetPropertyStr(P_Name);
|
|
|
|
if (!s) return "";
|
|
|
|
return s->GetCStr();
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-04-03 19:06:29 +00:00
|
|
|
|
|
|
|
void C4PropList::SetName(const char* NewName)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
|
|
|
if (!NewName)
|
2010-12-06 15:24:41 +00:00
|
|
|
ResetProperty(&Strings.P[P_Name]);
|
2009-04-03 19:06:29 +00:00
|
|
|
else
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-12-06 15:19:15 +00:00
|
|
|
SetProperty(P_Name, C4VString(NewName));
|
2009-04-03 19:06:29 +00:00
|
|
|
}
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-04-03 19:06:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2009-04-18 00:46:19 +00:00
|
|
|
C4Object * C4PropList::GetObject()
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-18 00:46:19 +00:00
|
|
|
if (prototype) return prototype->GetObject();
|
|
|
|
return 0;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-04-18 00:46:19 +00:00
|
|
|
|
2009-04-12 12:04:28 +00:00
|
|
|
C4Def * C4PropList::GetDef()
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-12 12:04:28 +00:00
|
|
|
if (prototype) return prototype->GetDef();
|
|
|
|
return 0;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-04-12 12:04:28 +00:00
|
|
|
|
2010-09-10 21:01:30 +00:00
|
|
|
C4Def const * C4PropList::GetDef() const
|
|
|
|
{
|
|
|
|
if (prototype) return prototype->GetDef();
|
|
|
|
return 0;
|
|
|
|
}
|
2009-04-12 12:04:28 +00:00
|
|
|
|
2010-03-21 23:40:03 +00:00
|
|
|
C4PropListNumbered * C4PropList::GetPropListNumbered()
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
if (prototype) return prototype->GetPropListNumbered();
|
|
|
|
return 0;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
|
2010-12-19 23:13:56 +00:00
|
|
|
C4Effect * C4PropList::GetEffect()
|
|
|
|
{
|
|
|
|
if (prototype) return prototype->GetEffect();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-04-12 12:04:28 +00:00
|
|
|
|
2009-05-19 22:12:11 +00:00
|
|
|
template<> template<>
|
|
|
|
unsigned int C4Set<C4Property>::Hash<C4String *>(C4String * e)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-07-15 18:26:53 +00:00
|
|
|
assert(e);
|
2009-05-19 22:12:11 +00:00
|
|
|
return e->Hash;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-05-19 22:12:11 +00:00
|
|
|
|
|
|
|
template<> template<>
|
|
|
|
bool C4Set<C4Property>::Equals<C4String *>(C4Property a, C4String * b)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-05-19 22:12:11 +00:00
|
|
|
return a.Key == b;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-05-19 22:12:11 +00:00
|
|
|
|
|
|
|
template<> template<>
|
|
|
|
unsigned int C4Set<C4Property>::Hash<C4Property>(C4Property p)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-05-19 22:12:11 +00:00
|
|
|
return p.Key->Hash;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-23 22:56:59 +00:00
|
|
|
|
2010-12-06 15:19:15 +00:00
|
|
|
bool C4PropList::GetPropertyByS(C4String * k, C4Value *pResult) const
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-23 22:56:59 +00:00
|
|
|
if (Properties.Has(k))
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-04-08 00:47:45 +00:00
|
|
|
*pResult = Properties.Get(k).Value;
|
2010-03-27 18:16:48 +00:00
|
|
|
return true;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-04-08 00:47:45 +00:00
|
|
|
else if(prototype)
|
2010-12-06 15:19:15 +00:00
|
|
|
return prototype->GetPropertyByS(k, pResult);
|
2010-04-08 00:47:45 +00:00
|
|
|
else
|
|
|
|
return false;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-27 18:16:48 +00:00
|
|
|
|
2010-09-10 21:01:30 +00:00
|
|
|
C4String * C4PropList::GetPropertyStr(C4PropertyName n) const
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-12-06 15:24:41 +00:00
|
|
|
C4String * k = &Strings.P[n];
|
2009-04-03 19:06:29 +00:00
|
|
|
if (Properties.Has(k))
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-03 19:06:29 +00:00
|
|
|
return Properties.Get(k).Value.getStr();
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-04-03 19:06:29 +00:00
|
|
|
if (prototype)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-03 19:06:29 +00:00
|
|
|
return prototype->GetPropertyStr(n);
|
|
|
|
}
|
2010-03-28 18:58:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2009-04-03 19:06:29 +00:00
|
|
|
|
2010-12-08 22:17:00 +00:00
|
|
|
C4PropertyName C4PropList::GetPropertyP(C4PropertyName n) const
|
|
|
|
{
|
|
|
|
C4String * k = &Strings.P[n];
|
|
|
|
if (Properties.Has(k))
|
|
|
|
{
|
|
|
|
C4String * v = Properties.Get(k).Value.getStr();
|
|
|
|
if (v >= &Strings.P[0] && v < &Strings.P[P_LAST])
|
|
|
|
return C4PropertyName(v - &Strings.P[0]);
|
|
|
|
return P_LAST;
|
|
|
|
}
|
|
|
|
if (prototype)
|
|
|
|
{
|
|
|
|
return prototype->GetPropertyP(n);
|
|
|
|
}
|
|
|
|
return P_LAST;
|
|
|
|
}
|
|
|
|
|
2010-09-10 21:01:30 +00:00
|
|
|
int32_t C4PropList::GetPropertyInt(C4PropertyName n) const
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-12-06 15:24:41 +00:00
|
|
|
C4String * k = &Strings.P[n];
|
2009-04-03 19:06:29 +00:00
|
|
|
if (Properties.Has(k))
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-03 19:06:29 +00:00
|
|
|
return Properties.Get(k).Value.getInt();
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-04-03 19:06:29 +00:00
|
|
|
if (prototype)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-03 19:06:29 +00:00
|
|
|
return prototype->GetPropertyInt(n);
|
|
|
|
}
|
2010-03-28 18:58:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2009-04-03 19:06:29 +00:00
|
|
|
|
2010-12-06 15:19:15 +00:00
|
|
|
void C4PropList::SetPropertyByS(C4String * k, const C4Value & to)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-09-08 12:54:39 +00:00
|
|
|
assert(!constant);
|
2010-12-06 15:24:41 +00:00
|
|
|
/*assert(Strings.Set.Has(k));*/
|
|
|
|
if (k == &Strings.P[P_Prototype] && to.GetType() == C4V_PropList)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-03 19:06:29 +00:00
|
|
|
prototype = to.GetData().PropList;
|
2010-03-19 00:21:54 +00:00
|
|
|
//return;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-05-19 22:12:11 +00:00
|
|
|
if (Properties.Has(k))
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-05-19 22:12:11 +00:00
|
|
|
Properties.Get(k).Value = to;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-05-19 22:12:11 +00:00
|
|
|
else
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-07-26 20:31:45 +00:00
|
|
|
C4Property p(k, to);
|
2009-05-19 22:12:11 +00:00
|
|
|
Properties.Add(p);
|
2009-04-03 19:06:29 +00:00
|
|
|
}
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-04-03 19:06:29 +00:00
|
|
|
|
|
|
|
void C4PropList::ResetProperty(C4String * k)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-03 19:06:29 +00:00
|
|
|
Properties.Remove(k);
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-04-18 00:46:19 +00:00
|
|
|
|
|
|
|
template<> template<>
|
2010-03-21 23:40:03 +00:00
|
|
|
unsigned int C4Set<C4PropListNumbered *>::Hash<int>(int e)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-18 00:46:19 +00:00
|
|
|
unsigned int hash = 4, tmp;
|
|
|
|
hash += e >> 16;
|
2010-03-27 16:05:02 +00:00
|
|
|
tmp = ((e & 0xffff) << 11) ^ hash;
|
|
|
|
hash = (hash << 16) ^ tmp;
|
|
|
|
hash += hash >> 11;
|
2009-04-18 00:46:19 +00:00
|
|
|
hash ^= hash << 3;
|
|
|
|
hash += hash >> 5;
|
|
|
|
hash ^= hash << 4;
|
|
|
|
hash += hash >> 17;
|
|
|
|
hash ^= hash << 25;
|
|
|
|
hash += hash >> 6;
|
|
|
|
return hash;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-04-18 00:46:19 +00:00
|
|
|
|
|
|
|
template<> template<>
|
2010-03-21 23:40:03 +00:00
|
|
|
unsigned int C4Set<C4PropListNumbered *>::Hash<C4PropList *>(C4PropList * e)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
return Hash(e->GetPropListNumbered()->Number);
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
|
|
|
|
template<> template<>
|
|
|
|
unsigned int C4Set<C4PropListNumbered *>::Hash<C4PropListNumbered *>(C4PropListNumbered * e)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-18 00:46:19 +00:00
|
|
|
return Hash(e->Number);
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2009-04-18 00:46:19 +00:00
|
|
|
|
|
|
|
template<> template<>
|
2010-03-21 23:40:03 +00:00
|
|
|
bool C4Set<C4PropListNumbered *>::Equals<int>(C4PropListNumbered * a, int b)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2009-04-18 00:46:19 +00:00
|
|
|
return a->Number == b;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2010-03-21 23:40:03 +00:00
|
|
|
|
|
|
|
template<> template<>
|
|
|
|
bool C4Set<C4PropListNumbered *>::Equals<C4PropList *>(C4PropListNumbered * a, C4PropList * b)
|
2010-03-28 18:58:01 +00:00
|
|
|
{
|
2010-03-21 23:40:03 +00:00
|
|
|
return a == b;
|
2010-03-28 18:58:01 +00:00
|
|
|
}
|
2011-02-06 21:30:31 +00:00
|
|
|
|
|
|
|
template<> template<>
|
|
|
|
unsigned int C4Set<C4PropList *>::Hash<C4PropList *>(C4PropList * e)
|
|
|
|
{
|
|
|
|
return C4Set<C4PropListNumbered *>::Hash(static_cast<int>(reinterpret_cast<intptr_t>(e)));
|
|
|
|
}
|