move callbacks into python class, simplify demobot
This commit is contained in:
parent
260386bcac
commit
05020f126e
4 changed files with 103 additions and 72 deletions
|
|
@ -16,15 +16,15 @@ import (
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
typedef void (*on_event_handler_ptr) (char*);
|
typedef void (*on_event_handler_ptr) (char*, void*);
|
||||||
typedef void (*on_message_handler_ptr) (char*);
|
typedef void (*on_message_handler_ptr) (char*, void*);
|
||||||
|
|
||||||
static inline void call_c_on_event_handler(on_event_handler_ptr ptr, char* jsonStr) {
|
static inline void call_c_on_event_handler(on_event_handler_ptr ptr, char* jsonStr, void* pobj) {
|
||||||
(ptr)(jsonStr);
|
(ptr)(jsonStr, pobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void call_c_on_message_handler(on_message_handler_ptr ptr, char* jsonStr) {
|
static inline void call_c_on_message_handler(on_message_handler_ptr ptr, char* jsonStr, void* pobj) {
|
||||||
(ptr)(jsonStr);
|
(ptr)(jsonStr, pobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
@ -36,27 +36,31 @@ matrix client with c callback
|
||||||
type CBClient struct {
|
type CBClient struct {
|
||||||
*mxclient.MXClient
|
*mxclient.MXClient
|
||||||
on_event_handler C.on_event_handler_ptr
|
on_event_handler C.on_event_handler_ptr
|
||||||
|
on_event_handler_pobj unsafe.Pointer
|
||||||
on_message_handler C.on_message_handler_ptr
|
on_message_handler C.on_message_handler_ptr
|
||||||
|
on_message_handler_pobj unsafe.Pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *CBClient) OnEvent(s string) {
|
func (cli *CBClient) OnEvent(s string) {
|
||||||
cStr := C.CString(s)
|
cStr := C.CString(s)
|
||||||
defer C.free(unsafe.Pointer(cStr))
|
defer C.free(unsafe.Pointer(cStr))
|
||||||
C.call_c_on_event_handler(cli.on_event_handler, cStr)
|
C.call_c_on_event_handler(cli.on_event_handler, cStr, cli.on_event_handler_pobj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *CBClient) OnMessage(s string) {
|
func (cli *CBClient) OnMessage(s string) {
|
||||||
cStr := C.CString(s)
|
cStr := C.CString(s)
|
||||||
defer C.free(unsafe.Pointer(cStr))
|
defer C.free(unsafe.Pointer(cStr))
|
||||||
C.call_c_on_message_handler(cli.on_message_handler, cStr)
|
C.call_c_on_message_handler(cli.on_message_handler, cStr, cli.on_message_handler_pobj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *CBClient) Set_on_event_handler(fn C.on_event_handler_ptr) {
|
func (cli *CBClient) Set_on_event_handler(fn C.on_event_handler_ptr, pobj unsafe.Pointer) {
|
||||||
cli.on_event_handler = fn
|
cli.on_event_handler = fn
|
||||||
|
cli.on_event_handler_pobj = pobj
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *CBClient) Set_on_message_handler(fn C.on_message_handler_ptr) {
|
func (cli *CBClient) Set_on_message_handler(fn C.on_message_handler_ptr, pobj unsafe.Pointer) {
|
||||||
cli.on_message_handler = fn
|
cli.on_message_handler = fn
|
||||||
|
cli.on_message_handler_pobj = pobj
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCClient creates a new Matrix Client ready for syncing
|
// NewCClient creates a new Matrix Client ready for syncing
|
||||||
|
|
@ -65,7 +69,7 @@ func NewCBClient(homeserverURL string, userID id.UserID, accessToken string) (*C
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &CBClient{client, nil, nil}, nil
|
return &CBClient{client, nil, nil, nil, nil}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -179,7 +183,7 @@ func apiv0_createclient(storage_path *C.char, url *C.char, userID *C.char, acces
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(fmt.Sprintf("ERR: %v", err))
|
return C.CString(fmt.Sprintf("ERR: %v", err))
|
||||||
}
|
}
|
||||||
client := &CBClient{mxclient, nil, nil}
|
client := &CBClient{mxclient, nil, nil, nil, nil}
|
||||||
cclients = append(cclients, client)
|
cclients = append(cclients, client)
|
||||||
return C.CString(fmt.Sprintf("{ \"id:\"SUCESS. ID=%d\n", len(cclients)))
|
return C.CString(fmt.Sprintf("{ \"id:\"SUCESS. ID=%d\n", len(cclients)))
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +194,7 @@ func apiv0_createclient_pass(mxpassfile_path *C.char, storage_path *C.char, url
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(fmt.Sprintf("ERR: %v", err))
|
return C.CString(fmt.Sprintf("ERR: %v", err))
|
||||||
}
|
}
|
||||||
client := &CBClient{mxclient, nil, nil}
|
client := &CBClient{mxclient, nil, nil, nil, nil}
|
||||||
mxclient.OnEvent = client.OnEvent
|
mxclient.OnEvent = client.OnEvent
|
||||||
mxclient.OnMessage = client.OnMessage
|
mxclient.OnMessage = client.OnMessage
|
||||||
cclients = append(cclients, client)
|
cclients = append(cclients, client)
|
||||||
|
|
@ -203,24 +207,24 @@ func apiv0_createclient_pass(mxpassfile_path *C.char, storage_path *C.char, url
|
||||||
}
|
}
|
||||||
|
|
||||||
//export apiv0_set_on_event_handler
|
//export apiv0_set_on_event_handler
|
||||||
func apiv0_set_on_event_handler(cid C.int, fn C.on_event_handler_ptr) *C.char {
|
func apiv0_set_on_event_handler(cid C.int, fn C.on_event_handler_ptr, pobj unsafe.Pointer) *C.char {
|
||||||
cli, err := getClient(int(cid))
|
cli, err := getClient(int(cid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(fmt.Sprintf("ERR: %v", err))
|
return C.CString(fmt.Sprintf("ERR: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.Set_on_event_handler(fn)
|
cli.Set_on_event_handler(fn, pobj)
|
||||||
return C.CString("SUCCESS.")
|
return C.CString("SUCCESS.")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export apiv0_set_on_message_handler
|
//export apiv0_set_on_message_handler
|
||||||
func apiv0_set_on_message_handler(cid C.int, fn C.on_message_handler_ptr) *C.char {
|
func apiv0_set_on_message_handler(cid C.int, fn C.on_message_handler_ptr, pobj unsafe.Pointer) *C.char {
|
||||||
cli, err := getClient(int(cid))
|
cli, err := getClient(int(cid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(fmt.Sprintf("ERR: %v", err))
|
return C.CString(fmt.Sprintf("ERR: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.Set_on_message_handler(fn)
|
cli.Set_on_message_handler(fn, pobj)
|
||||||
return C.CString("SUCCESS.")
|
return C.CString("SUCCESS.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ ffibuilder.set_source(
|
||||||
|
|
||||||
ffibuilder.cdef(
|
ffibuilder.cdef(
|
||||||
csource="""
|
csource="""
|
||||||
typedef void (*on_event_handler_ptr) (char*);
|
typedef void (*on_event_handler_ptr) (char*, void*);
|
||||||
typedef void (*on_message_handler_ptr) (char*);
|
typedef void (*on_message_handler_ptr) (char*, void*);
|
||||||
extern void FreeCString(char* s);
|
extern void FreeCString(char* s);
|
||||||
extern char* cli_discoverhs(char* mxid);
|
extern char* cli_discoverhs(char* mxid);
|
||||||
extern char* cli_mkmxtoken(char* mxid, char* pw);
|
extern char* cli_mkmxtoken(char* mxid, char* pw);
|
||||||
|
|
@ -28,8 +28,8 @@ ffibuilder.cdef(
|
||||||
extern char* apiv0_login(char* data);
|
extern char* apiv0_login(char* data);
|
||||||
extern char* apiv0_createclient(char* storage_path, char* hs, char* mxid, char* accessToken);
|
extern char* apiv0_createclient(char* storage_path, char* hs, char* mxid, char* accessToken);
|
||||||
extern char* apiv0_createclient_pass(char* mxpassfile, char* storage_path, char* hs, char* localpart, char* domain);
|
extern char* apiv0_createclient_pass(char* mxpassfile, char* storage_path, char* hs, char* localpart, char* domain);
|
||||||
extern char* apiv0_set_on_event_handler(int cid, on_event_handler_ptr ptr);
|
extern char* apiv0_set_on_event_handler(int cid, on_event_handler_ptr ptr, void* pobj);
|
||||||
extern char* apiv0_set_on_message_handler(int cid, on_message_handler_ptr ptr);
|
extern char* apiv0_set_on_message_handler(int cid, on_message_handler_ptr ptr, void* pobj);
|
||||||
extern char* apiv0_startclient(int cid);
|
extern char* apiv0_startclient(int cid);
|
||||||
extern char* apiv0_stopclient(int cid);
|
extern char* apiv0_stopclient(int cid);
|
||||||
extern char* apiv0_sendmessage(int cid, char* data);
|
extern char* apiv0_sendmessage(int cid, char* data);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ from time import time_ns
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
from smal.bot import SMALBot
|
from smal.bot import SMALBot
|
||||||
from _pygomx import lib, ffi
|
|
||||||
|
|
||||||
# setup logging, we want timestamps
|
# setup logging, we want timestamps
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
|
|
@ -18,17 +17,12 @@ logger.setLevel(level=logging.INFO)
|
||||||
DEFAULT_PREFIX = "!"
|
DEFAULT_PREFIX = "!"
|
||||||
|
|
||||||
|
|
||||||
@ffi.callback("void(char*)")
|
class DemoBot(SMALBot):
|
||||||
def on_event(evt):
|
|
||||||
e = ffi.string(evt)
|
def on_event(self, evt):
|
||||||
print("Got an event: ", e)
|
print("Got an event: ", e)
|
||||||
|
|
||||||
|
def on_message(self, msg):
|
||||||
@ffi.callback("void(char*)")
|
|
||||||
def on_message(msg):
|
|
||||||
m = ffi.string(msg).decode("utf-8")
|
|
||||||
|
|
||||||
msg = json.loads(m)
|
|
||||||
|
|
||||||
if msg["type"] != "m.room.message":
|
if msg["type"] != "m.room.message":
|
||||||
# not a room message
|
# not a room message
|
||||||
|
|
@ -64,9 +58,7 @@ def on_message(msg):
|
||||||
def main():
|
def main():
|
||||||
# create and run the bot
|
# create and run the bot
|
||||||
global bot
|
global bot
|
||||||
bot = SMALBot(DEFAULT_PREFIX)
|
bot = DemoBot(DEFAULT_PREFIX)
|
||||||
bot.SetOnEventHandler(on_event)
|
|
||||||
bot.SetOnMessageHandler(on_message)
|
|
||||||
bot.run()
|
bot.run()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,26 @@ class _MXClient:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._createMXClient()
|
self._createMXClient()
|
||||||
|
# ffi_selfhandle = ffi.new_handle(self)
|
||||||
|
# self._ffi_selfhandle = ffi_selfhandle
|
||||||
|
self._ffi_selfhandle = ffi.new_handle(self)
|
||||||
|
# self._ffi_selfhandle = ffi_selfhandle
|
||||||
|
|
||||||
|
r = lib.apiv0_set_on_event_handler(
|
||||||
|
self.client_id, on_event_callback, self._ffi_selfhandle
|
||||||
|
)
|
||||||
|
result = ffi.string(r)
|
||||||
|
lib.FreeCString(r)
|
||||||
|
if result.startswith(b"ERR:"):
|
||||||
|
raise APIError(result)
|
||||||
|
|
||||||
|
r = lib.apiv0_set_on_message_handler(
|
||||||
|
self.client_id, on_message_callback, self._ffi_selfhandle
|
||||||
|
)
|
||||||
|
result = ffi.string(r)
|
||||||
|
lib.FreeCString(r)
|
||||||
|
if result.startswith(b"ERR:"):
|
||||||
|
raise APIError(result)
|
||||||
|
|
||||||
def _createMXClient(self):
|
def _createMXClient(self):
|
||||||
r = lib.apiv0_createclient_pass(b".mxpass", b".", b"*", b"*", b"*")
|
r = lib.apiv0_createclient_pass(b".mxpass", b".", b"*", b"*", b"*")
|
||||||
|
|
@ -27,20 +47,6 @@ class _MXClient:
|
||||||
result_dict = json.loads(result)
|
result_dict = json.loads(result)
|
||||||
self.client_id = result_dict["id"]
|
self.client_id = result_dict["id"]
|
||||||
|
|
||||||
def SetOnEventHandler(self, fn):
|
|
||||||
r = lib.apiv0_set_on_event_handler(self.client_id, fn)
|
|
||||||
result = ffi.string(r)
|
|
||||||
lib.FreeCString(r)
|
|
||||||
if result.startswith(b"ERR:"):
|
|
||||||
raise APIError(result)
|
|
||||||
|
|
||||||
def SetOnMessageHandler(self, fn):
|
|
||||||
r = lib.apiv0_set_on_message_handler(self.client_id, fn)
|
|
||||||
result = ffi.string(r)
|
|
||||||
lib.FreeCString(r)
|
|
||||||
if result.startswith(b"ERR:"):
|
|
||||||
raise APIError(result)
|
|
||||||
|
|
||||||
def _sync(self):
|
def _sync(self):
|
||||||
r = lib.apiv0_startclient(self.client_id)
|
r = lib.apiv0_startclient(self.client_id)
|
||||||
result = ffi.string(r)
|
result = ffi.string(r)
|
||||||
|
|
@ -65,3 +71,32 @@ class _MXClient:
|
||||||
# if result.startswith(b"ERR:"):
|
# if result.startswith(b"ERR:"):
|
||||||
# raise APIError(result)
|
# raise APIError(result)
|
||||||
print("_sendmessage: ", result)
|
print("_sendmessage: ", result)
|
||||||
|
|
||||||
|
def process_event(self, evt):
|
||||||
|
if hasattr(self, "on_event") and callable(self.on_event):
|
||||||
|
self.on_event(evt)
|
||||||
|
else:
|
||||||
|
logger.warn(f"got event but on_event not declared: {evt}")
|
||||||
|
|
||||||
|
def process_message(self, msg):
|
||||||
|
if hasattr(self, "on_message") and callable(self.on_message):
|
||||||
|
self.on_message(msg)
|
||||||
|
else:
|
||||||
|
logger.warn(f"got message but on_message not declared: {msg}")
|
||||||
|
self._stopsync()
|
||||||
|
|
||||||
|
|
||||||
|
@ffi.callback("void(char*, void*)")
|
||||||
|
def on_event_callback(evt, pobj):
|
||||||
|
cli = ffi.from_handle(pobj)
|
||||||
|
e = ffi.string(evt).decode("utf-8")
|
||||||
|
evt = json.loads(e)
|
||||||
|
cli.process_event(evt)
|
||||||
|
|
||||||
|
|
||||||
|
@ffi.callback("void(char*, void*)")
|
||||||
|
def on_message_callback(msg, pobj):
|
||||||
|
cli = ffi.from_handle(pobj)
|
||||||
|
m = ffi.string(msg).decode("utf-8")
|
||||||
|
msg = json.loads(m)
|
||||||
|
cli.process_message(msg)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue