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
00033 #include "PythonTimeDistribution.h"
00034 #include "simlpy/SimulationException.h"
00035
00036 #include <iostream>
00037
00038 PythonTimeDistribution::PythonTimeDistribution() :
00039 m_f( 0 )
00040 {
00041 }
00042
00043 PythonTimeDistribution::~PythonTimeDistribution()
00044 {
00045 if ( 0 != m_f )
00046 {
00047 Py_DECREF( m_f );
00048 }
00049 }
00050
00051 Time
00052 PythonTimeDistribution::operator()( const Time& t )
00053 {
00054 if ( 0 == m_f )
00055 {
00056 std::cerr << "No function configured" << std::endl;
00057 throw SimulationException( __FILE__ , __LINE__ );
00058 }
00059 PyObject* l = PyList_New(0);
00060 if ( 0 == l )
00061 {
00062 std::cerr << "Could not allocate a new list" << std::endl;
00063 throw SimulationException( __FILE__ , __LINE__ );
00064 }
00065 PyObject* li = PyLong_FromLong( t.tv.tv_sec );
00066 if ( 0 == li )
00067 {
00068 Py_DECREF(l);
00069 std::cerr << "Could not allocate a new long" << std::endl;
00070 throw SimulationException( __FILE__ , __LINE__ );
00071 }
00072 if ( 0 > PyList_Append(l,li) )
00073 {
00074 Py_DECREF(l);
00075 Py_DECREF(li);
00076 std::cerr << "Error adding to the argument list" << std::endl;
00077 throw SimulationException( __FILE__ , __LINE__ );
00078 }
00079 li = PyLong_FromLong( t.tv.tv_usec );
00080 if ( 0 == li )
00081 {
00082 Py_DECREF(l);
00083 std::cerr << "Could not allocate a new long" << std::endl;
00084 throw SimulationException( __FILE__ , __LINE__ );
00085 }
00086 if ( 0 > PyList_Append(l,li) )
00087 {
00088 Py_DECREF(l);
00089 Py_DECREF(li);
00090 std::cerr << "Error adding to the argument list" << std::endl;
00091 throw SimulationException( __FILE__ , __LINE__ );
00092 }
00093 PyObject* r = PyObject_CallFunctionObjArgs( m_f, l, 0 );
00094 Py_DECREF(l);
00095 if ( 0 == r )
00096 {
00097 std::cerr << "Function generated an error" << std::endl;
00098 throw SimulationException( __FILE__ , __LINE__ );
00099 }
00100 if ( ! PyList_Check(r) )
00101 {
00102 Py_DECREF(r);
00103 std::cerr << "Function should have returned a list, but didn't"
00104 << std::endl;
00105 throw SimulationException( __FILE__ , __LINE__ );
00106 }
00107 if ( PyList_Size(r) < 2 )
00108 {
00109 Py_DECREF(r);
00110 std::cerr << "Function should have returned a list of length 2"
00111 << std::endl;
00112 throw SimulationException( __FILE__ , __LINE__ );
00113 }
00114 li = PyList_GetItem(r,0);
00115 if ( ! PyLong_Check( li ) )
00116 {
00117 Py_DECREF(r);
00118 std::cerr << "Returned list should have long int values" << std::endl;
00119 throw SimulationException( __FILE__ , __LINE__ );
00120 }
00121 long s = PyLong_AsLong(li);
00122 li = PyList_GetItem(r,1);
00123 if ( ! PyLong_Check( li ) )
00124 {
00125 Py_DECREF(r);
00126 std::cerr << "Returned list should have long int values" << std::endl;
00127 throw SimulationException( __FILE__ , __LINE__ );
00128 }
00129 long us = PyLong_AsLong(li);
00130 Time retval(s,us);
00131 Py_DECREF(r);
00132 return retval;
00133 }
00134
00135 void
00136 PythonTimeDistribution::setFunc( PyObject* f )
00137 {
00138 if ( 0 == f )
00139 {
00140 std::cerr << "NULL object passed" << std::endl;
00141 throw SimulationException( __FILE__ , __LINE__ );
00142 }
00143 if ( ! PyCallable_Check( f ) )
00144 {
00145 std::cerr << "Argument is not callable" << std::endl;
00146 throw SimulationException( __FILE__ , __LINE__ );
00147 }
00148 m_f = f;
00149 Py_INCREF(m_f);
00150 }