Skip to content

Commit

Permalink
New valuetype field for inputs and post-load callback for handler
Browse files Browse the repository at this point in the history
  • Loading branch information
psychogenic committed Jun 12, 2019
1 parent a84cc4d commit 6213823
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 11 deletions.
42 changes: 34 additions & 8 deletions src/ExternalModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ ExternalModule::~ExternalModule() {
}

bool ExternalModule::load() {
SERIALUI_DEBUG_OUTLN(F("EXT MOD LOAD"));

if (is_loaded) {
SERIALUI_DEBUG_OUTLN(F("already loaded"));
return true;
}

SERIALUI_DEBUG_OUTLN(F("EXT MOD LOAD"));
if (load_attempted) {
SERIALUI_DEBUG_OUTLN(F("already attempted to load (and failed)"));
return false;
Expand All @@ -95,32 +96,50 @@ bool ExternalModule::load() {
pModule = PyImport_Import(pName);
if (!pModule) {
SERIALUI_DEBUG_OUTLN("Failed to load module!");

if (PyErr_Occurred()) {
PyErr_Print();
}
return false;
}
SERIALUI_DEBUG_OUTLN("loaded module!");

// dict is a borrowed reference.
CPyObject dict = PyModule_GetDict(pModule);
if (!dict) {
PyErr_Print();
if (PyErr_Occurred()) {
PyErr_Print();
}
SERIALUI_DEBUG_OUTLN("Couldn't get dict");
return false;
}
CPyObject pHandlerName = PyDict_GetItemString(dict, "SerialUIHandler");
if (!pHandlerName) {
PyErr_Print();
if (PyErr_Occurred()) {
PyErr_Print();
}
SERIALUI_DEBUG_OUTLN("Couldn't get SerialUIHandler name");
return 1;
}
if (PyCallable_Check(pHandlerName)) {
pHandler = PyObject_CallObject(pHandlerName, nullptr);
if (! pHandler) {
if (PyErr_Occurred()) {
PyErr_Print();
}

return false;
}
PyDict_SetItem(dict, Py_BuildValue("s", "HANDLER"), pHandler);

} else {
SERIALUI_DEBUG_OUTLN("Couldn't instantiate SerialUIHandler");
return 1;
return false;
}

is_loaded = true;


PyObject* hb = PyObject_GetAttrString(pHandler, "heartbeat");
if (hb && PyCallable_Check(hb)) {
pHeartbeat = hb;
Expand All @@ -129,10 +148,17 @@ bool ExternalModule::load() {
});

} else {
PyErr_Clear(); // doesn't matter
PyErr_Clear(); // not implemented, doesn't matter
}

CPyObject loadedCallback = PyObject_GetAttrString(pHandler, "loaded");
if (loadedCallback && PyCallable_Check(loadedCallback)) {
CPyObject loadedRet = PyObject_CallObject(loadedCallback, nullptr);

} else {
PyErr_Clear(); // not implemented, doesn't matter
}

is_loaded = true;
return true;

}
Expand Down Expand Up @@ -197,7 +223,7 @@ bool ExternalModule::trigger(Menu::Item::Request::Request * req) {


bool ExternalModule::trigger(Menu::Item::Command * cmd) {
SERIALUI_DEBUG_OUT(F("ExternalModule::trigger() "));
SERIALUI_DEBUG_OUT(F("ExternalModule::trigger() cmd "));
if (!load()) {
SERIALUI_DEBUG_OUTLN(F("could not load"));
return false;
Expand Down
24 changes: 21 additions & 3 deletions src/ExternalPython.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ typedef struct { \
uint8_t id; \
baseType * sui_item; \
typeEnum type; \
uint8_t valuetype; \
itmType * itmAccessor; \
PyObject * callbacks[SUIPY_WRAPPER_MAXCALLBACKS]; \
} basename##Object; \
Expand All @@ -408,6 +409,7 @@ static PyMemberDef basename##_members[] = { \
{ "help", T_OBJECT_EX, offsetof(basename##Object, help), 0, "help string" }, \
{ "id", T_INT, offsetof(basename##Object, id), 0, "item id" }, \
{ "type", T_INT, offsetof(basename##Object, type), 0, "item type id" }, \
{ "valuetype", T_INT, offsetof(basename##Object, valuetype), 0, "item valuetype id" }, \
{ NULL } \
}; \
static PyObject * basename##_new(PyTypeObject *type, \
Expand All @@ -430,6 +432,7 @@ static PyObject * basename##_new(PyTypeObject *type, \
self->callbacks[i] = NULL; \
}\
self->id = 0; \
self->valuetype = 0; \
self->sui_item = NULL; \
self->itmAccessor = NULL; \
} \
Expand Down Expand Up @@ -807,6 +810,7 @@ static int SUIInputWrapper_init(SUIInputWrapperObject *self, PyObject *args,
self->sui_item = itm;
self->id = itm->id();
self->type = itm->type();

SERIALUI_DEBUG_OUTLN("Init request obj for id " << (int)self->id);
SerialUI::Python::SUIPyObjectsStore.addInput(self->id, (PyObject*)self);

Expand All @@ -818,6 +822,7 @@ static int SUIInputWrapper_init(SUIInputWrapperObject *self, PyObject *args,
return -1;
}
self->request = req;
self->valuetype = (uint8_t)(req->requestType());

return 0;
}
Expand Down Expand Up @@ -1216,6 +1221,18 @@ SUICommandWrapper_triggered(SUICommandWrapperObject *self, PyObject * args) {
Py_RETURN_NONE;
}

static PyObject *
SUICommandWrapper_dotrigger(SUICommandWrapperObject *self, PyObject * args) {
if (self->command) {
SERIALUI_DEBUG_OUTLN("Actually triggering command");
self->command->call(SerialUI::Globals::state()->currentMenu());
Py_RETURN_TRUE;
}

Py_RETURN_FALSE;

}


/*
* SUIItemContainer methods listing
Expand All @@ -1225,9 +1242,9 @@ static PyMethodDef SUICommandWrapper_methods[] = {
{ "triggered", (PyCFunction) SUICommandWrapper_triggered, METH_NOARGS,
"Called when command is triggered" },
{ "setOnTriggered", (PyCFunction) SUICommandWrapper_setOnTrigger, METH_VARARGS,
"Override tiggered() callback" },


"Override triggered() callback" },
{ "trigger", (PyCFunction) SUICommandWrapper_dotrigger, METH_NOARGS,
"Manually trigger this command" },
{ NULL } /* Sentinel */
};

Expand Down Expand Up @@ -1772,6 +1789,7 @@ static int SUITrackedState_init(SUITrackedStateObject *self, PyObject *args,
self->state_obj = self->sui_item;
self->id = self->sui_item->id();
self->type = self->state_obj->type();
self->valuetype = (uint8_t)self->type;

return 0;
}
Expand Down

0 comments on commit 6213823

Please sign in to comment.