diff --git a/desktop/api.cpp b/desktop/api.cpp index b564d5a..284d0c8 100644 --- a/desktop/api.cpp +++ b/desktop/api.cpp @@ -203,6 +203,8 @@ struct EsUndoManager { }; struct APIInstance { + uintptr_t referenceCount; + HashStore commands; _EsApplicationStartupInformation *startupInformation; @@ -814,6 +816,7 @@ APIInstance *InstanceSetup(EsInstance *instance) { APIInstance *apiInstance = (APIInstance *) EsHeapAllocate(sizeof(APIInstance), true); instance->_private = apiInstance; + apiInstance->referenceCount = 1; instance->undoManager = &apiInstance->undoManager; instance->undoManager->instance = instance; @@ -885,6 +888,7 @@ EsInstance *_EsInstanceCreate(size_t bytes, EsMessage *message, const char *appl if (message) { apiInstance->mainWindowHandle = message->createInstance.window; instance->window = EsWindowCreate(instance, ES_WINDOW_NORMAL); + EsInstanceOpenReference(instance); EsWindowSetTitle(instance->window, nullptr, 0); if (apiInstance->startupInformation && apiInstance->startupInformation->readHandle) { @@ -912,7 +916,28 @@ EsApplicationStartupRequest EsInstanceGetStartupRequest(EsInstance *_instance) { return request; } +void EsInstanceOpenReference(EsInstance *_instance) { + EsMessageMutexCheck(); + APIInstance *instance = (APIInstance *) _instance->_private; + EsAssert(instance->referenceCount); + instance->referenceCount++; +} + +void EsInstanceCloseReference(EsInstance *_instance) { + EsMessageMutexCheck(); + APIInstance *instance = (APIInstance *) _instance->_private; + instance->referenceCount--; + + if (!instance->referenceCount) { + EsMessage m = {}; + m.type = ES_MSG_INSTANCE_DESTROY; + m.instanceDestroy.instance = _instance; + EsMessagePost(nullptr, &m); + } +} + void EsInstanceDestroy(EsInstance *instance) { + EsMessageMutexCheck(); InspectorWindow **inspector = &((APIInstance *) instance->_private)->attachedInspector; if (*inspector) { @@ -923,8 +948,8 @@ void EsInstanceDestroy(EsInstance *instance) { UndoManagerDestroy(instance->undoManager); EsAssert(instance->window->instance == instance); - instance->window->destroyInstanceAfterClose = true; EsElementDestroy(instance->window); + EsInstanceCloseReference(instance); } EsWindow *WindowFromWindowID(EsObjectID id) { diff --git a/desktop/gui.cpp b/desktop/gui.cpp index cd564f3..c91145c 100644 --- a/desktop/gui.cpp +++ b/desktop/gui.cpp @@ -463,7 +463,7 @@ struct EsWindow : EsElement { uint32_t windowWidth, windowHeight; // TODO Replace this with a bitset? - bool willUpdate, toolbarFillMode, destroyInstanceAfterClose, doNotPaint; + bool willUpdate, toolbarFillMode, doNotPaint; bool restoreOnNextMove, resetPositionOnNextMove, receivedFirstResize, isMaximised; bool hovering, activated, appearActivated; bool visualizeRepaints, visualizeLayoutBounds, visualizePaintSteps; // Inspector properties. @@ -7253,14 +7253,10 @@ void UIProcessWindowManagerMessage(EsWindow *window, EsMessage *message, Process // Check if the window has been destroyed. if (message->type == ES_MSG_WINDOW_DESTROYED) { - if (window->destroyInstanceAfterClose) { - EsMessage m = {}; - m.type = ES_MSG_INSTANCE_DESTROY; - m.instanceDestroy.instance = window->instance; + if (window->instance) { EsAssert(window->instance->window == window); window->instance->window = nullptr; - window->instance = nullptr; - EsMessagePost(nullptr, &m); + EsInstanceCloseReference(window->instance); } EsAssert(window->handle == ES_INVALID_HANDLE); @@ -7546,7 +7542,7 @@ struct InspectorWindow : EsInstance { EsInstance *instance; // The instance being inspected. EsListView *elementList; - Array elements; + Array elements; // TODO This is being leaked. InspectorElementEntry hoveredElement; char *cCategoryFilter; @@ -8028,6 +8024,8 @@ void InspectorSetup(EsWindow *window) { InspectorWindow *inspector = (InspectorWindow *) EsHeapAllocate(sizeof(InspectorWindow), true); // TODO Freeing this. inspector->window = window; InstanceSetup(inspector); + EsInstanceOpenReference(inspector); + inspector->instance = window->instance; ((APIInstance *) inspector->_private)->internalOnly = true; window->instance = inspector; diff --git a/desktop/os.header b/desktop/os.header index c0402b7..6be18ab 100644 --- a/desktop/os.header +++ b/desktop/os.header @@ -2366,6 +2366,8 @@ function void EsCommandSetCallback(EsCommand *command, EsCommandCallback callbac function void EsCommandSetDisabled(EsCommand *command, bool disabled); function void EsCommandSetCheck(EsCommand *command, EsCheckState check, bool sendUpdatedMessage); +function void EsInstanceOpenReference(EsInstance *_instance); +function void EsInstanceCloseReference(EsInstance *_instance); function void EsInstanceDestroy(ES_INSTANCE_TYPE *instance); function void EsInstanceSetActiveUndoManager(ES_INSTANCE_TYPE *instance, EsUndoManager *manager); function void EsInstanceSetClassEditor(ES_INSTANCE_TYPE *instance, const EsInstanceClassEditorSettings *settings); diff --git a/util/api_table.ini b/util/api_table.ini index 5ad7a8c..f8e16f3 100644 --- a/util/api_table.ini +++ b/util/api_table.ini @@ -131,9 +131,11 @@ EsPipeRead=129 EsListViewInsert=130 EsListViewRemove=131 EsEventCreate=132 +EsInstanceOpenReference=133 EsBufferFormat=134 EsEventReset=135 EsEventSet=136 +EsInstanceCloseReference=137 EsMutexAcquire=140 EsMutexDestroy=141 EsMutexRelease=142