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