reference counting on API instances

This commit is contained in:
nakst 2021-11-14 18:59:45 +00:00
parent f4f69ea9c8
commit 2b288a82a6
4 changed files with 36 additions and 9 deletions

View File

@ -203,6 +203,8 @@ struct EsUndoManager {
};
struct APIInstance {
uintptr_t referenceCount;
HashStore<uint32_t, EsCommand *> 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) {

View File

@ -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<InspectorElementEntry> elements;
Array<InspectorElementEntry> 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;

View File

@ -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);

View File

@ -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