#ifndef _Value_h_
#define _Value_h_
class INameSpace;
class INameSpaceInfo : public IObject {
public:
virtual INameSpace* GetNameSpace() = 0;
virtual const ZString& GetName() = 0;
};
class IMDLBinaryFile : public IObject {
public:
virtual void AddImport(const ZString& str) = 0;
virtual bool AddImport(INameSpaceInfo* pnsInfo) = 0;
virtual void WriteString(const ZString& str) = 0;
virtual void WriteReference(const ZString& str) = 0;
virtual void WriteApply() = 0;
virtual ZFile* WriteBinary() = 0;
virtual void WriteList(DWORD count) = 0;
virtual void WriteNumber(float value) = 0;
virtual void WriteBoolean(bool value) = 0;
virtual void WritePair() = 0;
virtual void WriteEnd() = 0;
};
#define MDLMagic ((DWORD)0xdebadf00)
#define MDLVersion ((DWORD)0x00010000)
const DWORD ObjectEnd = 0;
const DWORD ObjectFloat = 1;
const DWORD ObjectString = 2;
const DWORD ObjectTrue = 3;
const DWORD ObjectFalse = 4;
const DWORD ObjectList = 5;
const DWORD ObjectApply = 6;
const DWORD ObjectBinary = 7;
const DWORD ObjectReference = 8;
const DWORD ObjectImport = 9;
const DWORD ObjectPair = 10;
class ValueList;
class Value : public IObject {
private:
TVector<TRef<Value> > m_pchildren; TList<Value*> m_listParents; TRef<INameSpaceInfo> m_pnsInfo; bool m_bChanged; virtual void InternalUpdate();
virtual void Evaluate();
virtual TRef<Value> Fold();
void RemoveParent(Value* pvalue);
void AddParent(Value* pvalue);
protected:
Value();
Value(Value*);
Value(Value*, Value*);
Value(Value*, Value*, Value*);
Value(Value*, Value*, Value*, Value*);
#ifdef _DEBUG
#endif
virtual void ChildChanged(Value* pvalue, Value* pvalueNew);
void Changed();
void AddChild(Value* pchild);
void SetChild(int index, Value* m_pvalueChild);
Value* GetChild(int index) const { return m_pchildren[index]; }
int GetChildCount() const { return m_pchildren.GetCount(); }
public:
virtual ~Value();
void ChangeTo(Value* pvalue);
bool HasChanged() { return m_bChanged; }
void Update();
virtual bool DoFold();
virtual bool IsConstant();
virtual int GetNodeCount();
void SetNameSpaceInfo(INameSpaceInfo* pnsInfo);
private:
void WriteInternal(IMDLBinaryFile* pfile);
public:
virtual void WriteChildren(IMDLBinaryFile* pfile);
virtual void Write(IMDLBinaryFile* pfile);
virtual void FillImportTable(IMDLBinaryFile* pfile);
static ZString Indent(int indent);
virtual ZString GetFunctionName();
virtual ZString GetString(int indent);
ZString GetChildString(int indent);
friend class ValueList;
};
#define DefineSubclassMembers(Type) \
Type(Value* pvalue0) : Value(pvalue0) {} \
Type(Value* pvalue0, Value* pvalue1) : Value(pvalue0, pvalue1) {} \
Type(Value* pvalue0, Value* pvalue1, Value* value2) : Value(pvalue0, pvalue1, value2) {} \
Type(Value* pvalue0, Value* pvalue1, Value* value2, Value* pvalue3) : Value(pvalue0, pvalue1, value2, pvalue3) {}
class ValueList : public Value {
public:
class Site {
private:
virtual bool RemoveValue(Value* pvalue) = 0;
friend class ValueList;
};
private:
Site* m_psite;
TList<TRef<Value> > m_list;
TList<TRef<Value> >::Iterator m_iter;
virtual void InternalUpdate();
virtual void ChildChanged(Value* pvalue, Value* pvalueNew);
public:
DefineCastMember(ValueList);
ValueList(Site* psite);
~ValueList();
void PushFront(Value* pvalue);
void PushEnd(Value* pvalue);
void Remove(Value* pvalue);
int GetCount();
Value* GetFirst();
Value* GetLast();
Value* GetNext();
Value* GetPrevious();
Value* GetCurrent();
Value* RemoveCurrent();
bool IsFirst();
bool IsLast();
ZString GetString(int indent);
bool DoFold();
int GetNodeCount();
void Write(IMDLBinaryFile* pmdlFile);
void FillImportTable(IMDLBinaryFile* pfile);
};
template<class StaticType>
class TStaticValue : public Value {
private:
StaticType m_value;
protected:
DefineSubclassMembers(TStaticValue);
StaticType& GetValueInternal()
{
return m_value;
}
TStaticValue()
{
}
public:
DefineCastMember(TStaticValue<StaticType>);
TStaticValue(const StaticType& value) :
m_value(value)
{
}
TRef<TStaticValue<StaticType> > MakeConstant()
{
return new TStaticValue(m_value);
}
const StaticType& GetValue()
{
Update();
return m_value;
}
bool IsConstant()
{
return true;
}
ZString GetString(int indent)
{
return ::GetString(indent, m_value);
}
void Write(IMDLBinaryFile* pmdlFile)
{
::Write(pmdlFile, m_value);
}
ZString GetFunctionName()
{
return ::GetFunctionName(m_value);
}
};
template<class StaticType, class FunctionName>
class TModifiableValue : public TStaticValue<StaticType> {
public:
TModifiableValue(const StaticType& value) :
TStaticValue<StaticType>(value)
{
}
void SetValue(const StaticType& value)
{
GetValueInternal() = value;
Changed();
}
bool IsConstant()
{
return false;
}
ZString GetFunctionName()
{
return FunctionName::GetName();
}
ZString GetString(int indent)
{
return FunctionName::GetName() + "(" + ::GetString(indent, GetValue()) +")";
}
void Write(IMDLBinaryFile* pmdlFile)
{
::Write(pmdlFile, GetValue());
pmdlFile->WriteReference(FunctionName::GetName());
pmdlFile->WriteApply();
}
};
template<class StaticType>
class TWrapValue : public TStaticValue<StaticType> {
protected:
void Evaluate()
{
GetValueInternal() = GetWrappedValue()->GetValue();
}
public:
TWrapValue(TStaticValue<StaticType>* pvalue) :
TStaticValue<StaticType>(pvalue)
{
}
void SetWrappedValue(TStaticValue<StaticType>* pvalue) { SetChild(0, pvalue); }
TStaticValue<StaticType>* GetWrappedValue() { return TStaticValue<StaticType>::Cast(GetChild(0)); }
};
ZString GetString(int indent, const ZString& str);
void Write(IMDLBinaryFile* pmdlFile, const ZString& value);
ZString GetFunctionName(const ZString& value);
typedef TStaticValue<ZString> StringValue;
class ModifiableStringName {
public:
static ZString GetName() { return "ModifiableString"; }
};
typedef TModifiableValue<ZString, ModifiableStringName> ModifiableString;
ZString GetString(int indent, const Color& color);
void Write(IMDLBinaryFile* pmdlFile, const Color& color);
ZString GetFunctionName(const Color& value);
typedef TStaticValue<Color> ColorValue;
class ModifiableColorName {
public:
static ZString GetName() { return "ModifiableColor"; }
};
typedef TModifiableValue<Color, ModifiableColorName> ModifiableColorValue;
ZString GetString(int indent, const Point& vec);
void Write(IMDLBinaryFile* pmdlFile, const Point& value);
ZString GetFunctionName(const Point& value);
typedef TStaticValue<Point> PointValue;
class ModifiablePointName {
public:
static ZString GetName() { return "ModifiablePoint"; }
};
typedef TModifiableValue<Point, ModifiablePointName> ModifiablePointValue;
ZString GetString(int indent, const Rect& vec);
void Write(IMDLBinaryFile* pmdlFile, const Rect& value);
ZString GetFunctionName(const Rect& value);
typedef TStaticValue<Rect> RectValue;
class ModifiableRectName {
public:
static ZString GetName() { return "ModifiableRect"; }
};
typedef TModifiableValue<Rect, ModifiableRectName> ModifiableRectValue;
typedef TWrapValue<Rect> WrapRectValue;
ZString GetString(int indent, const Orientation& orient);
void Write(IMDLBinaryFile* pmdlFile, const Orientation& value);
ZString GetFunctionName(const Orientation& value);
typedef TStaticValue<Orientation> OrientationValue;
class ModifiableOrientationName {
public:
static ZString GetName() { return "ModifiableOrientation"; }
};
typedef TModifiableValue<Orientation, ModifiableOrientationName> ModifiableOrientationValue;
ZString GetString(int indent, const Vector& vec);
void Write(IMDLBinaryFile* pmdlFile, const Vector& value);
ZString GetFunctionName(const Vector& value);
typedef TStaticValue<Vector> VectorValue;
class ModifiableVectorName {
public:
static ZString GetName() { return "ModifiableVector"; }
};
typedef TModifiableValue<Vector, ModifiableVectorName> ModifiableVectorValue;
ZString GetString(int indent, float value);
void Write(IMDLBinaryFile* pmdlFile, float value);
ZString GetFunctionName(float value);
typedef TStaticValue<float> Number;
class ModifiableNumberName {
public:
static ZString GetName() { return "ModifiableNumber"; }
};
typedef TModifiableValue<float, ModifiableNumberName> ModifiableNumber;
typedef TWrapValue<float> WrapNumber;
TRef<Number> Subtract(Number*, Number*);
TRef<Number> Add(Number*, Number*);
TRef<Number> Multiply(Number*, Number*);
TRef<Number> Divide(Number*, Number*);
TRef<Number> Sin(Number*);
TRef<Number> Cos(Number*);
TRef<Number> Or(Number*, Number*);
TRef<Number> And(Number*, Number*);
TRef<Number> XOr(Number*, Number*);
TRef<Number> Mod(Number*, Number*);
TRef<Number> Min(Number*, Number*);
TRef<Number> Max(Number*, Number*);
ZString GetString(int indent, bool value);
void Write(IMDLBinaryFile* pmdlFile, bool value);
ZString GetFunctionName(bool value);
typedef TStaticValue<bool> Boolean;
class ModifiableBooleanName {
public:
static ZString GetName() { return "ModifiableBoolean"; }
};
typedef TModifiableValue<bool, ModifiableBooleanName> ModifiableBoolean;
TRef<Boolean> And(Boolean*, Boolean*);
TRef<Boolean> Or(Boolean*, Boolean*);
TRef<Boolean> Not(Boolean*);
template<class Type>
class TListValue : public Value {
public:
typedef TList<Type, DefaultNoEquals> List;
private:
List m_list;
public:
List& GetList() { return m_list; }
ZString GetFunctionName()
{
return ZString();
}
ZString GetString(int indent)
{
ZString str = "[\n";
List::Iterator iter(m_list);
while (!iter.End()) {
str += Value::Indent(indent + 1) + ::GetString(indent, iter.Value());
iter.Next();
if (!iter.End()) {
str += ",\n";
} else {
str += "\n";
}
}
return str + Value::Indent(indent) + "]";
}
};
inline ZString GetString(IObject* pobject)
{
return StringValue::Cast(pobject)->GetValue();
}
inline float GetNumber(IObject* pobject)
{
return Number::Cast(pobject)->GetValue();
}
inline bool GetBoolean(IObject* pobject)
{
return Boolean::Cast(pobject)->GetValue();
}
inline Color GetColor(IObject* pobject)
{
return ColorValue::Cast(pobject)->GetValue();
}
inline Vector GetVector(IObject* pobject)
{
return VectorValue::Cast(pobject)->GetValue();
}
typedef TPointerListObject<IObject> IObjectList;
template<class Type>
class DoSetIndex {
public:
static void SetIndex(Type* pobject, int index)
{
pobject->SetIndex(index);
}
};
class DontSetIndex {
public:
static void SetIndex(void* pobject, int index)
{
}
};
template<class Type, class SetIndexType = DontSetIndex>
class TLookup {
public:
static void Parse(IObjectList* plist, int offset, TVector<TRef<Type> >& m_v)
{
int maxIndex = offset;
plist->GetFirst();
while (plist->GetCurrent() != NULL) {
TRef<IObjectPair> ppair; CastTo(ppair, plist->GetCurrent());
TRef<Number> pindex; CastTo(pindex, ppair->GetFirst() );
int index = (int)pindex->GetValue() + offset;
if (index > maxIndex) {
maxIndex = index;
}
plist->GetNext();
}
m_v.SetCount(maxIndex + 1);
plist->GetFirst();
while (plist->GetCurrent() != NULL) {
TRef<IObjectPair> ppair; CastTo(ppair, plist->GetCurrent());
TRef<Number> pindex; CastTo(pindex, ppair->GetFirst() );
TRef<Type> pobject = (Type*)(ppair->GetSecond());
int index = (int)pindex->GetValue() + offset;
m_v.Set(index, pobject);
SetIndexType::SetIndex(pobject, index);
plist->GetNext();
}
}
};
#endif