Modified common and the macOS port to exhibit the new init/main behavior. Now to adjust the tests.
This commit is contained in:
parent
faaccd0413
commit
514037ba6c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) \
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue