reactor-c
C Runtime for Lingua Franca
Loading...
Searching...
No Matches
python_port.c File Reference
#include <stddef.h>
#include <Python.h>
#include "python_port.h"
#include "reactor.h"
#include "api/schedule.h"
#include "api/reaction_macros.h"

Functions

void python_count_decrement (void *py_object)
 
PyObject * py_port_set (PyObject *self, PyObject *args)
 
void py_port_capsule_dealloc (generic_port_capsule_struct *self)
 
PyObject * py_port_capsule_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
 
PyObject * py_port_iter (PyObject *self)
 
PyObject * py_port_iter_next (PyObject *self)
 
PyObject * py_port_capsule_get_item (PyObject *self, PyObject *key)
 
int py_port_capsule_assign_get_item (PyObject *self, PyObject *item, PyObject *value)
 
Py_ssize_t py_port_length (PyObject *self)
 
int py_port_capsule_init (generic_port_capsule_struct *self, PyObject *args, PyObject *kwds)
 

Variables

PyTypeObject py_port_capsule_t
 
PyMappingMethods py_port_as_mapping
 
PyMemberDef py_port_capsule_members []
 
PyMethodDef py_port_capsule_methods []
 

Detailed Description

Author
Soroush Bateni (sorou.nosp@m.sh@u.nosp@m.tdall.nosp@m.as.e.nosp@m.du) @autohr Hou Seng Wong (house.nosp@m.ngw@.nosp@m.berke.nosp@m.ley..nosp@m.edu)

LICENSE

Copyright (c) 2022, The University of California at Berkeley. Copyright (c) 2021, The University of Texas at Dallas.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

DESCRIPTION

Implementation of functions defined in

See also
pythontarget.h

Function Documentation

◆ py_port_capsule_assign_get_item()

int py_port_capsule_assign_get_item ( PyObject * self,
PyObject * item,
PyObject * value )

This function is overloaded to prevent directly assigning to multiports. The set function currently is the only way to assign value to ports.

Parameters
selfThe port of type LinguaFranca.port_capsule
itemThe index (which is ignored)
valueThe value to be assigned (which is ignored)

◆ py_port_capsule_dealloc()

void py_port_capsule_dealloc ( generic_port_capsule_struct * self)

Called when a port_capsule has to be deallocated (generally by the Python garbage collector).

Parameters
selfAn instance of generic_port_instance_struct*

◆ py_port_capsule_get_item()

PyObject * py_port_capsule_get_item ( PyObject * self,
PyObject * key )

Get an item from a Linugua Franca port capsule type. If a port is a not a multiport, it will have a width of -2 (

See also
CGenerator.xtend). In this case, this function will return the port capsule itself. If a port is a multiport, this function will convert the index item and convert it into a C long long, and use it to access the underlying array stored in the PyCapsule as "port". A new non-multiport capsule is created and returned, which in turn can be used as an ordinary LinguaFranca.port_capsule.
Parameters
selfThe port which can be a multiport or a singular port
keyThe index (key) which is used to retrieve an item from the underlying C array if the port is a multiport.

◆ py_port_capsule_init()

int py_port_capsule_init ( generic_port_capsule_struct * self,
PyObject * args,
PyObject * kwds )

Initialize the port capsule self with the given optional values for port, value, is_present, and num_destinations. If any of these arguments are missing, the default values are assigned

See also
port_intance_new
Parameters
selfThe port_instance PyObject that follows the generic_port_instance_struct* internal structure
argsThe optional arguments that are:
  • port: A capsule that holds a void* to the underlying C port
  • value: value of the port
  • is_present: An indication of whether or not the value of the port is present at the current logical time.
  • current_index: Used to reference multiports in the iterator
  • width: Used to indicate the width of a multiport. If the port is not a multiport, this field will be -2.

◆ py_port_capsule_new()

PyObject * py_port_capsule_new ( PyTypeObject * type,
PyObject * args,
PyObject * kwds )

Create a new port_capsule. Note that a LinguaFranca.port_capsule PyObject follows the same structure as the

See also
generic_port_capsule_struct.

To initialize the port_capsule, this function first initializes a generic_port_capsule_struct* self using the tp_alloc property of port_capsule (

See also
py_port_capsule_t) and then assigns the members of self with default values of port= NULL, value = NULL, is_present = false, current_index = 0, width = -2.
Parameters
typeThe Python type object. In this case, py_port_capsule_t
argsThe optional arguments that are:
  • port: A capsule that holds a void* to the underlying C port
  • value: value of the port
  • is_present: An indication of whether or not the value of the port is present at the current logical time.
  • current_index: Used to reference multiports in the iterator
  • width: Used to indicate the width of a multiport. If the port is not a multiport, this field will be -2.
kwdsKeywords (
See also
Python keywords)

◆ py_port_iter()

PyObject * py_port_iter ( PyObject * self)

Return an iterator for self, which is a port. This function just have to exist to tell Python that ports are iterable.

For example to make for p in foo_multiport: p.set(42) possible in Python.

◆ py_port_iter_next()

PyObject * py_port_iter_next ( PyObject * self)

The function that is responsible for getting the next item in the iterator for a multiport.

This would make the following code possible in the Python target: for p in foo_multiport: p.set(42)

◆ py_port_length()

Py_ssize_t py_port_length ( PyObject * self)

A function that allows the invocation of len() on a port.

Parameters
selfA port of type LinguaFranca.port_capsule

◆ py_port_set()

PyObject * py_port_set ( PyObject * self,
PyObject * args )

Set the value and is_present field of self which is of type LinguaFranca.port_capsule

Each LinguaFranca.port_capsule includes a void* pointer of the C port (a.k.a. generic_port_instance_struct*).

See also
generic_port_capsule_struct in pythontarget.h

This function calls the underlying _LF_SET API.

See also
xtext/org.icyphy.linguafranca/src/lib/core/reactor.h

This function can be used to set any type of PyObject ranging from primitive types to complex lists and tuples. Moreover, this function is callable from Python target code by using port_name.out(value)

Some examples include port_name.out("Hello") port_name.out(5) port_name.out(["Hello", 5 , (2.8, "X")])

The port type given in the Lingua Franca is only used as a "suggestion" as per Python's duck typing principles. The end-user is responsible for appropriately handling types on the recieveing end of this port.

Parameters
selfThe output port (by name) or input of a contained reactor in form instance_name.port_name.
argscontains:
  • val: The value to insert into the port struct.

◆ python_count_decrement()

void python_count_decrement ( void * py_object)

Decrease the reference count of PyObject. When the reference count hits zero, Python can free its memory.

Parameters
py_objectA PyObject with count 1 or greater.

Variable Documentation

◆ py_port_as_mapping

PyMappingMethods py_port_as_mapping
Initial value:
= {(lenfunc)py_port_length, (binaryfunc)py_port_capsule_get_item,
int py_port_capsule_assign_get_item(PyObject *self, PyObject *item, PyObject *value)
Definition python_port.c:287
Py_ssize_t py_port_length(PyObject *self)
Definition python_port.c:297
PyObject * py_port_capsule_get_item(PyObject *self, PyObject *key)
Definition python_port.c:233

Methods that convert a LinguaFranca.port_capsule into a mapping, which allows it to be subscriptble.

◆ py_port_capsule_members

PyMemberDef py_port_capsule_members[]
Initial value:
= {
{"port", T_OBJECT, offsetof(generic_port_capsule_struct, port), READONLY, ""},
{"value", T_OBJECT, offsetof(generic_port_capsule_struct, value), READONLY, "Value of the port"},
{"is_present", T_BOOL, offsetof(generic_port_capsule_struct, is_present), READONLY,
"Check if value is present at current logical time"},
{"width", T_INT, offsetof(generic_port_capsule_struct, width), READONLY, "Width of the multiport"},
}
#define FEDERATED_CAPSULE_MEMBER
Definition python_capsule_extension.h:76
Definition python_port.h:91

◆ py_port_capsule_methods

PyMethodDef py_port_capsule_methods[]
Initial value:
= {
{"__getitem__", (PyCFunction)py_port_capsule_get_item, METH_O | METH_COEXIST, "x.__getitem__(y) <==> x[y]"},
{"set", (PyCFunction)py_port_set, METH_VARARGS, "Set value of the port as well as the is_present field"},
{NULL}
}
PyObject * py_port_set(PyObject *self, PyObject *args)
Definition python_port.c:81

◆ py_port_capsule_t

PyTypeObject py_port_capsule_t
Initial value:
= {
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "LinguaFranca.port_capsule",
.tp_doc = "port_capsule objects",
.tp_basicsize = sizeof(generic_port_capsule_struct),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_as_mapping = &py_port_as_mapping,
.tp_iter = py_port_iter,
.tp_iternext = py_port_iter_next,
.tp_init = (initproc)py_port_capsule_init,
.tp_dealloc = (destructor)py_port_capsule_dealloc,
.tp_members = py_port_capsule_members,
.tp_methods = py_port_capsule_methods,
}
PyObject * py_port_iter(PyObject *self)
Definition python_port.c:169
PyMemberDef py_port_capsule_members[]
Definition python_port.c:360
int py_port_capsule_init(generic_port_capsule_struct *self, PyObject *args, PyObject *kwds)
Definition python_port.c:326
PyMappingMethods py_port_as_mapping
Definition python_port.c:307
PyObject * py_port_capsule_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Definition python_port.c:146
void py_port_capsule_dealloc(generic_port_capsule_struct *self)
Definition python_port.c:120
PyObject * py_port_iter_next(PyObject *self)
Definition python_port.c:183
PyMethodDef py_port_capsule_methods[]
Definition python_port.c:374