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::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
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
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
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();
        }
    });
}
Esempio n. 7
0
//-------------------------------------------------------
void OdbcPersistor::Remove(const Safir::Dob::EntityProxy& entityProxy)
{
    Remove(entityProxy.GetEntityId());
}