improve code structure

Wed, 01 Nov 2023 21:00:33 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 01 Nov 2023 21:00:33 +0100
changeset 7
9dd76cbd6c90
parent 6
302971e8599b
child 8
756b49205a29

improve code structure

src/Makefile file | annotate | diff | comparison | revisions
src/ascension/ascension.h file | annotate | diff | comparison | revisions
src/ascension/context.h file | annotate | diff | comparison | revisions
src/ascension/core.h file | annotate | diff | comparison | revisions
src/ascension/error.h file | annotate | diff | comparison | revisions
src/ascension/utils.h file | annotate | diff | comparison | revisions
src/ascension/window.h file | annotate | diff | comparison | revisions
src/context.c file | annotate | diff | comparison | revisions
src/core.c file | annotate | diff | comparison | revisions
src/error.c file | annotate | diff | comparison | revisions
src/window.c file | annotate | diff | comparison | revisions
test/Makefile file | annotate | diff | comparison | revisions
test/sandbox.c file | annotate | diff | comparison | revisions
--- a/src/Makefile	Wed Nov 01 20:09:49 2023 +0100
+++ b/src/Makefile	Wed Nov 01 21:00:33 2023 +0100
@@ -27,7 +27,7 @@
 
 BUILD_DIR=../build/lib
 
-SRC  = core.c window.c
+SRC  = context.c error.c window.c
 
 OBJ = $(SRC:%.c=$(BUILD_DIR)/%.o)
 
@@ -40,12 +40,18 @@
 
 FORCE:
 
-$(BUILD_DIR)/core.o: core.c ascension/core.h ascension/datatypes.h
+$(BUILD_DIR)/context.o: context.c ascension/context.h ascension/window.h \
+ ascension/datatypes.h ascension/utils.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -c $<
 
-$(BUILD_DIR)/window.o: window.c ascension/window.h ascension/core.h \
- ascension/datatypes.h
+$(BUILD_DIR)/error.o: error.c ascension/context.h ascension/window.h \
+ ascension/datatypes.h ascension/error.h ascension/utils.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -c $<
 
+$(BUILD_DIR)/window.o: window.c ascension/window.h ascension/datatypes.h \
+ ascension/context.h ascension/window.h ascension/error.h
+	@echo "Compiling $<"
+	$(CC) -o $@ $(CFLAGS) -c $<
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ascension/ascension.h	Wed Nov 01 21:00:33 2023 +0100
@@ -0,0 +1,35 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * Copyright 2023 Mike Becker. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ASCENSION_H
+#define ASCENSION_H
+
+#include "context.h"
+#include "error.h"
+
+#endif /* ASCENSION_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ascension/context.h	Wed Nov 01 21:00:33 2023 +0100
@@ -0,0 +1,69 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * Copyright 2023 Mike Becker. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ASCENSION_CONTEXT_H
+#define ASCENSION_CONTEXT_H
+
+#include "window.h"
+
+#include <cx/buffer.h>
+#include <cx/list.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** The flag for the overall initialized state. */
+#define ASC_FLAG_INITILIZED  0x01u
+
+/** Flag is set, when error buffer contains new error information. */
+#define ASC_FLAG_HAS_ERROR  0x02u
+
+/** Flag is set, when SDL wants to quit the application. */
+#define ASC_FLAG_QUIT 0x80000000u
+
+/**
+ * The global ascension context.
+ */
+typedef struct AscContext {
+    unsigned int flags;
+    CxBuffer error_buffer;
+    AscWindow windows[ASC_MAX_WINDOWS];
+} AscContext;
+
+/** Global ascension context. */
+extern AscContext asc_context;
+
+void asc_context_initialize(void);
+void asc_context_destroy(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* ASCENSION_CONTEXT_H */
+
--- a/src/ascension/core.h	Wed Nov 01 20:09:49 2023 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- * Copyright 2023 Mike Becker. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ASCENSION_CORE_H
-#define ASCENSION_CORE_H
-
-#include <cx/string.h>
-#include <cx/buffer.h>
-#include <cx/list.h>
-
-#include "datatypes.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** The flag for the overall initialized state. */
-#define ASC_FLAG_INITILIZED  0x01u
-
-/** Flag is set, when error buffer contains new error information. */
-#define ASC_FLAG_HAS_ERROR  0x02u
-
-/** Flag is set, when SDL wants to quit the application. */
-#define ASC_FLAG_QUIT 0x80000000u
-
-typedef struct AscContext {
-    CxBuffer error_buffer;
-    CxList *windows;
-    unsigned int flags;
-} AscContext;
-
-/** Global ascension context. */
-extern AscContext asc_context;
-
-void asc_context_initialize(void);
-void asc_context_destroy(void);
-
-static inline bool asc_test_flag(unsigned int reg, int flag) {
-    return (reg & flag) == flag;
-}
-
-static inline void asc_set_flag(unsigned int *reg, int flag) {
-    *reg |= flag;
-}
-
-static inline void asc_clear_flag(unsigned int *reg, int flag) {
-    *reg &= ~flag;
-}
-
-void asc_error_cxstr(cxstring text);
-void asc_error_cchar(char const* text);
-void asc_error_cuchar(unsigned char const* text);
-
-#define asc_error(text) _Generic((text),     \
-    char const*: asc_error_cchar,            \
-    unsigned char const*: asc_error_cuchar,  \
-    char*: asc_error_cchar,                  \
-    unsigned char*: asc_error_cuchar,        \
-    cxstring: asc_error_cxstr)(text)
-
-bool asc_has_error(void);
-char const* asc_get_error(void);
-void asc_clear_error(void);
-
-#ifdef NDEBUG
-#define asc_dprintf(...)
-#else
-#define asc_dprintf(...) printf(__VA_ARGS__); putchar('\n')
-#endif
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* ASCENSION_CORE_H */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ascension/error.h	Wed Nov 01 21:00:33 2023 +0100
@@ -0,0 +1,63 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * Copyright 2023 Mike Becker. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ASCENSION_ERROR_H
+#define ASCENSION_ERROR_H
+
+#include <cx/string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void asc_error_cxstr(cxstring text);
+void asc_error_cchar(char const* text);
+void asc_error_cuchar(unsigned char const* text);
+
+#define asc_error(text) _Generic((text),     \
+    char const*: asc_error_cchar,            \
+    unsigned char const*: asc_error_cuchar,  \
+    char*: asc_error_cchar,                  \
+    unsigned char*: asc_error_cuchar,        \
+    cxstring: asc_error_cxstr)(text)
+
+bool asc_has_error(void);
+char const* asc_get_error(void);
+void asc_clear_error(void);
+
+#ifdef NDEBUG
+#define asc_dprintf(...)
+#else
+#define asc_dprintf(...) printf(__VA_ARGS__); putchar('\n')
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* ASCENSION_ERROR_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ascension/utils.h	Wed Nov 01 21:00:33 2023 +0100
@@ -0,0 +1,55 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * Copyright 2023 Mike Becker. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ASCENSION_UTILS_H
+#define ASCENSION_UTILS_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+static inline bool asc_test_flag(unsigned int reg, int flag) {
+    return (reg & flag) == flag;
+}
+
+static inline void asc_set_flag(unsigned int *reg, int flag) {
+    *reg |= flag;
+}
+
+static inline void asc_clear_flag(unsigned int *reg, int flag) {
+    *reg &= ~flag;
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* ASCENSION_UTILS_H */
+
--- a/src/ascension/window.h	Wed Nov 01 20:09:49 2023 +0100
+++ b/src/ascension/window.h	Wed Nov 01 21:00:33 2023 +0100
@@ -30,7 +30,13 @@
 
 #include <SDL2/SDL.h>
 
-#include "core.h"
+#include "datatypes.h"
+
+#ifndef ASC_MAX_WINDOWS
+/** The maximum number of windows that can exist simultaneously. */
+#define ASC_MAX_WINDOWS 4
+#endif // ASC_MAX_WINDOWS
+
 
 #ifdef __cplusplus
 extern "C" {
@@ -71,10 +77,14 @@
 /**
  * Creates and initializes a new window and a corresponding OpenGL context.
  *
- * @param window the window structure
+ * The index specified must not be in use by another window already.
+ * The maximum number of windows is defined by #ASC_MAX_WINDOWS.
+ *
+ * @param index the index of the new window
  * @param settings the settings to be used for initialization
+ * @return a pointer to the window data or \c NULL if initialization failed
  */
-void asc_window_initialize(AscWindow* window, AscWindowSettings const* settings);
+AscWindow *asc_window_initialize(unsigned int index, AscWindowSettings const* settings);
 
 /**
  * Destroys the window and its OpenGL context.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/context.c	Wed Nov 01 21:00:33 2023 +0100
@@ -0,0 +1,84 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * Copyright 2023 Mike Becker. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ascension/context.h"
+#include "ascension/error.h"
+#include "ascension/utils.h"
+
+#include <cx/linked_list.h>
+
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_ttf.h>
+
+AscContext asc_context;
+
+void asc_context_initialize(void) {
+    if (asc_test_flag(asc_context.flags, ASC_FLAG_INITILIZED))
+        return;
+    asc_clear_flag(&asc_context.flags, ASC_FLAG_HAS_ERROR);
+
+    // initialize error buffer
+    cxBufferInit(
+            &asc_context.error_buffer,
+            NULL,
+            256,
+            NULL,
+            CX_BUFFER_AUTO_EXTEND
+    );
+
+    // initialize data
+    memset(asc_context.windows, 0, sizeof (asc_context.windows));
+
+    // initialize SDL
+    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+        asc_error(SDL_GetError());
+    } else {
+        if (TTF_Init() < 0) {
+            asc_error(TTF_GetError());
+        }
+    }
+    SDL_ClearError();
+    asc_set_flag(&asc_context.flags, ASC_FLAG_INITILIZED);
+    asc_dprintf("Ascension context initialized.");
+}
+
+void asc_context_destroy(void) {
+    // destroy data
+    for (unsigned int i = 0 ; i < ASC_MAX_WINDOWS ; i++) {
+        asc_window_destroy(&asc_context.windows[i]);
+    }
+
+    // quit SDL
+    if (TTF_WasInit())
+        TTF_Quit();
+    SDL_Quit();
+
+    // destroy the error buffer
+    cxBufferDestroy(&asc_context.error_buffer);
+    asc_context.flags = 0;
+    asc_dprintf("Ascension context destroyed.");
+}
--- a/src/core.c	Wed Nov 01 20:09:49 2023 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- * Copyright 2023 Mike Becker. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ascension/core.h"
-
-#include <cx/linked_list.h>
-#include <cx/printf.h>
-
-#include <SDL2/SDL.h>
-#include <SDL2/SDL_ttf.h>
-
-AscContext asc_context;
-
-// forward declare the destructor functions that reside in other units
-void asc_window_destroy_impl(void* obj);
-
-void asc_context_initialize(void) {
-    if (asc_test_flag(asc_context.flags, ASC_FLAG_INITILIZED))
-        return;
-    asc_clear_flag(&asc_context.flags, ASC_FLAG_HAS_ERROR);
-
-    // initialize error buffer
-    cxBufferInit(
-            &asc_context.error_buffer,
-            NULL,
-            256,
-            NULL,
-            CX_BUFFER_AUTO_EXTEND
-    );
-
-    // initialize lists
-    asc_context.windows = cxLinkedListCreateSimple(CX_STORE_POINTERS);
-    asc_context.windows->simple_destructor =
-            (cx_destructor_func)asc_window_destroy_impl;
-
-    // initialize SDL
-    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
-        asc_error(SDL_GetError());
-    } else {
-        if (TTF_Init() < 0) {
-            asc_error(TTF_GetError());
-        }
-    }
-    SDL_ClearError();
-    asc_set_flag(&asc_context.flags, ASC_FLAG_INITILIZED);
-    asc_dprintf("Ascension context initialized.");
-}
-
-void asc_context_destroy(void) {
-    // destroy lists
-    cxListDestroy(asc_context.windows);
-
-    // quit SDL
-    if (TTF_WasInit())
-        TTF_Quit();
-    SDL_Quit();
-
-    // destroy the error buffer
-    cxBufferDestroy(&asc_context.error_buffer);
-    asc_context.flags = 0;
-    asc_dprintf("Ascension context destroyed.");
-}
-
-void asc_error_cchar(char const* text) {
-    asc_error_cxstr(cx_str(text));
-}
-
-void asc_error_cuchar(unsigned char const* text) {
-    asc_error_cxstr(cx_str((char const*)text));
-}
-
-void asc_error_cxstr(cxstring text) {
-    if (text.length == 0) return;
-
-    // write error to debug output
-    asc_dprintf("ERROR: %*.s", (int)text.length, text.ptr);
-
-    // write error to buffer
-    CxBuffer* buf = &asc_context.error_buffer;
-    cxBufferWrite(text.ptr, 1, text.length, buf);
-    cxBufferPut(buf, '\n');
-
-    asc_set_flag(&asc_context.flags, ASC_FLAG_HAS_ERROR);
-}
-
-bool asc_has_error(void) {
-    return asc_test_flag(asc_context.flags, ASC_FLAG_HAS_ERROR);
-}
-
-char const* asc_get_error(void) {
-    // we zero-terminate the current buffer contents before providing them
-    cxBufferPut(&asc_context.error_buffer, 0);
-    --asc_context.error_buffer.pos;
-    --asc_context.error_buffer.size;
-    return asc_context.error_buffer.space;
-}
-
-void asc_clear_error(void) {
-    cxBufferClear(&asc_context.error_buffer);
-    asc_clear_flag(&asc_context.flags, ASC_FLAG_HAS_ERROR);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/error.c	Wed Nov 01 21:00:33 2023 +0100
@@ -0,0 +1,71 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * Copyright 2023 Mike Becker. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ascension/context.h"
+#include "ascension/error.h"
+#include "ascension/utils.h"
+
+#include <cx/buffer.h>
+
+void asc_error_cchar(char const* text) {
+    asc_error_cxstr(cx_str(text));
+}
+
+void asc_error_cuchar(unsigned char const* text) {
+    asc_error_cxstr(cx_str((char const*)text));
+}
+
+void asc_error_cxstr(cxstring text) {
+    if (text.length == 0) return;
+
+    // write error to debug output
+    asc_dprintf("ERROR: %*.s", (int)text.length, text.ptr);
+
+    // write error to buffer
+    CxBuffer* buf = &asc_context.error_buffer;
+    cxBufferWrite(text.ptr, 1, text.length, buf);
+    cxBufferPut(buf, '\n');
+
+    asc_set_flag(&asc_context.flags, ASC_FLAG_HAS_ERROR);
+}
+
+bool asc_has_error(void) {
+    return asc_test_flag(asc_context.flags, ASC_FLAG_HAS_ERROR);
+}
+
+char const* asc_get_error(void) {
+    // we zero-terminate the current buffer contents before providing them
+    cxBufferPut(&asc_context.error_buffer, 0);
+    --asc_context.error_buffer.pos;
+    --asc_context.error_buffer.size;
+    return asc_context.error_buffer.space;
+}
+
+void asc_clear_error(void) {
+    cxBufferClear(&asc_context.error_buffer);
+    asc_clear_flag(&asc_context.flags, ASC_FLAG_HAS_ERROR);
+}
--- a/src/window.c	Wed Nov 01 20:09:49 2023 +0100
+++ b/src/window.c	Wed Nov 01 21:00:33 2023 +0100
@@ -26,6 +26,8 @@
  */
 
 #include "ascension/window.h"
+#include "ascension/context.h"
+#include "ascension/error.h"
 
 #include <cx/linked_list.h>
 #include <cx/printf.h>
@@ -50,11 +52,10 @@
 
 
 static void asc_event_window_resized(Uint32 id, Sint32 width, Sint32 height) {
-    CxIterator iter = cxListIterator(asc_context.windows);
-    cx_foreach(AscWindow*, w, iter) {
-        if (w->id == id) {
-            w->dimensions.width = width;
-            w->dimensions.height = height;
+    for (unsigned int i = 0 ; i < ASC_MAX_WINDOWS ; i++) {
+        if (asc_context.windows[i].id == id) {
+            asc_context.windows[i].dimensions.width = width;
+            asc_context.windows[i].dimensions.height = height;
             return;
         }
     }
@@ -87,9 +88,10 @@
     }
 
     // sync the windows
-    CxMutIterator windows = cxListMutIterator(asc_context.windows);
-    cx_foreach(AscWindow*, w, windows) {
-        asc_window_sync(w);
+    for (unsigned int i = 0 ; i < ASC_MAX_WINDOWS ; i++) {
+        if (asc_context.windows[i].id > 0) {
+            asc_window_sync(&asc_context.windows[i]);
+        }
     }
     return true;
 }
@@ -105,7 +107,18 @@
     settings->title = "Ascended Window";
 }
 
-void asc_window_initialize(AscWindow* window, AscWindowSettings const* settings) {
+AscWindow *asc_window_initialize(unsigned int index, AscWindowSettings const *settings) {
+    if (index >= ASC_MAX_WINDOWS) {
+        asc_error("Maximum number of windows exceeded.");
+        return NULL;
+    }
+    AscWindow *window = &asc_context.windows[index];
+    if (window->id > 0) {
+        asc_error("Cannot create window - slot already occupied.");
+        asc_dprintf("Tried to create window with index %u", index);
+        return NULL;
+    }
+
     Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
     flags |= settings->fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_RESIZABLE;
 
@@ -119,7 +132,7 @@
     );
     if (window->window == NULL) {
         asc_error(SDL_GetError());
-        return;
+        return NULL;
     }
 
     window->id = SDL_GetWindowID(window->window);
@@ -147,8 +160,7 @@
             glEnable(GL_DEBUG_OUTPUT);
             glDebugMessageCallback(asc_gl_debug_callback, NULL);
             asc_dprintf("Window %u initialized", window->id);
-            cxListAdd(asc_context.windows, window);
-            return;
+            return window;
         } else {
             asc_error(glewGetErrorString(err));
         }
@@ -164,8 +176,11 @@
     window->id = 0;
 }
 
-void asc_window_destroy_impl(AscWindow* window) {
-    // destory the GL context and the window
+void asc_window_destroy(AscWindow* window) {
+    // safeguard
+    if (window->id == 0) return;
+
+    // destroy the GL context and the window
     if (window->glctx != NULL) {
         SDL_GL_DeleteContext(window->glctx);
     }
@@ -178,19 +193,6 @@
     memset(window, 0, sizeof(AscWindow));
 }
 
-void asc_window_destroy(AscWindow* window) {
-    // find the window in the context and remove it
-    bool found = false;
-    CxMutIterator iter = cxListMutIterator(asc_context.windows);
-    cx_foreach(AscWindow*, w, iter) {
-        if (w == window) {
-            found = true;
-            cxIteratorFlagRemoval(iter);
-        }
-    }
-    if (!found) asc_window_destroy_impl(window);
-}
-
 void asc_window_sync(AscWindow const* window) {
     SDL_GL_MakeCurrent(window->window, window->glctx);
     SDL_GL_SwapWindow(window->window);
--- a/test/Makefile	Wed Nov 01 20:09:49 2023 +0100
+++ b/test/Makefile	Wed Nov 01 21:00:33 2023 +0100
@@ -38,8 +38,9 @@
 
 FORCE:
 
-$(BUILD_DIR)/sandbox.o: sandbox.c ../src/ascension/window.h \
- ../src/ascension/core.h ../src/ascension/datatypes.h
+$(BUILD_DIR)/sandbox.o: sandbox.c ../src/ascension/ascension.h \
+ ../src/ascension/context.h ../src/ascension/window.h \
+ ../src/ascension/datatypes.h ../src/ascension/error.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -c $<
 
--- a/test/sandbox.c	Wed Nov 01 20:09:49 2023 +0100
+++ b/test/sandbox.c	Wed Nov 01 21:00:33 2023 +0100
@@ -25,7 +25,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "ascension/window.h"
+#include <ascension/ascension.h>
 
 static bool show_message_box_on_error(SDL_Window* window) {
     if (asc_has_error()) {
@@ -48,12 +48,11 @@
     asc_window_settings_init_defaults(&settings);
     settings.title = "Sandbox Application";
 
-    AscWindow window;
-    asc_window_initialize(&window, &settings);
+    AscWindow *window = asc_window_initialize(0, &settings);
 
     while (asc_loop_next()) {
         // quit application on any error
-        if (show_message_box_on_error(window.window)) break;
+        if (show_message_box_on_error(window->window)) break;
 
 
     }

mercurial