/**************************************************************************** * 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 #endif #include "./object_p.h" /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ */ static AQH_LINK *AQH_Link_new(); static void AQH_Link_free(AQH_LINK *ln); static 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); o->refCount=1; GWEN_INHERIT_INIT(AQH_OBJECT, o); GWEN_LIST_INIT(AQH_OBJECT, o); o->eventLoop=eventLoop; o->linkList=AQH_Link_List_new(); return o; } void AQH_Object_IncRefCount(AQH_OBJECT *o) { if (o && o->refCount>0) o->refCount++; } void AQH_Object_free(AQH_OBJECT *o) { if (o && o->refCount>0) { if (--(o->refCount)==0) { AQH_Link_List_free(o->linkList); GWEN_LIST_FINI(AQH_OBJECT, o); GWEN_INHERIT_FINI(AQH_OBJECT, o); GWEN_FREE_OBJECT(o); } } } uint32_t AQH_Object_GetFlags(const AQH_OBJECT *o) { return (o && o->refCount)?o->flags:0; } void AQH_Object_SetFlags(AQH_OBJECT *o, uint32_t i) { if (o && o->refCount) o->flags=i; } void AQH_Object_AddFlags(AQH_OBJECT *o, uint32_t i) { if (o && o->refCount) o->flags|=i; } void AQH_Object_SubFlags(AQH_OBJECT *o, uint32_t i) { if (o && o->refCount) o->flags&=~i; } AQH_EVENT_LOOP *AQH_Object_GetEventLoop(const AQH_OBJECT *o) { return (o && o->refCount)?o->eventLoop:NULL; } AQH_LINK *_findLink(AQH_OBJECT *o, uint32_t signalId, uint32_t slotId, AQH_OBJECT *targetObject) { if (o && o->refCount) { 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 && o->refCount) { 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->refCount && o->signalHandlerFn) return o->signalHandlerFn(o, slotId, senderObject, param1, param2); return 0; } void AQH_Object_Enable(AQH_OBJECT *o) { if (o && o->refCount && o->enableFn) o->enableFn(o); } void AQH_Object_Disable(AQH_OBJECT *o) { if (o && o->refCount && o->disableFn) o->disableFn(o); } AQH_OBJECT_SIGNALHANDLER_FN AQH_Object_SetSignalHandlerFn(AQH_OBJECT *o, AQH_OBJECT_SIGNALHANDLER_FN f) { if (o && o->refCount) { 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 && o->refCount) { 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 && o->refCount) { 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); } }