bindings/python/ns3module_helpers.cc
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sat, 04 Jul 2009 08:15:48 +0200
changeset 4654 2eaebe77d66b
parent 3952 503e8d54ee1d
permissions -rw-r--r--
Added tag ns-3.5 for changeset c975274c9707
     1 #include "ns3/ref-count-base.h"
     2 #include "ns3module.h"
     3 
     4 
     5 namespace ns3{
     6 
     7 void PythonCompleteConstruct (Ptr<Object> object, TypeId typeId, const AttributeList &attributes)
     8 {
     9   object->SetTypeId (typeId);
    10   object->Object::Construct (attributes);
    11 }
    12 
    13 }
    14 
    15 
    16 
    17 class PythonEventImpl : public ns3::EventImpl
    18 {
    19 private:
    20     PyObject *m_callback;
    21     PyObject *m_args;
    22 public:
    23     PythonEventImpl (PyObject *callback, PyObject *args)
    24     {
    25         m_callback = callback;
    26         Py_INCREF(m_callback);
    27         m_args = args;
    28         Py_INCREF(m_args);
    29     }
    30     virtual ~PythonEventImpl ()
    31     {
    32         PyGILState_STATE __py_gil_state;
    33         __py_gil_state = (PyEval_ThreadsInitialized() ? PyGILState_Ensure() : (PyGILState_STATE) 0);
    34 
    35         Py_DECREF(m_callback);
    36         Py_DECREF(m_args);
    37 
    38         if (PyEval_ThreadsInitialized())
    39             PyGILState_Release(__py_gil_state);
    40     }
    41     virtual void Notify ()
    42     {
    43         PyGILState_STATE __py_gil_state;
    44         __py_gil_state = (PyEval_ThreadsInitialized() ? PyGILState_Ensure() : (PyGILState_STATE) 0);
    45         
    46         PyObject *retval = PyObject_CallObject(m_callback, m_args);
    47         if (retval) {
    48             if (retval != Py_None) {
    49                 PyErr_SetString(PyExc_TypeError, "event callback should return None");
    50                 PyErr_Print();
    51             }
    52             Py_DECREF(retval);
    53         } else {
    54              PyErr_Print();
    55         }
    56 
    57         if (PyEval_ThreadsInitialized())
    58             PyGILState_Release(__py_gil_state);
    59     }
    60 };
    61 
    62 
    63 PyObject *
    64 _wrap_Simulator_Schedule(PyNs3Simulator *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs,
    65                          PyObject **return_exception)
    66 {
    67     PyObject *exc_type, *traceback;
    68     PyObject *py_time;
    69     PyObject *py_callback;
    70     PyObject *user_args;
    71     ns3::Ptr<PythonEventImpl> py_event_impl;
    72     PyNs3EventId *py_EventId;
    73 
    74     if (kwargs && PyObject_Length(kwargs) > 0) {
    75         PyErr_SetString(PyExc_TypeError, "keyword arguments not supported");
    76         goto error;
    77     }
    78 
    79     if (PyTuple_GET_SIZE(args) < 2) {
    80         PyErr_SetString(PyExc_TypeError, "ns3.Simulator.Schedule needs at least 2 arguments");
    81         goto error;
    82     }
    83     py_time = PyTuple_GET_ITEM(args, 0);
    84     py_callback = PyTuple_GET_ITEM(args, 1);
    85 
    86     if (!PyObject_IsInstance(py_time, (PyObject*) &PyNs3Time_Type)) {
    87         PyErr_SetString(PyExc_TypeError, "Parameter 1 should be a ns3.Time instance");
    88         goto error;
    89     }
    90     if (!PyCallable_Check(py_callback)) {
    91         PyErr_SetString(PyExc_TypeError, "Parameter 2 should be callable");
    92         goto error;
    93     }
    94     user_args = PyTuple_GetSlice(args, 2, PyTuple_GET_SIZE(args));
    95     py_event_impl = ns3::Create<PythonEventImpl>(py_callback, user_args);
    96     Py_DECREF(user_args);
    97 
    98     py_EventId = PyObject_New(PyNs3EventId, &PyNs3EventId_Type);
    99     py_EventId->obj = new ns3::EventId(
   100        ns3::Simulator::Schedule(*((PyNs3Time *) py_time)->obj, py_event_impl));
   101     return (PyObject *) py_EventId;
   102 
   103 error:
   104     PyErr_Fetch(&exc_type, return_exception, &traceback);
   105     Py_XDECREF(exc_type);
   106     Py_XDECREF(traceback);
   107     return NULL;
   108 }
   109 
   110 
   111 PyObject *
   112 _wrap_Simulator_ScheduleNow(PyNs3Simulator *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs,
   113                             PyObject **return_exception)
   114 {
   115     PyObject *exc_type, *traceback;
   116     PyObject *py_callback;
   117     PyObject *user_args;
   118     ns3::Ptr<PythonEventImpl> py_event_impl;
   119     PyNs3EventId *py_EventId;
   120 
   121     if (kwargs && PyObject_Length(kwargs) > 0) {
   122         PyErr_SetString(PyExc_TypeError, "keyword arguments not supported");
   123         goto error;
   124     }
   125 
   126     if (PyTuple_GET_SIZE(args) < 1) {
   127         PyErr_SetString(PyExc_TypeError, "ns3.Simulator.Schedule needs at least 1 argument");
   128         goto error;
   129     }
   130     py_callback = PyTuple_GET_ITEM(args, 0);
   131 
   132     if (!PyCallable_Check(py_callback)) {
   133         PyErr_SetString(PyExc_TypeError, "Parameter 2 should be callable");
   134         goto error;
   135     }
   136     user_args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
   137     py_event_impl = ns3::Create<PythonEventImpl>(py_callback, user_args);
   138     Py_DECREF(user_args);
   139 
   140     py_EventId = PyObject_New(PyNs3EventId, &PyNs3EventId_Type);
   141     py_EventId->obj = new ns3::EventId(ns3::Simulator::ScheduleNow(py_event_impl));
   142     return (PyObject *) py_EventId;
   143 
   144 error:
   145     PyErr_Fetch(&exc_type, return_exception, &traceback);
   146     Py_XDECREF(exc_type);
   147     Py_XDECREF(traceback);
   148     return NULL;
   149 }
   150 
   151 
   152 PyObject *
   153 _wrap_Simulator_ScheduleDestroy(PyNs3Simulator *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs,
   154                                 PyObject **return_exception)
   155 {
   156     PyObject *exc_type, *traceback;
   157     PyObject *py_callback;
   158     PyObject *user_args;
   159     ns3::Ptr<PythonEventImpl> py_event_impl;
   160     PyNs3EventId *py_EventId;
   161 
   162     if (kwargs && PyObject_Length(kwargs) > 0) {
   163         PyErr_SetString(PyExc_TypeError, "keyword arguments not supported");
   164         goto error;
   165     }
   166 
   167     if (PyTuple_GET_SIZE(args) < 1) {
   168         PyErr_SetString(PyExc_TypeError, "ns3.Simulator.Schedule needs at least 1 argument");
   169         goto error;
   170     }
   171     py_callback = PyTuple_GET_ITEM(args, 0);
   172 
   173     if (!PyCallable_Check(py_callback)) {
   174         PyErr_SetString(PyExc_TypeError, "Parameter 2 should be callable");
   175         goto error;
   176     }
   177     user_args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
   178     py_event_impl = ns3::Create<PythonEventImpl>(py_callback, user_args);
   179     Py_DECREF(user_args);
   180 
   181     py_EventId = PyObject_New(PyNs3EventId, &PyNs3EventId_Type);
   182     py_EventId->obj = new ns3::EventId(ns3::Simulator::ScheduleDestroy(py_event_impl));
   183     return (PyObject *) py_EventId;
   184 
   185 error:
   186     PyErr_Fetch(&exc_type, return_exception, &traceback);
   187     Py_XDECREF(exc_type);
   188     Py_XDECREF(traceback);
   189     return NULL;
   190 }
   191 
   192 
   193 PyObject *
   194 _wrap_TypeId_LookupByNameFailSafe(PyNs3TypeId *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs,
   195                                   PyObject **return_exception)
   196 {
   197     bool ok;
   198     const char *name;
   199     Py_ssize_t name_len;
   200     ns3::TypeId tid;
   201     PyNs3TypeId *py_tid;
   202     const char *keywords[] = {"name", NULL};
   203     
   204     if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *) "s#", (char **) keywords, &name, &name_len)) {
   205         PyObject *exc_type, *traceback;
   206         PyErr_Fetch(&exc_type, return_exception, &traceback);
   207         Py_XDECREF(exc_type);
   208         Py_XDECREF(traceback);
   209         return NULL;
   210     }
   211     ok = ns3::TypeId::LookupByNameFailSafe(std::string(name, name_len), &tid);
   212     if (!ok)
   213     {
   214         PyErr_Format(PyExc_KeyError, "The ns3 type with name `%s' is not registered", name);
   215         return NULL;
   216     }
   217 
   218     py_tid = PyObject_New(PyNs3TypeId, &PyNs3TypeId_Type);
   219     py_tid->obj = new ns3::TypeId (tid);
   220     PyNs3TypeId_wrapper_registry[(void *) py_tid->obj] = (PyObject *) py_tid;    
   221     
   222     return (PyObject *) py_tid;
   223 }
   224 
   225 
   226 class CommandLinePythonValueSetter : public ns3::RefCountBase
   227 {
   228     PyObject *m_namespace;
   229     std::string m_variable;
   230 public:
   231     CommandLinePythonValueSetter (PyObject *ns, std::string const &variable) {
   232         Py_INCREF(ns);
   233         m_namespace = ns;
   234         m_variable = variable;
   235     }
   236     bool Parse (std::string value) {
   237         PyObject *pyvalue = PyString_FromStringAndSize (value.data(), value.size());
   238         PyObject_SetAttrString (m_namespace, (char *) m_variable.c_str(), pyvalue);
   239         if (PyErr_Occurred()) {
   240             PyErr_Print();
   241             return false;
   242         }
   243         return true;
   244     }
   245     virtual ~CommandLinePythonValueSetter () {
   246         Py_DECREF (m_namespace);
   247         m_namespace = NULL;
   248     }
   249     
   250 };
   251 
   252 PyObject *
   253 _wrap_CommandLine_AddValue(PyNs3CommandLine *self, PyObject *args, PyObject *kwargs,
   254                            PyObject **return_exception)
   255 {
   256     const char *name, *help, *variable = NULL;
   257     PyObject *py_namespace = NULL;
   258     const char *keywords[] = {"name", "help", "variable", "namespace", NULL};
   259     
   260     if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *) "ss|sO", (char **) keywords, &name, &help, &variable, &py_namespace)) {
   261         PyObject *exc_type, *traceback;
   262         PyErr_Fetch(&exc_type, return_exception, &traceback);
   263         Py_XDECREF(exc_type);
   264         Py_XDECREF(traceback);
   265         return NULL;
   266     }
   267     
   268     if (variable == NULL) {
   269         variable = name;
   270     }
   271     if (py_namespace == NULL) {
   272         py_namespace = (PyObject *) self;
   273     }
   274 
   275     ns3::Ptr<CommandLinePythonValueSetter> setter = ns3::Create<CommandLinePythonValueSetter> (py_namespace, variable);
   276     self->obj->AddValue (name, help, ns3::MakeCallback (&CommandLinePythonValueSetter::Parse, setter));
   277 
   278     Py_INCREF(Py_None);
   279     return Py_None;
   280 }
   281 
   282 
   283 PyObject *
   284 _wrap_Simulator_Run(PyNs3Simulator *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs,
   285                     PyObject **return_exception)
   286 {
   287     const char *keywords[] = {"signal_check_frequency", NULL};
   288     int signal_check_frequency = 100;
   289     
   290     if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *) "|i", (char **) keywords, &signal_check_frequency)) {
   291         PyObject *exc_type, *traceback;
   292         PyErr_Fetch(&exc_type, return_exception, &traceback);
   293         Py_XDECREF(exc_type);
   294         Py_XDECREF(traceback);
   295         return NULL;
   296     }
   297 
   298     PyThreadState *py_thread_state = NULL;
   299 
   300     if (signal_check_frequency == -1)
   301     {
   302         if (PyEval_ThreadsInitialized ())
   303             py_thread_state = PyEval_SaveThread();
   304         ns3::Simulator::Run();
   305         if (py_thread_state)
   306             PyEval_RestoreThread(py_thread_state);
   307     } else {
   308         while (!ns3::Simulator::IsFinished())
   309         {        
   310             if (PyEval_ThreadsInitialized())
   311                 py_thread_state = PyEval_SaveThread();
   312 
   313             for (int n = signal_check_frequency; n > 0 && !ns3::Simulator::IsFinished(); --n)
   314             {        
   315                 ns3::Simulator::RunOneEvent();
   316             }
   317             
   318             if (py_thread_state)
   319                 PyEval_RestoreThread(py_thread_state);
   320             PyErr_CheckSignals();
   321             if (PyErr_Occurred())
   322                 return NULL;
   323         }
   324     }
   325     Py_INCREF(Py_None);
   326     return Py_None;
   327 }
   328