//===========================================================================// // File: Attribute.hpp // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 08/25/97 JMA Infrastructure changes // // 08/25/97 ECH Infrastructure changes // //---------------------------------------------------------------------------// // Copyright (C) 1994-97, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #pragma once #include "Adept.hpp" #include "Entity.hpp" namespace Adept { //########################################################################## //######################## AttributeEntry ############################ //########################################################################## class AttributeEntry: public Stuff::Plug { friend class AttributeTable; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: AttributeEntry( Entity::AttributeID attribute_ID, const char *attribute_name, RegisteredClass::ClassID attribute_type, Entity::AttributePointer attribute_address ); virtual ~AttributeEntry(); void TestInstance() const {} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: virtual void SetValue( Entity *entity, void *new_value ); virtual void GetValue( Entity *entity, void *new_value ); virtual bool GetChangedValue( Entity *entity, void *new_value, void *current_value, Stuff::Scalar difference_threshold ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: Entity::AttributeID attributeID; Stuff::MString attributeName; RegisteredClass::ClassID attributeType; protected: Entity::AttributePointer attributeAddress; }; //########################################################################## //###################### DirectAttributeEntryOf ###################### //########################################################################## template class DirectAttributeEntryOf: public AttributeEntry { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: DirectAttributeEntryOf( Entity::AttributeID attribute_ID, const char *attribute_name, Entity::AttributePointer attribute_address ); ~DirectAttributeEntryOf(); void TestInstance() const {} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: void SetValue( Entity *entity, void *new_value ); bool GetChangedValue( Entity *entity, void *new_value, void *current_value, Stuff::Scalar difference_threshold ); void GetValue( Entity *entity, void *new_value ); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // template DirectAttributeEntryOf::DirectAttributeEntryOf( Entity::AttributeID attribute_ID, const char *attribute_name, Entity::AttributePointer attribute_address ): AttributeEntry( attribute_ID, attribute_name, ID, attribute_address ) { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // template DirectAttributeEntryOf::~DirectAttributeEntryOf() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // template void DirectAttributeEntryOf::SetValue( Entity *entity, void *new_value ) { Check_Object(entity); Check_Pointer(new_value); Verify(attributeAddress != NULL); void *pointer = &(entity->*attributeAddress); *Cast_Pointer(T*,pointer) = *Cast_Pointer(T*,new_value); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // template void DirectAttributeEntryOf::GetValue( Entity *entity, void *new_value ) { Check_Object(entity); Check_Pointer(new_value); Verify(attributeAddress != NULL); void *pointer = &(entity->*attributeAddress); *Cast_Pointer(T*,new_value) = *Cast_Pointer(T*,pointer); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // template bool DirectAttributeEntryOf::GetChangedValue( Entity *entity, void *new_value, void *current_value, Stuff::Scalar diff_threshold ) { Check_Object(entity); Check_Pointer(new_value); Check_Pointer(current_value); Verify(attributeAddress != NULL); void *pointer = &(entity->*attributeAddress); if ( !Close_Enough( *Cast_Pointer(T*, pointer), *Cast_Pointer(T*, current_value), diff_threshold ) ) { *Cast_Pointer(T*, new_value) = *Cast_Pointer(T*, pointer); return true; } return false; } //########################################################################## //##################### IndirectAttributeEntryOf ##################### //########################################################################## template class IndirectAttributeEntryOf: public AttributeEntry { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: IndirectAttributeEntryOf( Entity::AttributeID attribute_ID, const char *attribute_name, Entity::AttributePointer attribute_address ); ~IndirectAttributeEntryOf(); void TestInstance() const {} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: void SetValue( Entity *entity, void *new_value ); bool GetChangedValue( Entity *entity, void *new_value, void *current_value, Stuff::Scalar difference_threshold ); void GetValue( Entity *entity, void *new_value ); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // template IndirectAttributeEntryOf::IndirectAttributeEntryOf( Entity::AttributeID attribute_ID, const char *attribute_name, Entity::AttributePointer attribute_address ): AttributeEntry( attribute_ID, attribute_name, ID, attribute_address ) { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // template IndirectAttributeEntryOf::~IndirectAttributeEntryOf() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // template void IndirectAttributeEntryOf::SetValue( Entity *entity, void *new_value ) { Check_Object(entity); Check_Pointer(new_value); Verify(attributeAddress != NULL); void *pointer = &(entity->*attributeAddress); **Cast_Pointer(T**, pointer) = *Cast_Pointer(T*, new_value); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // template void IndirectAttributeEntryOf::GetValue( Entity *entity, void *new_value ) { Check_Object(entity); Check_Pointer(new_value); Verify(attributeAddress != NULL); void *pointer = &(entity->*attributeAddress); *Cast_Pointer(T*, new_value) = **Cast_Pointer(T**, pointer); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // template bool IndirectAttributeEntryOf::GetChangedValue( Entity *entity, void *new_value, void *current_value, Stuff::Scalar diff_threshold ) { Check_Object(entity); Check_Pointer(new_value); Check_Pointer(current_value); Verify(attributeAddress != NULL); void *pointer = &(entity->*attributeAddress); if ( !Close_Enough( **Cast_Pointer(T**, pointer), *Cast_Pointer(T*, current_value), diff_threshold ) ) { *Cast_Pointer(T*, new_value) = **Cast_Pointer(T**, pointer); return true; } return false; } //########################################################################## //################### IndirectStateAttributeEntry #################### //########################################################################## class IndirectStateAttributeEntry: public AttributeEntry { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: IndirectStateAttributeEntry( Entity::AttributeID attribute_ID, const char *attribute_name, RegisteredClass::ClassID attribute_type, Entity::AttributePointer attribute_address ); ~IndirectStateAttributeEntry(); void TestInstance() const {} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: void GetValue( Entity *entity, void *new_value ); }; //########################################################################## //#################### DirectStateAttributeEntry ##################### //########################################################################## class DirectStateAttributeEntry: public AttributeEntry { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: DirectStateAttributeEntry( Entity::AttributeID attribute_ID, const char *attribute_name, RegisteredClass::ClassID attribute_type, Entity::AttributePointer attribute_address ); ~DirectStateAttributeEntry(); void TestInstance() const {} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: void GetValue( Entity *entity, void *new_value ); }; //########################################################################## //######################## AttributeTable ############################ //########################################################################## class AttributeTable #if defined(_ARMOR) : public Stuff::Signature #endif { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: AttributeTable(); ~AttributeTable(); void TestInstance() {} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // public: void CopyFrom(AttributeTable *attribute_table); void AddAttributeEntry(AttributeEntry *attribute_entry); AttributeEntry* GetAttributeEntry(Entity::AttributeID attribute_ID); AttributeEntry* GetAttributeEntry(const char *attribute_name); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // private: Stuff::TableOf attributesByID; Stuff::TableOf attributesByName; #if defined(_ARMOR) bool verifyTable; void VerifyTable(); #endif }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // inline AttributeEntry* AttributeTable::GetAttributeEntry(Entity::AttributeID attribute_ID) { #if defined(_ARMOR) VerifyTable(); #endif Stuff::TableIteratorOf iterator(&attributesByID); return iterator.GetNth(attribute_ID); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // inline AttributeEntry* AttributeTable::GetAttributeEntry(const char *attribute_name) { #if defined(_ARMOR) VerifyTable(); #endif return attributesByName.Find(attribute_name); } }