add 3rd callback type for non-matrix and non-sync things

This commit is contained in:
saces 2026-02-13 23:51:41 +01:00
parent 0d8ea81dbd
commit 3a4f6cdbdb
5 changed files with 62 additions and 4 deletions

View file

@ -27,6 +27,7 @@ type MXClient struct {
*mautrix.Client *mautrix.Client
OnEvent func(string) OnEvent func(string)
OnMessage func(string) OnMessage func(string)
OnSystem func(string)
_directMap map[id.RoomID][]id.UserID _directMap map[id.RoomID][]id.UserID
} }
@ -240,7 +241,7 @@ func NewMXClient(homeserverURL string, userID id.UserID, accessToken string) (*M
client.Store = cryptoStore client.Store = cryptoStore
mxclient := &MXClient{client, nil, nil, make(map[id.RoomID][]id.UserID)} mxclient := &MXClient{client, nil, nil, nil, make(map[id.RoomID][]id.UserID)}
syncer.ParseEventContent = true syncer.ParseEventContent = true
syncer.OnEvent(client.StateStoreSyncHandler) syncer.OnEvent(client.StateStoreSyncHandler)

View file

@ -19,6 +19,7 @@ import (
#include <stdlib.h> #include <stdlib.h>
typedef void (*on_event_handler_ptr) (char*, void*); typedef void (*on_event_handler_ptr) (char*, void*);
typedef void (*on_message_handler_ptr) (char*, void*); typedef void (*on_message_handler_ptr) (char*, void*);
typedef void (*on_sys_handler_ptr) (char*, void*);
static inline void call_c_on_event_handler(on_event_handler_ptr ptr, char* jsonStr, void* pobj) { static inline void call_c_on_event_handler(on_event_handler_ptr ptr, char* jsonStr, void* pobj) {
(ptr)(jsonStr, pobj); (ptr)(jsonStr, pobj);
@ -28,6 +29,10 @@ static inline void call_c_on_message_handler(on_message_handler_ptr ptr, char* j
(ptr)(jsonStr, pobj); (ptr)(jsonStr, pobj);
} }
static inline void call_c_on_sys_handler(on_message_handler_ptr ptr, char* jsonStr, void* pobj) {
(ptr)(jsonStr, pobj);
}
*/ */
import "C" import "C"
@ -42,6 +47,8 @@ type CBClient struct {
on_event_handler_pobj unsafe.Pointer 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 on_message_handler_pobj unsafe.Pointer
on_sys_handler C.on_sys_handler_ptr
on_sys_handler_pobj unsafe.Pointer
syncCancelFunc context.CancelCauseFunc syncCancelFunc context.CancelCauseFunc
} }
@ -57,6 +64,12 @@ func (cli *CBClient) OnMessage(s string) {
C.call_c_on_message_handler(cli.on_message_handler, cStr, cli.on_message_handler_pobj) C.call_c_on_message_handler(cli.on_message_handler, cStr, cli.on_message_handler_pobj)
} }
func (cli *CBClient) OnSystem(s string) {
cStr := C.CString(s)
defer C.free(unsafe.Pointer(cStr))
C.call_c_on_sys_handler(cli.on_sys_handler, cStr, cli.on_sys_handler_pobj)
}
func (cli *CBClient) Set_on_event_handler(fn C.on_event_handler_ptr, pobj unsafe.Pointer) { 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 cli.on_event_handler_pobj = pobj
@ -67,13 +80,18 @@ func (cli *CBClient) Set_on_message_handler(fn C.on_message_handler_ptr, pobj un
cli.on_message_handler_pobj = pobj cli.on_message_handler_pobj = pobj
} }
func (cli *CBClient) Set_on_sys_handler(fn C.on_sys_handler_ptr, pobj unsafe.Pointer) {
cli.on_sys_handler = fn
cli.on_sys_handler_pobj = pobj
}
// NewCClient creates a new Matrix Client ready for syncing // NewCClient creates a new Matrix Client ready for syncing
func NewCBClient(homeserverURL string, userID id.UserID, accessToken string) (*CBClient, error) { func NewCBClient(homeserverURL string, userID id.UserID, accessToken string) (*CBClient, error) {
client, err := mxclient.NewMXClient(homeserverURL, userID, accessToken) client, err := mxclient.NewMXClient(homeserverURL, userID, accessToken)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &CBClient{client, nil, nil, nil, nil, nil}, nil return &CBClient{client, nil, nil, nil, nil, nil, nil, nil}, nil
} }
/* /*
@ -187,7 +205,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, nil, nil, nil} client := &CBClient{mxclient, nil, nil, nil, 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)))
} }
@ -198,9 +216,10 @@ 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, nil, nil, nil} client := &CBClient{mxclient, nil, nil, nil, nil, nil, nil, nil}
mxclient.OnEvent = client.OnEvent mxclient.OnEvent = client.OnEvent
mxclient.OnMessage = client.OnMessage mxclient.OnMessage = client.OnMessage
mxclient.OnSystem = client.OnSystem
cclients = append(cclients, client) cclients = append(cclients, client)
out, err := json.Marshal(map[string]any{"id": len(cclients) - 1, "userid": client.UserID.String(), "deviceid": client.DeviceID.String()}) out, err := json.Marshal(map[string]any{"id": len(cclients) - 1, "userid": client.UserID.String(), "deviceid": client.DeviceID.String()})
if err != nil { if err != nil {
@ -232,6 +251,17 @@ func apiv0_set_on_message_handler(cid C.int, fn C.on_message_handler_ptr, pobj u
return C.CString("SUCCESS.") return C.CString("SUCCESS.")
} }
//export apiv0_set_on_sys_handler
func apiv0_set_on_sys_handler(cid C.int, fn C.on_sys_handler_ptr, pobj unsafe.Pointer) *C.char {
cli, err := getClient(int(cid))
if err != nil {
return C.CString(fmt.Sprintf("ERR: %v", err))
}
cli.Set_on_sys_handler(fn, pobj)
return C.CString("SUCCESS.")
}
//export apiv0_startclient //export apiv0_startclient
func apiv0_startclient(cid C.int) *C.char { func apiv0_startclient(cid C.int) *C.char {
cli, err := getClient(int(cid)) cli, err := getClient(int(cid))

View file

@ -27,6 +27,7 @@ ffibuilder.cdef(
csource=""" csource="""
typedef void (*on_event_handler_ptr) (char*, void*); typedef void (*on_event_handler_ptr) (char*, void*);
typedef void (*on_message_handler_ptr) (char*, void*); typedef void (*on_message_handler_ptr) (char*, void*);
typedef void (*on_sys_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);
@ -42,6 +43,7 @@ ffibuilder.cdef(
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, void* pobj); 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, void* pobj); extern char* apiv0_set_on_message_handler(int cid, on_message_handler_ptr ptr, void* pobj);
extern char* apiv0_set_on_sys_handler(int cid, on_sys_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);

View file

@ -16,6 +16,9 @@ DEFAULT_PREFIX = "!"
class DemoBot(SMALBot): class DemoBot(SMALBot):
def on_sys(self, ntf):
print("Got a system notification: ", ntf)
def on_event(self, evt): def on_event(self, evt):
print("Got an event: ", e) print("Got an event: ", e)

View file

@ -50,6 +50,14 @@ class _MXClient:
if result.startswith(b"ERR:"): if result.startswith(b"ERR:"):
raise APIError(result) raise APIError(result)
r = lib.apiv0_set_on_sys_handler(
self.client_id, on_sys_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"*")
@ -97,6 +105,12 @@ class _MXClient:
else: else:
logger.warn(f"got message but on_message not declared: {msg}") logger.warn(f"got message but on_message not declared: {msg}")
def process_sys(self, ntf):
if hasattr(self, "on_sys") and callable(self.on_sys):
self.on_sys(ntf)
else:
logger.warn(f"got systen notification but on_sys not declared: {ntf}")
@ffi.callback("void(char*, void*)") @ffi.callback("void(char*, void*)")
def on_event_callback(evt, pobj): def on_event_callback(evt, pobj):
@ -112,3 +126,11 @@ def on_message_callback(msg, pobj):
m = ffi.string(msg).decode("utf-8") m = ffi.string(msg).decode("utf-8")
msg = json.loads(m) msg = json.loads(m)
cli.process_message(msg) cli.process_message(msg)
@ffi.callback("void(char*, void*)")
def on_sys_callback(msg, pobj):
cli = ffi.from_handle(pobj)
m = ffi.string(msg).decode("utf-8")
sys = json.loads(m)
cli.process_sys(sys)