// getObject() -- Get/Find the object (component) we're sending to Component* Component::SendData::getObject(Component* gobj, const char* const id, const int n) { // Did we already find the object? if (obj == nullptr) { // No, then try to find it among our components ... Pair* p = nullptr; if (n <= 0) { // When n is zero (or less) just use 'id' as // the name when finding the object. p = gobj->findByName(id); } else { // --- // When n is greater than zero, use 'id' as a format // with 'n' to get the name. Great for items in rows // or columns. // Example: n = 5 // id = xxx.%d // gives name = xxx.5 // --- char name[128]; std::sprintf(name,id,n); p = gobj->findByName(name); } if (p != nullptr) obj = static_cast<Component*>(p->object()); } return obj; }
//------------------------------------------------------------------------------ // updateData() -- Update non-time critical (background) stuff here //------------------------------------------------------------------------------ void Component::updateData(const LCreal dt) { // Update all my children PairStream* subcomponents = getComponents(); if (subcomponents != 0) { if (selection != 0) { // When we've selected only one if (selected != 0) selected->updateData(dt); } else { // When we should update them all List::Item* item = subcomponents->getFirstItem(); while (item != 0) { Pair* pair = (Pair*)(item->getValue()); Component* obj = (Component*)( pair->object() ); if (obj != 0) obj->updateData(dt); item = item->getNext(); } } subcomponents->unref(); subcomponents = 0; } // Update our log file if (elog0 != 0) { elog0->updateData(dt); } }
//------------------------------------------------------------------------------ // reset() -- Reset parameters //------------------------------------------------------------------------------ void Component::reset() { PairStream* subcomponents = getComponents(); if (subcomponents != 0) { if (selection != 0) { // When we've selected only one if (selected != 0) selected->reset(); } else { // When we should reset them all List::Item* item = subcomponents->getFirstItem(); while (item != 0) { Pair* pair = (Pair*)(item->getValue()); Component* obj = (Component*)( pair->object() ); if (obj != 0) obj->reset(); item = item->getNext(); } } subcomponents->unref(); subcomponents = 0; } // Reset the log file if (elog0 != 0) { elog0->reset(); } }
bool StateMachine::setSlotStateMachines(const PairStream* const msg) { // First remove the old list; and make sure we tell the old stMachList // that we're no longer their container. if (stMachList != nullptr) { List::Item* item = stMachList->getFirstItem(); while (item != nullptr) { Pair* p = static_cast<Pair*>(item->getValue()); Component* q = static_cast<Component*>(p->object()); q->container(nullptr); item = item->getNext(); } stMachList = nullptr; } // Build a new list containing only StateMachine class (or derived) objects if (msg != nullptr) { PairStream* newList = new PairStream(); // For each object in the list; if it's a StateMachine (or derived from) then // clone the object and add it to the new list. const List::Item* item = msg->getFirstItem(); while (item != nullptr) { const Pair* p = static_cast<const Pair*>(item->getValue()); const StateMachine* q = dynamic_cast<const StateMachine*>(p->object()); if (q != nullptr) { Pair* cp = static_cast<Pair*>(p->clone()); StateMachine* cq = static_cast<StateMachine*>(cp->object()); cq->container(this); newList->put(cp); } else { std::cerr << "StateMachine::setSlotStateMachines(): " << *p->slot() << " is not a StateMachine!" << std::endl; } item = item->getNext(); } // Set the pointer to the new stMach list stMachList = newList; } return true; }
// Send an event message to component 'id' bool Component::send(const char* const id, const int event) { bool val {}; Pair* p = findByName(id); if (p != nullptr) { const auto g = static_cast<Component*>(p->object()); val = g->event(event); } return val; }
// Send an event message to component 'id' bool Component::send(const char* const id, const int event) { bool val = false; Pair* p = findByName(id); if (p != 0) { Component* g = (Component*) p->object(); val = g->event(event); } return val; }
//------------------------------------------------------------------------------ // select() -- select one of our components, using String or Number //------------------------------------------------------------------------------ bool Component::select(const String* const name) { bool ok {true}; selected = nullptr; setSelectionName(nullptr); if (name != nullptr) { setSelectionName(name); Pair* p = findByName(*name); if (p != nullptr) selected = static_cast<Component*>(p->object()); else { std::cerr << "Component::select: name not found!" << std::endl; ok = false; } } return ok; }
//------------------------------------------------------------------------------ // select() -- select one of our components, using String or Number //------------------------------------------------------------------------------ bool Component::select(const String* const name) { bool ok = true; selected = 0; setSelectionName(0); if (name != 0) { setSelectionName(name); Pair* p = findByName(*name); if (p != 0) selected = (Component*) p->object(); else { std::cerr << "Component::select: name not found!" << std::endl; ok = false; } } return ok; }
// ----------------------------------------------------------------- // Sets the state machine 'name' or zero to clear. Return true // if successful. If the 'code' is CHK_CUR_STATE or GET_NEXT_STATE // then we do NOT actually set the stMach, but we only check to // see if the stMach 'name' exists. // ----------------------------------------------------------------- bool StateMachine::setStMach(const char* const name, const StateTableCode code) { bool ok = false; if (code == CURR_STATE) { // Current state is now also the previous state StateMachine* oldStMach = stMach; // First, check to see if they're asking for the same state // as our current state. ok = (stMachName == nullptr && name == nullptr); if (!ok && stMachName != nullptr && name != nullptr) { ok = *stMachName == name; } // When they're not the same then we make a switch ... if (!ok) { if (name != nullptr) { Pair* p = findStMachByName(name); if (p != nullptr) { stMach = static_cast<StateMachine*>(p->object()); stMachName = p->slot(); ok = true; } } else { // 'name' is null, so set the new state to null. stMach = nullptr; stMachName = nullptr; ok = true; } if (ok) { pStMach = oldStMach; } } } else { // -- only need to look to see if this named state machine exists. ok = (findStMachByName(name) != nullptr); } return ok; }
bool Component::select(const Number* const num) { bool ok {true}; selected = nullptr; setSelectionName(nullptr); if (num != nullptr) { setSelectionName(num); Pair* p = findByIndex(num->getInt()); if (p != nullptr) { selected = static_cast<Component*>(p->object()); } else { std::cerr << "Component::select: index out of range; num = " << num->getInt() << std::endl; ok = false; } } return ok; }
bool Component::select(const Number* const num) { bool ok = true; selected = 0; setSelectionName(0); if (num != 0) { setSelectionName(num); Pair* p = findByIndex(num->getInt()); if (p != 0) { selected = (Component*) p->object(); } else { std::cerr << "Component::select: index out of range; num = " << num->getInt() << std::endl; ok = false; } } return ok; }
//------------------------------------------------------------------------------ // shutdownNotification() -- Default shutdown //------------------------------------------------------------------------------ bool Component::shutdownNotification() { // Tell all of our components PairStream* subcomponents = getComponents(); if (subcomponents != 0) { List::Item* item = subcomponents->getFirstItem(); while (item != 0) { Pair* pair = (Pair*)(item->getValue()); Component* p = (Component*) pair->object(); p->event(SHUTDOWN_EVENT); item = item->getNext(); } subcomponents->unref(); subcomponents = 0; } shutdown = true; return shutdown; }
// ----------------------------------------------------------------- // reset() -- Resets the state machine // ----------------------------------------------------------------- void StateMachine::reset() { BaseClass::reset(); // Reset our state machine list if (stMachList != nullptr) { List::Item* item = stMachList->getFirstItem(); while (item != nullptr) { Pair* p = static_cast<Pair*>(item->getValue()); Component* q = static_cast<Component*>(p->object()); q->reset(); item = item->getNext(); } } // Goto our RESET state state = INVALID_STATE; substate = INVALID_STATE; stMach = nullptr; stMachName = nullptr; arg = nullptr; goTo(INIT_STATE); }
//------------------------------------------------------------------------------ // processComponents() -- process our new components list; // -- Add the components from the input list, 'list', to a new list, 'newList' // make sure they are all of type Component (or derived from it) // tell them that we are their container // -- Add an optional component to the end of the new list // -- Swap our 'components' list with the new list, newList // -- Handle selections. //------------------------------------------------------------------------------ void Component::processComponents( PairStream* const list, const std::type_info& filter, Pair* const add, Component* const remove ) { PairStream* oldList = components.getRefPtr(); // --- // Our dynamic_cast (see below) already filters on the Component class // --- bool skipFilter = false; if (&filter == 0) skipFilter = true; else if (filter == typeid(Component)) skipFilter = true; // --- // Create a new list, copy (filter) the component pairs and set their container pointers // --- PairStream* newList = new PairStream(); if (list != 0) { // Add the (filtered) components to the new list and set their container List::Item* item = list->getFirstItem(); while (item != 0) { Pair* pair = (Pair*) item->getValue(); Component* cp = dynamic_cast<Component*>( pair->object() ); if ( cp != 0 && cp != remove && (skipFilter || cp->isClassType(filter)) ) { newList->put(pair); cp->container(this); } else if ( cp != 0 && cp == remove ) { cp->container(0); } item = item->getNext(); } } // --- // Add the optional component // --- if (add != 0) { Component* cp = dynamic_cast<Component*>( add->object() ); if ( cp != 0 && (skipFilter || cp->isClassType(filter)) ) { newList->put(add); cp->container(this); } } // --- // Swap lists // --- components = newList; newList->unref(); // --- // Anything selected? // --- if (selection != 0) { if (selection->isClassType(typeid(String))) { String str(*((String*)selection)); select(&str); } else { Integer num(((Number*)selection)->getInt()); select(&num); } } if (oldList != 0) { oldList->unref(); } }