TriloBot Simulator (C++, Qt4, Flex, Readline, Boost)
File detail
Source code
/*
* Copyright (C) 2008 Jakub Filak <xfilak01@stud.fit.vutbr.cz>
*
* This file is part of rob08
*
* rob08 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* rob08 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rob08. If not, see <http://www.gnu.org/licenses/>.
*/
#include "simulator.h"
//
// Component State
//
struct State::Members
{
Members( const std::string& id, DateTime st = DateTime::Now() )
: compid( id ),
stamp( st )
{}
std::string compid;
DateTime stamp;
};
State::State( const std::string& id, DateTime st, double speed, double radius, double size, const struct Position& pos )
: BaseMovingObject( speed, radius, size, pos ),
pimpl( new State::Members( id, st ) )
{
this->SetSpeed( speed );
this->SetRadius( radius );
this->SetSize( size );
this->SetPosition( pos );
}
State::~State()
{ delete pimpl; }
const std::string& State::ComponentID() const
{ return pimpl->compid; }
State* State::Clone() {
return new State(this->pimpl->compid,
this->pimpl->stamp,
this->Speed(),
this->Radius(),
this->Size(),
this->Position());
}
const DateTime& State::Stamp() const
{ return pimpl->stamp; }
void State::ImplSerialize( std::ostream& output ) {
BaseMovingObject::ImplSerialize( output );
StateSerialize( output );
}
void State::StateSerialize( std::ostream& output ) {
output << std::endl
<< this->pimpl->compid << std::endl
<< this->pimpl->stamp;
}
void State::ImplDeserialize( std::istream& input ) {
BaseMovingObject::ImplDeserialize( input );
StateDeserialize( input );
}
void State::StateDeserialize( std::istream& input ) {
input >> this->pimpl->compid >> this->pimpl->stamp;
}
//
// StateContainer
//
const std::string StateContainer::SER_START("SC_START");
const std::string StateContainer::SER_NEXT("SC_NEXT");
const std::string StateContainer::SER_FINISH("SC_FINISH");
struct StateContainer::Members
{
Members()
: current(), next()
{}
StatePtr current;
StatePtr next;
};
StateContainer::StateContainer()
: pimpl( new StateContainer::Members() )
{}
StateContainer::~StateContainer()
{ delete this->pimpl; }
void StateContainer::UpdateStates( const DateTime& now ) {
if( 0 != this->pimpl->next.get()
&& this->pimpl->next->Stamp() <= now )
{ // if next stamp < now then next is current
this->pimpl->current = this->pimpl->next;
this->pimpl->next = StatePtr();
}
}
StatePtr StateContainer::Current( const DateTime& now ) {
this->UpdateStates( now );
return this->pimpl->current;
}
StateContainer& StateContainer::Current( StatePtr current ) {
assert( 0 != current.get() || !"Current state must not be empty" );
if( 0 != this->pimpl->next.get()
&& this->pimpl->next->Stamp() <= current->Stamp() )
{ // If next stamp < current stamp, then next is invalid
this->pimpl->next = StatePtr();
}
// TODO: maybe if arg current is 0 and now >= next->Stamp() then clear next
this->pimpl->current = current;
return *this;
}
StatePtr StateContainer::Next(const DateTime& now) {
this->UpdateStates( now );
return this->pimpl->next;
}
StateContainer& StateContainer::Next( StatePtr next ) {
this->pimpl->next = next;
return *this;
}
void StateContainer::Serialize( std::ostream& output ) {
output << SER_START << std::endl;
if( 0 != this->pimpl->current.get() ) {
this->pimpl->current->Serialize( output );
}
if( 0 != this->pimpl->next.get() ) {
if( 0 != this->pimpl->current.get() ) {
output << std::endl;
}
output << SER_NEXT << std::endl;
this->pimpl->next->Serialize( output );
}
output << std::endl << SER_FINISH;
}
void StateContainer::Deserialize( std::istream& input ) {
std::string info;
// READ SCS
input >> info;
if( 0 != this->pimpl->current.get() ) {
this->pimpl->current->Deserialize( input );
}
// read SCF or SCNS
input >> info;
if( info == SER_FINISH ) {
// No next state deserialized
this->pimpl->next = StatePtr();
}
else {
this->pimpl->next = StatePtr( this->pimpl->current->Clone() );
this->pimpl->next->Deserialize( input );
// If it hasn't next state and
// inpute has then input must be cleared
while( info != SER_FINISH ) {
input >> info;
}
}
}