aqhome: started rewriting IPC module.
started with basic event interface using unix fd and timers.
This commit is contained in:
@@ -70,6 +70,7 @@
|
|||||||
hexfile
|
hexfile
|
||||||
data
|
data
|
||||||
events
|
events
|
||||||
|
events2
|
||||||
client
|
client
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
@@ -82,6 +83,7 @@
|
|||||||
aqhhexfile
|
aqhhexfile
|
||||||
aqhdata
|
aqhdata
|
||||||
aqhevents
|
aqhevents
|
||||||
|
aqhevents2
|
||||||
aqhclient
|
aqhclient
|
||||||
</useTargets>
|
</useTargets>
|
||||||
|
|
||||||
|
|||||||
88
aqhome/events2/0BUILD
Normal file
88
aqhome/events2/0BUILD
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?xml?>
|
||||||
|
|
||||||
|
<gwbuild>
|
||||||
|
|
||||||
|
<target type="ConvenienceLibrary" name="aqhevents2" >
|
||||||
|
|
||||||
|
<includes type="c" >
|
||||||
|
$(gwenhywfar_cflags)
|
||||||
|
$(aqdatabase_cflags)
|
||||||
|
-I$(topsrcdir)
|
||||||
|
-I$(topbuilddir)
|
||||||
|
</includes>
|
||||||
|
|
||||||
|
<includes type="tm2" >
|
||||||
|
--include=$(builddir)
|
||||||
|
--include=$(srcdir)
|
||||||
|
--include=$(aqdatabase_AQDATABASE_TYPEMAKERDIR)/c
|
||||||
|
</includes>
|
||||||
|
|
||||||
|
|
||||||
|
<define name="BUILDING_AQHOME" />
|
||||||
|
|
||||||
|
<setVar name="local/cflags">$(visibility_cflags)</setVar>
|
||||||
|
|
||||||
|
|
||||||
|
<setVar name="tm2flags" >
|
||||||
|
--api=AQHOME_API
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/typefiles" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/built_sources" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/built_headers_pub">
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
|
||||||
|
<setVar name="local/built_headers_priv" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
|
||||||
|
<headers dist="false" install="$(pkgincludedir)/data" >
|
||||||
|
$(local/built_headers_pub)
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
|
<headers dist="true" install="$(pkgincludedir)/data" >
|
||||||
|
eventloop.h
|
||||||
|
object.h
|
||||||
|
fdobject.h
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
|
<headers dist="true" >
|
||||||
|
eventloop_p.h
|
||||||
|
object_p.h
|
||||||
|
fdobject_p.h
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
|
<sources>
|
||||||
|
$(local/typefiles)
|
||||||
|
|
||||||
|
eventloop.c
|
||||||
|
eventloop_select.c
|
||||||
|
object.c
|
||||||
|
fdobject.c
|
||||||
|
</sources>
|
||||||
|
|
||||||
|
|
||||||
|
<extradist>
|
||||||
|
</extradist>
|
||||||
|
|
||||||
|
|
||||||
|
<useTargets>
|
||||||
|
</useTargets>
|
||||||
|
|
||||||
|
<subdirs>
|
||||||
|
</subdirs>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</target>
|
||||||
|
|
||||||
|
</gwbuild>
|
||||||
79
aqhome/events2/eventloop.c
Normal file
79
aqhome/events2/eventloop.c
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "./eventloop_p.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_EVENT_LOOP *AQH_EventLoop_new()
|
||||||
|
{
|
||||||
|
AQH_EVENT_LOOP *eventLoop;
|
||||||
|
|
||||||
|
GWEN_NEW_OBJECT(AQH_EVENT_LOOP, eventLoop);
|
||||||
|
eventLoop->fdObjectList=AQH_Object_List2_new();
|
||||||
|
eventLoop->timerObjectList=AQH_Object_List2_new();
|
||||||
|
|
||||||
|
return eventLoop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_EventLoop_free(AQH_EVENT_LOOP *eventLoop)
|
||||||
|
{
|
||||||
|
if (eventLoop) {
|
||||||
|
AQH_Object_List2_free(eventLoop->timerObjectList);
|
||||||
|
AQH_Object_List2_free(eventLoop->fdObjectList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_EventLoop_AddFdObject(AQH_EVENT_LOOP *eventLoop, AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
if (eventLoop && o && NULL==AQH_Object_List2_Contains(eventLoop->fdObjectList, o)) {
|
||||||
|
AQH_Object_List2_PushBack(eventLoop->fdObjectList, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_EventLoop_DelFdObject(AQH_EVENT_LOOP *eventLoop, AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
if (eventLoop && o)
|
||||||
|
AQH_Object_List2_Remove(eventLoop->fdObjectList, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_EventLoop_AddTimerObject(AQH_EVENT_LOOP *eventLoop, AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
if (eventLoop && o && NULL==AQH_Object_List2_Contains(eventLoop->timerObjectList, o)) {
|
||||||
|
AQH_Object_List2_PushBack(eventLoop->timerObjectList, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_EventLoop_DelTimerObject(AQH_EVENT_LOOP *eventLoop, AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
if (eventLoop && o)
|
||||||
|
AQH_Object_List2_Remove(eventLoop->timerObjectList, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
32
aqhome/events2/eventloop.h
Normal file
32
aqhome/events2/eventloop.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_EVENTLOOP_H
|
||||||
|
#define AQH_EVENTLOOP_H
|
||||||
|
|
||||||
|
typedef struct AQH_EVENT_LOOP AQH_EVENT_LOOP;
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/events2/object.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API AQH_EVENT_LOOP *AQH_EventLoop_new();
|
||||||
|
AQHOME_API void AQH_EventLoop_free(AQH_EVENT_LOOP *eventLoop);
|
||||||
|
|
||||||
|
AQHOME_API void AQH_EventLoop_Run(AQH_EVENT_LOOP *eventLoop);
|
||||||
|
|
||||||
|
AQHOME_API void AQH_EventLoop_AddFdObject(AQH_EVENT_LOOP *eventLoop, AQH_OBJECT *o);
|
||||||
|
AQHOME_API void AQH_EventLoop_DelFdObject(AQH_EVENT_LOOP *eventLoop, AQH_OBJECT *o);
|
||||||
|
|
||||||
|
AQHOME_API void AQH_EventLoop_AddTimerObject(AQH_EVENT_LOOP *eventLoop, AQH_OBJECT *o);
|
||||||
|
AQHOME_API void AQH_EventLoop_DelTimerObject(AQH_EVENT_LOOP *eventLoop, AQH_OBJECT *o);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
25
aqhome/events2/eventloop_p.h
Normal file
25
aqhome/events2/eventloop_p.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_EVENTLOOP_P_H
|
||||||
|
#define AQH_EVENTLOOP_P_H
|
||||||
|
|
||||||
|
#include "./eventloop.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct AQH_EVENT_LOOP
|
||||||
|
{
|
||||||
|
AQH_OBJECT_LIST2 *fdObjectList;
|
||||||
|
AQH_OBJECT_LIST2 *timerObjectList;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
173
aqhome/events2/eventloop_select.c
Normal file
173
aqhome/events2/eventloop_select.c
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "./eventloop_p.h"
|
||||||
|
#include "./fdobject.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* forward declarations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int _sampleFdsIntoSet(AQH_OBJECT_LIST2 *ol, fd_set *fds, int mode);
|
||||||
|
static void _markReadyFdObjects(AQH_OBJECT_LIST2 *ol, fd_set *fds, int mode);
|
||||||
|
static void _signalReadyFdObjects(AQH_OBJECT_LIST2 *ol);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* code
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void AQH_EventLoop_Run(AQH_EVENT_LOOP *eventLoop)
|
||||||
|
{
|
||||||
|
fd_set fdRead;
|
||||||
|
fd_set fdWrite;
|
||||||
|
int highestFd=-1;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
FD_ZERO(&fdRead);
|
||||||
|
FD_ZERO(&fdWrite);
|
||||||
|
|
||||||
|
highestFd=_sampleFdsIntoSet(eventLoop->fdObjectList, &fdRead, AQH_FDOBJECT_FDMODE_READ);
|
||||||
|
rv=_sampleFdsIntoSet(eventLoop->fdObjectList, &fdWrite, AQH_FDOBJECT_FDMODE_WRITE);
|
||||||
|
highestFd=(rv>highestFd)?rv:highestFd;
|
||||||
|
|
||||||
|
if (highestFd>-1) {
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
tv.tv_sec=0;
|
||||||
|
tv.tv_usec=200000;
|
||||||
|
rv=select(highestFd+1, &fdRead, &fdWrite, NULL, &tv);
|
||||||
|
if (rv>0) {
|
||||||
|
/* some fds became active */
|
||||||
|
_markReadyFdObjects(eventLoop->fdObjectList, &fdRead, AQH_FDOBJECT_FDMODE_READ);
|
||||||
|
_markReadyFdObjects(eventLoop->fdObjectList, &fdWrite, AQH_FDOBJECT_FDMODE_WRITE);
|
||||||
|
_signalReadyFdObjects(eventLoop->fdObjectList);
|
||||||
|
}
|
||||||
|
else if (rv<0) {
|
||||||
|
if (errno!=EINTR) {
|
||||||
|
/* error */
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on SELECT: %d (%s)", errno, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* no fd became active (TODO: maybe signal deep idle objects?) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _sampleFdsIntoSet(AQH_OBJECT_LIST2 *ol, fd_set *fds, int mode)
|
||||||
|
{
|
||||||
|
AQH_OBJECT_LIST2_ITERATOR *it;
|
||||||
|
int highestFd=-1;
|
||||||
|
|
||||||
|
it=AQH_Object_List2_First(ol);
|
||||||
|
if (it) {
|
||||||
|
AQH_OBJECT *o;
|
||||||
|
|
||||||
|
o=AQH_Object_List2Iterator_Data(it);
|
||||||
|
while(o) {
|
||||||
|
int m;
|
||||||
|
|
||||||
|
m=AQH_FdObject_GetFdMode(o);
|
||||||
|
if (m==mode) {
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd=AQH_FdObject_GetFd(o);
|
||||||
|
if (fd>-1) {
|
||||||
|
highestFd=(fd>highestFd)?fd:highestFd;
|
||||||
|
FD_SET(fd, fds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
o=AQH_Object_List2Iterator_Next(it);
|
||||||
|
}
|
||||||
|
AQH_Object_List2Iterator_free(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return highestFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _markReadyFdObjects(AQH_OBJECT_LIST2 *ol, fd_set *fds, int mode)
|
||||||
|
{
|
||||||
|
AQH_OBJECT_LIST2_ITERATOR *it;
|
||||||
|
|
||||||
|
it=AQH_Object_List2_First(ol);
|
||||||
|
if (it) {
|
||||||
|
AQH_OBJECT *o;
|
||||||
|
|
||||||
|
o=AQH_Object_List2Iterator_Data(it);
|
||||||
|
while(o) {
|
||||||
|
int m;
|
||||||
|
|
||||||
|
m=AQH_FdObject_GetFdMode(o);
|
||||||
|
if (m==mode) {
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd=AQH_FdObject_GetFd(o);
|
||||||
|
if (FD_ISSET(fd, fds))
|
||||||
|
AQH_Object_AddFlags(o, AQH_OBJECT_FLAGS_FIRE);
|
||||||
|
}
|
||||||
|
o=AQH_Object_List2Iterator_Next(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
AQH_Object_List2Iterator_free(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _signalReadyFdObjects(AQH_OBJECT_LIST2 *ol)
|
||||||
|
{
|
||||||
|
AQH_OBJECT_LIST2_ITERATOR *it;
|
||||||
|
|
||||||
|
it=AQH_Object_List2_First(ol);
|
||||||
|
if (it) {
|
||||||
|
AQH_OBJECT *o;
|
||||||
|
|
||||||
|
o=AQH_Object_List2Iterator_Data(it);
|
||||||
|
while(o) {
|
||||||
|
if (AQH_Object_GetFlags(o) & AQH_OBJECT_FLAGS_FIRE) {
|
||||||
|
AQH_Object_SubFlags(o, AQH_OBJECT_FLAGS_FIRE);
|
||||||
|
AQH_Object_EmitSignal(o, AQH_FDOBJECT_SIGNAL_ISREADY, 0, NULL);
|
||||||
|
}
|
||||||
|
o=AQH_Object_List2Iterator_Next(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
AQH_Object_List2Iterator_free(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
140
aqhome/events2/fdobject.c
Normal file
140
aqhome/events2/fdobject.c
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project Gwenhywfar.
|
||||||
|
* Gwenhywfar (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "./fdobject_p.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/inherit.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_INHERIT(AQH_OBJECT, AQH_FDOBJECT)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* forward declarations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
||||||
|
static void _cbEnable(AQH_OBJECT *o);
|
||||||
|
static void _cbDisable(AQH_OBJECT *o);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* implementations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
AQH_OBJECT *AQH_FdObject_new(AQH_EVENT_LOOP *eventLoop, int fd, int mode)
|
||||||
|
{
|
||||||
|
AQH_OBJECT *o;
|
||||||
|
AQH_FDOBJECT *xo;
|
||||||
|
|
||||||
|
o=AQH_Object_new(eventLoop);
|
||||||
|
GWEN_NEW_OBJECT(AQH_FDOBJECT, xo);
|
||||||
|
GWEN_INHERIT_SETDATA(AQH_OBJECT, AQH_FDOBJECT, o, xo, _freeData);
|
||||||
|
xo->fd=fd;
|
||||||
|
xo->fdMode=mode;
|
||||||
|
|
||||||
|
AQH_Object_SetEnableFn(o, _cbEnable);
|
||||||
|
AQH_Object_SetDisableFn(o, _cbDisable);
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void GWENHYWFAR_CB _freeData(GWEN_UNUSED void *bp, void *p)
|
||||||
|
{
|
||||||
|
AQH_FDOBJECT *xo;
|
||||||
|
|
||||||
|
xo=(AQH_FDOBJECT*)p;
|
||||||
|
GWEN_FREE_OBJECT(xo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_FdObject_GetFdMode(const AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
if (o) {
|
||||||
|
AQH_FDOBJECT *xo;
|
||||||
|
|
||||||
|
xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_FDOBJECT, o);
|
||||||
|
if (xo)
|
||||||
|
return xo->fdMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_FdObject_SetFdMode(AQH_OBJECT *o, int i)
|
||||||
|
{
|
||||||
|
if (o) {
|
||||||
|
AQH_FDOBJECT *xo;
|
||||||
|
|
||||||
|
xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_FDOBJECT, o);
|
||||||
|
if (xo)
|
||||||
|
xo->fdMode=i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_FdObject_GetFd(const AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
if (o) {
|
||||||
|
AQH_FDOBJECT *xo;
|
||||||
|
|
||||||
|
xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_FDOBJECT, o);
|
||||||
|
if (xo)
|
||||||
|
return xo->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _cbEnable(AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
if (o) {
|
||||||
|
AQH_EVENT_LOOP *eventLoop;
|
||||||
|
|
||||||
|
eventLoop=AQH_Object_GetEventLoop(o);
|
||||||
|
if (eventLoop)
|
||||||
|
AQH_EventLoop_AddFdObject(eventLoop, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _cbDisable(AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
if (o) {
|
||||||
|
AQH_EVENT_LOOP *eventLoop;
|
||||||
|
|
||||||
|
eventLoop=AQH_Object_GetEventLoop(o);
|
||||||
|
if (eventLoop)
|
||||||
|
AQH_EventLoop_DelFdObject(eventLoop, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
36
aqhome/events2/fdobject.h
Normal file
36
aqhome/events2/fdobject.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project Gwenhywfar.
|
||||||
|
* Gwenhywfar (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_FDOBJECT_H
|
||||||
|
#define AQH_FDOBJECT_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/events2/object.h>
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AQH_FDOBJECT_FDMODE_READ=1,
|
||||||
|
AQH_FDOBJECT_FDMODE_WRITE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AQH_FDOBJECT_SIGNAL_ISREADY=AQH_OBJECT_SIGNAL_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API AQH_OBJECT *AQH_FdObject_new(AQH_EVENT_LOOP *eventLoop, int fd, int mode);
|
||||||
|
|
||||||
|
AQHOME_API int AQH_FdObject_GetFdMode(const AQH_OBJECT *o);
|
||||||
|
AQHOME_API void AQH_FdObject_SetFdMode(AQH_OBJECT *o, int i);
|
||||||
|
|
||||||
|
AQHOME_API int AQH_FdObject_GetFd(const AQH_OBJECT *o);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
23
aqhome/events2/fdobject_p.h
Normal file
23
aqhome/events2/fdobject_p.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project Gwenhywfar.
|
||||||
|
* Gwenhywfar (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_FDOBJECT_P_H
|
||||||
|
#define AQH_FDOBJECT_P_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "./fdobject.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AQH_FDOBJECT AQH_FDOBJECT;
|
||||||
|
struct AQH_FDOBJECT {
|
||||||
|
int fdMode;
|
||||||
|
int fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
276
aqhome/events2/object.c
Normal file
276
aqhome/events2/object.c
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "./object_p.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* forward declarations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
AQH_LINK *AQH_Link_new();
|
||||||
|
void AQH_Link_free(AQH_LINK *ln);
|
||||||
|
|
||||||
|
AQH_LINK *_findLink(AQH_OBJECT *o, uint32_t signalId, uint32_t slotId, AQH_OBJECT *targetObject);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* list, inherit
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
GWEN_LIST_FUNCTIONS(AQH_LINK, AQH_Link)
|
||||||
|
|
||||||
|
GWEN_INHERIT_FUNCTIONS(AQH_OBJECT)
|
||||||
|
GWEN_LIST_FUNCTIONS(AQH_OBJECT, AQH_Object)
|
||||||
|
GWEN_LIST2_FUNCTIONS(AQH_OBJECT, AQH_Object)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* code
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
AQH_OBJECT *AQH_Object_new(AQH_EVENT_LOOP *eventLoop)
|
||||||
|
{
|
||||||
|
AQH_OBJECT *o;
|
||||||
|
|
||||||
|
GWEN_NEW_OBJECT(AQH_OBJECT, o);
|
||||||
|
GWEN_INHERIT_INIT(AQH_OBJECT, o);
|
||||||
|
GWEN_LIST_INIT(AQH_OBJECT, o);
|
||||||
|
o->eventLoop=eventLoop;
|
||||||
|
o->linkList=AQH_Link_List_new();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Object_free(AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
if (o) {
|
||||||
|
GWEN_INHERIT_FINI(AQH_OBJECT, o);
|
||||||
|
GWEN_LIST_FINI(AQH_OBJECT, o);
|
||||||
|
|
||||||
|
AQH_Link_List_free(o->linkList);
|
||||||
|
|
||||||
|
GWEN_FREE_OBJECT(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_Object_GetFlags(const AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
return o?o->flags:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Object_SetFlags(AQH_OBJECT *o, uint32_t i)
|
||||||
|
{
|
||||||
|
if (o)
|
||||||
|
o->flags=i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Object_AddFlags(AQH_OBJECT *o, uint32_t i)
|
||||||
|
{
|
||||||
|
if (o)
|
||||||
|
o->flags|=i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Object_SubFlags(AQH_OBJECT *o, uint32_t i)
|
||||||
|
{
|
||||||
|
if (o)
|
||||||
|
o->flags&=~i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_EVENT_LOOP *AQH_Object_GetEventLoop(const AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
return o?o->eventLoop:NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_LINK *_findLink(AQH_OBJECT *o, uint32_t signalId, uint32_t slotId, AQH_OBJECT *targetObject)
|
||||||
|
{
|
||||||
|
if (o) {
|
||||||
|
AQH_LINK *ln;
|
||||||
|
|
||||||
|
ln=AQH_Link_List_First(o->linkList);
|
||||||
|
while(ln) {
|
||||||
|
if (ln->signalIdForSender==signalId &&
|
||||||
|
ln->signalIdForTarget==slotId &&
|
||||||
|
ln->targetObject==targetObject)
|
||||||
|
return ln;
|
||||||
|
ln=AQH_Link_List_Next(ln);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Object_AddLink(AQH_OBJECT *o, uint32_t signalId, uint32_t slotId, AQH_OBJECT *targetObject)
|
||||||
|
{
|
||||||
|
AQH_LINK *ln;
|
||||||
|
|
||||||
|
ln=_findLink(o, signalId, slotId, targetObject);
|
||||||
|
if (ln==NULL) {
|
||||||
|
ln=AQH_Link_new();
|
||||||
|
ln->signalIdForSender=signalId;
|
||||||
|
ln->signalIdForTarget=slotId;
|
||||||
|
ln->targetObject=targetObject;
|
||||||
|
AQH_Link_List_Add(ln, o->linkList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Object_DelLink(AQH_OBJECT *o, uint32_t signalId, uint32_t slotId, AQH_OBJECT *targetObject)
|
||||||
|
{
|
||||||
|
AQH_LINK *ln;
|
||||||
|
|
||||||
|
ln=_findLink(o, signalId, slotId, targetObject);
|
||||||
|
if (ln) {
|
||||||
|
AQH_Link_List_Del(ln);
|
||||||
|
AQH_Link_free(ln);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_Object_EmitSignal(AQH_OBJECT *o, uint32_t signalId, int param1, void *param2)
|
||||||
|
{
|
||||||
|
int signalWasHandled=0;
|
||||||
|
|
||||||
|
if (o) {
|
||||||
|
AQH_LINK *ln;
|
||||||
|
|
||||||
|
ln=AQH_Link_List_First(o->linkList);
|
||||||
|
while(ln) {
|
||||||
|
if (ln->signalIdForSender==signalId && ln->targetObject) {
|
||||||
|
if (AQH_Object_HandleSignal(ln->targetObject, ln->signalIdForTarget, o, param1, param2))
|
||||||
|
signalWasHandled=1;
|
||||||
|
}
|
||||||
|
ln=AQH_Link_List_Next(ln);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return signalWasHandled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_Object_HandleSignal(AQH_OBJECT *o, uint32_t slotId, AQH_OBJECT *senderObject, int param1, void *param2)
|
||||||
|
{
|
||||||
|
if (o && o->signalHandlerFn)
|
||||||
|
return o->signalHandlerFn(o, slotId, senderObject, param1, param2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Object_Enable(AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
if (o && o->enableFn)
|
||||||
|
o->enableFn(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Object_Disable(AQH_OBJECT *o)
|
||||||
|
{
|
||||||
|
if (o && o->disableFn)
|
||||||
|
o->disableFn(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_OBJECT_SIGNALHANDLER_FN AQH_Object_SetSignalHandlerFn(AQH_OBJECT *o, AQH_OBJECT_SIGNALHANDLER_FN f)
|
||||||
|
{
|
||||||
|
if (o) {
|
||||||
|
AQH_OBJECT_SIGNALHANDLER_FN oldFn;
|
||||||
|
|
||||||
|
oldFn=o->signalHandlerFn;
|
||||||
|
o->signalHandlerFn=f;
|
||||||
|
return oldFn;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_OBJECT_ENABLE_FN AQH_Object_SetEnableFn(AQH_OBJECT *o, AQH_OBJECT_ENABLE_FN f)
|
||||||
|
{
|
||||||
|
if (o) {
|
||||||
|
AQH_OBJECT_ENABLE_FN oldFn;
|
||||||
|
|
||||||
|
oldFn=o->enableFn;
|
||||||
|
o->enableFn=f;
|
||||||
|
return oldFn;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_OBJECT_DISABLE_FN AQH_Object_SetDisableFn(AQH_OBJECT *o, AQH_OBJECT_DISABLE_FN f)
|
||||||
|
{
|
||||||
|
if (o) {
|
||||||
|
AQH_OBJECT_DISABLE_FN oldFn;
|
||||||
|
|
||||||
|
oldFn=o->disableFn;
|
||||||
|
o->disableFn=f;
|
||||||
|
return oldFn;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_LINK *AQH_Link_new()
|
||||||
|
{
|
||||||
|
AQH_LINK *ln;
|
||||||
|
|
||||||
|
GWEN_NEW_OBJECT(AQH_LINK, ln);
|
||||||
|
GWEN_LIST_INIT(AQH_LINK, ln);
|
||||||
|
|
||||||
|
return ln;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Link_free(AQH_LINK *ln)
|
||||||
|
{
|
||||||
|
if (ln) {
|
||||||
|
GWEN_LIST_FINI(AQH_LINK, ln);
|
||||||
|
GWEN_FREE_OBJECT(ln);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
121
aqhome/events2/object.h
Normal file
121
aqhome/events2/object.h
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_OBJECT_H
|
||||||
|
#define AQH_OBJECT_H
|
||||||
|
|
||||||
|
#include "aqhome/api.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/inherit.h>
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/list2.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_OBJECT_FLAGS_FIRE 0x80000000L
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AQH_OBJECT_SIGNAL_LAST=10 /* reserve signal ids 0-9 */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* @name Type Definition
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
typedef struct AQH_OBJECT AQH_OBJECT;
|
||||||
|
GWEN_INHERIT_FUNCTION_LIB_DEFS(AQH_OBJECT, AQHOME_API)
|
||||||
|
GWEN_LIST_FUNCTION_LIB_DEFS(AQH_OBJECT, AQH_Object, AQHOME_API)
|
||||||
|
GWEN_LIST2_FUNCTION_LIB_DEFS(AQH_OBJECT, AQH_Object, AQHOME_API)
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/events2/eventloop.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* @name Virtual Function Declarations
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
typedef int (*AQH_OBJECT_SIGNALHANDLER_FN)(AQH_OBJECT *o, uint32_t slotId, AQH_OBJECT *senderObject, int param1, void *param2);
|
||||||
|
typedef void (*AQH_OBJECT_ENABLE_FN)(AQH_OBJECT *o);
|
||||||
|
typedef void (*AQH_OBJECT_DISABLE_FN)(AQH_OBJECT *o);
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* @name Construction, Destruction
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
AQHOME_API AQH_OBJECT *AQH_Object_new(AQH_EVENT_LOOP *eventLoop);
|
||||||
|
AQHOME_API void AQH_Object_free(AQH_OBJECT *o);
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* @name Manipulate Flags
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
AQHOME_API uint32_t AQH_Object_GetFlags(const AQH_OBJECT *o);
|
||||||
|
AQHOME_API void AQH_Object_SetFlags(AQH_OBJECT *o, uint32_t i);
|
||||||
|
AQHOME_API void AQH_Object_AddFlags(AQH_OBJECT *o, uint32_t i);
|
||||||
|
AQHOME_API void AQH_Object_SubFlags(AQH_OBJECT *o, uint32_t i);
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* @name Getters, Setters
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
AQHOME_API AQH_EVENT_LOOP *AQH_Object_GetEventLoop(const AQH_OBJECT *o);
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* @name Link Handling
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
AQHOME_API void AQH_Object_AddLink(AQH_OBJECT *o, uint32_t signalId, uint32_t slotId, AQH_OBJECT *targetObject);
|
||||||
|
AQHOME_API void AQH_Object_DelLink(AQH_OBJECT *o, uint32_t signalId, uint32_t slotId, AQH_OBJECT *targetObject);
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* @name Virtual Function Declarations
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
AQHOME_API int AQH_Object_EmitSignal(AQH_OBJECT *o, uint32_t signalId, int param1, void *param2);
|
||||||
|
AQHOME_API int AQH_Object_HandleSignal(AQH_OBJECT *o, uint32_t slotId, AQH_OBJECT *senderObject, int param1, void *param2);
|
||||||
|
AQHOME_API void AQH_Object_Enable(AQH_OBJECT *o);
|
||||||
|
AQHOME_API void AQH_Object_Disable(AQH_OBJECT *o);
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* @name Setter for Virtual Functions
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
AQHOME_API AQH_OBJECT_SIGNALHANDLER_FN AQH_Object_SetSignalHandlerFn(AQH_OBJECT *o, AQH_OBJECT_SIGNALHANDLER_FN f);
|
||||||
|
AQHOME_API AQH_OBJECT_ENABLE_FN AQH_Object_SetEnableFn(AQH_OBJECT *o, AQH_OBJECT_ENABLE_FN f);
|
||||||
|
AQHOME_API AQH_OBJECT_DISABLE_FN AQH_Object_SetDisableFn(AQH_OBJECT *o, AQH_OBJECT_DISABLE_FN f);
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
46
aqhome/events2/object_p.h
Normal file
46
aqhome/events2/object_p.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project Gwenhywfar.
|
||||||
|
* Gwenhywfar (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_OBJECT_P_H
|
||||||
|
#define AQH_OBJECT_P_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "./object.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AQH_LINK AQH_LINK;
|
||||||
|
GWEN_LIST_FUNCTION_DEFS(AQH_LINK, AQH_Link)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct AQH_LINK {
|
||||||
|
GWEN_LIST_ELEMENT(AQH_LINK)
|
||||||
|
|
||||||
|
uint32_t signalIdForSender;
|
||||||
|
uint32_t signalIdForTarget;
|
||||||
|
AQH_OBJECT *targetObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct AQH_OBJECT {
|
||||||
|
GWEN_INHERIT_ELEMENT(AQH_OBJECT)
|
||||||
|
GWEN_LIST_ELEMENT(AQH_OBJECT)
|
||||||
|
|
||||||
|
uint32_t flags;
|
||||||
|
AQH_EVENT_LOOP *eventLoop;
|
||||||
|
|
||||||
|
AQH_LINK_LIST *linkList;
|
||||||
|
|
||||||
|
AQH_OBJECT_SIGNALHANDLER_FN signalHandlerFn;
|
||||||
|
AQH_OBJECT_ENABLE_FN enableFn;
|
||||||
|
AQH_OBJECT_DISABLE_FN disableFn;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user