We value your input! Please participate in Archicad 28 Home Screen and Tooltips/Quick Tutorials survey
2017-09-07 01:28 PM - last edited on 2022-12-06 02:00 PM by Daniel Kassai
API_Guid g_guidPrev = APINULLGuid; bool g_hasSelected = false; GSErrCode Observer_DetachAllElems() { API_Elem_Head** elemHead; Int32 nElems = 0; GSErrCode err = ACAPI_Element_GetObservedElements(&elemHead, &nElems); if (err != NoError) { WriteReport("["__FUNC__"] ERROR %s - ACAPI_Element_GetObservedElements", ErrId2Name(err)); return err; } for (Int32 i = 0; i < nElems; i++) { err = ACAPI_Element_DetachObserver(&(*elemHead)); if (err != NoError) WriteReport("["__FUNC__"] ERROR %s - ACAPI_Element_DetachObserver()", ErrId2Name(err)); } BMKillHandle((GSHandle*)&elemHead); return err; } GSErrCode Observer_AttachElem(API_Guid guid) { // Get element head API_Elem_Head head; BNZeroMemory(&head, sizeof(head)); head.guid = guid; GSErrCode err = ACAPI_Element_GetHeader(&head, APIElemMask_FloorPlan); if (err != NoError) { WriteReport("["__FUNC__"] ERROR %s - ACAPI_Element_GetHeader()", ErrId2Name(err)); return err; } // Attach elem to observer err = ACAPI_Element_AttachObserver(&head, NULL); if (err != NoError) WriteReport("["__FUNC__"] ERROR %s - ACAPI_Element_AttachObserver()", ErrId2Name(err)); return err; } static GSErrCode __ACENV_CALL ElemObserverEventHandler(const API_NotifyElementType* /*elemType*/) { // Empty function return NoError; } // ElemObserverEventHandler GSErrCode InitializeElemObserverHandler() { const GSErrCode err = ACAPI_Notify_InstallElementObserver(ElemObserverEventHandler); if (err != NoError) DBGPrintlnf("[Error] %s "__FUNC__" - ACAPI_Notify_InstallElementObserver(ElemObserverEventHandler)", ErrId2Name(err)); return err; } static GSErrCode __ACENV_CALL SelectionChangeHandler(const API_Neig *selElemNeig) { if (selElemNeig == nullptr) return NoError; if (selElemNeig->neigID == APINeig_None) { WriteReport("All elements deselected"); if (g_hasSelected) // Deselected (currently no selection & previously has selection) { g_hasSelected = false; // Detach previous elem Observer_DetachAllElems(); } return NoError; } API_Neig** selNeigs; API_SelectionInfo selectionInfo; BNZeroMemory(&selectionInfo, sizeof(selectionInfo)); GSErrCode err = ACAPI_Selection_Get(&selectionInfo, &selNeigs, true); BMKillHandle((GSHandle*)&selectionInfo.marquee.coords); if (err == APIERR_NOSEL) { WriteReport("["__FUNC__"] ERROR %s - ACAPI_Selection_Get()", ErrId2Name(err)); err = NoError; if (g_hasSelected) // Deselected (currently no selection & previously has selection) { g_hasSelected = false; // Detach previous elem Observer_DetachAllElems(); BMKillHandle((GSHandle*)&selNeigs); return err; } } if (err != NoError) { WriteReport("["__FUNC__"] ERROR %s - ACAPI_Selection_Get()", ErrId2Name(err)); BMKillHandle((GSHandle*)&selNeigs); return err; } if (selectionInfo.typeID != API_SelEmpty) { // collect indexes of selected dimensiosn const UInt32 nSel = BMGetHandleSize((GSHandle)selNeigs) / sizeof (API_Neig); if (nSel != 1) { // exit since invalid selection, accept only single select BMKillHandle((GSHandle*)&selNeigs); return err; } // Valid selection: single select API_Guid guid = (*selNeigs)[0].guid; BMKillHandle((GSHandle*)&selNeigs); if (g_guidPrev == guid) // Exit now if selected elem did not change return NoError; // Detach previous elem Observer_DetachAllElems(); g_guidPrev = guid; g_hasSelected = true; // Check if elem is already being observed API_Elem_Head** elemHead; Int32 nElems = 0; err = ACAPI_Element_GetObservedElements(&elemHead, &nElems); if (err != NoError) { WriteReport("["__FUNC__"] ERROR %s - ACAPI_Element_GetObservedElements", ErrId2Name(err)); return err; } for (Int32 i = 0; i < nElems; i++) { if ((*elemHead).guid == guid) // Exit if already observed { BMKillHandle((GSHandle*)&elemHead); return NoError; } } BMKillHandle((GSHandle*)&elemHead); // Attach elem to observer Observer_AttachElem(guid); } return NoError; } // SelectionChangeHandler GSErrCode InitializeSelectionChangeHandler() { const GSErrCode err = ACAPI_Notify_CatchSelectionChange(SelectionChangeHandler); if (err != NoError) DBGPrintlnf("[Error] %s "__FUNC__" - ACAPI_Notify_CatchSelectionChange(SelectionChangeHandler)", ErrId2Name(err)); return err; }
2017-09-07 06:16 PM
Erenford wrote:Have you debugged into this code to determine where the crash occurs? That might yield valuable clues to the source of the problem.
Greetings, I'm having problems when using two Notification handlers. Basically it's a palette that uses SelectionChangeHandler to detect selected element (if wall is selected, it will show stuff) then ElemObserverHandler to detect changes from that element so the palette can update automatically. I attach elems to the observer in the SelectionChangeHandler function if it detects valid selection.
2017-09-08 05:33 AM
Ralph wrote:Yes I forgot to mention that. I've tried but the crash occurs even before entering the SelectionChangeHandler function. I inserted a debug print at the very start of the function, did the actions above, and it crashes before printing it, immediately right after pressing undo.
Have you debugged into this code to determine where the crash occurs? That might yield valuable clues to the source of the problem.
2017-09-11 11:13 AM
2017-09-11 11:17 AM
Erenford wrote:What was the element observer doing? It wasn't trying to work on a deleted element by any chance?
[WORKAROUND]
Ok I did a workaround for this issue by removing the Elem Observer entirely. I noticed that SelectionChangeHandler gets called anyway at probably most user action so I figured I can check the elem change in there instead of a separate handler. I tested it and it seems to work fine.
I still don't know what the cause of the crashes though.
2017-09-12 04:41 AM
Ralph wrote:No I only used the
What was the element observer doing? It wasn't trying to work on a deleted element by any chance?
2017-09-12 11:02 AM
2017-09-13 03:51 AM
Mihály wrote:Great thanks for the notification, I'll mark this as solved then.
Hello Erenford,
Thank you your comment. Unfortunately this is an ArchiCAD bug which is already in our bug database. We will try to do the best to fix it and place into the next update.