#ifndef _Value_h_ #define _Value_h_ ////////////////////////////////////////////////////////////////////////////// // // NameSpaceInfo // ////////////////////////////////////////////////////////////////////////////// class INameSpace; class INameSpaceInfo : public IObject { public: virtual INameSpace* GetNameSpace() = 0; virtual const ZString& GetName() = 0; }; ////////////////////////////////////////////////////////////////////////////// // // Binary MDL Files // ////////////////////////////////////////////////////////////////////////////// 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; ////////////////////////////////////////////////////////////////////////////// // // Forward Declarations // ////////////////////////////////////////////////////////////////////////////// class ValueList; ////////////////////////////////////////////////////////////////////////////// // // Value headers // ////////////////////////////////////////////////////////////////////////////// class Value : public IObject { private: // vtable // 1 DWORD // m_count // 1 DWORD TVector > m_pchildren; // 2 DWORDS TList m_listParents; // 3 DWORDS TRef m_pnsInfo; // 1 DWORD bool m_bChanged; // 1 DWORD virtual void InternalUpdate(); virtual void Evaluate(); virtual TRef 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 /* #define EnableDebugString ZString m_strDebug; virtual void UpdateDebugString(); */ #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(); // // NameSpace // void SetNameSpaceInfo(INameSpaceInfo* pnsInfo); // // MDL Binary Files // private: void WriteInternal(IMDLBinaryFile* pfile); public: virtual void WriteChildren(IMDLBinaryFile* pfile); virtual void Write(IMDLBinaryFile* pfile); virtual void FillImportTable(IMDLBinaryFile* pfile); // // MDL Text Files // 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) {} ////////////////////////////////////////////////////////////////////////////// // // Value List // ////////////////////////////////////////////////////////////////////////////// class ValueList : public Value { public: class Site { private: virtual bool RemoveValue(Value* pvalue) = 0; friend class ValueList; }; private: Site* m_psite; TList > m_list; TList >::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); // // Value members // bool DoFold(); int GetNodeCount(); void Write(IMDLBinaryFile* pmdlFile); void FillImportTable(IMDLBinaryFile* pfile); }; ////////////////////////////////////////////////////////////////////////////// // // Static Value // ////////////////////////////////////////////////////////////////////////////// template class TStaticValue : public Value { private: StaticType m_value; protected: DefineSubclassMembers(TStaticValue); StaticType& GetValueInternal() { return m_value; } TStaticValue() { } public: DefineCastMember(TStaticValue); TStaticValue(const StaticType& value) : m_value(value) { } TRef > 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); } }; ////////////////////////////////////////////////////////////////////////////// // // Constant Static Value // ////////////////////////////////////////////////////////////////////////////// template class TModifiableValue : public TStaticValue { public: TModifiableValue(const StaticType& value) : TStaticValue(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(); } }; ////////////////////////////////////////////////////////////////////////////// // // Wrap Value // ////////////////////////////////////////////////////////////////////////////// template class TWrapValue : public TStaticValue { protected: // // Value members // void Evaluate() { GetValueInternal() = GetWrappedValue()->GetValue(); } public: TWrapValue(TStaticValue* pvalue) : TStaticValue(pvalue) { } void SetWrappedValue(TStaticValue* pvalue) { SetChild(0, pvalue); } TStaticValue* GetWrappedValue() { return TStaticValue::Cast(GetChild(0)); } }; ////////////////////////////////////////////////////////////////////////////// // // String Value // ////////////////////////////////////////////////////////////////////////////// ZString GetString(int indent, const ZString& str); void Write(IMDLBinaryFile* pmdlFile, const ZString& value); ZString GetFunctionName(const ZString& value); typedef TStaticValue StringValue; class ModifiableStringName { public: static ZString GetName() { return "ModifiableString"; } }; typedef TModifiableValue ModifiableString; ////////////////////////////////////////////////////////////////////////////// // // Color Value // ////////////////////////////////////////////////////////////////////////////// ZString GetString(int indent, const Color& color); void Write(IMDLBinaryFile* pmdlFile, const Color& color); ZString GetFunctionName(const Color& value); typedef TStaticValue ColorValue; class ModifiableColorName { public: static ZString GetName() { return "ModifiableColor"; } }; typedef TModifiableValue ModifiableColorValue; ////////////////////////////////////////////////////////////////////////////// // // Point Value // ////////////////////////////////////////////////////////////////////////////// ZString GetString(int indent, const Point& vec); void Write(IMDLBinaryFile* pmdlFile, const Point& value); ZString GetFunctionName(const Point& value); typedef TStaticValue PointValue; class ModifiablePointName { public: static ZString GetName() { return "ModifiablePoint"; } }; typedef TModifiableValue ModifiablePointValue; ////////////////////////////////////////////////////////////////////////////// // // Rect Value // ////////////////////////////////////////////////////////////////////////////// ZString GetString(int indent, const Rect& vec); void Write(IMDLBinaryFile* pmdlFile, const Rect& value); ZString GetFunctionName(const Rect& value); typedef TStaticValue RectValue; class ModifiableRectName { public: static ZString GetName() { return "ModifiableRect"; } }; typedef TModifiableValue ModifiableRectValue; typedef TWrapValue WrapRectValue; ////////////////////////////////////////////////////////////////////////////// // // Orientation Value // ////////////////////////////////////////////////////////////////////////////// ZString GetString(int indent, const Orientation& orient); void Write(IMDLBinaryFile* pmdlFile, const Orientation& value); ZString GetFunctionName(const Orientation& value); typedef TStaticValue OrientationValue; class ModifiableOrientationName { public: static ZString GetName() { return "ModifiableOrientation"; } }; typedef TModifiableValue ModifiableOrientationValue; ////////////////////////////////////////////////////////////////////////////// // // Vector Value // ////////////////////////////////////////////////////////////////////////////// ZString GetString(int indent, const Vector& vec); void Write(IMDLBinaryFile* pmdlFile, const Vector& value); ZString GetFunctionName(const Vector& value); typedef TStaticValue VectorValue; class ModifiableVectorName { public: static ZString GetName() { return "ModifiableVector"; } }; typedef TModifiableValue ModifiableVectorValue; ////////////////////////////////////////////////////////////////////////////// // // Number Value // ////////////////////////////////////////////////////////////////////////////// ZString GetString(int indent, float value); void Write(IMDLBinaryFile* pmdlFile, float value); ZString GetFunctionName(float value); typedef TStaticValue Number; class ModifiableNumberName { public: static ZString GetName() { return "ModifiableNumber"; } }; typedef TModifiableValue ModifiableNumber; typedef TWrapValue WrapNumber; TRef Subtract(Number*, Number*); TRef Add(Number*, Number*); TRef Multiply(Number*, Number*); TRef Divide(Number*, Number*); TRef Sin(Number*); TRef Cos(Number*); TRef Or(Number*, Number*); TRef And(Number*, Number*); TRef XOr(Number*, Number*); TRef Mod(Number*, Number*); TRef Min(Number*, Number*); TRef Max(Number*, Number*); ////////////////////////////////////////////////////////////////////////////// // // Boolean Value // ////////////////////////////////////////////////////////////////////////////// ZString GetString(int indent, bool value); void Write(IMDLBinaryFile* pmdlFile, bool value); ZString GetFunctionName(bool value); typedef TStaticValue Boolean; class ModifiableBooleanName { public: static ZString GetName() { return "ModifiableBoolean"; } }; typedef TModifiableValue ModifiableBoolean; TRef And(Boolean*, Boolean*); TRef Or(Boolean*, Boolean*); TRef Not(Boolean*); ////////////////////////////////////////////////////////////////////////////// // // List of statics as a Value // ////////////////////////////////////////////////////////////////////////////// template class TListValue : public Value { public: typedef TList 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) + "]"; } }; ////////////////////////////////////////////////////////////////////////////// // // Casts // ////////////////////////////////////////////////////////////////////////////// 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(); } ////////////////////////////////////////////////////////////////////////////// // // Object List // ////////////////////////////////////////////////////////////////////////////// typedef TPointerListObject IObjectList; ////////////////////////////////////////////////////////////////////////////// // // Object Lookup Table // ////////////////////////////////////////////////////////////////////////////// template class DoSetIndex { public: static SetIndex(Type* pobject, int index) { pobject->SetIndex(index); } }; class DontSetIndex { public: static SetIndex(void* pobject, int index) { } }; template class TLookup { public: static Parse(IObjectList* plist, int offset, TVector >& m_v) { int maxIndex = offset; plist->GetFirst(); while (plist->GetCurrent() != NULL) { TRef ppair; CastTo(ppair, plist->GetCurrent()); TRef 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 ppair; CastTo(ppair, plist->GetCurrent()); TRef pindex; CastTo(pindex, ppair->GetFirst() ); TRef pobject = (Type*)(ppair->GetSecond()); int index = (int)pindex->GetValue() + offset; m_v.Set(index, pobject); SetIndexType::SetIndex(pobject, index); plist->GetNext(); } } }; #endif