#include "munga.h" #pragma hdrstop #include "controls.h" #include "app.h" #if defined(DEBUG) # define Test_Tell(n) DEBUG_STREAM << n #else # define Test_Tell(n) #endif //############################################################################ //####################### ControlsInstance ############################# //############################################################################ ControlsInstance::ControlsInstance( ClassID class_ID, ModeMask mode_mask, Plug *dependant ): Node(class_ID), dependantPlug(this) { Check_Pointer(this); modeMask = mode_mask; dependantPlug.Add(dependant); Check_Fpu(); } ControlsInstance::~ControlsInstance() { Check(this); Check_Fpu(); } void ControlsInstance::Update(void *) { Fail("ControlsInstance::Update not overridden!"); } // //############################################################################# //############################################################################# // void ControlsInstance::ReleaseLinkHandler( Socket*, Plug* ) { Unregister_Object(this); delete this; Check_Fpu(); } //############################################################################ //######################### ControlsMappingGroup ############################# //############################################################################ // // The ControlsMappingGroup object maintains a group of ControlInstances. // // ControlsMappingGroup.Update() will call ControlsInstance.Update() // for each instance in the group. // ControlsMappingGroup::ControlsMappingGroup(): Node(ControlsMappingGroup::ControlsMappingGroupClassID), instanceList(this) { Check_Pointer(this); Check_Fpu(); } ControlsMappingGroup::~ControlsMappingGroup() { Check(this); Remove(0); // remove all mappings Check_Fpu(); } void ControlsMappingGroup::Remove(ModeMask mode_mask) { Check(this); ChainIteratorOf i(instanceList); ControlsInstance *controls_instance; while ((controls_instance=i.ReadAndNext()) != NULL) { Check(controls_instance); //--------------------------------------------- // Remove mapping bit(s) //--------------------------------------------- controls_instance->modeMask &= ~mode_mask; //--------------------------------------------- // If no bits left, delete mapping //--------------------------------------------- if (controls_instance->modeMask == (ModeMask)0) { Unregister_Object(controls_instance); delete controls_instance; } } Check_Fpu(); } void ControlsMappingGroup::Update(void *data_source, ModeMask mode_mask) { Check(this); Check_Pointer(data_source); ChainIteratorOf i(instanceList); ControlsInstance *controls_instance; while ((controls_instance=i.ReadAndNext()) != NULL) { //------------------------------------------------ // Process only if at least one mode bit matches //------------------------------------------------ Check(controls_instance); if (controls_instance->modeMask & mode_mask) { controls_instance->Update(data_source); } } Check_Fpu(); } Logical ControlsMappingGroup::CurrentFilterStatus(ModeMask mode_mask) { Check(this); ChainIteratorOf i(instanceList); ControlsInstance *controls_instance; while ((controls_instance=i.ReadAndNext()) != NULL) { Check(controls_instance); if (controls_instance->modeMask & mode_mask) { Check_Fpu(); return True; } } Check_Fpu(); return False; } //############################################################################ //########################### ControlsManager ################################ //############################################################################ //--------------------------------------------------------------------------- // Class derivation //--------------------------------------------------------------------------- Derivation* ControlsManager::GetClassDerivations() { static Derivation classDerivations(Receiver::GetClassDerivations(), "ControlsManager"); return &classDerivations; } unsigned int ControlsManager::nextOwnerID=0; ControlsManager *ControlsManager::headControlsManager = NULL; // //############################################################################ // ControlsManager // // Creator method //---------------------------------------------------------------------------- // Enter: virtualDataPtr //############################################################################ // ControlsManager::ControlsManager( ClassID class_ID, SharedData &shared_data ): Receiver( class_ID, shared_data ) { activeDestination = NULL; activeReceiver = NULL; activeMessageID = (Receiver::MessageID) 0; activeDependant = NULL; //---------------------------------------------------- // Add this object to the chain //---------------------------------------------------- nextControlsManager = headControlsManager; headControlsManager = this; Check_Fpu(); } // //############################################################################ // ~ControlsManager // // Destructor method //############################################################################ // ControlsManager::~ControlsManager() { //---------------------------------------------------- // Unlink this object from the chain //---------------------------------------------------- ControlsManager *controls_manager, *previous_controls_manager(NULL); // // Search for 'this' in the chain // for( controls_manager = headControlsManager; controls_manager != NULL; controls_manager = controls_manager->nextControlsManager ) { if (controls_manager == this) { // // Found! head of list? // if (previous_controls_manager == NULL) { headControlsManager = nextControlsManager; } // // Not head, remove from chain // else { previous_controls_manager->nextControlsManager = nextControlsManager; } break; } // // Keep track of 'previous' object // previous_controls_manager = controls_manager; } Check_Fpu(); } void ControlsManager::Remove(ModeMask /*mode_mask*/) { Fail("ControlsManager::Remove should not be called!\n"); } void ControlsManager::Execute() { Fail("ControlsManager::Execute should not be called!\n"); } void ControlsManager::StartMappableButtonsConfigure( void *active_direct_target, Receiver *target, Plug *dependant, Receiver::MessageID active_message_id, ModeMask remove_mode_mask, ModeMask add_mode_mask ) { Check(this); activeReceiver = target; activeMessageID = active_message_id; activeDestination = active_direct_target; activeDependant = dependant; Check(application); ModeManager *mode_manager = application->GetModeManager(); Check(mode_manager); mode_manager->RemoveModeMask(remove_mode_mask); mode_manager->AddModeMask(add_mode_mask); Check_Fpu(); } void ControlsManager::StopMappableButtonsConfigure( ModeMask remove_mode_mask, ModeMask add_mode_mask ) { Check(this); Check(application); ModeManager *mode_manager = application->GetModeManager(); Check(mode_manager); mode_manager->RemoveModeMask(remove_mode_mask); mode_manager->AddModeMask(add_mode_mask); activeDestination = NULL; activeReceiver = NULL; activeMessageID = (Receiver::MessageID) 0; activeDependant = NULL; Check_Fpu(); } void ControlsManager::AddOrEraseMappableButton( int /*button_number*/, ModeMask /*mode_mask*/ ) { Check(this); Check_Fpu(); } // //############################################################################ // TestInstance // //############################################################################ // Logical ControlsManager::TestInstance() const { return IsDerivedFrom(*GetClassDerivations()); } // //############################################################################ // Shutdown // //############################################################################ // void ControlsManager::Shutdown() { ControlsManager *controls_manager; for( controls_manager = headControlsManager; controls_manager != NULL; controls_manager = controls_manager->nextControlsManager ) { controls_manager->LocalShutdown(); } Check_Fpu(); } void ControlsManager::LocalShutdown() { Check(this); Check_Fpu(); } //######################################################################### //############################# ControlsString ############################ //######################################################################### int ControlsString::nextID = 1; ControlsString::ControlsString( const char *new_string, int keypad_unit_number, Receiver *receiver_pointer, Receiver::MessageID message_id, int user_code ): Node(RegisteredClass::ControlsStringClassID) { Test_Tell( "ControlsString creator('" new_string << "'," << keypad_unit_number << "," << receiver_pointer << "," << message_id << ")\n" ); Check_Pointer(this); Check_Pointer(new_string); Check(receiver_pointer); //---------------------------------------------- // Assign unique ID //---------------------------------------------- id = nextID++; matchStringPointer = new_string; keypadUnitNumber = keypad_unit_number; //---------------------------------------------- // Save message data //---------------------------------------------- receiverPointer = receiver_pointer; messageID = message_id; userCode = user_code; //---------------------------------------------- // Clear the buffer //---------------------------------------------- string[0] = '\0'; stringLength = 0; Check_Fpu(); } ControlsString::~ControlsString() { Test_Tell("ControlsString destructor\n"); Check(this); Check_Fpu(); } Logical ControlsString::TestInstance() const { return True; } void ControlsString::Update(int keypad_unit_number, ControlsKey new_key) { Test_Tell( "ControlsString::Update(" << keypad_unit_number << "," << new_key << "\n" ); Check(this); //---------------------------------------------- // Update only if proper keyboard unit //---------------------------------------------- if (keypad_unit_number == keypadUnitNumber) { //-------------------------------------- // Get string length //-------------------------------------- Check_Pointer(matchStringPointer); int length = strlen(matchStringPointer); if (length > maxStringLength) { length = maxStringLength; } if (stringLength > length) // in case matchString changes { stringLength = length; string[stringLength] = '\0'; } //-------------------------------------- // Update string buffer //-------------------------------------- if (stringLength < length) { string[stringLength++] = (char) new_key; string[stringLength] = '\0'; } else { if (length > 1) { memmove(&string[0],&string[1], length-1); } string[length-1] = (char) new_key; } Test_Tell("string=" << string << "\n"); //-------------------------------------- // Check for match //-------------------------------------- if (strnicmp(string, matchStringPointer, length) == 0) { Test_Tell( "ControlsString::Update, '" << matchStringPointer << "' matched!\n" ); //-------------------------------------- // Match found, send message //-------------------------------------- Check(receiverPointer); Check(application); ControlsStringMessage message(messageID, this->userCode); receiverPointer->Dispatch(&message); //-------------------------------------- // Clear the string //-------------------------------------- string[0] = '\0'; stringLength = 0; } } Check_Fpu(); } //######################################################################### //######################## ControlsStringManager ########################## //######################################################################### ControlsStringManager::ControlsStringManager() : Node(RegisteredClass::ControlsStringManagerClassID), instanceList(this) { Test_Tell("ControlsStringManager creator\n"); Check_Pointer(this); } ControlsStringManager::~ControlsStringManager() { Test_Tell("ControlsStringManager destructor\n"); Check(this); //---------------------------------------------- // Remove all ControlStrings //---------------------------------------------- Remove(0); Check_Fpu(); } Logical ControlsStringManager::TestInstance() const { return True; } ControlsStringID ControlsStringManager::Add( const char *new_string, int keypad_unit_number, Receiver *receiver_pointer, Receiver::MessageID message_id, int user_code ) { Test_Tell("ControlsStringManager::Add(" << new_string << "," << keypad_unit_number << "," << receiver_pointer << "," << message_id << "\n" ); Check(this); Check_Pointer(new_string); Check(receiver_pointer); //---------------------------------------------- // Create the ControlsString //---------------------------------------------- ControlsString *string_item = new ControlsString( new_string, keypad_unit_number, receiver_pointer, message_id, user_code ); Check(string_item); Register_Object(string_item); //---------------------------------------------- // Add to the instance list //---------------------------------------------- instanceList.Add(string_item); //---------------------------------------------- // return the new string's (unique) ID //---------------------------------------------- Check_Fpu(); return string_item->id; } void ControlsStringManager::Remove(ControlsStringID string_id) { Test_Tell("ControlsStringManager::Remove(" << string_id << ")\n"); Check(this); ChainIteratorOf i(instanceList); ControlsString *controls_string; //---------------------------------------------- // Search for the given ID (or universal match) //---------------------------------------------- while ((controls_string=i.ReadAndNext()) != NULL) { Check(controls_string); if ( (string_id == 0) || (controls_string->id == string_id) ) { Unregister_Object(controls_string); delete controls_string; //------------------------------------------ // If this is not a 'universal' remove, // we're done (ID's are unique) //------------------------------------------ if (string_id != 0) { break; } } } Check_Fpu(); } void ControlsStringManager::Update( int keypad_unit_number, ControlsKey new_key ) { Test_Tell("ControlsStringManager::Update(" << keypad_unit_number << "," << new_key << ")\n" ); Check(this); //-------------------------------------- // Update all matching string items //-------------------------------------- ChainIteratorOf i(instanceList); ControlsString *controls_string; while ((controls_string=i.ReadAndNext()) != NULL) { Check(controls_string); controls_string->Update(keypad_unit_number, new_key); } Check_Fpu(); } #if defined(TEST_CLASS) #include "controls.tcp" #endif