예제 #1
0
    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);
}
예제 #4
0
    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());
        }
    }
예제 #5
0
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);
}
예제 #7
0
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);
    }
}
예제 #9
0
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);
            }
        }
    }     
}
예제 #10
0
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);
}
예제 #11
0
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;
            }
        }
    }
}
예제 #12
0
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);
}
예제 #13
0
//-------------------------------------------------------
void OdbcPersistor::Remove(const Safir::Dob::EntityProxy& entityProxy)
{
    Remove(entityProxy.GetEntityId());
}
예제 #14
0
    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);
        }

    }