00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "simlpy/interpreter_defs.h"
00032 #include "simlpy/interpreter_hooks.h"
00033
00034 #include <iostream>
00035
00036 #include "TrafficGenerator.h"
00037 #include "simlpy/Clock.h"
00038 #include "PythonTimeDistribution.h"
00039 #include "PythonBundleMaker.h"
00040 #include "simlpy/SimulationException.h"
00041
00042 TrafficGenerator::TrafficGenerator() :
00043 m_timeDist( 0 ),
00044 m_maker( 0 )
00045 {
00046 }
00047
00048 TrafficGenerator::~TrafficGenerator()
00049 {
00050 if ( 0 != m_timeDist ) delete m_timeDist;
00051 if ( 0 != m_maker ) delete m_maker;
00052 }
00053
00054 Entity*
00055 TrafficGenerator::create() const
00056 {
00057 return new TrafficGenerator;
00058 }
00059
00060 void
00061 TrafficGenerator::configure( const Entity::ArgList& args )
00062 {
00063 unsigned int nargs = args.size();
00064 if ( nargs < 2 )
00065 {
00066 std::cerr << "config() takes at least 2 arguments ("
00067 << nargs << " given)"
00068 << std::endl;
00069 throw SimulationException( __FILE__ , __LINE__ );
00070 }
00071
00072 std::string command = parse_string(args[0]);
00073 if ( "time_dist" == command )
00074 {
00075 if ( ! PyCallable_Check( args[1] ) )
00076 {
00077 std::cerr << "second argument isn't callable" << std::endl;
00078 throw SimulationException( __FILE__ , __LINE__ );
00079 }
00080 PythonTimeDistribution* ptd = new PythonTimeDistribution;
00081 ptd->setFunc(args[1]);
00082 setTimeDistribution( ptd );
00083 }
00084 else if ( "generator" == command )
00085 {
00086 if ( ! PyCallable_Check( args[1] ) )
00087 {
00088 std::cerr << "second argument isn't callable" << std::endl;
00089 throw SimulationException( __FILE__ , __LINE__ );
00090 }
00091 PythonBundleMaker* pbm = new PythonBundleMaker;
00092 pbm->setFunc(args[1]);
00093 setBundleMaker( pbm );
00094 }
00095 else
00096 {
00097 std::cerr << "Unrecognized configuration option: " << command
00098 << std::endl;
00099 throw SimulationException( __FILE__ , __LINE__ );
00100 }
00101 }
00102
00103 void
00104 TrafficGenerator::emit( const Entity::ArgList& args )
00105 {
00106 int nargs = args.size();
00107 if ( nargs < 1 )
00108 {
00109 std::cerr << "emit() takes at least 1 argument ("
00110 << nargs << " given)"
00111 << std::endl;
00112 throw SimulationException( __FILE__ , __LINE__ );
00113 }
00114 Time t = parse_time(args[0]);
00115 Clock::schedule( new TrafficTrigger(this,this,t) );
00116 }
00117
00118 void
00119 TrafficGenerator::setTimeDistribution( TimeDistribution* td )
00120 {
00121 if ( 0 == td ) return;
00122 if ( 0 != m_timeDist ) delete m_timeDist;
00123 m_timeDist = td;
00124 }
00125
00126 void
00127 TrafficGenerator::setBundleMaker( BundleMaker* bm )
00128 {
00129 if ( 0 == bm ) return;
00130 if ( 0 != m_maker ) delete m_maker;
00131 m_maker = bm;
00132 }
00133
00134 bool
00135 TrafficGenerator::handler( TrafficTrigger& event )
00136 {
00137 if ( 0 == m_timeDist ) return false;
00138 if ( 0 == m_maker ) return false;
00139 Time now = Clock::time();
00140 m_maker->generate();
00141 Time t = (*m_timeDist)( now );
00142 Clock::tentative( new TrafficTrigger( this, this, t ) );
00143 return true;
00144 }
00145
00146
00147 TrafficTrigger::TrafficTrigger( Entity* source,
00148 TrafficGenerator* destination,
00149 const Time& t ) :
00150 Event( source, t ),
00151 m_destination( destination )
00152 {
00153 }
00154
00155 TrafficTrigger::~TrafficTrigger()
00156 {
00157 }
00158
00159 bool
00160 TrafficTrigger::handle()
00161 {
00162 return m_destination->handler( *this );
00163 }