void JoystickEntityHandler::OnDeletedEntityInternal(const Safir::Dob::EntityProxy &entityProxy) { Safir::Logging::SendSystemLog(Safir::Logging::Informational, L"delete Joystick entity: " + entityProxy.GetEntityId().ToString()); m_engine->DeleteJoystickCB(entityProxy.GetEntityId()); }
//------------------------------------------------------- void PersistenceHandler::HandleTimeout() { const auto now = boost::chrono::steady_clock::now(); // Don't iterate through all unless we are due for a write timeout. if (now > m_nextTimeout) { m_nextTimeout = boost::chrono::steady_clock::time_point::max(); for (auto entity = m_toBeWritten.begin(); entity != m_toBeWritten.end(); ++entity) { // Should we write this object? if (entity->second.second && entity->second.first < now) { // The object is dirty and its time to write it try { const Safir::Dob::EntityProxy entityProxy = m_dobConnection.Read(entity->first); m_debug << "Periodic write time ended for entity " << entityProxy.GetEntityId() << std::endl; Write(entityProxy,true); // Set next write time ... entity->second.first = now + m_writePeriod[entity->first.GetTypeId()]; // ...and reset dirty flag entity->second.second = false; } catch(const Safir::Dob::NotFoundException &) { // This could happen if the instance has been deleted but we haven't been told yet // Just fall through and erase it from our internal structure. The delete callback will // take care of this. } } if (entity->second.first < m_nextTimeout) { m_nextTimeout = entity->second.first; } } } m_writeTimer.expires_from_now(boost::chrono::seconds(1)); m_writeTimer.async_wait([this](const boost::system::error_code& error) { if (!error) { HandleTimeout(); } }); }
//------------------------------------------------------- void PersistenceHandler::Write(const Safir::Dob::EntityProxy& entityProxy, const bool update) { m_debug << "Will try to persist entity " << entityProxy.GetEntityId() << std::endl; const char* blob = entityProxy.GetBlob(); Safir::Dob::Typesystem::BinarySerialization bin = std::vector<char>(blob,blob+Safir::Dob::Typesystem::Internal::BlobOperations::GetSize(blob)); Store(entityProxy.GetEntityId(), entityProxy.GetOwner(), bin, update); }
void JoystickEntityHandler::OnNewEntityInternal(const Safir::Dob::EntityProxy &entityProxy) { Safir::Logging::SendSystemLog(Safir::Logging::Informational, L"New Joystick entity: " + entityProxy.GetEntityId().ToString()); const Consoden::TankGame::JoystickPtr joystick_ptr = boost::static_pointer_cast<Consoden::TankGame::Joystick>(entityProxy.GetEntity()); if (joystick_ptr->GameId() == m_gameId) { // Joystick for our game m_engine->NewJoystickCB(joystick_ptr->TankId().GetVal(), entityProxy.GetEntityId()); } }
void Player::OnDeletedEntity(const Safir::Dob::EntityProxy entityProxy, const bool) { if (entityProxy.GetTypeId()==Consoden::TankGame::GameState::ClassTypeId && entityProxy.GetInstanceId()==m_currentGameId) { if (m_myJoystickId!=Safir::Dob::Typesystem::InstanceId()) { m_connection.Delete(Safir::Dob::Typesystem::EntityId(Consoden::TankGame::Joystick::ClassTypeId, m_myJoystickId), m_myHandlerId); } m_logic.reset(); m_myJoystickId=Safir::Dob::Typesystem::InstanceId(); m_currentGameId=Safir::Dob::Typesystem::InstanceId(); m_currentTankId=-1; } }
//------------------------------------------------------- void PersistenceHandler::OnDeletedEntity(const Safir::Dob::EntityProxy entityProxy, const bool deletedByOwner) { // Remove it from the throttling structure if it happens to be there m_toBeWritten.erase(entityProxy.GetEntityId()); // only remove if removed by owner... Otherwise it is probably because the system shut down or the application died if( !deletedByOwner ) { return; } m_debug << "Removing entity " << entityProxy.GetEntityId() << std::endl; Remove(entityProxy); }
void Player::OnNewEntity(const Safir::Dob::EntityProxy entityProxy) { Consoden::TankGame::GameStatePtr gameState=boost::dynamic_pointer_cast<Consoden::TankGame::GameState>(entityProxy.GetEntity()); if (gameState) { for (int i=0; i<gameState->TanksArraySize(); ++i) { if (!gameState->Tanks()[i].IsNull() && gameState->Tanks()[i].GetPtr()->PlayerId().GetVal()==m_myPlayerId) { //we participate in this game m_currentGameId=entityProxy.GetInstanceId(); m_currentTankId=gameState->Tanks()[i].GetPtr()->TankId(); m_myJoystickId=Safir::Dob::Typesystem::InstanceId::GenerateRandom(); Consoden::TankGame::JoystickPtr joystick=Consoden::TankGame::Joystick::Create(); joystick->PlayerId()=m_myPlayerId; joystick->GameId()=m_currentGameId; joystick->TankId()=m_currentTankId; joystick->Counter()=0; m_connection.SetAll(joystick, m_myJoystickId, m_myHandlerId); m_logic.reset(new TankLogic(m_currentTankId, boost::bind(&Player::SetJoystick, this, _1, _2, _3, _4))); break; } } } }
//------------------------------------------------------- void PersistenceHandler::HandleEntity(const Safir::Dob::EntityProxy& entityProxy, const bool update) { auto writePeriodIt = m_writePeriod.find(entityProxy.GetTypeId()); if (writePeriodIt != m_writePeriod.cend()) { // This entity type has a write period limit const auto now = boost::chrono::steady_clock::now(); const auto writePeriod = writePeriodIt->second; auto toBeWrittenIt = m_toBeWritten.find(entityProxy.GetEntityId()); if (toBeWrittenIt == m_toBeWritten.cend()) { // If the entity instance doesn't exist in the map then this instance has never been written. // Write it right away! Write(entityProxy, update); m_toBeWritten[entityProxy.GetEntityId()] = std::make_pair(now + writePeriod, false); // dirty flag m_nextTimeout = now; // Force timeout and a recalculation of nextTimeout } else if (m_toBeWritten[entityProxy.GetEntityId()].first < now) { // This instance hasn't been written within its write period // Write it right away! Write(entityProxy, update); toBeWrittenIt->second.first = now + writePeriod; // next timeout toBeWrittenIt->second.second = false; // dirty flag m_nextTimeout = now; // Force timeout and a recalculation of nextTimeout } else { // Otherwise, mark the entity as dirty and wait until the timer strikes. toBeWrittenIt->second.second = true; } } else { Write(entityProxy, update); } }
void DopeApp::OnNewEntity(const Safir::Dob::EntityProxy entityProxy) { if (entityProxy.GetTypeId() == Safir::Dob::PersistentDataStatus::ClassTypeId) { if (!m_persistenceStarted) { std::wcout << L"Dope is started as standby persistence. Active persistence is running on node "; std::wcout << entityProxy.GetInstanceId().GetRawValue() << "." << std::endl; m_persistenceStarted = true; if (Safir::Dob::PersistenceParameters::StandaloneMode()) { // Start saving persistent data Start(false); } } } }
void Ponger::Pong(const Safir::Dob::EntityProxy& entityProxy) { const Safir::Dob::Typesystem::InstanceId instance = entityProxy.GetInstanceId(); // std::wcout << "Pong " << instance << std::endl; PingPongTable::iterator findIt = m_pingPongTable.find(instance); //if it is not in the table it is the first time we've seen it, so add to the table if (findIt == m_pingPongTable.end()) { findIt = m_pingPongTable.insert(std::make_pair(instance,Safir::Dob::Typesystem::InstanceId::GenerateRandom())).first; } m_entity->Number() = boost::static_pointer_cast<DoseStressTest::Ping>(entityProxy.GetEntity())->Number(); m_entity->WhichPing() = instance; m_connection.SetAll(m_entity,findIt->second,m_handler); }
void Player::OnUpdatedEntity(const Safir::Dob::EntityProxy entityProxy) { Consoden::TankGame::GameStatePtr gameState=boost::dynamic_pointer_cast<Consoden::TankGame::GameState>(entityProxy.GetEntity()); if (gameState && m_logic && entityProxy.GetInstanceId()==m_currentGameId) { if (gameState->Winner().GetVal() == Consoden::TankGame::Winner::Unknown) { try { m_logic->MakeMove(gameState); } catch(...) { std::cout<<"Caught unhandled exception in TankLogic!"<<std::endl; } } } }
void Ponger::OnDeletedEntity(const Safir::Dob::EntityProxy entityProxy, const bool /*deletedByOwner*/) { const Safir::Dob::Typesystem::InstanceId instance = entityProxy.GetInstanceId(); PingPongTable::iterator findIt = m_pingPongTable.find(instance); if (findIt == m_pingPongTable.end()) { std::wostringstream ostr; ostr << "Got a delete for an instance that I haven't seen before! instanceId = " << instance; ErrorReporter::Log(Safir::Dob::Typesystem::Utilities::ToUtf8(ostr.str())); std::wcout << ostr.str() << std::endl; return; } m_connection.Delete(Safir::Dob::Typesystem::EntityId(DoseStressTest::Pong::ClassTypeId,findIt->second),m_handler); m_pingPongTable.erase(findIt); }
//------------------------------------------------------- void OdbcPersistor::Remove(const Safir::Dob::EntityProxy& entityProxy) { Remove(entityProxy.GetEntityId()); }
void JoystickEntityHandler::MoveJoystick() { // Safir::Logging::SendSystemLog(Safir::Logging::Critical, // L"JoystickEntityHandler::MoveJoystick"); Safir::Dob::EntityProxy entityProxy = m_connection.Read(m_JoystickEntity); Consoden::TankGame::JoystickPtr joystick = boost::static_pointer_cast<Consoden::TankGame::Joystick>(entityProxy.GetEntity()); Consoden::TankGame::Direction::Enumeration newDirection; // Make a random movement float r = random(); r = r / RAND_MAX; // Since moving backwards will kill the tank, make that unprobable (1%) if (r < 0.01) { // Backwards (1%) newDirection = InvertDirection(m_LastDirection); MoveDirection(newDirection, joystick); m_LastDirection = newDirection; } else if (r < 0.41) { // Forward (40%) newDirection = m_LastDirection; MoveDirection(newDirection, joystick); m_LastDirection = newDirection; } else if (r < 0.61) { // Turn right (20%) newDirection = TurnRight(m_LastDirection); MoveDirection(newDirection, joystick); m_LastDirection = newDirection; } else if (r < 0.81) { // Turn left (20%) newDirection = TurnLeft(m_LastDirection); MoveDirection(newDirection, joystick); m_LastDirection = newDirection; } else { // Stand still (19%) MoveDirection(Consoden::TankGame::Direction::Neutral, joystick); } // Set a random fire direction r = random(); r = r / RAND_MAX; if (r < 0.25) { TowerDirection(Consoden::TankGame::Direction::Left, joystick); } else if (r < 0.50) { TowerDirection(Consoden::TankGame::Direction::Right, joystick); } else if (r < 0.75) { TowerDirection(Consoden::TankGame::Direction::Up, joystick); } else { TowerDirection(Consoden::TankGame::Direction::Down, joystick); } // Fire? r = random(); r = r / RAND_MAX; if (r < 0.2) { // Yes! 20% Fire(true, joystick); } else { // No! 80% Fire(false, joystick); } }