Modified common and the macOS port to exhibit the new init/main behavior. Now to adjust the tests.

This commit is contained in:
Pietro Gagliardi 2020-05-09 01:24:40 -04:00
parent faaccd0413
commit 514037ba6c
4 changed files with 84 additions and 20 deletions

View File

@ -1,24 +1,47 @@
// 19 april 2019 // 19 april 2019
#include "uipriv.h" #include "uipriv.h"
static bool initialized = false; enum {
stateUninitialized,
stateBeforeMain,
stateInMain,
stateQuitting,
stateAfterMain,
stateError,
};
static int state = stateUninitialized;
#define initialized() (state != stateUninitialized && state != stateError)
bool uiInit(void *options, uiInitError *err) bool uiInit(void *options, uiInitError *err)
{ {
if (err == NULL) if (state != stateUninitialized) {
uiprivProgrammerErrorMultipleCalls(uiprivFunc);
state = stateError;
return false; return false;
if (err->Size != sizeof (uiInitError)) }
if (options != NULL) {
uiprivProgrammerErrorBadInitOptions(uiprivFunc);
state = stateError;
return false; return false;
}
if (initialized) if (err == NULL) {
return uiprivInitReturnErrorf(err, "libui already initialized"); uiprivProgrammerErrorNullPointer("uiInitError", uiprivFunc);
state = stateError;
if (options != NULL)
return uiprivInitReturnErrorf(err, "options parameter to uiInit() must be NULL");
if (!uiprivSysInit(options, err))
return false; return false;
initialized = true; }
if (err->Size != sizeof (uiInitError)) {
uiprivProgrammerErrorWrongStructSize(err->Size, "uiInitError", uiprivFunc);
state = stateError;
return false;
}
if (!uiprivSysInit(options, err)) {
state = stateError;
return false;
}
state = stateBeforeMain;
return true; return true;
} }
@ -44,9 +67,39 @@ bool uiprivInitReturnErrorf(uiInitError *err, const char *fmt, ...)
return false; return false;
} }
void uiMain(void)
{
if (!uiprivCheckInitializedAndThread())
return;
if (state != stateBeforeMain) {
uiprivProgrammerErrorMultipleCalls(uiprivFunc);
return;
}
state = stateInMain;
uiprivSysMain();
state = stateAfterMain;
}
void uiQuit(void)
{
if (!uiprivCheckInitializedAndThread())
return;
if (state == stateQuitting || state == stateAfterMain) {
uiprivProgrammerErrorMultipleCalls(uiprivFunc);
return;
}
if (state != stateInMain) {
// the above handle the other states, so stateBeforeMain is what's left
uiprivProgrammerErrorQuitBeforeMain(uiprivFunc);
return;
}
state = stateQuitting;
uiprivSysQuit();
}
void uiQueueMain(void (*f)(void *data), void *data) void uiQueueMain(void (*f)(void *data), void *data)
{ {
if (!initialized) { if (!initialized()) {
uiprivProgrammerErrorNotInitialized(uiprivFunc); uiprivProgrammerErrorNotInitialized(uiprivFunc);
return; return;
} }
@ -56,7 +109,7 @@ void uiQueueMain(void (*f)(void *data), void *data)
bool uiprivCheckInitializedAndThreadImpl(const char *func) bool uiprivCheckInitializedAndThreadImpl(const char *func)
{ {
// While it does seem risky to not lock this, if this changes during the execution of this function it means only that it was changed from a different thread, and since it can only change from false to true, an error will be reported anyway. // While it does seem risky to not lock this, if this changes during the execution of this function it means only that it was changed from a different thread, and since it can only change from false to true, an error will be reported anyway.
if (!initialized) { if (!initialized()) {
uiprivProgrammerErrorNotInitialized(func); uiprivProgrammerErrorNotInitialized(func);
return false; return false;
} }

View File

@ -24,6 +24,19 @@
// } // }
// main {
#define uiprivProgrammerErrorMultipleCalls(func) \
uiprivProgrammerError("%s(): attempt to call more than once", func)
#define uiprivProgrammerErrorBadInitOptions(func) \
uiprivProgrammerError("%s(): invalid uiInitOptions passed", func)
#define uiprivProgrammerErrorQuitBeforeMain(func) \
uiprivProgrammerError("%s(): attempt to call before uiMain()", func)
// }
// controls { // controls {
#define uiprivProgrammerErrorRequiredControlMethodMissing(typeName, tableType, methodName, func) \ #define uiprivProgrammerErrorRequiredControlMethodMissing(typeName, tableType, methodName, func) \

View File

@ -40,6 +40,8 @@ extern bool uiprivSysInit(void *options, uiInitError *err);
uiprivPrintfFunc( uiprivPrintfFunc(
extern bool uiprivInitReturnErrorf(uiInitError *err, const char *fmt, ...), extern bool uiprivInitReturnErrorf(uiInitError *err, const char *fmt, ...),
2, 3); 2, 3);
extern void uiprivSysMain(void);
extern void uiprivSysQuit(void);
extern void uiprivSysQueueMain(void (*f)(void *data), void *data); extern void uiprivSysQueueMain(void (*f)(void *data), void *data);
extern bool uiprivCheckInitializedAndThreadImpl(const char *func); extern bool uiprivCheckInitializedAndThreadImpl(const char *func);
#define uiprivCheckInitializedAndThread() uiprivCheckInitializedAndThreadImpl(uiprivFunc) #define uiprivCheckInitializedAndThread() uiprivCheckInitializedAndThreadImpl(uiprivFunc)

View File

@ -56,17 +56,13 @@ bool uiprivSysInit(void *options, uiInitError *err)
return true; return true;
} }
void uiMain(void) void uiprivSysMain(void)
{ {
if (!uiprivCheckInitializedAndThread())
return;
[uiprivApp run]; [uiprivApp run];
} }
void uiQuit(void) void uiprivSysQuit(void)
{ {
if (!uiprivCheckInitializedAndThread())
return;
@autoreleasepool { @autoreleasepool {
NSEvent *e; NSEvent *e;