void InterpolateComponent::OnVarNameChanged(Variant *pDataObject) { if (m_pComponentName->length()) { EntityComponent * pComp = GetParent()->GetComponentByName(*m_pComponentName); if (!pComp) { LogError("InterpolateComponent %s is unable to find component %s to set its var %s", GetName().c_str(), m_pComponentName->c_str(), pDataObject->GetString().c_str()); assert(!"Check out your log!"); return; } m_pVar = pComp->GetVar(pDataObject->GetString()); // If the target component gets deleted we mustn't access its variants anymore pComp->GetFunction("OnDelete")->sig_function.connect(1, boost::bind(&InterpolateComponent::NullifyVarPointer, this, _1)); } else { m_pVar = GetParent()->GetVar(pDataObject->GetString()); } }
void MessageManager::Deliver(Message *m) { if (m->GetClass() == MESSAGE_CLASS_ENTITY) { if (m->GetTargetComponent()) { switch (m->GetType()) { case MESSAGE_TYPE_SET_ENTITY_VARIANT: m->GetTargetComponent()->GetVar(m->GetVarName())->Set(m->Get()); break; case MESSAGE_TYPE_CALL_ENTITY_FUNCTION: m->GetTargetComponent()->GetShared()->CallFunctionIfExists(m->GetVarName(), &m->GetVariantList()); break; case MESSAGE_TYPE_REMOVE_COMPONENT: //actually, we're targeting an entity but adding this component... m->GetTargetEntity()->AddComponent(m->GetTargetComponent()); m->ClearComponent(); break; default: LogError("Message delivery error"); assert(0); break; } } else if (m->GetTargetEntity()) { switch (m->GetType()) { case MESSAGE_TYPE_CALL_COMPONENT_FUNCTION_BY_NAME: { EntityComponent *pComp = m->GetTargetEntity()->GetComponentByName(m->GetStringParm()); if (pComp) { pComp->GetFunction(m->GetVarName())->m_sig_function(&m->GetVariantList()); } else { LogMsg("Warning: Entity %s doesn't have a component named %s to call %s on", m->GetTargetEntity()->GetName().c_str(), m->GetStringParm().c_str(), m->GetVarName().c_str()); } } break; case MESSAGE_TYPE_SET_ENTITY_VARIANT: m->GetTargetEntity()->GetVar(m->GetVarName())->Set(m->Get()); break; case MESSAGE_TYPE_CALL_ENTITY_FUNCTION: m->GetTargetEntity()->GetFunction(m->GetVarName())->m_sig_function(&m->GetVariantList()); break; case MESSAGE_TYPE_CALL_ENTITY_FUNCTION_RECURSIVELY: if (m->GetType() == MESSAGE_TYPE_GUI_CLICK_START) { //this function is sort of a hack to fake a mouse click, used with automation stuff for stress tests //fake out our touch tracker, will override the 11th finger touch.. BaseApp::GetBaseApp()->GetTouch(C_MAX_TOUCHES_AT_ONCE-1)->SetWasHandled(false); BaseApp::GetBaseApp()->GetTouch(C_MAX_TOUCHES_AT_ONCE-1)->SetWasPreHandled(false); BaseApp::GetBaseApp()->GetTouch(C_MAX_TOUCHES_AT_ONCE-1)->SetIsDown(true); BaseApp::GetBaseApp()->GetTouch(C_MAX_TOUCHES_AT_ONCE-1)->SetPos(m->GetVariantList().Get(1).GetVector2()); } m->GetTargetEntity()->CallFunctionRecursively(m->GetVarName(), &m->GetVariantList()); break; case MESSAGE_TYPE_REMOVE_COMPONENT: m->GetTargetEntity()->RemoveComponentByName(m->GetVarName()); break; default: LogError("Message delivery error"); assert(0); break; } //entity's shared space } else { switch (m->GetType()) { case MESSAGE_TYPE_CALL_STATIC_FUNCTION: (m->GetFunctionPointer())(&m->GetVariantList()); break; default: //LogError("Message delivery error"); break; //Not actually an error, if an entity is killed while a message is in transit, it will set the entity //to null and some messages may end up here as they are undeliverable } } } else //MESSAGE_CLASS_MOUSE, MESSAGE_CLASS_GAME { BaseApp::GetBaseApp()->OnMessage(*m); } }
void App::Update() { //game can think here. The baseApp::Update() will run Update() on all entities, if any are added. The only one //we use in this example is one that is watching for the Back (android) or Escape key to quit that we setup earlier. BaseApp::Update(); if (!m_bDidPostInit) { //stuff I want loaded during the first "Update" m_bDidPostInit = true; //for android, so the back key (or escape on windows) will quit out of the game Entity *pEnt = GetEntityRoot()->AddEntity(new Entity); EntityComponent *pComp = pEnt->AddComponent(new CustomInputComponent); //tell the component which key has to be hit for it to be activated pComp->GetVar("keycode")->Set(uint32(VIRTUAL_KEY_BACK)); //attach our function so it is called when the back key is hit pComp->GetFunction("OnActivated")->sig_function.connect(1, boost::bind(&App::OnExitApp, this, _1)); //nothing will happen unless we give it input focus pEnt->AddComponent(new FocusInputComponent); //ACCELTEST: To test the accelerometer uncomment below: (will print values to the debug output) //SetAccelerometerUpdateHz(25); //default is 0, disabled //GetBaseApp()->m_sig_accel.connect(1, boost::bind(&App::OnAccel, this, _1)); //TRACKBALL/ARCADETEST: Uncomment below to see log messages on trackball/key movement input pComp = pEnt->AddComponent(new ArcadeInputComponent); GetBaseApp()->m_sig_arcade_input.connect(1, boost::bind(&App::OnArcadeInput, this, _1)); //these arrow keys will be triggered by the keyboard, if applicable AddKeyBinding(pComp, "Left", VIRTUAL_KEY_DIR_LEFT, VIRTUAL_KEY_DIR_LEFT); AddKeyBinding(pComp, "Right", VIRTUAL_KEY_DIR_RIGHT, VIRTUAL_KEY_DIR_RIGHT); AddKeyBinding(pComp, "Up", VIRTUAL_KEY_DIR_UP, VIRTUAL_KEY_DIR_UP); AddKeyBinding(pComp, "Down", VIRTUAL_KEY_DIR_DOWN, VIRTUAL_KEY_DIR_DOWN); AddKeyBinding(pComp, "Shift", VIRTUAL_KEY_CONTROL, VIRTUAL_KEY_CONTROL); AddKeyBinding(pComp, "Fire", VIRTUAL_KEY_CONTROL, VIRTUAL_KEY_GAME_FIRE); //INPUT TEST - wire up input to some functions to manually handle. AppInput will use LogMsg to //send them to the log. (Each device has a way to view a debug log in real-time) GetBaseApp()->m_sig_input.connect(&AppInput); /* //file handling test, if TextScanner.h is included at the top.. TextScanner t; t.m_lines.push_back("Testing 123"); t.m_lines.push_back("F**k ya'll!"); t.m_lines.push_back("Whoopsopsop!"); LogMsg("Saving file..."); t.SaveFile("temp.txt"); TextScanner b; b.LoadFile("temp.txt"); b.DumpToLog(); */ } //game is thinking. if (g_game->game_state_ == 1) //we update the objects { g_game->update(); } }