diff --git a/CMakeLists.txt b/CMakeLists.txt index e076dc6..da7aeaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,12 +11,13 @@ function(print var) message("${var} = ${${var}}") endfunction() -#TODO: Might want to remove this +# ~ DEFAULT TO DEBUG IF TYPE NOT SET ~ # if(NOT CMAKE_BUILD_TYPE) message("[Archeus] Build Type not set, defaulting to Debug") set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Default to Debug" FORCE) endif() +# ~ COMPILER OPTIONS ~ # add_compile_options( "-Wall" "-Werror" "-fexceptions" "$<$:-O0;-g3;-ggdb;-DARC_DEBUG;>" @@ -28,13 +29,13 @@ option(ARCHEUS_DEFAULT_CONFIG "Build with default config keys" ON) option(ARCHEUS_TESTS "Build with tests" OFF) set(ARCHEUS_WINDOW_BACKEND "NONE" CACHE STRING "Window Backend to build with") -set_property(CACHE ARCHEUS_WINDOW_BACKEND PROPERTY STRINGS NONE SDL2 GLFW) +set_property(CACHE ARCHEUS_WINDOW_BACKEND PROPERTY STRINGS NONE SDL2 SDL3 GLFW) set(ARCHEUS_INPUT_BACKEND "NONE" CACHE STRING "Input Backend to build with, most likely should match Window Backend") -set_property(CACHE ARCHEUS_INPUT_BACKEND PROPERTY STRINGS NONE SDL2 GLFW) +set_property(CACHE ARCHEUS_INPUT_BACKEND PROPERTY STRINGS NONE SDL2 SDL3 GLFW) set(ARCHEUS_GRAPHICS_BACKEND "NONE" CACHE STRING "Graphics Backend to build with") -set_property(CACHE ARCHEUS_GRAPHICS_BACKEND PROPERTY STRINGS NONE SDL2 OPENGL) +set_property(CACHE ARCHEUS_GRAPHICS_BACKEND PROPERTY STRINGS NONE SDL2 SDL3 OPENGL) if(UNIX) set(ARCHEUS_CONSOLE_BACKEND "NONE" CACHE STRING "Console Backend to build with") @@ -81,6 +82,7 @@ set(ARCHEUS_SOURCES src/std/vector/inline.c src/math/circle.c + src/math/config.c src/math/obround.c src/math/point.c src/math/rectangle.c @@ -98,6 +100,10 @@ none_check_and_init_needed(ARCHEUS_FLAGS ARCHEUS_SOURCES ${ARCHEUS_WINDOW_BACKEN include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/archeus_sdl2.cmake) sdl2_check_and_init_needed(ARCHEUS_SOURCES ARCHEUS_INCLUDE_DIRECTORIES ARCHEUS_LINK_LIBRARIES ${ARCHEUS_WINDOW_BACKEND} ${ARCHEUS_INPUT_BACKEND} ${ARCHEUS_GRAPHICS_BACKEND}) +# ~ SDL3 ~ # +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/archeus_sdl3.cmake) +sdl3_check_and_init_needed(ARCHEUS_SOURCES ARCHEUS_INCLUDE_DIRECTORIES ARCHEUS_LINK_LIBRARIES ${ARCHEUS_WINDOW_BACKEND} ${ARCHEUS_INPUT_BACKEND} ${ARCHEUS_GRAPHICS_BACKEND}) + # ~ OPENGL ~ # include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/archeus_opengl.cmake) opengl_check_and_init_needed(ARCHEUS_FLAGS ARCHEUS_SOURCES ${ARCHEUS_GRAPHICS_BACKEND}) @@ -130,14 +136,14 @@ if(ARCHEUS_TESTS) add_executable(tests tests/test.c - #tests/std/config.c - #tests/std/entity.c - #tests/std/hashtable.c - #tests/std/lexer.c - #tests/std/parser.c - #tests/std/parser/csv.c - #tests/std/parser/parserlang.c - #tests/std/vector.c + tests/std/config.c + tests/std/entity.c + tests/std/hashtable.c + tests/std/lexer.c + tests/std/parser.c + tests/std/parser/csv.c + tests/std/parser/parserlang.c + tests/std/vector.c tests/std/vector/inline.c ${ARCHEUS_SOURCES} diff --git a/cmake/archeus_sdl2.cmake b/cmake/archeus_sdl2.cmake index 1e8e380..8b22655 100644 --- a/cmake/archeus_sdl2.cmake +++ b/cmake/archeus_sdl2.cmake @@ -1,4 +1,5 @@ set(ARCHEUS_SDL2_WINDOW_SOURCES + packages/graphics/sdl/config.c packages/graphics/sdl/window.c packages/graphics/sdl/renderer.c ) diff --git a/cmake/archeus_sdl3.cmake b/cmake/archeus_sdl3.cmake new file mode 100644 index 0000000..4a1cbc3 --- /dev/null +++ b/cmake/archeus_sdl3.cmake @@ -0,0 +1,89 @@ +set(ARCHEUS_SDL3_WINDOW_SOURCES + packages/graphics/sdl3/config.c + packages/graphics/sdl3/window.c + packages/graphics/sdl3/renderer.c +) + +set(ARCHEUS_SDL3_INPUT_SOURCES + packages/input/sdl3/input.c + packages/input/sdl3/keyboard.c + packages/input/sdl3/mouse.c + + #TODO: remove this + packages/audio/sdl3/config.c +) + +set(ARCHEUS_SDL3_GRAPHICS_SOURCES + packages/graphics/sdl3/circle.c + packages/graphics/sdl3/config.c + packages/graphics/sdl3/line.c + packages/graphics/sdl3/obround.c + packages/graphics/sdl3/rectangle.c + packages/graphics/sdl3/sprite.c + packages/graphics/sdl3/spritesheet.c + packages/graphics/sdl3/text.c +) + +function(sdl3_check_and_init_needed _ARCHEUS_SOURCES _ARCHEUS_INCLUDE_DIRECTORIES _ARCHEUS_LINK_LIBRARIES ARCHEUS_WINDOW_BACKEND ARCHEUS_INPUT_BACKEND ARCHEUS_GRAPHICS_BACKEND) + #if no backend uses sdl return + if(NOT ${ARCHEUS_WINDOW_BACKEND} STREQUAL "SDL3" AND NOT ${ARCHEUS_INPUT_BACKEND} STREQUAL "SDL3" AND NOT ${ARCHEUS_GRAPHICS_BACKEND} STREQUAL "SDL3") + return() + endif() + + #get needed libraries for backends + find_package(SDL3 REQUIRED) + + #add to include directories + list(APPEND ${_ARCHEUS_INCLUDE_DIRECTORIES} + PRIVATE ${SDL3_INCLUDE_DIRS} + ) + + #add to link libraries + list(APPEND ${_ARCHEUS_LINK_LIBRARIES} + PUBLIC ${SDL3_LIBRARIES} + ) + + #add matching files for the selected backends + if(${ARCHEUS_WINDOW_BACKEND} STREQUAL "SDL3") + list(APPEND ${_ARCHEUS_SOURCES} ${ARCHEUS_SDL3_WINDOW_SOURCES}) + endif() + + if(${ARCHEUS_INPUT_BACKEND} STREQUAL "SDL3") + #TODO: remove this + find_package(SDL3_mixer REQUIRED) + + list(APPEND ${_ARCHEUS_SOURCES} ${ARCHEUS_SDL3_INPUT_SOURCES}) + + #TODO: remove this + list(APPEND ${_ARCHEUS_LINK_LIBRARIES} + PUBLIC SDL3_mixer::SDL3_mixer + ) + endif() + + if(${ARCHEUS_GRAPHICS_BACKEND} STREQUAL "SDL3") + find_package(SDL3_image REQUIRED) + find_package(SDL3_ttf REQUIRED) + + #find_package(PkgConfig REQUIRED) + #pkg_check_modules(SDL3_GFX REQUIRED SDL3_gfx) + + list(APPEND ${_ARCHEUS_SOURCES} ${ARCHEUS_SDL3_GRAPHICS_SOURCES}) + + #add to include directories + list(APPEND ${_ARCHEUS_INCLUDE_DIRECTORIES} + PRIVATE ${SDL3IMAGE_INCLUDE_DIRS} + #PRIVATE ${SDL3_GFX_INCLUDE_DIRS} + ) + + #add to link libraries + list(APPEND ${_ARCHEUS_LINK_LIBRARIES} + PUBLIC SDL3_image::SDL3_image + PUBLIC SDL3_ttf::SDL3_ttf + #PUBLIC ${SDL3_GFX_LIBRARIES} + ) + endif() + + set(${_ARCHEUS_SOURCES} ${${_ARCHEUS_SOURCES}} PARENT_SCOPE) + set(${_ARCHEUS_INCLUDE_DIRECTORIES} ${${_ARCHEUS_INCLUDE_DIRECTORIES}} PARENT_SCOPE) + set(${_ARCHEUS_LINK_LIBRARIES} ${${_ARCHEUS_LINK_LIBRARIES}} PARENT_SCOPE) +endfunction() diff --git a/doc/doxygen/doxygen-awesome-css/header.html b/doc/doxygen/doxygen-awesome-css/header.html index f0d2b33..87e4e0b 100644 --- a/doc/doxygen/doxygen-awesome-css/header.html +++ b/doc/doxygen/doxygen-awesome-css/header.html @@ -21,7 +21,7 @@ $search $mathjax $extrastylesheet - + diff --git a/doc/pages/standard.md b/doc/pages/standard.md index 2b4bbc9..a03c1fd 100644 --- a/doc/pages/standard.md +++ b/doc/pages/standard.md @@ -4,7 +4,7 @@ Archeus' standard library is a collection of basic datatypes that does not depen - @subpage standard-array "ARC_Array" - @subpage standard-bool "ARC_Bool" -- @subpage standard-chemical "ARC_Chemical" +- @subpage standard-config "ARC_Config" - @subpage standard-errno "ARC_Errno" - @subpage standard-hashtable "ARC_Hashtable" - @subpage standard-io "ARC_IO" diff --git a/doc/pages/standard/array.md b/doc/pages/standard/array.md index 9e95a0f..0f3536c 100644 --- a/doc/pages/standard/array.md +++ b/doc/pages/standard/array.md @@ -9,9 +9,7 @@ The API Reference for ::ARC_Array can be found here: arc/std/array.h # Example ```c -#include -#include -#include +#include //initing the array (as it is a basic type there is no ARC_Array_Create or ARC_Array_Destroy) ARC_Array exampleArray; diff --git a/doc/pages/standard/bool.md b/doc/pages/standard/bool.md index 1db0df2..ddb3633 100644 --- a/doc/pages/standard/bool.md +++ b/doc/pages/standard/bool.md @@ -9,7 +9,7 @@ The API Reference for ::ARC_Bool can be found here: arc/std/bool.h # Basic Example ```c -#include +#include ARC_Bool example = ARC_True; @@ -30,7 +30,7 @@ if(example == ARC_True){ #define ARC_True 1 #define ARC_False 0 -#include +#include ARC_Bool example = ARC_False; diff --git a/doc/pages/standard/chemical.md b/doc/pages/standard/config.md similarity index 66% rename from doc/pages/standard/chemical.md rename to doc/pages/standard/config.md index e698e8b..3f387c4 100644 --- a/doc/pages/standard/chemical.md +++ b/doc/pages/standard/config.md @@ -1,5 +1,5 @@ -\page standard-chemical ARC_Chemical +\page standard-config ARC_Config This type is being actively worked on. It will be a config type to read in .chemical files. The name was chosen from the four ethers that Archeus can be broken down into (Chemical, Life, Light, and Reflective) -*This page will be written after completing the ::ARC_Chemical type* +*This page will be written after completing the ::ARC_Config type* diff --git a/doc/pages/standard/errno.md b/doc/pages/standard/errno.md index 5346c61..ce270d4 100644 --- a/doc/pages/standard/errno.md +++ b/doc/pages/standard/errno.md @@ -13,7 +13,7 @@ When throwing errors, ::arc_errno should usually be set to an ARC_ERRNO_ define # Basic Example ```c -#include +#include void ARC_Example_ThrowNullError(){ uint32_t *exampleNumber = NULL; @@ -35,8 +35,7 @@ Sometimes the error will have data that could be helpful when debugging, so ther # Example With Variables ```c -#include -#include +#include void ARC_Example_ThrowPathError(ARC_String *path){ ARC_String *data; diff --git a/doc/pages/standard/lexer.md b/doc/pages/standard/lexer.md index 8fc6d13..0743fe6 100644 --- a/doc/pages/standard/lexer.md +++ b/doc/pages/standard/lexer.md @@ -1 +1,64 @@ \page standard-lexer ARC_Lexer + +# Basic Overview + +The ::ARC_Lexer type takes rules for what a token in, then takes a string and splits it up into tokens based on the rules. + +The API Reference for ::ARC_Lexer can be found here: arc/std/lexer.h + +Note: @ref standard-config "ARC_Config" uses a lot of functions from the lexer + +# Basic Example + +```c +#include + +const uint32_t TOKEN_NULL = 0; +const uint32_t TOKEN_NUMBER = 1; +const uint32_t TOKEN_ALPHA_LOWER_CHAR = 2; +const uint32_t TOKEN_ALPHA_UPPER_CHAR = 3; +const uint32_t TOKEN_HYPHEN = 4; + +//private function to initialize the lexer rules for the language +void ARC_Example_InitLexerRulesFn(ARC_Lexer *lexer){ + //null + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(TOKEN_NULL, 0)); + + //number + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(TOKEN_NUMBER, '0', '9')); + + //alphabetic characters + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(TOKEN_ALPHA_LOWER_CHAR, 'a', 'z')); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(TOKEN_ALPHA_UPPER_CHAR, 'A', 'Z')); + + //hyphen + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(TOKEN_HYPHEN, '-')); +} + +int main(){ + ARC_Lexer *lexer; + ARC_Lexer_Create(&lexer); + + //add the rules to the lexer + ARC_Example_InitLexerRulesFn(lexer); + + //create the example string to lex + ARC_String *exampleString; + ARC_String_CreateWithStrlen(&exampleString, "T-1000"); + + //this function handles cleanup for the string + ARC_Lexer_LexString(lexer, &exampleString); + + //loop through all the tokens printing the lexed contents + for(uint32_t index = 0; index < ARC_Lexer_GetTokenSize(lexer); index++){ + ARC_LexerToken *token = ARC_Lexer_GetToken(lexer, index); + + printf("%u) Token Rule: %u\n", index, token->rule); + } + + //cleanup + ARC_Lexer_Destroy(lexer); + + return 0; +} +``` diff --git a/doc/pages/standard/parser.md b/doc/pages/standard/parser.md index 9e52d44..3a79163 100644 --- a/doc/pages/standard/parser.md +++ b/doc/pages/standard/parser.md @@ -1 +1,87 @@ \page standard-parser ARC_Parser + +# Basic Overview + +The ::ARC_Parser type is a generic parsing type. To create the type it is recommeded you use ARC_Parser_CreateFromString( + +# Basic Example + +```c +const char *languageCString = + " -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE \n" + " -> | LAMBDA\n" + " -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE | NUMBER\n"; + +#define ARC_DOC_UNDERSCORE 1 +#define ARC_DOC_NUMBER 2 +#define ARC_DOC_ALPHA_UPPER_CHAR 3 +#define ARC_DOC_ALPHA_LOWER_CHAR 4 +#define ARC_DOC_VARIABLE 5 +#define ARC_DOC_VARIABLE_NAME 6 +#define ARC_DOC_VARIABLE_CHAR 7 + +void ARC_TEST_InitLexerRulesFn(ARC_Lexer *lexer){ + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_TEST_TAG_UNDERSCORE, '_' )); + + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_TEST_TAG_NUMBER , '0', '9')); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_TEST_TAG_ALPHA_LOWER_CHAR, 'a', 'z')); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_TEST_TAG_ALPHA_UPPER_CHAR, 'A', 'Z')); +} + +uint32_t ARC_TEST_GetStringIdFn(ARC_String *string){ + if(ARC_String_EqualsCStringWithStrlen(string, "LAMBDA")){ + return ARC_PARSER_TAG_LAMBDA; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "UNDERSCORE")){ + return ARC_TEST_TAG_UNDERSCORE; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "NUMBER")){ + return ARC_TEST_TAG_NUMBER; + } + if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_UPPER_CHAR")){ + return ARC_TEST_TAG_ALPHA_UPPER_CHAR; + } + if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_LOWER_CHAR")){ + return ARC_TEST_TAG_ALPHA_LOWER_CHAR; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_TEST_TAG_VARIABLE; + } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_TEST_TAG_VARIABLE_NAME; + } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_TEST_TAG_VARIABLE_CHAR; + } + + return ~(uint32_t)0; +} + +void ARC_TESTData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ +} + +void ARC_TESTData_DestroyFn(void *data, ARC_Bool clear, void *userData){ +} + +int main(){ + ARC_String *languageString; + ARC_String_CreateWithStrlen(&languageString, (char *)languageCString); + + ARC_Parser *parser; + ARC_ParserData_CreateFn createCharFn = ARC_TESTData_CreateFn; + ARC_ParserData_DestroyFn destroyCharFn = ARC_TESTData_DestroyFn; + ARC_Parser_CreateFromString(&parser, languageString, ARC_TEST_InitLexerRulesFn, ARC_TEST_GetStringIdFn, &createCharFn, &destroyCharFn, NULL); + ARC_String_Destroy(languageString); + + //this destroys string, so no need for cleanup + ARC_String *tempString; + ARC_String_CreateWithStrlen(&tempString, "variable123"); + ARC_Parser_Parse(parser, &tempString); + + // cleanup + ARC_Parser_Destroy(parser); +} +``` diff --git a/doc/pages/standard/vector.md b/doc/pages/standard/vector.md index 0e1a4f3..9949b1c 100644 --- a/doc/pages/standard/vector.md +++ b/doc/pages/standard/vector.md @@ -9,9 +9,7 @@ The API Reference for ::ARC_Vector can be found here: arc/std/vector.h # Basic Example: ```c -#include -#include -#include +#include //creating an array with no callbacks (the simplest example of the array) ARC_Vector *vector; @@ -51,9 +49,7 @@ A handy feature of this implmentation fo a vector is the ability to add a compar # Comparison Callback Example ```c -#include -#include -#include +#include //the comparison callback to check if two integer pointers hold the same value ARC_Bool ARC_Example_VectorCompareDataFn(void *dataA, void *dataB){ @@ -85,10 +81,10 @@ int main(){ //print the values within the vector for(uint32_t index = 0; index < ARC_Vector_GetSize(vector); index++){ //cast the return value back to what it initially was - valueRef = (int32_t *)ARC_Vector_Get(vector, index); + int32_t *valueRef = (int32_t *)ARC_Vector_Get(vector, index); //print out the index and value - printf("%d) %d\n", index, *value); + printf("%d) %d\n", index, *valueRef); } //remove the value @@ -97,10 +93,10 @@ int main(){ //print the values again to show that the value was removed for(uint32_t index = 0; index < ARC_Vector_GetSize(vector); index++){ //cast the return value back to what it initially was - valueRef = (int32_t *)ARC_Vector_Get(vector, index); + int32_t *valueRef = (int32_t *)ARC_Vector_Get(vector, index); //print out the index and value - printf("%d) %d\n", index, *value); + printf("%d) %d\n", index, *valueRef); } //cleanup @@ -115,10 +111,7 @@ As the vector takes a pointer, usually that pointer is allocated right before be # Destruction Callback Example ```c -#include -#include -#include -#include +#include //the destruction callback to free the allocated int32_t values void ARC_Example_VectorDestroyDataFn(void *data){ @@ -147,10 +140,10 @@ int main(){ //print the values within the vector for(uint32_t index = 0; index < ARC_Vector_GetSize(vector); index++){ //cast the return value back to what it initially was - valueRef = (int32_t *)ARC_Vector_Get(vector, index); + int32_t *valueRef = (int32_t *)ARC_Vector_Get(vector, index); //print out the index and value - printf("%d) %d\n", index, *value); + printf("%d) %d\n", index, *valueRef); } //example to demonstrate that there is no memory leak on removal due to the destroy callback @@ -159,10 +152,10 @@ int main(){ //print the values again to show that the value was removed for(uint32_t index = 0; index < ARC_Vector_GetSize(vector); index++){ //cast the return value back to what it initially was - valueRef = (int32_t *)ARC_Vector_Get(vector, index); + int32_t valueRef = (int32_t *)ARC_Vector_Get(vector, index); //print out the index and value - printf("%d) %d\n", index, *value); + printf("%d) %d\n", index, *valueRef); } //cleanup diff --git a/doc/style.md b/doc/style.md index c592e4e..fee12b3 100644 --- a/doc/style.md +++ b/doc/style.md @@ -1,3 +1,5 @@ +@page style-guide Style Guide + # Introduction This document outlines the style for any C code that is to be stored within this repository. This document will most likely be changed over time as the style becomes more set. @@ -10,7 +12,7 @@ This document outlines the style for any C code that is to be stored within this # Code Layout ## Indentation -Use 4 spaces for indentation, the only exception to this rule is for multi line comments +Use 4 spaces for indentation, the only exception to this rule is for doxygen multi line comments Closing braces over multiple lines should match up with the initial declaration like: ```c @@ -47,7 +49,7 @@ As of now there is no maximum line length ## Blank Lines As of now there should never be more than two blank lines next to each other -## Organizing lines +## Organizing Lines This is up to the programmer to decide what is most readable. The suggestion is to group lines together that relate to each other. Example: ```c void DOC_Type_ExampleFunction(){ @@ -61,7 +63,7 @@ void DOC_Type_ExampleFunction(){ } ``` -## Inline functions +## Inline Functions Do not use inline functions, always indent functions even if they are short. Example: ```c //do not do this @@ -119,6 +121,9 @@ uint32_t *a, b, c; The only time to pass a value as a pointer is if: - It cannot be copied - It is being modified + - It is to be stored in a void * + - It is being created or destroyed + - The type is not defined in a header # Header Layout ## Include Guards @@ -160,7 +165,7 @@ Before getting into naming conventions it is important to note that this style u ``` DOC_ ARC_ -TBYTE_ +EXAMPLE_ NAMESPACE_ ``` @@ -176,7 +181,7 @@ Defines and constants should be in all caps with a namespace and as descriptive ```c #define DOC_MEMORY_BLOCK_SIZE 6 -const uint8_t DOC_LOBY_MAX_ENTITIES 12; +const uint8_t DOC_LOBBY_MAX_ENTITIES 12; ``` ## Functions @@ -200,7 +205,7 @@ typedef DOC_Bool (* DOC_Type_PollDataFn)(void *userdata); ``` ## Variables -Variables are lower camel case and should be as self documenting as possible, do not use acronyms (type out the full thing). Also using one letter is usually not recommended (x, y, and in for loops i can sometimes be ok). Remember readability is crucial. +Variables are lower camel case and should be as self documenting as possible. Do not use acronyms, and try to avoid shortening words as much as possible. Also using one letter is usually not recommended (x, y, and i in for loops are times using single letters can be ok). Remember readability is crucial. # Herb's Suggestions I'd suggest avoiding ternary operators, else, and else if statements as much as possible. Usually returning instead of else statements makes the code more readable in my opinion. Also ternary operators almost always can be made more readable if put into an if statement. diff --git a/include/arc/audio/config.h b/include/arc/audio/config.h index 2eb9750..88644f6 100644 --- a/include/arc/audio/config.h +++ b/include/arc/audio/config.h @@ -6,17 +6,17 @@ extern "C" { #endif #include -#include "arc/std/string.h" +//#include "arc/std/string.h" -typedef struct ARC_Config ARC_Config; -void ARC_AudioConfig_Init(ARC_Config *config); +//typedef struct ARC_Config ARC_Config; +//void ARC_AudioConfig_Init(ARC_Config *config); -uint8_t ARC_Audio_Read(ARC_Config *config, ARC_String *string, void **value); +//uint8_t ARC_Audio_Read(ARC_Config *config, ARC_String *string, void **value); -void ARC_Audio_Delete(ARC_Config *config, ARC_String *string, void *value); +//void ARC_Audio_Delete(ARC_Config *config, ARC_String *string, void *value); #ifdef __cplusplus } #endif -#endif //ARC_AUDIO_CONFIG_H_ \ No newline at end of file +#endif //ARC_AUDIO_CONFIG_H_ diff --git a/include/arc/engine/engine.h b/include/arc/engine/engine.h index 64d1d29..7b0c2d4 100644 --- a/include/arc/engine/engine.h +++ b/include/arc/engine/engine.h @@ -12,15 +12,17 @@ extern "C" { #include "arc/input/keyboard.h" #include "arc/math/point.h" #include "arc/std/bool.h" +#include "arc/std/entity.h" #include "arc/std/handler.h" typedef struct ARC_EngineData { - ARC_Window *window; - ARC_Renderer *renderer; - ARC_Handler *state; - ARC_Input *input; - ARC_Mouse *mouse; - ARC_Keyboard *keyboard; + ARC_Window *window; + ARC_Renderer *renderer; + ARC_Handler *state; + ARC_Input *input; + ARC_Mouse *mouse; + ARC_Keyboard *keyboard; + ARC_EntitySystem *entitySystem; double dt; ARC_Bool running; @@ -34,7 +36,7 @@ typedef struct ARC_EngineData { * @param cleanFn the state cleanup function * @param windowSIze the size of window to create passed as an ARC_Point */ -void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanFn, ARC_Point windowSize); +void ARC_EngineData_Create(ARC_EngineData **data, ARC_Point windowSize); /** * @breif destroys an ARC_EngineData type diff --git a/include/arc/engine/state.h b/include/arc/engine/state.h index ae43005..0011933 100644 --- a/include/arc/engine/state.h +++ b/include/arc/engine/state.h @@ -5,20 +5,54 @@ extern "C" { #endif +/** + * @brief +*/ typedef void (* ARC_State_UpdateFn)(void *data); + +/** + * @brief +*/ typedef void (* ARC_State_RenderFn)(void *data); + +/** + * @brief +*/ +typedef void (* ARC_State_DestroyDataFn)(void *data); + +/** + * @brief +*/ typedef struct ARC_State { ARC_State_UpdateFn updateFn; ARC_State_RenderFn renderFn; + void *data; + ARC_State_DestroyDataFn *destroyDataFn; } ARC_State; +/** + * @brief +*/ +void ARC_State_Create(ARC_State **state, ARC_State_UpdateFn updateFn, ARC_State_RenderFn renderFn, void *data, ARC_State_DestroyDataFn *destroyDataFn); + +/** + * @brief +*/ +void ARC_State_Destroy(ARC_State *state); + +/** + * @brief +*/ void ARC_State_Update(void *data); +/** + * @brief +*/ void ARC_State_Render(void *data); #ifdef __cplusplus } #endif -#endif // ARC_ENGINE_STATE_H_ \ No newline at end of file +#endif // ARC_ENGINE_STATE_H_ diff --git a/include/arc/graphics/circle.h b/include/arc/graphics/circle.h index 11696f1..15d9af2 100644 --- a/include/arc/graphics/circle.h +++ b/include/arc/graphics/circle.h @@ -10,9 +10,9 @@ extern "C" { #include "arc/math/circle.h" #include -void ARC_Circle_Render(ARC_Circle *circle, ARC_Renderer *renderer, ARC_Color *color); +void ARC_Circle_Render(ARC_Circle circle, ARC_Renderer *renderer, ARC_Color color); -void ARC_Circle_RenderFill(ARC_Circle *circle, ARC_Renderer *renderer, ARC_Color *color); +void ARC_Circle_RenderFill(ARC_Circle circle, ARC_Renderer *renderer, ARC_Color color); #ifdef __cplusplus } diff --git a/include/arc/graphics/config.h b/include/arc/graphics/config.h index b173267..0177590 100644 --- a/include/arc/graphics/config.h +++ b/include/arc/graphics/config.h @@ -8,10 +8,33 @@ extern "C" { #include "arc/std/config.h" #include "arc/graphics/renderer.h" -void ARC_GraphicsConfig_Init(ARC_Config *config, ARC_Renderer *renderer); +/** + * @brief +*/ +void ARC_Config_InitGraphics(ARC_Config *config, ARC_Renderer *renderer); + +/** + * @brief +*/ +void ARC_ConfigType_SpritesheetCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief +*/ +void ARC_ConfigType_SpritesheetDestroyFn(ARC_Config *config, void *type); + +/** + * @brief +*/ +void ARC_ConfigType_SpriteCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief +*/ +void ARC_ConfigType_SpriteDestroyFn(ARC_Config *config, void *type); #ifdef __cplusplus } #endif -#endif // !ARC_GRAPHICS_CONFIG_H_ \ No newline at end of file +#endif // !ARC_GRAPHICS_CONFIG_H_ diff --git a/include/arc/graphics/line.h b/include/arc/graphics/line.h index 55207f6..9cfd620 100644 --- a/include/arc/graphics/line.h +++ b/include/arc/graphics/line.h @@ -7,10 +7,10 @@ extern "C" { #include "arc/graphics/color.h" #include "arc/graphics/renderer.h" -#include "arc/math/rectangle.h" +#include "arc/math/point.h" #include -void ARC_Line_Render(int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2, ARC_Renderer *renderer, ARC_Color *color); +void ARC_Line_Render(ARC_Point point1, ARC_Point point2, ARC_Renderer *renderer, ARC_Color color); #ifdef __cplusplus } diff --git a/include/arc/graphics/rectangle.h b/include/arc/graphics/rectangle.h index d1bc881..f334bba 100644 --- a/include/arc/graphics/rectangle.h +++ b/include/arc/graphics/rectangle.h @@ -10,13 +10,13 @@ extern "C" { #include "arc/math/rectangle.h" #include -void ARC_Rect_Render(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color); +void ARC_Rect_Render(ARC_Rect rect, ARC_Renderer *renderer, ARC_Color color); -void ARC_Rect_RenderFill(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color); +void ARC_Rect_RenderFill(ARC_Rect rect, ARC_Renderer *renderer, ARC_Color color); -void ARC_FRect_Render(ARC_FRect *rect, ARC_Renderer *renderer, ARC_Color *color); +void ARC_FRect_Render(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color); -void ARC_FRect_RenderFill(ARC_FRect *rect, ARC_Renderer *renderer, ARC_Color *color); +void ARC_FRect_RenderFill(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color); #ifdef __cplusplus } diff --git a/include/arc/graphics/renderer.h b/include/arc/graphics/renderer.h index e5f7ab4..0d7e925 100644 --- a/include/arc/graphics/renderer.h +++ b/include/arc/graphics/renderer.h @@ -5,22 +5,21 @@ extern "C" { #endif +#include + /** * @brief predefien ARC_EngineData so as not to get circular reference */ typedef struct ARC_EngineData ARC_EngineData; /** - * @note ARC_RendererType is determined by which window library you are using + * @note ARC_RendererType is determined by which window backend you are using */ typedef struct ARC_RendererType ARC_Renderer; /** * @brief creates ARC_Renderer type with ARC_EngineData * - * @note the parameter data is determined by which graphics library you are using - * please refer to the graphics library section to see what needs to be passed - * * @param renderer ARC_Renderer to initialize * @param data the engine data to create from */ @@ -43,12 +42,63 @@ void ARC_Renderer_Clear(ARC_Renderer *renderer); /** * @brief renders the renderer * - * @note the renderer will most likely be drawn to from ARC_EngineData - * - * @param renderer the renderer to render + * @param renderer renders all buffers and current renderer to window */ void ARC_Renderer_Render(ARC_Renderer *renderer); +/** + * @brief + * + * @param renderer + * @param zIndex +*/ +void ARC_Renderer_InitBuffer(ARC_Renderer *renderer, uint32_t zIndex); + +/** + * @brief + * + * @param renderer + * @param zIndex +*/ +void ARC_Renderer_RemoveBuffer(ARC_Renderer *renderer, uint32_t zIndex); + +/** + * @brief + * + * @param renderer + * @param zIndex +*/ +void ARC_Renderer_RenderBuffer(ARC_Renderer *renderer, uint32_t zIndex); + +/** + * @brief + * + * @param renderer +*/ +void ARC_Renderer_RenderBuffers(ARC_Renderer *renderer); + +/** + * @brief + * + * @param renderer +*/ +void ARC_Renderer_ClearBuffers(ARC_Renderer *renderer); + +/** + * @brief + * + * @param renderer + * @param zIndex +*/ +void ARC_Renderer_SetCurrentBuffer(ARC_Renderer *renderer, uint32_t zIndex); + +/** + * @brief + * + * @param renderer +*/ +void ARC_Renderer_UnsetBuffer(ARC_Renderer *renderer); + #ifdef __cplusplus } #endif diff --git a/include/arc/graphics/sprite.h b/include/arc/graphics/sprite.h index fe71bf9..3f9f9e3 100644 --- a/include/arc/graphics/sprite.h +++ b/include/arc/graphics/sprite.h @@ -11,27 +11,49 @@ extern "C" { #include "arc/math/rectangle.h" #include "arc/std/array.h" +/** + * @brief +*/ +typedef enum ARC_SpriteAxis { + ARC_SPRITE_AXIS_NONE = 0x00, + ARC_SPRITE_AXIS_Y = 0x01, + ARC_SPRITE_AXIS_X = 0x02, +} ARC_SpriteAxix; + /** * @brief a sprite type - * - * @note the actual type should be define by overriding for a graphics api - */ -typedef struct ARC_Sprite ARC_Sprite; +*/ +typedef struct ARC_Sprite { + ARC_Spritesheet *spritesheet; + ARC_Array frames; + uint32_t frameIndex; + + double angle; + + ARC_FPoint origin; + + float opacity; + + ARC_SpriteAxix axis; + + float animationCurrentTime; + float animationTime; +} ARC_Sprite; /** * @brief creates ARC_Sprite type * * @param sprite ARC_Sprite that is being created * @param spritesheet ARC_Spritesheet that ARC_Sprite will be pulled from - * @param frames ARC_Array of bounds of sprite on spritesheet - */ -void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array *frames); + * @param frames ARC_Array of ARC_FRect bounds of sprite on spritesheet +*/ +void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array frames); /** * @brief destroys ARC_Sprite type * * @param sprite ARC_Sprite to destroy - */ +*/ void ARC_Sprite_Destroy(ARC_Sprite *sprite); /** @@ -39,20 +61,8 @@ void ARC_Sprite_Destroy(ARC_Sprite *sprite); * * @param newSprite ARC_Sprite that is being copied to and created * @param oldSprite ARC_Sprite contents that are being copied - */ -void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite); - -//TODO: temp -/** - * @brief sets ARC_Sprite's opacity - * - * @param sprite ARC_Sprite that is changing opacity - * @param opacity new opacity for ARC_Sprite - * - * @note this is temp because opacity probably should be a value - * bigger than 255 */ -void ARC_Sprite_SetOpacity(ARC_Sprite *sprite, uint8_t opacity); +void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite); /** * @brief renders ARC_Sprite type @@ -60,51 +70,75 @@ void ARC_Sprite_SetOpacity(ARC_Sprite *sprite, uint8_t opacity); * @param sprite ARC_Sprite that will be rendered * @param renderer ARC_Renderer that is handling rendering * @param renderBounds area of renderer that ARC_Sprite will be rendered to - */ -void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds); - -//TODO: move this to a better location -typedef enum ARC_Sprite_Axis { - ARC_SPRITE_AXIS_NONE = 0x00, - ARC_SPRITE_AXIS_Y = 0x01, - ARC_SPRITE_AXIS_X = 0x02, -} ARC_Sprite_Axix; +*/ +void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FRect renderBounds); /** - * @brief renders ARC_Sprite type with flip + * @brief renders ARC_Sprite type at a point and at a set scale * - * @param sprite ARC_Sprite that will be rendered - * @param renderer ARC_Renderer that is handling rendering - * @param renderBounds area of renderer that ARC_Sprite will be rendered to - * @param axis axis to flip sprite - */ -void ARC_Sprite_RenderFlip(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, enum ARC_Sprite_Axis axis); + * @param sprite ARC_Sprite that will be rendered + * @param renderer ARC_Renderer that is handling rendering + * @param point point on the renderer that ARC_Sprite will be rendered to (will be scaled as well) + * @param scale the scale to render at +*/ +void ARC_Sprite_RenderAt(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FPoint point, double scale); /** - * @brief renders ARC_Sprite type with rotation + * @brief switches ARC_Sprite's frames to next for animation * - * @param sprite ARC_Sprite that will be rendered - * @param renderer ARC_Renderer that is handling rendering - * @param renderBounds area of renderer that ARC_Sprite will be rendered to - * @param angle angle to rotate ARC_Sprite - * @param center point to rotate ARC_Sprite around - */ -void ARC_Sprite_RenderRotated(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, ARC_Point *center, double angle); + * @param sprite ARC_Sprite that is having its frame updated +*/ +void ARC_Sprite_IterateFrame(ARC_Sprite *sprite); + +/** + * @brief switches ARC_Sprite's frames to next for animation + * + * @param sprite ARC_Sprite that is being animated (having its frame updated based on delta time) + * @param deltatime the ammount of time elapsed in seconds (stored as a float where 1.0 is a second) since last animated +*/ +void ARC_Sprite_AnimateFrame(ARC_Sprite *sprite, float deltatime); /** * @brief switches ARC_Sprite's frame to specified index * * @param sprite ARC_Sprite that is having its frame set * @param index uint32_t to set ARC_Sprite's frame index to - */ +*/ void ARC_Sprite_SetFrameIndex(ARC_Sprite *sprite, uint32_t index); /** - * @brief switches ARC_Sprite's frames to next for animation + * @brief sets the origin point of the sprite (the rotation and position point) * - * @param sprite ARC_Sprite that is having its frame updated - */ -void ARC_Sprite_IterateFrame(ARC_Sprite *sprite); + * @param sprite ARC_Sprite that is having its angle set + * @param angle the given agnel in degrees to rotate around (rotated clockwise) +*/ +void ARC_Sprite_SetAngle(ARC_Sprite *sprite, double angle); + +/** + * @brief sets the origin point of the sprite (the rotation and position point) + * + * @param sprite ARC_Sprite that is having its origin set + * @param origin the point on the arc sprite (based on its bounds/frame) to rotate around +*/ +void ARC_Sprite_SetOrigin(ARC_Sprite *sprite, ARC_FPoint origin); + +/** + * @brief sets ARC_Sprite's opacity + * + * @note opacity is a float value between 0.0 and 1.0 (1.0 is fully opaque) + * + * @param sprite ARC_Sprite that is changing opacity + * @param opacity new opacity for ARC_Sprite +*/ +void ARC_Sprite_SetOpacity(ARC_Sprite *sprite, float opacity); + +/** + * @brief sets ARC_Sprite's framerate for + * + * @param sprite ARC_Sprite to change its frame rate + * @param rate the new framerate as a float in seconds (1.0 is one second) +*/ +void ARC_Sprite_SetFrameRate(ARC_Sprite *sprite, float rate); /** * @brief gets ARC_Sprite's current frame @@ -112,22 +146,22 @@ void ARC_Sprite_IterateFrame(ARC_Sprite *sprite); * @param sprite ARC_Sprite to get frame from * * @return index ARC_Sprite's current frame index - */ +*/ uint32_t ARC_Sprite_GetFrameIndex(ARC_Sprite *sprite); /** * @brief returns the current bounds based on the ARC_Sprite's frames * * @param sprite ARC_Sprite to get bounds from - */ -ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite); +*/ +ARC_FRect *ARC_Sprite_GetBounds(ARC_Sprite *sprite); /** * @brief returns the array of bounds that a sprite has * * @param sprite ARC_Sprite to get all the bounds from */ -ARC_Array *ARC_Sprite_GetAllBounds(ARC_Sprite *sprite); +ARC_Array ARC_Sprite_GetAllBounds(ARC_Sprite *sprite); #ifdef __cplusplus } diff --git a/include/arc/graphics/spritesheet.h b/include/arc/graphics/spritesheet.h index 1d03ce5..30be531 100644 --- a/include/arc/graphics/spritesheet.h +++ b/include/arc/graphics/spritesheet.h @@ -11,16 +11,73 @@ extern "C" { #include "arc/graphics/renderer.h" #include "arc/std/string.h" +/** + * @brief the spritesheet type, it will be defined within the backend (most likely in the backend's spritesheet header) +*/ typedef struct ARC_Spritesheet ARC_Spritesheet; +/** + * @brief creates a spritesheet from a given filepath and renderer + * + * @note this function only reads in pngs currently, will be updated later to support more file extensions + * + * @param[out] spritesheet ARC_Spritesheet to create + * @param[in] renderer the renderer used to create the spritesheet + * @param[in] path the path of the spritesheet to read in +*/ void ARC_Spritesheet_CreateFromFile(ARC_Spritesheet **spritesheet, ARC_Renderer *renderer, ARC_String *path); +/** + * @brief destroys a given spritehseet + * + * @param[in] spritesheet ARC_Spritesheet to free +*/ void ARC_Spritesheet_Destroy(ARC_Spritesheet *spritesheet); -void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect *sheetBounds, ARC_Renderer *renderer, ARC_Rect *renderBounds); +/** + * @brief renders the texture of a spritesheet + * + * @param[in] spritesheet ARC_Spritesheet to render + * @param[in] renderer the renderer to draw to + * @param[in] renderBounds the area of the renderer to copy the spritesheet to +*/ +void ARC_Spritesheet_Render(ARC_Spritesheet *spritesheet, ARC_Renderer *renderer, ARC_FRect renderBounds); +/** + * @brief renders a section of a spritesheet + * + * @param[in] spritesheet ARC_Spritesheet to render part of + * @param[in] sheetBounds the area of the spritesheet to render + * @param[in] renderer the renderer to draw to + * @param[in] renderBounds the area of the renderer to copy the spritesheet area to +*/ +void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect sheetBounds, ARC_Renderer *renderer, ARC_FRect renderBounds); + +/** + * @brief renders a tile of a spritesheet + * + * @note if the tile size is zero this function will error + * + * @param[in] spritesheet ARC_Spritesheet to render tile from + * @param[in] tilePosition the coordinate of a tile to render (will be multiplied by tile size) + * @param[in] renderer the renderer to draw to + * @param[in] renderBounds the area of the renderer to copy the tile to +*/ +void ARC_Spritesheet_RenderTile(ARC_Spritesheet *spritesheet, ARC_Point tilePosition, ARC_Renderer *renderer, ARC_FRect renderBounds); + +/** + * @brief gets the x and y size of a given spritesheet in pixels + * + * @param[in] spritesheet ARC_Spritesheet to get the size of +*/ ARC_Point ARC_Spritesheet_GetSize(ARC_Spritesheet *spritesheet); -uint32_t *ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet); + +/** + * @brief gets the length of a tile (square) in pixels of a spritesheet + * + * @param[in] spritesheet gets the tilesize of a spritesheet +*/ +uint32_t ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet); #ifdef __cplusplus } diff --git a/include/arc/graphics/text.h b/include/arc/graphics/text.h index 3838fd7..9f6bcd2 100644 --- a/include/arc/graphics/text.h +++ b/include/arc/graphics/text.h @@ -9,22 +9,47 @@ extern "C" { #include "arc/graphics/color.h" #include "arc/graphics/renderer.h" #include "arc/math/point.h" +#include "arc/math/rectangle.h" #include "arc/std/string.h" -typedef struct ARC_Text ARC_Text; +typedef struct ARC_Text { + ARC_String *name; + int32_t fontSize; + ARC_FRect bounds; + + ARC_Color color; + + void *backendData; +} ARC_Text; + +/** + * @brief +*/ void ARC_Text_Create(ARC_Text **text, ARC_String *path, int32_t size, ARC_Color color); -void ARC_Text_Destroy(ARC_Text *font); +/** + * @brief +*/ +void ARC_Text_Destroy(ARC_Text *text); +/** + * @brief +*/ void ARC_Text_SetString(ARC_Text *text, ARC_Renderer *renderer, ARC_String *string); +/** + * @brief +*/ void ARC_Text_Render(ARC_Text *text, ARC_Renderer *renderer); +/** + * @brief +*/ void ARC_Text_SetPos(ARC_Text *text, ARC_Point pos); #ifdef __cplusplus } #endif -#endif //ARC_STD_STRING_H_ \ No newline at end of file +#endif //ARC_STD_STRING_H_ diff --git a/include/arc/input/mouse.h b/include/arc/input/mouse.h index 5f60780..bb7fe9c 100644 --- a/include/arc/input/mouse.h +++ b/include/arc/input/mouse.h @@ -35,7 +35,7 @@ void ARC_Mouse_CreateWithInput(ARC_Mouse **mouse, ARC_Input *input); void ARC_Mouse_Destroy(ARC_Mouse *mouse); void ARC_Mouse_Update(ARC_Mouse *mouse); -ARC_Point *ARC_Mouse_GetCoords(ARC_Mouse *mouse); +ARC_FPoint *ARC_Mouse_GetCoords(ARC_Mouse *mouse); ARC_MouseState ARC_Mouse_GetState(ARC_Mouse *mouse, ARC_MouseButton button); int32_t *ARC_Mouse_GetScrollY(ARC_Mouse *mouse); diff --git a/include/arc/math/circle.h b/include/arc/math/circle.h index 60d9acb..b93f406 100644 --- a/include/arc/math/circle.h +++ b/include/arc/math/circle.h @@ -25,6 +25,8 @@ typedef struct ARC_DCircle { double r; } ARC_DCircle; +void TEMP_Circle_Placeholder(void); + #ifdef __cplusplus } #endif diff --git a/include/arc/math/config.h b/include/arc/math/config.h index 85027a0..483a863 100644 --- a/include/arc/math/config.h +++ b/include/arc/math/config.h @@ -6,21 +6,57 @@ extern "C" { #endif #include -#include "arc/std/string.h" -typedef struct ARC_Config ARC_Config; -//void ARC_MathConfig_Init(ARC_Config *config); -// -//uint8_t ARC_Point_Read (ARC_Config *config, ARC_String *string, void **value); -//uint8_t ARC_Rect_Read (ARC_Config *config, ARC_String *string, void **value); -//uint8_t ARC_RectArray_Read(ARC_Config *config, ARC_String *string, void **value); -// -//void ARC_Point_Delete (ARC_Config *config, ARC_String *string, void *value); -//void ARC_Rect_Delete (ARC_Config *config, ARC_String *string, void *value); -//void ARC_RectArray_Delete(ARC_Config *config, ARC_String *string, void *value); +#include "arc/std/config.h" + +/** + * @brief +*/ +void ARC_Config_InitMath(ARC_Config *config); + +/** + * @brief +*/ +void ARC_ConfigType_PointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief +*/ +void ARC_ConfigType_PointDestroyFn(ARC_Config *config, void *type); + +/** + * @brief +*/ +void ARC_ConfigType_FPointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief +*/ +void ARC_ConfigType_FPointDestroyFn(ARC_Config *config, void *type); + +/** + * @brief +*/ +void ARC_ConfigType_RectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief +*/ +void ARC_ConfigType_RectDestroyFn(ARC_Config *config, void *type); + +/** + * @brief +*/ +void ARC_ConfigType_FRectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief +*/ +void ARC_ConfigType_FRectDestroyFn(ARC_Config *config, void *type); + #ifdef __cplusplus } #endif -#endif //ARC_MATH_CONFIG_H_ \ No newline at end of file +#endif //ARC_MATH_CONFIG_H_ diff --git a/include/arc/math/point.h b/include/arc/math/point.h index 2af564b..8194524 100644 --- a/include/arc/math/point.h +++ b/include/arc/math/point.h @@ -27,8 +27,27 @@ typedef struct ARC_DPoint { double y; } ARC_DPoint; +typedef struct ARC_Rect ARC_Rect; +typedef struct ARC_FRect ARC_FRect; + ARC_FPoint ARC_FPoint_Lerp(ARC_FPoint *start, ARC_FPoint *end, float t); +/** + * @brief centers point on given bounds + * + * @param point ARC_Point to be centered + * @param bounds ARC_Rect area to center point on + */ +void ARC_Point_CenterOn(ARC_Point *point, ARC_Rect bounds); + +/** + * @brief centers fpoint on given bounds + * + * @param point ARC_FPoint to be centered + * @param bounds ARC_FRect area to center point on + */ +void ARC_FPoint_CenterOn(ARC_FPoint *point, ARC_FRect bounds); + #ifdef __cplusplus } #endif diff --git a/include/arc/math/rectangle.h b/include/arc/math/rectangle.h index 7427579..05b4210 100644 --- a/include/arc/math/rectangle.h +++ b/include/arc/math/rectangle.h @@ -4,6 +4,7 @@ #include #include "point.h" #include "vector2.h" +#include "arc/std/bool.h" #ifdef __cplusplus extern "C" { @@ -36,7 +37,7 @@ typedef struct ARC_FRect { * @param rect ARC_Rect to be centered * @param bounds ARC_Rect area to center rect on */ -void ARC_Rect_CenterOn(ARC_Rect *rect, ARC_Rect *bounds); +void ARC_Rect_CenterOn(ARC_Rect *rect, ARC_Rect bounds); /** * @brief centers rect on given bounds @@ -44,7 +45,23 @@ void ARC_Rect_CenterOn(ARC_Rect *rect, ARC_Rect *bounds); * @param rect ARC_FRect to be centered * @param bounds ARC_FRect area to center rect on */ -void ARC_FRect_CenterOn(ARC_FRect *rect, ARC_FRect *bounds); +void ARC_FRect_CenterOn(ARC_FRect *rect, ARC_FRect bounds); + +/** + * @brief centers rect on a given point + * + * @param rect ARC_Rect to be centered + * @param bounds ARC_Point point to center rect on + */ +void ARC_Rect_CenterOnPoint(ARC_Rect *rect, ARC_Point center); + +/** + * @brief centers rect on a given point + * + * @param rect ARC_FRect to be centered + * @param bounds ARC_FPoint point to center rect on + */ +void ARC_FRect_CenterOnPoint(ARC_FRect *rect, ARC_FPoint center); /** * @brief casts Rect to FRect @@ -53,7 +70,7 @@ void ARC_FRect_CenterOn(ARC_FRect *rect, ARC_FRect *bounds); * * @return ARC_FRect */ -ARC_FRect ARC_Rect_CastToFRect(ARC_Rect *rect); +ARC_FRect ARC_Rect_CastToFRect(ARC_Rect rect); /** * @brief casts FRect to Rect @@ -62,7 +79,7 @@ ARC_FRect ARC_Rect_CastToFRect(ARC_Rect *rect); * * @return ARC_Rect */ -ARC_Rect ARC_FRect_CastToRect(ARC_FRect *rect); +ARC_Rect ARC_FRect_CastToRect(ARC_FRect rect); /** * @brief checks if two ARC_Rects intersect @@ -70,9 +87,9 @@ ARC_Rect ARC_FRect_CastToRect(ARC_FRect *rect); * @param rect1 ARC_Rect that will be checked against rect2 * @param rect2 ARC_Rect that will be checked against rect1 * - * @return 1 if they intersect, 0 if they don't intersect + * @return ARC_True if they intersect, ARC_False if they don't intersect */ -int32_t ARC_Rect_Intersects(ARC_Rect *rect1, ARC_Rect *rect2); +ARC_Bool ARC_Rect_Intersects(ARC_Rect rect1, ARC_Rect rect2); /** * @brief checks if two ARC_FRects intersect @@ -80,9 +97,9 @@ int32_t ARC_Rect_Intersects(ARC_Rect *rect1, ARC_Rect *rect2); * @param rect1 ARC_FRect that will be checked against rect2 * @param rect2 ARC_FRect that will be checked against rect1 * - * @return 1 if they intersect, 0 if they don't intersect + * @return ARC_True if they intersect, ARC_False if they don't intersect */ -int32_t ARC_FRect_Intersects(ARC_FRect *rect1, ARC_FRect *rect2); +ARC_Bool ARC_FRect_Intersects(ARC_FRect rect1, ARC_FRect rect2); /** * @brief checks if ARC_Rect intersects with point @@ -90,9 +107,9 @@ int32_t ARC_FRect_Intersects(ARC_FRect *rect1, ARC_FRect *rect2); * @param rect ARC_Rect that will be checked against point * @param point ARC_Point that will be checked against rect * - * @return 1 if they intersect, 0 if they don't intersect + * @return ARC_True if they intersect, ARC_False if they don't intersect */ -int32_t ARC_Rect_IntersectsPoint(ARC_Rect *rect, ARC_Point *point); +ARC_Bool ARC_Rect_IntersectsPoint(ARC_Rect rect, ARC_Point point); /** * @brief checks if ARC_FRect intersects with point @@ -100,9 +117,9 @@ int32_t ARC_Rect_IntersectsPoint(ARC_Rect *rect, ARC_Point *point); * @param rect ARC_FRect that will be checked against point * @param point ARC_Point that will be checked against rect * - * @return 1 if they intersect, 0 if they don't intersect + * @return ARC_True if they intersect, ARC_False if they don't intersect */ -int32_t ARC_FRect_IntersectsPoint(ARC_FRect *rect, ARC_Point *point); +ARC_Bool ARC_FRect_IntersectsPoint(ARC_FRect rect, ARC_Point point); /** * @brief checks if ARC_Rect intersects a line diff --git a/include/arc/math/vector2.h b/include/arc/math/vector2.h index ba98114..3207cda 100644 --- a/include/arc/math/vector2.h +++ b/include/arc/math/vector2.h @@ -28,6 +28,30 @@ void ARC_Vector2_Normalize(ARC_Vector2 *vector); */ void ARC_Vector2_RotateDegree(ARC_Vector2 *vector, float angle); +/** + * @brief + * + * @param vector1 + * @param vector2 +*/ +float ARC_Vector2_CrossProduct(ARC_Vector2 vector1, ARC_Vector2 vector2); + +/** + * @brief + * + * @param vector + * @param scalar +*/ +ARC_Vector2 ARC_Vector2_CrossProductScalar(ARC_Vector2 vector, float scalar); + +/** + * @brief + * + * @param scalar + * @param vector +*/ +ARC_Vector2 ARC_Vector2_ScalarCrossProduct(float scalar, ARC_Vector2 vector); + #ifdef __cplusplus } #endif diff --git a/include/arc/std/array.h b/include/arc/std/array.h index aee55e0..2c7973a 100644 --- a/include/arc/std/array.h +++ b/include/arc/std/array.h @@ -19,4 +19,4 @@ typedef struct ARC_Array { } #endif -#endif //ARC_STD_ARRAY_H_ \ No newline at end of file +#endif // !ARC_STD_ARRAY_H_ diff --git a/include/arc/std/bool.h b/include/arc/std/bool.h index bd59824..1f52752 100644 --- a/include/arc/std/bool.h +++ b/include/arc/std/bool.h @@ -20,4 +20,4 @@ extern "C" { } #endif -#endif //ARC_STD_BOOL_H_ +#endif // !ARC_STD_BOOL_H_ diff --git a/include/arc/std/config.h b/include/arc/std/config.h index 956e93a..dae3309 100644 --- a/include/arc/std/config.h +++ b/include/arc/std/config.h @@ -5,40 +5,53 @@ extern "C" { #endif -#include #include "arc/std/parser.h" +#include /** - * @brief the config type for archeus, loads in a config file which syntax is specified in the documentation - * @TODO: add documentation link here + * @brief the config type for archeus, loads in a .chemical file which syntax is specified in the documentation */ typedef struct ARC_Config ARC_Config; /** * @brief a function callback to create a type stored within a config + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register */ -typedef void (* ARC_ConfigType_CopyFn)(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config); +typedef void (* ARC_ConfigType_CopyFn)(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); /** * @brief a function callback to destroy a type + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed */ -typedef void (* ARC_ConfigType_DestroyFn)(void *type); +typedef void (* ARC_ConfigType_DestroyFn)(ARC_Config *config, void *type); /** * @brief the functions for used for loading and unloading a type, the name will be the key of a hashtable */ typedef struct ARC_ConfigType { + uint32_t size; ARC_ConfigType_CopyFn copyFn; ARC_ConfigType_DestroyFn destroyFn; + void *userdata; } ARC_ConfigType; /** * @brief creates the arc config type (a type that loads in config files and can have types added to it) + * + * @param[out] ARC_Config to create */ void ARC_Config_Create(ARC_Config **config); /** * @brief destroys an ARC_Config type + * + * @param[in] config ARC_Config to destroy */ void ARC_Config_Destroy(ARC_Config *config); @@ -62,6 +75,60 @@ void ARC_Config_RegisterType(ARC_Config *config, ARC_String *typeName, ARC_Confi */ void ARC_Config_RegisterTypeWithCStr(ARC_Config *config, const char *typeNameCStr, ARC_ConfigType type); +/** + * @brief add a value with a given keyname + * + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group + * @note not specifying the group will use the current group + * @note this function uses ARC_Config_AddWithCStr so it shares error messages with that function + * @note value will be freed on cleanup or remove + * + * @param[in] config ARC_Config to add value to + * @param[in] type the type of a variable to add to specified group + * @param[in] name name of a variable to add to specified group + * @param[in] value the value of the variable to add, will be freed +*/ +void ARC_Config_Add(ARC_Config *config, ARC_String *type, ARC_String *name, void *value); + +/** + * @brief add a value with a given keyname + * + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group + * @note not specifying the group will use the current group + * @note value will be freed on cleanup or remove + * + * @param[in] config ARC_Config to add value to + * @param[in] type the type of a variable to add to specified group + * @param[in] name name of a variable to add to specified group + * @param[in] value the value of the variable to add, will be freed +*/ +void ARC_Config_AddWithCStr(ARC_Config *config, const char *type, const char *name, void *value); + +/** + * @brief remove a value with a given keyname + * + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group + * @note not specifying the group will use the current group + * @note this function uses ARC_Config_RemoveWithCStr so it shares error messages with that function + * + * @param[in] config ARC_Config to remove value from + * @param[in] name name of a variable to remove to specified group + * @param[in] isArray a boolean to specify if the variable is an array +*/ +void ARC_Config_Remove(ARC_Config *config, ARC_String *name, ARC_Bool isArray); + +/** + * @brief remove a value with a given keyname + * + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group + * @note not specifying the group will use the current group + * + * @param[in] config ARC_Config to remove value from + * @param[in] name name of a variable to remove to specified group + * @param[in] isArray a boolean to specify if the variable is an array +*/ +void ARC_Config_RemoveWithCStr(ARC_Config *config, const char *name, ARC_Bool isArray); + /** * @brief sets current group in config * @@ -70,7 +137,7 @@ void ARC_Config_RegisterTypeWithCStr(ARC_Config *config, const char *typeNameCSt * * @param[in] config ARC_Config we are setting current group in * @param[in] groupname name of group that will be set - */ +*/ void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupName); /** @@ -80,59 +147,117 @@ void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupName); * * @param[in] config ARC_Config we are setting current group in * @param[in] groupname name of group that will be set - */ +*/ void ARC_Config_SetGroupWithCStr(ARC_Config *config, const char *groupName); /** * @brief get a value from a given name * - * @note name should be prefaced with :: to specify group + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group * * @param[in] config ARC_Config to get value from * @param[in] name name of a variable that has been read in * * @return the stored element on success, or NULL on failure - */ +*/ void *ARC_Config_Get(ARC_Config *config, ARC_String *name); /** * @brief get a value from a given keyname * - * @note name should be prefaced with :: to specify group + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group * @note this function uses ARC_Config_Get so it shares error messages with that function * * @param[in] config ARC_Config to get value from * @param[in] name name of a variable that has been read in * * @return the stored element on success, or NULL on failure - */ +*/ void *ARC_Config_GetWithCStr(ARC_Config *config, const char *name); /** - * @brief TODO: write this + * @brief takes a given string and loads it into the config + * + * @breif config the config to load the string to + * @breif string the string to load into the config */ void ARC_Config_LoadFromString(ARC_Config *config, ARC_String **string); /** - * @brief TODO: write this + * @brief takes a given file path and loads it into the config + * + * @note this path will be based on wherever the executable is run from + * + * @breif config the config to load the file to + * @breif path the location of the .chemical file to load */ void ARC_Config_LoadFromFile(ARC_Config *config, ARC_String *path); /** - * @brief TODO: write this + * @brief takes a given file path and loads it into the config + * + * @note this path will be based on wherever the executable is run from + * + * @breif config the config to load the file to + * @breif path the location of the .chemical file to load +*/ +void ARC_Config_LoadFromFileWithCStr(ARC_Config *config, const char *path); + +/** + * @brief takes a given file path and unloads it into the config + * + * @note this path will be based on wherever the executable is run from + * + * @breif config the config to unload the file from + * @breif path the location of the .chemical file to unload */ void ARC_Config_UnloadFromString(ARC_Config *config, ARC_String **string); /** - * @brief TODO: write this + * @brief takes a given file path and unloads it into the config + * + * @note this path will be based on wherever the executable is run from + * + * @breif config the config to unload the file from + * @breif path the location of the .chemical file to unload */ -void ARC_Config_UnloadFromFile(ARC_Config *config, ARC_String *data); +void ARC_Config_UnloadFromFile(ARC_Config *config, ARC_String *path); +/** + * @brief takes a given file path and unloads it into the config + * + * @note this path will be based on wherever the executable is run from + * + * @breif config the config to unload the file from + * @breif path the location of the .chemical file to unload +*/ +void ARC_Config_UnloadFromFileWithCStr(ARC_Config *config, const char *path); + +/** + * @{ + * @brief defaults used by arc config can be defined before building to change them +*/ +#ifndef ARC_CONFIG_DEFAULT_GROUP #define ARC_CONFIG_DEFAULT_GROUP " " -#define ARC_CONFIG_GROUP_TAG_NAME "group" -#define ARC_CONFIG_GROUP_SEPARATOR "::" +#endif -//the grouping is based on the ascii table, but the ids are sequential to make finding tokens quicker (look at the lexer continious for more explanation) +#ifndef ARC_CONFIG_GROUP_TAG_NAME +#define ARC_CONFIG_GROUP_TAG_NAME "group" +#endif + +#ifndef ARC_CONFIG_GROUP_SEPARATOR +#define ARC_CONFIG_GROUP_SEPARATOR "::" +#endif +/** + * @} +*/ + +/** + * @{ + * @brief tokens used in the config langauge, defined here for use in ARC_ConfigType_CopyFn and ARC_ConfigType_DestroyFn + * + * @note the grouping is based on the ascii table, but the ids are sequential to make finding tokens quicker (look at the lexer continious for more explanation) +*/ #define ARC_CONFIG_TAB 0x01 #define ARC_CONFIG_NEWLINE 0x02 @@ -176,30 +301,312 @@ void ARC_Config_UnloadFromFile(ARC_Config *config, ARC_String *data); #define ARC_CONFIG_CLOSE_CURLY_BRACE 0x25 #define ARC_CONFIG_TILDE 0x26 -#define ARC_CONFIG_LANGUAGE 0x27 -#define ARC_CONFIG_GROUP 0x28 -#define ARC_CONFIG_GROUP_NAME 0x29 -#define ARC_CONFIG_GROUP_ARGS 0x2A -#define ARC_CONFIG_VARIABLE_LINES 0x2B -#define ARC_CONFIG_VARIABLE_LINE 0x2C -#define ARC_CONFIG_ALLOW_SPACE 0x2D -#define ARC_CONFIG_TYPE 0x2E -#define ARC_CONFIG_VALUE 0x2F -#define ARC_CONFIG_NESTED_VALUE 0x30 -#define ARC_CONFIG_VALUE_ARGS 0x31 -#define ARC_CONFIG_VARIABLE 0x32 -#define ARC_CONFIG_VARIABLE_NAME 0x33 -#define ARC_CONFIG_VARIABLE_CHAR 0x34 -#define ARC_CONFIG_STRING 0x35 -#define ARC_CONFIG_STRING_CHARS 0x36 -#define ARC_CONFIG_STRING_CHAR 0x37 -#define ARC_CONFIG_ESCAPE_CHAR 0x38 -#define ARC_CONFIG_NUMBER_SIGN 0x39 -#define ARC_CONFIG_NUMBER_TAG 0x3A -#define ARC_CONFIG_WHITESPACE 0x3B +#define ARC_CONFIG_LANGUAGE 0x27 +#define ARC_CONFIG_GROUP 0x28 +#define ARC_CONFIG_GROUP_NAME 0x29 +#define ARC_CONFIG_GROUP_ARGS 0x2A +#define ARC_CONFIG_VARIABLE_LINES 0x2B +#define ARC_CONFIG_VARIABLE_LINE 0x2C +#define ARC_CONFIG_ALLOW_SPACE 0x2D +#define ARC_CONFIG_TYPE 0x2E +#define ARC_CONFIG_VALUE 0x2F +#define ARC_CONFIG_NESTED_VALUE 0x30 +#define ARC_CONFIG_VALUE_ARGS 0x31 +#define ARC_CONFIG_ARRAY 0x32 +#define ARC_CONFIG_VARIABLE 0x33 +#define ARC_CONFIG_VARIABLE_NAME 0x34 +#define ARC_CONFIG_VARIABLE_CHAR 0x35 +#define ARC_CONFIG_STRING 0x36 +#define ARC_CONFIG_STRING_CHARS 0x37 +#define ARC_CONFIG_STRING_CHAR 0x38 +#define ARC_CONFIG_ESCAPE_CHAR 0x39 +#define ARC_CONFIG_FLOAT 0x3A +#define ARC_CONFIG_NUMBER_SIGN 0x3B +#define ARC_CONFIG_NUMBER_TAG 0x3C +#define ARC_CONFIG_WHITESPACE 0x3D +#define ARC_CONFIG_COMMENT 0x3E +#define ARC_CONFIG_LINE_COMMENT 0x3F +#define ARC_CONFIG_MULTI_LINE_COMMENT 0x40 +#define ARC_CONFIG_LINE_CHARS 0x41 +#define ARC_CONFIG_MULTI_LINE_CHARS 0x42 +#define ARC_CONFIG_COMMENT_CHAR 0x43 +/** + * @} +*/ + +/** + * @brief inits a config type with the standard config settings + * + * @param config the config to init +*/ +void ARC_Config_InitStd(ARC_Config *config); + +/** + * @brief a function callback to create an ARC_Bool stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_BoolCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy an ARC_Bool type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_BoolDestroyFn(ARC_Config *config, void *type); + +/** + * @brief a function callback to create an int8_t stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_Int8CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy an int8_t type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_Int8DestroyFn(ARC_Config *config, void *type); + +/** + * @brief a function callback to create an uint8_t stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_Uint8CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy an uint8_t type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_Uint8DestroyFn(ARC_Config *config, void *type); + +/** + * @brief a function callback to create an int16_t stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_Int16CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy an int16_t type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_Int16DestroyFn(ARC_Config *config, void *type); + +/** + * @brief a function callback to create an uint16_t stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_Uint16CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy an uint16_t type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_Uint16DestroyFn(ARC_Config *config, void *type); + +/** + * @brief a function callback to create an int32_t stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_Int32CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy an int32_t type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_Int32DestroyFn(ARC_Config *config, void *type); + +/** + * @brief a function callback to create an uint32_t stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_Uint32CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy an uint32_t type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_Uint32DestroyFn(ARC_Config *config, void *type); + +/** + * @brief a function callback to create an int64_t stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_Int64CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy an int64_t type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_Int64DestroyFn(ARC_Config *config, void *type); + +/** + * @brief a function callback to create an uint64_t stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_Uint64CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy an uint64_t type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_Uint64DestroyFn(ARC_Config *config, void *type); + +/** + * @brief a function callback to create a float stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_FloatCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy a float type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_FloatDestroyFn(ARC_Config *config, void *type); + +/** + * @brief a function callback to create a double stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_DoubleCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy a double type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_DoubleDestroyFn(ARC_Config *config, void *type); + +/** + * @brief a function callback to create an ARC_String stored within a config + * + * @note this function is an ARC_ConfigType_CopyFn callback + * + * @param[out] type the place to store the type copy, should be set to NULL on error + * @param[in] parsedData the parsed data used to copy from. will be as defined in the language + * @param[in] config the config that is reading in the data, can be used within the copy function to add a new type (check ARC_ConfigType_SpriteCopyFn for an example) + * @param[in] userdata userdata that was stored in the type during type register +*/ +void ARC_ConfigType_StringCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata); + +/** + * @brief a function callback to destroy an ARC_String type + * + * @note this function is an ARC_ConfigType_DestroyFn callback + * + * @param[in] config the config that is destroying the data, can be used within the destroy function to remove a previously added tag (check ARC_ConfigType_SpriteDestroyFn for an example) + * @param[in] type the type to be destroyed +*/ +void ARC_ConfigType_StringDestroyFn(ARC_Config *config, void *type); #ifdef __cplusplus } #endif -#endif //ARC_STD_CONFIG_H_ +#endif // !ARC_STD_CONFIG_H_ diff --git a/include/arc/std/defaults/config.h b/include/arc/std/defaults/config.h deleted file mode 100644 index 99daa6a..0000000 --- a/include/arc/std/defaults/config.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef ARC_DEFAULTS_CONFIG_H_ -#define ARC_DEFAULTS_CONFIG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "arc/std/string.h" - -typedef struct ARC_Config ARC_Config; -void ARC_Defaults_ConfigKey_Create(ARC_Config *config); - -uint8_t ARC_ConfigKey_Read_Uint8_t (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Int8_t (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Uint16_t (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Int16_t (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Uint32_t (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Int32_t (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Uint64_t (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Int64_t (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Char (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Int (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Long (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Float (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_Double (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_String (ARC_Config *config, ARC_String *string, void **value); -uint8_t ARC_ConfigKey_Read_StringArray(ARC_Config *config, ARC_String *string, void **value); - -void ARC_ConfigKey_Delete_Uint8_t (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Int8_t (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Uint16_t (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Int16_t (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Uint32_t (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Int32_t (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Uint64_t (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Int64_t (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Char (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Int (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Long (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Float (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_Double (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_String (ARC_Config *config, ARC_String *string, void *value); -void ARC_ConfigKey_Delete_StringArray(ARC_Config *config, ARC_String *string, void *value); - -#ifdef __cplusplus -} -#endif - -#endif //ARC_DEFAULTS_CONFIG_H_ \ No newline at end of file diff --git a/include/arc/std/entity.h b/include/arc/std/entity.h index 10d9112..59da830 100644 --- a/include/arc/std/entity.h +++ b/include/arc/std/entity.h @@ -15,12 +15,12 @@ extern "C" { typedef struct ARC_EntitySystem ARC_EntitySystem; /** - * @brief an entity component system type + * @brief an entity type (just an id) */ typedef uint32_t ARC_Entity; /** - * @brief an entity component system type + * @brief flags to define an entities current state */ typedef enum ARC_EntityFlags { ARC_ENTITY_DEAD = 0, @@ -33,12 +33,16 @@ typedef enum ARC_EntityFlags { typedef uint32_t ARC_EntityComponent; /** - * @brief + * @brief a callback function for components attached to an entity to create an empty type when a new entity is created + * + * @param[out] type, the place to create an empty type */ typedef void (* ARC_EntityCoponent_CreateEmptyFn)(void **type); /** - * @brief + * @brief creates an empty entity system, use ARC_EntitySystem_RegisterComponent to add compenents to the entity system + * + * @parm[out] entitySystem an empty entity system */ void ARC_EntitySystem_Create(ARC_EntitySystem **entitySystem); @@ -57,37 +61,68 @@ void ARC_EntitySystem_Destroy(ARC_EntitySystem *entitySystem); * @param[in] entitySystem the entity system to register the component to * @param[in] componentSize the size of the component to register * - * @return an id for for the component + * @return a uint32_t id for for the component */ uint32_t ARC_EntitySystem_RegisterComponent(ARC_EntitySystem *entitySystem, uint32_t componentSize); /** - * @brief + * @brief inits an empty entity, usually use ARC_EntitySystem_AddComponent to add compenets to the entity this function creates + * + * @param[in] entitySystem the entitySystem to init a new entity in + * + * @return an ARC_Entity that holds the id of the newly inited slot */ ARC_Entity ARC_EntitySystem_InitEntity(ARC_EntitySystem *entitySystem); /** - * @brief + * @brief releases an entity from a given entity system + * + * @param[in] entitySystem the entity system to remove the entity from + * @param[in] entity the entity to remove */ void ARC_EntitySystem_ReleaseEntity(ARC_EntitySystem *entitySystem, ARC_Entity entity); /** - * @brief + * @brief adds a component to a given entity within an entity system + * + * @note data will be copied, so if data was created elsewere it needs to be freed elsewhere + * + * @param[in] entitySystem the entity system that holds the entity which is being modified + * @param[in] entity the entity as an id which a component is being added to + * @param[in] component the id of the compenent for the entity system + * @param[in] data the components data as a void * */ void ARC_EntitySystem_AddComponent(ARC_EntitySystem *entitySystem, ARC_Entity entity, ARC_EntityComponent component, void *data); /** - * @brief + * @brief checks if an entity has a component within an entity system + * + * @param[in] entitySystem the entity system that holds the entity which is being checked + * @param[in] entity the entity as an id + * @param[in] component the id of the compenent for the entity system + * + * @return ARC_True if the entity has the given component, otherwise ARC_False */ ARC_Bool ARC_EntitySystem_HasComponent(ARC_EntitySystem *entitySystem, ARC_Entity entity, ARC_EntityComponent component); /** - * @brief + * @brief retrieves a components data for a specific entity + * + * @param[in] entitySystem the entity system that holds the entity which is being retrieved + * + * @param[in] entity the entity as an id + * @param[in] component the id of the compenent for the entity system + * @return the components data as a void * on success, otherwise NULL */ void *ARC_EntitySystem_GetComponentData(ARC_EntitySystem *entitySystem, ARC_Entity entity, ARC_EntityComponent component); /** - * @brief + * @brief retrieves all entities which have the given components + * + * @note this function will not check for exact matches, it just returns the entitys which have all the components (the entity might have more components than what is given) + * + * @param[in] entitySystem the entity system to query entities from + * @param[in] components the components a entity has to have to match */ ARC_Array ARC_EntitySystem_QueryComponentsData(ARC_EntitySystem *entitySystem, ARC_Array components); diff --git a/include/arc/std/errno.h b/include/arc/std/errno.h index 79fb015..d969b24 100644 --- a/include/arc/std/errno.h +++ b/include/arc/std/errno.h @@ -23,7 +23,7 @@ extern int32_t arc_errno; extern FILE *arc_errno_log_file; #ifndef ARC_DEBUG_LOG_STREAM_OVERRIDE - //this functin will be called on start, handy to set the log file to stdout if it is not overrided + //this function will be called on start, handy to set the log file to stdout if it is not overrided void __attribute__ ((constructor)) ARC_Errno_SetDefaultStream(void); #endif // !ARC_DEBUG_LOG_STREAM_OVERRIDE #endif // !ARC_DEBUG diff --git a/include/arc/std/handler.h b/include/arc/std/handler.h index b057e62..b5c7fe8 100644 --- a/include/arc/std/handler.h +++ b/include/arc/std/handler.h @@ -5,55 +5,34 @@ extern "C" { #endif -#include "arc/std/bool.h" +#include "arc/std/vector.h" #include /** * @brief a handler type - */ +*/ typedef struct ARC_Handler ARC_Handler; -/** - * @brief data comparison function ptr - * - * @note this is used for comparison within vectors - * - * @param a first data struct - * @param b second data struct - * - * @return 0 when a == b - */ -typedef ARC_Bool (* ARC_Handler_CompareDataFn)(void *a, void *b); - /** * @brief a function that will take iterated data * * @param data iterated data from ARC_Handler_Iterate - */ +*/ typedef void (* ARC_Handler_DataFn)(void *data); -/** - * @brief a function that will be used during destruction of trash vector - * - * @param data data that is being destroyed from trash - */ -typedef void (* ARC_Handler_CleanDataFn)(void *data); - /** * @brief creates ARC_Handler type * - * @param config ARC_Handler to initialize - * @param compareFn function to remove handler data - * @param cleanFn function to clean data in handler - * can be null - */ -void ARC_Handler_Create(ARC_Handler **handler, ARC_Handler_CompareDataFn *compareFn, ARC_Handler_CleanDataFn cleanFn); + * @param config ARC_Handler to initialize + * @param destroyDataFn function to clean data in handler, can be null +*/ +void ARC_Handler_Create(ARC_Handler **handler, ARC_Vector_DestroyDataFn *destroyDataFn); /** * @brief destroyes ARC_Handler type * * @param handler ARC_Handler to destory - */ +*/ void ARC_Handler_Destroy(ARC_Handler *handler); /** @@ -61,21 +40,9 @@ void ARC_Handler_Destroy(ARC_Handler *handler); * * @param handler ARC_Handler to add to * @param data data that is being added - */ +*/ void ARC_Handler_Add(ARC_Handler *handler, void *data); -/** - * @brief remove from handler - * - * @note the data that is removed is stored in a trash vector - * the ARC_Handler_Clean function must be called clean the trash vector - * the trash vector is to make sure a state is not deleted while being run - * - * @param handler ARC_Handler to remove from - * @param data data that is being removed - */ -void ARC_Handler_Remove(ARC_Handler *handler, void *data); - /** * @brief remove from handler * @@ -85,7 +52,7 @@ void ARC_Handler_Remove(ARC_Handler *handler, void *data); * * @param handler ARC_Handler to remove from * @param index index of data that is being removed - */ +*/ void ARC_Handler_RemoveIndex(ARC_Handler *handler, uint32_t index); /** @@ -93,14 +60,14 @@ void ARC_Handler_RemoveIndex(ARC_Handler *handler, uint32_t index); * * @param handler ARC_Handler to iterate through * @param datafn function that will be called on each element of data - */ +*/ void ARC_Handler_Iterate(ARC_Handler *handler, ARC_Handler_DataFn datafn); /** * @brief clears all data from handler and puts it in trash vector * * @param handler ARC_Handler to clear data from - */ +*/ void ARC_Handler_Clear(ARC_Handler *handler); /** @@ -109,18 +76,18 @@ void ARC_Handler_Clear(ARC_Handler *handler); * @note cleanfn's main purpose is to help manage memory * * @param handler ARC_Handler to remove trash from - */ +*/ void ARC_Handler_Clean(ARC_Handler *handler); /** - * @brief gets size of vector + * @brief gets size of elements stored in the handler * * @param handler ARC_handler to get size from - */ +*/ uint32_t ARC_Handler_GetSize(ARC_Handler *handler); #ifdef __cplusplus } #endif -#endif //ARC_STD_HANDLER_H_ \ No newline at end of file +#endif // !ARC_STD_HANDLER_H_ diff --git a/include/arc/std/hashtable.h b/include/arc/std/hashtable.h index 965762e..01118ff 100644 --- a/include/arc/std/hashtable.h +++ b/include/arc/std/hashtable.h @@ -7,7 +7,6 @@ extern "C" { #include "arc/std/bool.h" #include -#include /** * @brief a hashing function ptr @@ -126,4 +125,4 @@ void ARC_Hashtable_RunIteration(ARC_Hashtable *hashtable, ARC_Hashtable_Iterator } #endif -#endif //ARC_STD_HASHTABLE_H_ +#endif // !ARC_STD_HASHTABLE_H_ diff --git a/include/arc/std/io.h b/include/arc/std/io.h index 9a79e5d..bb2b406 100644 --- a/include/arc/std/io.h +++ b/include/arc/std/io.h @@ -5,8 +5,8 @@ extern "C" { #endif -#include #include "arc/std/string.h" +#include /** * @brief get string and size from file @@ -39,4 +39,4 @@ void ARC_IO_WriteStrToFile(ARC_String *path, ARC_String *data); } #endif -#endif //ARC_STD_IO_H_ \ No newline at end of file +#endif // !ARC_STD_IO_H_ diff --git a/include/arc/std/lexer.h b/include/arc/std/lexer.h index 111d04c..cdf57b5 100644 --- a/include/arc/std/lexer.h +++ b/include/arc/std/lexer.h @@ -4,6 +4,7 @@ #ifdef __cplusplus extern "C" { #endif + #include "arc/std/string.h" #include @@ -220,7 +221,7 @@ ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(uint32_t * @brief creates a ARC_LexerTokenRule with a given id and string * * @note this is intended as a helper funtion - * #note string will not be freed (it will be copied and the copy will be freed) + * @note string will not be freed (it will be copied and the copy will be freed) * * @param[in] id a tokens id (basically the token value) * @param[in] character the string to match against, will be copied @@ -233,7 +234,7 @@ ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchStringRule(uint32_t id * @brief creates a ARC_LexerTokenRule with a given id and string * * @note this is intended as a helper funtion - * #note string will not be freed (it will be copied and the copy will be freed) + * @note string will not be freed (it will be copied and the copy will be freed) * * @param[in] id a tokens id (basically the token value) * @param[in] character the string to match against, will be copied @@ -242,76 +243,6 @@ ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchStringRule(uint32_t id */ ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(uint32_t id, ARC_String *string); -/** - * @{ - * @brief basic tokens -*/ -#define ARC_LEXER_TOKEN_NULL 0 -#define ARC_LEXER_TOKEN_NUMBER 1 -#define ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR 2 -#define ARC_LEXER_TOKEN_ALPHA_UPPER_CHAR 3 -#define ARC_LEXER_TOKEN_WHITESPACE 4 -/** - * @} -*/ - -/** - * @{ - * @brief basic token type ids, chars, and tags -*/ -#define ARC_LEXER_TOKEN_NEWLINE_ID 5 -#define ARC_LEXER_TOKEN_NEWLINE_CHAR '\n' -#define ARC_LEXER_TOKEN_COLON_ID 6 -#define ARC_LEXER_TOKEN_COLON_CHAR ':' -#define ARC_LEXER_TOKEN_COLON_TAG "COLON" -#define ARC_LEXER_TOKEN_SEMICOLON_ID 7 -#define ARC_LEXER_TOKEN_SEMICOLON_CHAR ';' -#define ARC_LEXER_TOKEN_SEMICOLON_TAG "SEMICOLON" -#define ARC_LEXER_TOKEN_COMMA_ID 8 -#define ARC_LEXER_TOKEN_COMMA_CHAR ',' -#define ARC_LEXER_TOKEN_COMMA_TAG "COMMA" -#define ARC_LEXER_TOKEN_PERIOD_ID 9 -#define ARC_LEXER_TOKEN_PERIOD_CHAR '.' -#define ARC_LEXER_TOKEN_PERIOD_TAG "PERIOD" -#define ARC_LEXER_TOKEN_FORWARD_SLASH_ID 10 -#define ARC_LEXER_TOKEN_FORWARD_SLASH_CHAR '/' -#define ARC_LEXER_TOKEN_FORWARD_SLASH_TAG "FORWARD_SLASH" -#define ARC_LEXER_TOKEN_BACK_SLASH_ID 11 -#define ARC_LEXER_TOKEN_BACK_SLASH_CHAR '\\' -#define ARC_LEXER_TOKEN_BACK_SLASH_TAG "BACK_SLASH" -#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_ID 12 -#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_CHAR '(' -#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_TAG "LEFT_PARENTHESIS" -#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_ID 13 -#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_CHAR ')' -#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_TAG "RIGHT_PARENTHESIS" -#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_ID 14 -#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_CHAR '{' -#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_TAG "LEFT_CURLY_BRACE" -#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_ID 15 -#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_CHAR '}' -#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_TAG "RIGHT_CURLY_BRACE" -#define ARC_LEXER_TOKEN_BANG_ID 16 -#define ARC_LEXER_TOKEN_BANG_CHAR '!' -#define ARC_LEXER_TOKEN_BANG_TAG "BANG" -#define ARC_LEXER_TOKEN_AT_ID 17 -#define ARC_LEXER_TOKEN_AT_CHAR '!' -#define ARC_LEXER_TOKEN_AT_TAG "AT" -#define ARC_LEXER_TOKEN_HASH_ID 18 -#define ARC_LEXER_TOKEN_HASH_CHAR '#' -#define ARC_LEXER_TOKEN_HASH_TAG "HASH" -#define ARC_LEXER_TOKEN_PERCENT_ID 19 -#define ARC_LEXER_TOKEN_PERCENT_CHAR '%' -#define ARC_LEXER_TOKEN_PERCENT_TAG "PERCENT" -/** - * @} -*/ - -/** - * @brief adds a bunch of basic token rules (matching the BasicTokens above) -*/ -void ARC_Lexer_InitBasicTokenRules(ARC_Lexer *lexer); - #ifdef __cplusplus } #endif diff --git a/include/arc/std/parser/helpers.h b/include/arc/std/parser/helpers.h index e06f5c5..c4cc4db 100644 --- a/include/arc/std/parser/helpers.h +++ b/include/arc/std/parser/helpers.h @@ -6,7 +6,6 @@ extern "C" { #endif #include "arc/std/parser.h" -#include /** * @brief recurses through a tag token adding token strings to a main string diff --git a/include/arc/std/queue.h b/include/arc/std/queue.h index 50f4098..db69452 100644 --- a/include/arc/std/queue.h +++ b/include/arc/std/queue.h @@ -54,4 +54,4 @@ uint32_t ARC_Queue_Size(ARC_Queue *queue); } #endif -#endif //ARC_STD_QUEUE_H_ +#endif // !ARC_STD_QUEUE_H_ diff --git a/include/arc/std/stack.h b/include/arc/std/stack.h index daf1496..2de1b9e 100644 --- a/include/arc/std/stack.h +++ b/include/arc/std/stack.h @@ -54,4 +54,4 @@ uint32_t ARC_Stack_Size(ARC_Stack *stack); } #endif -#endif //ARC_STD_STACK_H_ \ No newline at end of file +#endif // !ARC_STD_STACK_H_ diff --git a/include/arc/std/string.h b/include/arc/std/string.h index 56d36eb..3ad7b67 100644 --- a/include/arc/std/string.h +++ b/include/arc/std/string.h @@ -5,8 +5,8 @@ extern "C" { #endif -#include #include "bool.h" +#include /** * @brief substring position within a string @@ -379,4 +379,4 @@ void ARC_String_ReplaceMatchingCStringWithStrlen(ARC_String **string, char *patt } #endif -#endif //ARC_STD_STRING_H_ +#endif // !ARC_STD_STRING_H_ diff --git a/include/archeus.h b/include/archeus.h new file mode 100644 index 0000000..fe01b4a --- /dev/null +++ b/include/archeus.h @@ -0,0 +1,69 @@ +#ifndef ARC_H_ +#define ARC_H_ + +/* ~ c libraries ~ */ +#include +#include +#include +#include + +/* ~ audio ~ */ +#include "arc/audio/audio.h" + +/* ~ engine ~ */ +#include "arc/engine/engine.h" +#include "arc/engine/state.h" + +/* ~ graphics ~ */ +#include "arc/graphics/circle.h" +#include "arc/graphics/color.h" +#include "arc/graphics/config.h" +#include "arc/graphics/line.h" +#include "arc/graphics/obround.h" +#include "arc/graphics/rectangle.h" +#include "arc/graphics/renderer.h" +#include "arc/graphics/sprite.h" +#include "arc/graphics/spritesheet.h" +#include "arc/graphics/text.h" +#include "arc/graphics/view.h" +#include "arc/graphics/window.h" + +/* ~ input ~ */ +#include "arc/input/keyboard.h" +#include "arc/input/mouse.h" + +/* ~ linux only ~ */ +//TODO: add linux only stuff here + +/* ~ math ~ */ +#include "arc/math/circle.h" +#include "arc/math/config.h" +#include "arc/math/obround.h" +#include "arc/math/point.h" +#include "arc/math/rectangle.h" +#include "arc/math/vector2.h" +#include "arc/math/vector3.h" + +/* ~ std ~ */ +#include "arc/std/array.h" +#include "arc/std/bool.h" +#include "arc/std/config.h" +#include "arc/std/entity.h" +#include "arc/std/errno.h" +#include "arc/std/handler.h" +#include "arc/std/hashtable.h" +#include "arc/std/io.h" +#include "arc/std/lexer.h" +#include "arc/std/parser.h" +#include "arc/std/parser/csv.h" +#include "arc/std/parser/helpers.h" +#include "arc/std/parser/parserlang.h" +//#include "arc/std/queue.h" +//#include "arc/std/stack.h" +#include "arc/std/string.h" +//#include "arc/std/time.h" +#include "arc/std/vector.h" +#include "arc/std/vector/inline.h" + + +#endif //!ARC_H_ diff --git a/packages/audio/sdl/config.c b/packages/audio/sdl/config.c index b925b62..0b068b8 100644 --- a/packages/audio/sdl/config.c +++ b/packages/audio/sdl/config.c @@ -7,7 +7,7 @@ #include "arc/audio/audio.h" // #define ARC_DEFAULT_CONFIG -#include "arc/std/defaults/config.h" +//#include "arc/std/defaults/config.h" // //void ARC_AudioConfig_Init(ARC_Config *config){ // ARC_Config_AddKeyCString(config, (char *)"ARC_Audio", 9, ARC_Audio_Read, ARC_Audio_Delete); @@ -40,4 +40,4 @@ //void ARC_Audio_Delete(ARC_Config* config, ARC_String *string, void *value){ // Mix_FreeChunk(((ARC_Audio *)value)->chunk); // free((ARC_Audio *)value); -//} \ No newline at end of file +//} diff --git a/packages/audio/sdl3/audio.c b/packages/audio/sdl3/audio.c new file mode 100644 index 0000000..3b1ad27 --- /dev/null +++ b/packages/audio/sdl3/audio.c @@ -0,0 +1,7 @@ +#include "arc/audio/audio.h" +#include "audio.h" +#include + +void ARC_Audio_Play(ARC_Audio *audio){ + Mix_PlayChannel(-1, audio->chunk, 0); +} \ No newline at end of file diff --git a/packages/audio/sdl3/audio.h b/packages/audio/sdl3/audio.h new file mode 100644 index 0000000..3aa6d08 --- /dev/null +++ b/packages/audio/sdl3/audio.h @@ -0,0 +1,10 @@ +#ifndef ARC_SDL_AUDIO_H_ +#define ARC_SDL_AUDIO_H_ + +#include + +typedef struct ARC_Audio { + Mix_Chunk *chunk; +} ARC_Audio; + +#endif // !ARC_SDL_AUDIO_H_ diff --git a/packages/audio/sdl3/config.c b/packages/audio/sdl3/config.c new file mode 100644 index 0000000..0b068b8 --- /dev/null +++ b/packages/audio/sdl3/config.c @@ -0,0 +1,43 @@ +#include "arc/audio/config.h" + +#include "audio.h" +#include +#include "arc/std/config.h" +#include "arc/std/errno.h" +#include "arc/audio/audio.h" + +// #define ARC_DEFAULT_CONFIG +//#include "arc/std/defaults/config.h" +// +//void ARC_AudioConfig_Init(ARC_Config *config){ +// ARC_Config_AddKeyCString(config, (char *)"ARC_Audio", 9, ARC_Audio_Read, ARC_Audio_Delete); +//} +// +//uint8_t ARC_Audio_Read(ARC_Config *config, ARC_String *string, void **value){ +// ARC_Config_Get(config, string, value); +// if(*value){ +// return 1; +// } +// +// if(string->data[0] != '"' || string->data[string->length - 1] != '"'){ +// ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("in ARC_Point_Read(config, string, value); no matching quotes: %s", string->data); +// arc_errno = ARC_ERRNO_DATA; +// return 0; +// } +// +// ARC_Audio *audio = (ARC_Audio *)malloc(sizeof(ARC_Audio)); +// +// ARC_String *path; +// ARC_String_CopySubstring(&path, string, 1, string->length - 2); +// audio->chunk = Mix_LoadWAV(path->data); +// +// //TODO: get error message if not loaded +// +// *value = (void *)audio; +// return 0; +//} +// +//void ARC_Audio_Delete(ARC_Config* config, ARC_String *string, void *value){ +// Mix_FreeChunk(((ARC_Audio *)value)->chunk); +// free((ARC_Audio *)value); +//} diff --git a/packages/graphics/sdl/circle.c b/packages/graphics/sdl/circle.c index c4e4ca6..9ea460c 100644 --- a/packages/graphics/sdl/circle.c +++ b/packages/graphics/sdl/circle.c @@ -2,11 +2,11 @@ #include //Modified from https://stackoverflow.com/questions/38334081/how-to-draw-circles-arcs-and-vector-graphics-in-sdl -void ARC_Circle_Render(ARC_Circle *circle, ARC_Renderer *renderer, ARC_Color *color){ - circleRGBA((SDL_Renderer *)renderer, (Sint16)circle->x, (Sint16)circle->y, (Sint16)circle->r, (Uint8)color->r, (Uint8)color->g, (Uint8)color->b, (Uint8)color->a); +void ARC_Circle_Render(ARC_Circle circle, ARC_Renderer *renderer, ARC_Color color){ + circleRGBA((SDL_Renderer *)renderer, (Sint16)circle.x, (Sint16)circle.y, (Sint16)circle.r, (Uint8)color.r, (Uint8)color.g, (Uint8)color.b, (Uint8)color.a); } //TODO: very temp -void ARC_Circle_RenderFill(ARC_Circle *circle, ARC_Renderer *renderer, ARC_Color *color){ - filledCircleRGBA((SDL_Renderer *)renderer, (Sint16)circle->x, (Sint16)circle->y, (Sint16)circle->r, (Uint8)color->r, (Uint8)color->g, (Uint8)color->b, (Uint8)color->a); +void ARC_Circle_RenderFill(ARC_Circle circle, ARC_Renderer *renderer, ARC_Color color){ + filledCircleRGBA((SDL_Renderer *)renderer, (Sint16)circle.x, (Sint16)circle.y, (Sint16)circle.r, (Uint8)color.r, (Uint8)color.g, (Uint8)color.b, (Uint8)color.a); } diff --git a/packages/graphics/sdl/config.c b/packages/graphics/sdl/config.c index 2ebfcc6..529bba3 100644 --- a/packages/graphics/sdl/config.c +++ b/packages/graphics/sdl/config.c @@ -5,8 +5,8 @@ #include "renderer.h" #include "sprite.h" #include "spritesheet.h" -#include "arc/std/array.h" #include "arc/std/string.h" +#include "arc/std/parser/helpers.h" #include "arc/std/errno.h" #include "arc/graphics/sprite.h" #include "arc/graphics/spritesheet.h" @@ -14,142 +14,59 @@ #include "arc/math/point.h" #include "arc/math/rectangle.h" -// #define ARC_DEFAULT_CONFIG -#include "arc/std/defaults/config.h" +void ARC_Config_InitGraphics(ARC_Config *config, ARC_Renderer *renderer){ + ARC_Config_RegisterTypeWithCStr(config, "ARC_Spritesheet", (ARC_ConfigType){ ARC_ConfigType_SpritesheetCopyFn, ARC_ConfigType_SpritesheetDestroyFn, renderer}); + ARC_Config_RegisterTypeWithCStr(config, "ARC_Sprite" , (ARC_ConfigType){ ARC_ConfigType_SpriteCopyFn , ARC_ConfigType_SpriteDestroyFn , renderer}); +} + +void ARC_ConfigType_SpritesheetString(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_Renderer *renderer = (ARC_Renderer *)userdata; + + //get the string chars between the quotes + ARC_ParserTagToken *stringCharsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 1); + + //get the path + ARC_String *path; + ARC_String_Create(&path, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&path, stringCharsTagToken); + + //read in and set the texture + ARC_Spritesheet_CreateFromFile((ARC_Spritesheet **)type, renderer, path); + + //cleanup + ARC_String_Destroy(path); +} + +void ARC_ConfigType_SpritesheetCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ParserTagToken *valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + + switch(valueTagToken->id){ + case ARC_CONFIG_STRING: + ARC_ConfigType_SpritesheetString(type, valueTagToken, config, userdata); + break; + + case ARC_CONFIG_NESTED_VALUE: + return; + + default: + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_SpritesheetCopyFn(type, parsedData, config, userdata), cannot use a value that is not a string or nested value. Look at documention for this function for more info"); + break; + } +} + +void ARC_ConfigType_SpritesheetDestroyFn(void *type){ + ARC_Spritesheet_Destroy((ARC_Spritesheet *)type); +} + +void ARC_ConfigType_SpriteCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ +} + +void ARC_ConfigType_SpriteDestroyFn(void *type){ +} + + -//SDL_Renderer *global_renderer; -// -//uint8_t ARC_SDL_Texture_Read(ARC_Config *config, ARC_String *string, void **value); -//uint8_t ARC_Spritesheet_Read(ARC_Config *config, ARC_String *string, void **value); -//uint8_t ARC_Sprite_Read (ARC_Config *config, ARC_String *string, void **value); -// -//void ARC_SDL_Texture_Delete(ARC_Config *config, ARC_String *string, void *value); -//void ARC_Spritesheet_Delete(ARC_Config *config, ARC_String *string, void *value); -//void ARC_Sprite_Delete (ARC_Config *config, ARC_String *string, void *value); -// -//void ARC_GraphicsConfig_Init(ARC_Config *config, ARC_Renderer *renderer){ -// global_renderer = (SDL_Renderer *)renderer; -// ARC_Config_AddKeyCString(config, (char *)"SDL_Texture" , 11, ARC_SDL_Texture_Read, ARC_SDL_Texture_Delete); -// ARC_Config_AddKeyCString(config, (char *)"ARC_Spritesheet", 15, ARC_Spritesheet_Read, ARC_Spritesheet_Delete); -// ARC_Config_AddKeyCString(config, (char *)"ARC_Sprite" , 10, ARC_Sprite_Read , ARC_Sprite_Delete ); -//} -// -//uint64_t ARC_GraphicsConfig_GetIndexAndErrorCheck(ARC_String *string, char *search, uint64_t searchLength){ -// uint64_t separator = ARC_String_FindCString(string, ",", 1); -// -// if(separator == ~(uint64_t)0){ -// arc_errno = ARC_ERRNO_DATA; -// } -// -// return separator; -//} -// -//int32_t ARC_SDL_Texture_Load(const char *path, SDL_Texture **texture){ -// IMG_Init(IMG_INIT_PNG); -// SDL_Surface *surface = IMG_Load(path); -// if(!surface){ -// printf("Error: reading png '%s'\nSDL_Image Error: %s", path, IMG_GetError()); -// return 1; // GE_SDL_ERRNO_ -// } -// -// SDL_BlendMode tempMode; -// SDL_GetSurfaceBlendMode(surface, &tempMode); -// *texture = SDL_CreateTextureFromSurface(global_renderer, surface); -// SDL_GetTextureBlendMode(*texture, &tempMode); -// -// SDL_FreeSurface(surface); -// IMG_Quit(); -// -// return 0; -//} -// -//uint8_t ARC_SDL_Texture_Read(ARC_Config* config, ARC_String *string, void **value){ -// ARC_Config_Get(config, string, value); -// if(*value){ -// return 1; -// } -// -// ARC_String *tempStr, *textureStr; -// ARC_String_StripEndsWhitespace(&tempStr, string); -// -// ARC_String_CopySubstring(&textureStr, tempStr, 1, tempStr->length - 2); -// ARC_String_Destroy(tempStr); -// -// ARC_SDL_Texture_Load(textureStr->data, (SDL_Texture **)value); -// -// ARC_String_Destroy(textureStr); -// return 0; -//} -// -//void ARC_Spritesheet_ReadTexture(ARC_Config *config, ARC_String *string, uint32_t *size, void **value){ -// SDL_Texture *texture; -// -// ARC_String *tempStr, *textureStr; -// ARC_String_StripEndsWhitespace(&tempStr, string); -// -// //check for reference -// ARC_Config_Get(config, tempStr, (void **)&texture); -// if(!texture && (tempStr->data[0] != '"' || tempStr->data[string->length - 1] != '"')){ -// arc_errno = ARC_ERRNO_DATA; -// } -// -// ARC_String_CopySubstring(&textureStr, tempStr, 1, tempStr->length - 2); -// ARC_String_Destroy(tempStr); -// -// //try reading in the texture -// if(!texture){ -// ARC_SDL_Texture_Read(config, string, (void **)&texture); -// if(arc_errno){ -// *value = NULL; -// } -// } -// -// ARC_String_Destroy(textureStr); -// -// *value = malloc(sizeof(ARC_Spritesheet)); -// ((ARC_Spritesheet *) *value)->texture = texture; -// ((ARC_Spritesheet *) *value)->size = size; -//} -// -//uint8_t ARC_Spritesheet_Read(ARC_Config* config, ARC_String *string, void **value){ -// if(string->data[0] != '{' || string->data[string->length - 1] != '}'){ -// ARC_Spritesheet_ReadTexture(config, string, NULL, value); -// return 0; -// } -// -// uint64_t split = ARC_GraphicsConfig_GetIndexAndErrorCheck(string, ",", 1); -// if(arc_errno){ -// return 0; -// } -// -// ARC_String *temp, *textureStr, *sizeStr; -// ARC_String_CopySubstring(&temp, string, 1, split - 2); -// ARC_String_StripEndsWhitespace(&textureStr, temp); -// ARC_String_Destroy(temp); -// -// ARC_String_CopySubstring(&temp, string, split + 1, string->length - (split + 2)); -// ARC_String_StripEndsWhitespace(&sizeStr, temp); -// ARC_String_Destroy(temp); -// -// uint32_t *size; -// ARC_Config_Get(config, string, (void **)&size); -// if(!size){ -// ARC_ConfigKey_Read_Uint32_t(config, sizeStr, (void **)&size); -// if(arc_errno){ -// ARC_String_Destroy(sizeStr); -// ARC_String_Destroy(textureStr); -// return ARC_ERRNO_DATA; -// } -// } -// -// ARC_Spritesheet_ReadTexture(config, textureStr, size, value); -// -// ARC_String_Destroy(sizeStr); -// ARC_String_Destroy(textureStr); -// -// return 0; -//} -// //uint8_t ARC_Sprite_Read(ARC_Config* config, ARC_String *string, void **value){ // ARC_Config_Get(config, string, value); // if(*value){ @@ -308,4 +225,4 @@ // } // // free(spriteValue); -//} \ No newline at end of file +//} diff --git a/packages/graphics/sdl/line.c b/packages/graphics/sdl/line.c index 64e21cd..7ff0c07 100644 --- a/packages/graphics/sdl/line.c +++ b/packages/graphics/sdl/line.c @@ -1,8 +1,7 @@ #include "arc/graphics/line.h" #include "renderer.h" -#include -void ARC_Line_Render(int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2, ARC_Renderer *renderer, ARC_Color *color){ - SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color->r, color->g, color->b, color->a); - SDL_RenderDrawLine((SDL_Renderer *)renderer, *x1, *y1, *x2, *y2); -} \ No newline at end of file +void ARC_Line_Render(ARC_Point point1, ARC_Point point2, ARC_Renderer *renderer, ARC_Color color){ + SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color.r, color.g, color.b, color.a); + SDL_RenderDrawLine((SDL_Renderer *)renderer, point1.x, point1.y, point2.x, point2.y); +} diff --git a/packages/graphics/sdl/rectangle.c b/packages/graphics/sdl/rectangle.c index 356bd3f..1287401 100644 --- a/packages/graphics/sdl/rectangle.c +++ b/packages/graphics/sdl/rectangle.c @@ -2,22 +2,22 @@ #include "renderer.h" #include -void ARC_Rect_Render(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color){ - SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color->r, color->g, color->b, color->a); - SDL_RenderDrawRect((SDL_Renderer *)renderer, (SDL_Rect *) rect); +void ARC_Rect_Render(ARC_Rect rect, ARC_Renderer *renderer, ARC_Color color){ + SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color.r, color.g, color.b, color.a); + SDL_RenderDrawRect((SDL_Renderer *)renderer, (SDL_Rect *)&rect); } -void ARC_Rect_RenderFill(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color){ - SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color->r, color->g, color->b, color->a); - SDL_RenderFillRect((SDL_Renderer *)renderer, (SDL_Rect *) rect); +void ARC_Rect_RenderFill(ARC_Rect rect, ARC_Renderer *renderer, ARC_Color color){ + SDL_SetRenderDrawColor((SDL_Renderer *)renderer, color.r, color.g, color.b, color.a); + SDL_RenderFillRect((SDL_Renderer *)renderer, (SDL_Rect *)&rect); } -void ARC_FRect_Render(ARC_FRect *rect, ARC_Renderer *renderer, ARC_Color *color){ +void ARC_FRect_Render(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color){ ARC_Rect casted = ARC_FRect_CastToRect(rect); - ARC_Rect_Render(&casted, renderer, color); + ARC_Rect_Render(casted, renderer, color); } -void ARC_FRect_RenderFill(ARC_FRect *rect, ARC_Renderer *renderer, ARC_Color *color){ +void ARC_FRect_RenderFill(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color){ ARC_Rect casted = ARC_FRect_CastToRect(rect); - ARC_Rect_RenderFill(&casted, renderer, color); -} \ No newline at end of file + ARC_Rect_RenderFill(casted, renderer, color); +} diff --git a/packages/graphics/sdl/renderer.c b/packages/graphics/sdl/renderer.c index c6971d8..2b2df82 100644 --- a/packages/graphics/sdl/renderer.c +++ b/packages/graphics/sdl/renderer.c @@ -30,9 +30,7 @@ void ARC_Renderer_Destroy(ARC_Renderer *renderer){ } void ARC_Renderer_Clear(ARC_Renderer *renderer){ - //TODO: changed for school, also need to add the ability to change render draw color - //SDL_SetRenderDrawColor((SDL_Renderer *)renderer, 0x1c, 0x2c, 0x3c, 0x00); - SDL_SetRenderDrawColor((SDL_Renderer *)renderer, 0x15, 0x2a, 0x26, 0x00); + SDL_SetRenderDrawColor((SDL_Renderer *)renderer, 0x1c, 0x2c, 0x3c, 0xff); SDL_RenderClear((SDL_Renderer *)renderer); } diff --git a/packages/graphics/sdl/spritesheet.c b/packages/graphics/sdl/spritesheet.c index ad06e10..eaa496b 100644 --- a/packages/graphics/sdl/spritesheet.c +++ b/packages/graphics/sdl/spritesheet.c @@ -3,29 +3,45 @@ #include "spritesheet.h" #include "renderer.h" #include "arc/math/point.h" +#include "arc/std/errno.h" #include #include #include -//TODO: Temp function void ARC_Spritesheet_CreateFromFile(ARC_Spritesheet **spritesheet, ARC_Renderer *renderer, ARC_String *path){ - *spritesheet = (ARC_Spritesheet *)malloc(sizeof(ARC_Spritesheet)); - + //TODO: allow other types of images + //init image as a png IMG_Init(IMG_INIT_PNG); + + //get and check the SDL surface SDL_Surface *surface = IMG_Load(path->data); if(!surface){ - printf("Error: reading png '%s'\nSDL_Image Error: %s", path->data, IMG_GetError()); + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Spritesheet_CreateFromFile(spritesheet, renderer, path), could not read path \"%s\", SDL2_Image Error: %s", path->data, IMG_GetError()); + + //cleanup + IMG_Quit(); + + //set the spritesheet to null and throw an error + *spritesheet = NULL; + return; } + //create the place to store the spritesheet + *spritesheet = (ARC_Spritesheet *)malloc(sizeof(ARC_Spritesheet)); + + //set the texture SDL_BlendMode tempMode; SDL_GetSurfaceBlendMode(surface, &tempMode); (*spritesheet)->texture = SDL_CreateTextureFromSurface((SDL_Renderer *)renderer, surface); - SDL_GetTextureBlendMode((*spritesheet)->texture, &tempMode); + SDL_SetTextureBlendMode((*spritesheet)->texture, tempMode); + //set the tile size to empty + (*spritesheet)->size = 0; + + //cleanup SDL_FreeSurface(surface); IMG_Quit(); - - ARC_Spritesheet_GetSize(*spritesheet); } void ARC_Spritesheet_Destroy(ARC_Spritesheet *spritesheet){ @@ -33,8 +49,32 @@ void ARC_Spritesheet_Destroy(ARC_Spritesheet *spritesheet){ free(spritesheet); } -void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect *sheetBounds, ARC_Renderer *renderer, ARC_Rect *renderBounds){ - SDL_RenderCopy((SDL_Renderer *)renderer, spritesheet->texture, (SDL_Rect *)sheetBounds, (SDL_Rect *)renderBounds); +void ARC_Spritesheet_Render(ARC_Spritesheet *spritesheet, ARC_Renderer *renderer, ARC_Rect renderBounds){ + SDL_RenderCopy((SDL_Renderer *)renderer, spritesheet->texture, NULL, (SDL_Rect *)&renderBounds); +} + +void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect sheetBounds, ARC_Renderer *renderer, ARC_Rect renderBounds){ + SDL_RenderCopy((SDL_Renderer *)renderer, spritesheet->texture, (SDL_Rect *)&sheetBounds, (SDL_Rect *)&renderBounds); +} + +void ARC_Spritesheet_RenderTile(ARC_Spritesheet *spritesheet, ARC_Point tilePosition, ARC_Renderer *renderer, ARC_Rect renderBounds){ + //error when size is 0 + if(spritesheet->size == 0){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR("ARC_Spritesheet_RenderTile(spritesheet, tilePosition, renderer, renderBounds), could not render a tile of size 0"); + return; + } + + //get bounds based on the sheet size + ARC_Rect sheetBounds = { + spritesheet->size * tilePosition.x, + spritesheet->size * tilePosition.y, + spritesheet->size, + spritesheet->size + }; + + //render the bounds + SDL_RenderCopy((SDL_Renderer *)renderer, spritesheet->texture, (SDL_Rect *)&sheetBounds, (SDL_Rect *)&renderBounds); } ARC_Point ARC_Spritesheet_GetSize(ARC_Spritesheet *spritesheet){ @@ -43,6 +83,6 @@ ARC_Point ARC_Spritesheet_GetSize(ARC_Spritesheet *spritesheet){ return size; } -uint32_t *ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet){ +uint32_t ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet){ return spritesheet->size; } diff --git a/packages/graphics/sdl/spritesheet.h b/packages/graphics/sdl/spritesheet.h index 51094a1..b0f5972 100644 --- a/packages/graphics/sdl/spritesheet.h +++ b/packages/graphics/sdl/spritesheet.h @@ -6,7 +6,7 @@ struct ARC_Spritesheet { SDL_Texture *texture; - uint32_t *size; + uint32_t size; }; #endif // !ARC_SDL_SPRITESHEET_H_ diff --git a/packages/graphics/sdl3/circle.c b/packages/graphics/sdl3/circle.c new file mode 100644 index 0000000..b68a9e2 --- /dev/null +++ b/packages/graphics/sdl3/circle.c @@ -0,0 +1,12 @@ +#include "arc/graphics/circle.h" +//#include + +//Modified from https://stackoverflow.com/questions/38334081/how-to-draw-circles-arcs-and-vector-graphics-in-sdl +void ARC_Circle_Render(ARC_Circle circle, ARC_Renderer *renderer, ARC_Color color){ +// circleRGBA((SDL_Renderer *)renderer, (Sint16)circle.x, (Sint16)circle.y, (Sint16)circle.r, (Uint8)color.r, (Uint8)color.g, (Uint8)color.b, (Uint8)color.a); +} + +//TODO: very temp +void ARC_Circle_RenderFill(ARC_Circle circle, ARC_Renderer *renderer, ARC_Color color){ +// filledCircleRGBA((SDL_Renderer *)renderer, (Sint16)circle.x, (Sint16)circle.y, (Sint16)circle.r, (Uint8)color.r, (Uint8)color.g, (Uint8)color.b, (Uint8)color.a); +} diff --git a/packages/graphics/sdl3/config.c b/packages/graphics/sdl3/config.c new file mode 100644 index 0000000..082ac80 --- /dev/null +++ b/packages/graphics/sdl3/config.c @@ -0,0 +1,227 @@ +#include "arc/graphics/config.h" + +#include "spritesheet.h" +#include "arc/graphics/sprite.h" +#include "arc/graphics/spritesheet.h" +#include "arc/math/config.h" +#include "arc/math/point.h" +#include "arc/math/rectangle.h" +#include "arc/std/errno.h" +#include "arc/std/string.h" +#include "arc/std/parser/helpers.h" +#include "arc/std/vector/inline.h" +#include +#include +#include + +void ARC_Config_InitGraphics(ARC_Config *config, ARC_Renderer *renderer){ + ARC_Config_RegisterTypeWithCStr(config, "ARC_Spritesheet", (ARC_ConfigType){ sizeof(ARC_Spritesheet), ARC_ConfigType_SpritesheetCopyFn, ARC_ConfigType_SpritesheetDestroyFn, renderer}); + ARC_Config_RegisterTypeWithCStr(config, "ARC_Sprite" , (ARC_ConfigType){ sizeof(ARC_Sprite) , ARC_ConfigType_SpriteCopyFn , ARC_ConfigType_SpriteDestroyFn , renderer}); +} + +void ARC_ConfigType_SpritesheetString(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_Renderer *renderer = (ARC_Renderer *)userdata; + + //get the string chars between the quotes + ARC_ParserTagToken *stringCharsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 1); + + //get the path + ARC_String *path; + ARC_String_Create(&path, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&path, stringCharsTagToken); + + //read in and set the texture + ARC_Spritesheet_CreateFromFile((ARC_Spritesheet **)type, renderer, path); + + //cleanup + ARC_String_Destroy(path); +} + +void ARC_ConfigType_SpritesheetCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ParserTagToken *valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + + switch(valueTagToken->id){ + case ARC_CONFIG_STRING: + ARC_ConfigType_SpritesheetString(type, valueTagToken, config, userdata); + break; + + case ARC_CONFIG_NESTED_VALUE: + return; + + default: + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_SpritesheetCopyFn(type, parsedData, config, userdata), cannot use a value that is not a string or nested value. Look at documention for this function for more info"); + break; + } +} + +void ARC_ConfigType_SpritesheetDestroyFn(ARC_Config *config, void *type){ + ARC_Spritesheet_Destroy((ARC_Spritesheet *)type); +} + +void ARC_ConfigType_SpriteCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + //go into the tag + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_NESTED_VALUE){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_SpriteCopyFn(type, parsedData, config, userdata), parsed data was not a "); + *type = NULL; + return; + } + + // -> OPEN_CURLY_BRACE CLOSE_CURLY_BRACE + ARC_ParserTagToken *valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 2); + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ + //TODO: error here + } + + ARC_Sprite *sprite; + ARC_Sprite_Create(&sprite, NULL, (ARC_Array){ 0, NULL }); + + //really large number in case a system has 64 digit pointer addresses + char pointerCString[64]; + sprintf(pointerCString, "%p", (void *)sprite); + + /* ~ spritesheet ~ */ + + // -> COMMA | + ARC_ParserTagToken *valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + + //check if spritesheet exist + ARC_String *valueString; + ARC_String_Create(&valueString, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&valueString, valueTagToken); + + ARC_Spritesheet *spritesheet = (ARC_Spritesheet *)ARC_Config_Get(config, valueString); + if(spritesheet == NULL){ + //create a name based on the type and the sprite pointer to have a unique name for cleanup on remove + ARC_String *spritesheetName; + ARC_String_CreateWithStrlen(&spritesheetName, pointerCString); + ARC_String_AppendCStringWithStrlen(&spritesheetName, "ARC_Spritesheet"); + + //copy the spritesheet + ARC_Spritesheet *sheet; + ARC_ConfigType_SpritesheetCopyFn((void *)&sheet, valueTagToken, config, userdata); + + //add the new spritesheet type to the config + ARC_Config_AddWithCStr(config, "ARC_Spritesheet", spritesheetName->data, (void *)sheet); + + //cleanup + ARC_String_Destroy(spritesheetName); + } + + //set the spritesheet to the sprite + sprite->spritesheet = spritesheet; + + //cleanup + ARC_String_Destroy(valueString); + valueString = NULL; + + /* ~ bounds aka frames ~ */ + + // -> COMMA | + valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 4); + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ + //TODO: error here + } + + // -> COMMA | + valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + + //check if bounds exist + ARC_String_Create(&valueString, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&valueString, valueTagToken); + + ARC_Array *bounds = (ARC_Array *)ARC_Config_Get(config, valueString); + if(bounds == NULL){ + //create a temporary vector to read in the array + ARC_VectorInline *typeVector; + ARC_VectorInline_Create(&typeVector, sizeof(ARC_FRect), NULL, NULL); + + // -> | | | | + valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueTagToken->tagTokens, 0); + + // -> COMMA | + while(valueArgsTagToken->id == ARC_CONFIG_VALUE_ARGS){ + valueTagToken = ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + + //copy the type and store it in the vector + void *typeData = NULL; + ARC_ConfigType_FRectCopyFn(&typeData, valueTagToken, config, userdata); + ARC_VectorInline_Add(typeVector, typeData); + + //if this value args was the last one break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ + break; + } + + //get the next valueArgs + valueArgsTagToken = ARC_Vector_Get(valueArgsTagToken->tagTokens, 4); + } + + //copy the data in an ARC_Array + ARC_Array typeVectorArray = ARC_VectorInline_GetData(typeVector); + bounds = (ARC_Array *)malloc(sizeof(ARC_Array)); + bounds->size = typeVectorArray.size; + bounds->data = NULL; + + if(typeVectorArray.size != 0){ + //copy the vector into the array's data + bounds->data = (void *)malloc(sizeof(ARC_FRect) * typeVectorArray.size); + memcpy(bounds->data, typeVectorArray.data, typeVectorArray.size); + } + + //create a name based on the type and the sprite pointer to have a unique name for cleanup on remove + ARC_String *boundsName; + ARC_String_CreateWithStrlen(&boundsName, pointerCString); + ARC_String_AppendCStringWithStrlen(&boundsName, "ARC_FRect"); + + //add the new ARC_FRect as ARC_Array type to the config + ARC_Config_AddWithCStr(config, "ARC_FRect", boundsName->data, (void *)bounds); + + //cleanup + ARC_String_Destroy(boundsName); + } + + //set the bounds to the frames + sprite->frames = *bounds; + + //cleanup + ARC_String_Destroy(valueString); + + //set the type + *type = sprite; +} + +void ARC_ConfigType_SpriteDestroyFn(ARC_Config *config, void *type){ + ARC_Sprite *sprite = (ARC_Sprite *)type; + + //really large number in case a system has 64 digit pointer addresses + char pointerCString[64]; + sprintf(pointerCString, "%p", (void *)sprite); + + /* ~ spritesheet ~ */ + //create a name based on the type and the sprite pointer to have a unique name for cleanup on remove + ARC_String *spritesheetName; + ARC_String_CreateWithStrlen(&spritesheetName, pointerCString); + ARC_String_AppendCStringWithStrlen(&spritesheetName, "ARC_Spritesheet"); + + //TODO: FIX THIS + //remove the spritesheet from the config (it won't error if it doesn't exist) + //ARC_Config_RemoveWithCStr(config, spritesheetName->data, ARC_False); + + /* ~ ARC_FRect Array ~ */ + //create a name based on the type and the sprite pointer to have a unique name for cleanup on remove + ARC_String *boundsName; + ARC_String_CreateWithStrlen(&boundsName, pointerCString); + ARC_String_AppendCStringWithStrlen(&boundsName, "ARC_FRect"); + + //TODO: FIX THIS + //remove the ARC_FRect from the config (it won't error if it doesn't exist) + //ARC_Config_RemoveWithCStr(config, boundsName->data, ARC_False); + + //cleanup + ARC_String_Destroy(boundsName); + ARC_String_Destroy(spritesheetName); + +} diff --git a/packages/graphics/sdl3/line.c b/packages/graphics/sdl3/line.c new file mode 100644 index 0000000..12ea67e --- /dev/null +++ b/packages/graphics/sdl3/line.c @@ -0,0 +1,7 @@ +#include "arc/graphics/line.h" +#include "renderer.h" + +void ARC_Line_Render(ARC_Point point1, ARC_Point point2, ARC_Renderer *renderer, ARC_Color color){ + SDL_SetRenderDrawColor(renderer->renderer, color.r, color.g, color.b, color.a); + SDL_RenderLine(renderer->renderer, point1.x, point1.y, point2.x, point2.y); +} diff --git a/packages/graphics/sdl3/obround.c b/packages/graphics/sdl3/obround.c new file mode 100644 index 0000000..bf1f669 --- /dev/null +++ b/packages/graphics/sdl3/obround.c @@ -0,0 +1,13 @@ +#include "arc/graphics/obround.h" +#include "renderer.h" +#include + +//Modified from https://stackoverflow.com/questions/38334081/how-to-draw-circles-arcs-and-vector-graphics-in-sdl +void ARC_Obround_Render(ARC_Obround *obround, ARC_Renderer *renderer, ARC_Color *color){ + //TODO: write this +} + +void ARC_FObround_Render(ARC_FObround *obround, ARC_Renderer *renderer, ARC_Color *color){ + ARC_Obround casted = ARC_FObround_CastToObround(obround); + ARC_Obround_Render(&casted, renderer, color); +} diff --git a/packages/graphics/sdl3/rectangle.c b/packages/graphics/sdl3/rectangle.c new file mode 100644 index 0000000..2837483 --- /dev/null +++ b/packages/graphics/sdl3/rectangle.c @@ -0,0 +1,23 @@ +#include "arc/graphics/rectangle.h" +#include "renderer.h" +#include + +void ARC_Rect_Render(ARC_Rect rect, ARC_Renderer *renderer, ARC_Color color){ + ARC_FRect casted = ARC_Rect_CastToFRect(rect); + ARC_FRect_Render(casted, renderer, color); +} + +void ARC_Rect_RenderFill(ARC_Rect rect, ARC_Renderer *renderer, ARC_Color color){ + ARC_FRect casted = ARC_Rect_CastToFRect(rect); + ARC_FRect_RenderFill(casted, renderer, color); +} + +void ARC_FRect_Render(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color){ + SDL_SetRenderDrawColor(renderer->renderer, color.r, color.g, color.b, color.a); + SDL_RenderRect(renderer->renderer, (SDL_FRect *)&rect); +} + +void ARC_FRect_RenderFill(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color){ + SDL_SetRenderDrawColor(renderer->renderer, color.r, color.g, color.b, color.a); + SDL_RenderFillRect(renderer->renderer, (SDL_FRect *)&rect); +} diff --git a/packages/graphics/sdl3/renderer.c b/packages/graphics/sdl3/renderer.c new file mode 100644 index 0000000..939b62e --- /dev/null +++ b/packages/graphics/sdl3/renderer.c @@ -0,0 +1,136 @@ +#include "arc/graphics/renderer.h" +#include "renderer.h" + +#include +#include +#include "arc/engine/engine.h" +#include "arc/graphics/window.h" +#include "arc/std/bool.h" +#include "arc/std/errno.h" + +uint32_t ARC_Renderer_BuffersHashtableHashFn(void *key){ + return *(uint32_t *)key; +} + +ARC_Bool ARC_Renderer_BuffersHashtableKeyCompareFn(void *key1, void *key2){ + return (ARC_Bool)(*(uint32_t *)key1 == *(uint32_t *)key2); +} + +void ARC_Renderer_BuffersHashtableDestroy(void *key, void *value){ + free((uint32_t *)key); + SDL_DestroyTexture(value); +} + +void ARC_Renderer_CreateWithEngineData(ARC_Renderer **renderer, ARC_EngineData *data){ + if(!data){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR("ARC_Renderer_CreateWithEngineData(**renderer, NULL)"); + return; + } + + *renderer = (ARC_Renderer *)malloc(sizeof(ARC_Renderer)); + + /* ~ Renderer ~ */ + (*renderer)->renderer = SDL_CreateRenderer((SDL_Window *)(data->window), NULL); + + if((*renderer)->renderer == NULL){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("SDL_CreateRenderer(%p, NULL);", (void *)data->window); + free(renderer); + return; + } + + SDL_SetRenderDrawBlendMode((*renderer)->renderer, SDL_BLENDMODE_BLEND); + + /* ~ Buffers ~ */ + ARC_Hashtable_HashFn hashFn = ARC_Renderer_BuffersHashtableHashFn; + ARC_Hashtable_KeyCompareFn keyCompareFn = ARC_Renderer_BuffersHashtableKeyCompareFn; + ARC_Hashtable_DestroyKeyValueFn destroyKeyValueFn = ARC_Renderer_BuffersHashtableDestroy; + ARC_Hashtable_Create(&((*renderer)->buffers), &hashFn, &keyCompareFn, &destroyKeyValueFn); + + /* ~ Clear Color ~ */ + (*renderer)->clearColor = (ARC_Color){ 0x1c, 0x2c, 0x3c, 0xff }; +} + +void ARC_Renderer_Destroy(ARC_Renderer *renderer){ + ARC_Hashtable_Destroy(renderer->buffers); + SDL_DestroyRenderer(renderer->renderer); + free(renderer); +} + +void ARC_Renderer_Clear(ARC_Renderer *renderer){ + SDL_SetRenderTarget(renderer->renderer, NULL); + SDL_SetRenderDrawColor(renderer->renderer, renderer->clearColor.r, renderer->clearColor.g, renderer->clearColor.b, renderer->clearColor.a); + SDL_RenderClear(renderer->renderer); + + ARC_Renderer_ClearBuffers(renderer); +} + +void ARC_Renderer_Render(ARC_Renderer *renderer){ + SDL_RenderPresent(renderer->renderer); +} + +void ARC_Renderer_InitBuffer(ARC_Renderer *renderer, uint32_t zIndex){ + SDL_Texture *buffer = (SDL_Texture *)ARC_Hashtable_Get(renderer->buffers, &zIndex); + if(buffer != NULL){ + //buffer was already created, do nothing + return; + } + + SDL_Rect viewPort = { 0, 0, 0, 0 }; + + SDL_GetRenderViewport(renderer->renderer, &viewPort); + + buffer = SDL_CreateTexture(renderer->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, viewPort.w - viewPort.x, viewPort.h - viewPort.y); + + uint32_t *index = (uint32_t *)malloc(sizeof(uint32_t)); + *index = zIndex; + ARC_Hashtable_Add(renderer->buffers, index, buffer); +} + +void ARC_Renderer_RemoveBuffer(ARC_Renderer *renderer, uint32_t zIndex){ + ARC_Hashtable_Remove(renderer->buffers, &zIndex); +} + +void ARC_Renderer_RenderBuffer(ARC_Renderer *renderer, uint32_t zIndex){ + SDL_Texture *buffer = (SDL_Texture *)ARC_Hashtable_Get(renderer->buffers, &zIndex); + + SDL_RenderTexture(renderer->renderer, buffer, NULL, NULL); +} + +//TODO: write this +void ARC_Renderer_BuffersHashtableRenderIteratorFn(void *key, void *value, void *userData){ +} + +//TODO: write this +void ARC_Renderer_RenderBuffers(ARC_Renderer *renderer){ +} + +//private function to iterate and clear each available buffer +void ARC_Renderer_BuffersHashtableClearIteratorFn(void *key, void *value, void *userData){ + ARC_Renderer *renderer = (ARC_Renderer *)userData; + + SDL_Texture *buffer = (SDL_Texture *)value; + + SDL_SetRenderTarget(renderer->renderer, buffer); + SDL_SetRenderDrawColor(renderer->renderer, 0x00, 0x00, 0x00, 0x00); + SDL_RenderClear(renderer->renderer); +} + +void ARC_Renderer_ClearBuffers(ARC_Renderer *renderer){ + ARC_Hashtable_RunIteration(renderer->buffers, ARC_Renderer_BuffersHashtableClearIteratorFn, (void *)renderer); +} + +void ARC_Renderer_SetCurrentBuffer(ARC_Renderer *renderer, uint32_t zIndex){ + SDL_Texture *buffer = (SDL_Texture *)ARC_Hashtable_Get(renderer->buffers, &zIndex); + SDL_SetRenderTarget(renderer->renderer, buffer); + + if(buffer != NULL){ + //TODO: probs throw an error + return; + } +} + +void ARC_Renderer_UnsetBuffer(ARC_Renderer *renderer){ + SDL_SetRenderTarget(renderer->renderer, NULL); +} diff --git a/packages/graphics/sdl3/renderer.h b/packages/graphics/sdl3/renderer.h new file mode 100644 index 0000000..423f931 --- /dev/null +++ b/packages/graphics/sdl3/renderer.h @@ -0,0 +1,18 @@ +#ifndef ARC_SDL_RENDERER_H_ +#define ARC_SDL_RENDERER_H_ + +#include "arc/graphics/color.h" +#include "arc/graphics/renderer.h" +#include "arc/graphics/window.h" +#include "arc/std/hashtable.h" +#include + +typedef struct ARC_RendererType { + SDL_Renderer *renderer; + + ARC_Hashtable *buffers; + + ARC_Color clearColor; +} ARC_RendererType; + +#endif // !ARC_SDL_RENDERER_H_ diff --git a/packages/graphics/sdl3/sprite.c b/packages/graphics/sdl3/sprite.c new file mode 100644 index 0000000..6809bfd --- /dev/null +++ b/packages/graphics/sdl3/sprite.c @@ -0,0 +1,127 @@ +#include "arc/graphics/sprite.h" + +#include "renderer.h" +#include "spritesheet.h" +#include "arc/math/point.h" +#include "arc/math/rectangle.h" +#include "arc/std/errno.h" +#include +#include + +void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array frames){ + *sprite = (ARC_Sprite *)malloc(sizeof(ARC_Sprite)); + (*sprite)->spritesheet = spritesheet; + (*sprite)->frames = frames; + (*sprite)->frameIndex = 0; + + (*sprite)->angle = 0.0; + + (*sprite)->origin = (ARC_FPoint){ 0.0, 0.0 }; + + //called this way to also set the alpha mod + ARC_Sprite_SetOpacity(*sprite, 1.0f); + + (*sprite)->axis = ARC_SPRITE_AXIS_NONE; + + (*sprite)->animationCurrentTime = 0.0f; + (*sprite)->animationTime = 1.0f / 24.0f; +} + +void ARC_Sprite_Destroy(ARC_Sprite *sprite){ + free(sprite); +} + +void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite){ + *newSprite = (ARC_Sprite *)malloc(sizeof(ARC_Sprite)); + (*newSprite)->spritesheet = oldSprite->spritesheet; + (*newSprite)->frames = oldSprite->frames; + (*newSprite)->frameIndex = oldSprite->frameIndex; + (*newSprite)->angle = oldSprite->angle; + (*newSprite)->origin = oldSprite->origin; + (*newSprite)->opacity = oldSprite->opacity; +} + +void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FRect renderBounds){ + SDL_RenderTexture(renderer->renderer, sprite->spritesheet->texture, ((SDL_FRect *)sprite->frames.data) + sprite->frameIndex, (SDL_FRect *)&renderBounds); +} + +void ARC_Sprite_RenderAt(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FPoint point, double scale){ + ARC_FRect sourceRect = ((ARC_FRect *)(sprite->frames.data))[sprite->frameIndex]; + //TODO: check that this works + ARC_FRect destinationRect = { + (point.x - sprite->origin.x) * scale, + (point.y - sprite->origin.y) * scale, + sourceRect.w * scale, + sourceRect.h * scale + }; + + //TODO: probably want to optomize this + SDL_FlipMode flip = SDL_FLIP_NONE; + if(sprite->axis & ARC_SPRITE_AXIS_X){ + flip |= SDL_FLIP_HORIZONTAL; + } + + if(sprite->axis & ARC_SPRITE_AXIS_Y){ + flip |= SDL_FLIP_VERTICAL; + } + + SDL_RenderTextureRotated(renderer->renderer, sprite->spritesheet->texture, (SDL_FRect *)&sourceRect, (SDL_FRect *)&destinationRect, sprite->angle, (SDL_FPoint *)&(sprite->origin), flip); +} + +void ARC_Sprite_IterateFrame(ARC_Sprite *sprite){ + sprite->frameIndex++; + + if(sprite->frameIndex == sprite->frames.size){ + sprite->frameIndex = 0; + } +} + +void ARC_Sprite_AnimateFrame(ARC_Sprite *sprite, float deltatime){ + sprite->animationCurrentTime += deltatime; + + if(sprite->animationCurrentTime >= sprite->animationTime){ + sprite->animationCurrentTime -= sprite->animationTime; + ARC_Sprite_IterateFrame(sprite); + } +} + +void ARC_Sprite_SetFrameIndex(ARC_Sprite *sprite, uint32_t index){ + if(sprite->frames.size <= index){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("in ARC_Sprite_SetFrameIndex(sprite, %d); index out of bounds", index); + return; + } + sprite->frameIndex = index; +} + +void ARC_Sprite_SetAngle(ARC_Sprite *sprite, double angle){ + sprite->angle = angle; +} + +void ARC_Sprite_SetOrigin(ARC_Sprite *sprite, ARC_FPoint origin){ + sprite->origin = origin; +} + +void ARC_Sprite_SetOpacity(ARC_Sprite *sprite, float opacity){ + sprite->opacity = opacity; + if(sprite->spritesheet != NULL){ + SDL_SetTextureAlphaMod((SDL_Texture *)sprite->spritesheet->texture, sprite->opacity); + } +} + +void ARC_Sprite_SetFrameRate(ARC_Sprite *sprite, float rate){ + sprite->animationCurrentTime = 0; + sprite->animationTime = rate; +} + +uint32_t ARC_Sprite_GetFrameIndex(ARC_Sprite *sprite){ + return sprite->frameIndex; +} + +ARC_FRect *ARC_Sprite_GetBounds(ARC_Sprite *sprite){ + return (ARC_FRect *)sprite->frames.data + sprite->frameIndex; +} + +ARC_Array ARC_Sprite_GetAllBounds(ARC_Sprite *sprite){ + return sprite->frames; +} diff --git a/packages/graphics/sdl3/spritesheet.c b/packages/graphics/sdl3/spritesheet.c new file mode 100644 index 0000000..82e005e --- /dev/null +++ b/packages/graphics/sdl3/spritesheet.c @@ -0,0 +1,87 @@ +#include "arc/graphics/spritesheet.h" + +#include "spritesheet.h" +#include "renderer.h" +#include "arc/math/point.h" +#include "arc/std/errno.h" +#include +#include +#include + +void ARC_Spritesheet_CreateFromFile(ARC_Spritesheet **spritesheet, ARC_Renderer *renderer, ARC_String *path){ + //TODO: allow other types of images + + //get and check the SDL surface + SDL_Surface *surface = IMG_Load(path->data); + if(!surface){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Spritesheet_CreateFromFile(spritesheet, renderer, path), could not read path \"%s\"", path->data); + + //set the spritesheet to null and throw an error + *spritesheet = NULL; + return; + } + + //create the place to store the spritesheet + *spritesheet = (ARC_Spritesheet *)malloc(sizeof(ARC_Spritesheet)); + + //set the texture + SDL_BlendMode tempMode; + SDL_GetSurfaceBlendMode(surface, &tempMode); + (*spritesheet)->texture = SDL_CreateTextureFromSurface(renderer->renderer, surface); + SDL_SetTextureBlendMode((*spritesheet)->texture, tempMode); + SDL_SetTextureScaleMode((*spritesheet)->texture, SDL_SCALEMODE_NEAREST); + + //set the tile size to empty + (*spritesheet)->size = 0; + + //cleanup + SDL_DestroySurface(surface); +} + +void ARC_Spritesheet_Destroy(ARC_Spritesheet *spritesheet){ + SDL_DestroyTexture(spritesheet->texture); + free(spritesheet); +} + +void ARC_Spritesheet_Render(ARC_Spritesheet *spritesheet, ARC_Renderer *renderer, ARC_FRect renderBounds){ + SDL_RenderTexture(renderer->renderer, spritesheet->texture, NULL, (SDL_FRect *)&renderBounds); +} + +void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect sheetBounds, ARC_Renderer *renderer, ARC_FRect renderBounds){ + ARC_FRect bounds = ARC_Rect_CastToFRect(sheetBounds); + SDL_RenderTexture(renderer->renderer, spritesheet->texture, (SDL_FRect *)&bounds, (SDL_FRect *)&renderBounds); +} + +void ARC_Spritesheet_RenderTile(ARC_Spritesheet *spritesheet, ARC_Point tilePosition, ARC_Renderer *renderer, ARC_FRect renderBounds){ + //error when size is 0 + if(spritesheet->size == 0){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR("ARC_Spritesheet_RenderTile(spritesheet, tilePosition, renderer, renderBounds), could not render a tile of size 0"); + return; + } + + //get bounds based on the sheet size + ARC_FRect sheetBounds = { + spritesheet->size * tilePosition.x, + spritesheet->size * tilePosition.y, + spritesheet->size, + spritesheet->size + }; + + //render the bounds + SDL_RenderTexture(renderer->renderer, spritesheet->texture, (SDL_FRect *)&sheetBounds, (SDL_FRect *)&renderBounds); +} + +ARC_Point ARC_Spritesheet_GetSize(ARC_Spritesheet *spritesheet){ + float x = 0.0; + float y = 0.0; + + SDL_GetTextureSize(spritesheet->texture, &x, &y); + + return (ARC_Point){ x, y }; +} + +uint32_t ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet){ + return spritesheet->size; +} diff --git a/packages/graphics/sdl3/spritesheet.h b/packages/graphics/sdl3/spritesheet.h new file mode 100644 index 0000000..c7927d7 --- /dev/null +++ b/packages/graphics/sdl3/spritesheet.h @@ -0,0 +1,12 @@ +#ifndef ARC_SDL_SPRITESHEET_H_ +#define ARC_SDL_SPRITESHEET_H_ + +#include "arc/graphics/spritesheet.h" +#include + +struct ARC_Spritesheet { + SDL_Texture *texture; + uint32_t size; +}; + +#endif // !ARC_SDL_SPRITESHEET_H_ diff --git a/packages/graphics/sdl3/text.c b/packages/graphics/sdl3/text.c new file mode 100644 index 0000000..50c2d76 --- /dev/null +++ b/packages/graphics/sdl3/text.c @@ -0,0 +1,69 @@ +#include "arc/graphics/text.h" + +#include "renderer.h" +#include "arc/graphics/color.h" +#include "arc/math/point.h" +#include "arc/math/rectangle.h" +#include "arc/std/string.h" +#include +#include + +#include + +void ARC_Text_Create(ARC_Text **text, ARC_String *path, int32_t size, ARC_Color color){ + *text = (ARC_Text *)malloc(sizeof(ARC_Text)); + + ARC_String_Copy(&(*text)->name, path); + + (*text)->fontSize = size; + (*text)->bounds = (ARC_FRect){ 0.0f, 0.0f, 0.0f, 0.0f }; + (*text)->color = color; + (*text)->backendData = NULL; + + //TODO: fix this + if(TTF_Init() == false) { + printf("TTF_Init: %s\n", SDL_GetError()); + exit(2); + } +} + +void ARC_Text_Destroy(ARC_Text *font){ + if(font->backendData != NULL){ + SDL_DestroyTexture((SDL_Texture *)font->backendData); + } + + ARC_String_Destroy(font->name); + free(font); +} + +void ARC_Text_SetString(ARC_Text *text, ARC_Renderer *renderer, ARC_String *string){ + TTF_Font *ttfont = TTF_OpenFont(text->name->data, text->fontSize); + SDL_Color textColor = (SDL_Color){ text->color.r, text->color.g, text->color.b, text->color.a }; + + SDL_Surface *surface = TTF_RenderText_Blended(ttfont, string->data, 0, textColor); + + text->bounds.w = surface->w; + text->bounds.h = surface->h; + + if(text->backendData != NULL){ + SDL_DestroyTexture((SDL_Texture *)text->backendData); + } + text->backendData = (void *)SDL_CreateTextureFromSurface(renderer->renderer, surface); + + SDL_DestroySurface(surface); + TTF_CloseFont(ttfont); +} + +void ARC_Text_Render(ARC_Text *text, ARC_Renderer *renderer){ + if(text->backendData == NULL){ + return; + } + + SDL_FRect bounds = (SDL_FRect){ text->bounds.x, text->bounds.y, text->bounds.w, text->bounds.h }; + SDL_RenderTexture(renderer->renderer, (SDL_Texture *)(text->backendData), NULL, &bounds); +} + +void ARC_Text_SetPos(ARC_Text *text, ARC_Point pos){ + text->bounds.x = pos.x; + text->bounds.y = pos.y; +} diff --git a/packages/graphics/sdl3/view.c b/packages/graphics/sdl3/view.c new file mode 100644 index 0000000..135b125 --- /dev/null +++ b/packages/graphics/sdl3/view.c @@ -0,0 +1,35 @@ +#include "arc/graphics/view.h" + +#include "arc/std/errno.h" +#include +#include + +void ARC_View_Create(ARC_View **view, ARC_Renderer *renderer, ARC_Rect bounds){ + *view = (ARC_View *)malloc(sizeof(ARC_View)); + (*view)->renderer = renderer; + (*view)->bounds = bounds; +} + +void ARC_View_Destroy(ARC_View *view){ + free(view); +} + +void ARC_View_Render(ARC_View *view, ARC_View_RenderFn renderFn, void *data){ +// int err = SDL_RenderSetViewport((SDL_Renderer *)view->renderer, (const SDL_Rect *)&(view->bounds)); +// if(err){ +// ARC_DEBUG_LOG_ERROR(ARC_ERRNO_DATA, "in src/graphics/sdl/view.c ARC_View_Render(view, renderFn), SDL_RenderSetViewport(...) returned: %d", err); +// return; +// } +// +// renderFn(data); +// +// err = SDL_RenderSetViewport((SDL_Renderer *)view->renderer, NULL); +// if(err){ +// ARC_DEBUG_LOG(ARC_ERRNO_DATA, "in src/graphics/sdl/view.c ARC_View_Render(view, NULL), SDL_RenderSetViewport(...) returned: %d", err); +// return; +// } +} + +ARC_Rect ARC_View_GetBounds(ARC_View *view){ + return view->bounds; +} diff --git a/packages/graphics/sdl3/window.c b/packages/graphics/sdl3/window.c new file mode 100644 index 0000000..b5ac150 --- /dev/null +++ b/packages/graphics/sdl3/window.c @@ -0,0 +1,26 @@ +#include "arc/graphics/window.h" + +#include "window.h" +#include "arc/std/errno.h" +#include + +void ARC_Window_Create(ARC_Window **window, ARC_WindowInfo *info){ + if(!info){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR("ARC_Window_Create(**window, NULL)"); + return; + } + + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); + + *window = (ARC_Window *)SDL_CreateWindow((const char *)info->title, info->w, info->h, 0); + + if(window == NULL){ + arc_errno = ARC_ERRNO_NULL; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("SDL_CreateWindow(%s, %d, %d, %x);", info->title, info->w, info->h, 0); + } +} + +void ARC_Window_Destroy(ARC_Window *window){ + SDL_DestroyWindow((SDL_Window *) window); +} diff --git a/packages/graphics/sdl3/window.h b/packages/graphics/sdl3/window.h new file mode 100644 index 0000000..7933318 --- /dev/null +++ b/packages/graphics/sdl3/window.h @@ -0,0 +1,9 @@ +#ifndef ARC_SDL_WINDOW_H_ +#define ARC_SDL_WINDOW_H_ + +#include "arc/graphics/window.h" +#include + +typedef SDL_Window ARC_WindowType; + +#endif // !ARC_SDL_WINDOW_H_ diff --git a/packages/input/sdl3/input.c b/packages/input/sdl3/input.c new file mode 100644 index 0000000..014e51d --- /dev/null +++ b/packages/input/sdl3/input.c @@ -0,0 +1,45 @@ +#include "arc/input/input.h" +#include "input.h" + +#include "arc/input/mouse.h" +#include "arc/input/keyboard.h" + +#include +#include + +void ARC_Input_CreateWithEngineData(ARC_Input **input, ARC_EngineData *data){ + *input = (ARC_Input *)malloc(sizeof(ARC_Input)); + + (*input)->event = (SDL_Event *)malloc(sizeof(SDL_Event)); + + ARC_Keyboard_CreateWithInput(&((*input)->keyboard), *input); + ARC_Mouse_CreateWithInput(&((*input)->mouse), *input); +} + +void ARC_Input_Destroy(ARC_Input *input){ + ARC_Keyboard_Destroy(input->keyboard); + ARC_Mouse_Destroy(input->mouse); + + free(input->event); + free(input); +} + +ARC_Bool ARC_Input_Update(ARC_Input *input){ + SDL_PollEvent(input->event); + if(input->event->type == SDL_EVENT_QUIT){ + return ARC_False; + } + + ARC_Keyboard_Update(input->keyboard); + ARC_Mouse_Update(input->mouse); + + return ARC_True; +} + +ARC_Keyboard *ARC_Input_GetKeyboard(ARC_Input *input){ + return input->keyboard; +} + +ARC_Mouse *ARC_Input_GetMouse(ARC_Input *input){ + return input->mouse; +} diff --git a/packages/input/sdl3/input.h b/packages/input/sdl3/input.h new file mode 100644 index 0000000..a18f3a0 --- /dev/null +++ b/packages/input/sdl3/input.h @@ -0,0 +1,15 @@ +#ifndef ARC_SDL_INPUT_H_ +#define ARC_SDL_INPUT_H_ + +#include "arc/input/keyboard.h" +#include "arc/input/mouse.h" +#include + +struct ARC_Input { + ARC_Keyboard *keyboard; + ARC_Mouse *mouse; + + SDL_Event *event; +}; + +#endif // !ARC_SDL_INPUT_H_ diff --git a/packages/input/sdl3/keyboard.c b/packages/input/sdl3/keyboard.c new file mode 100644 index 0000000..0c47e7d --- /dev/null +++ b/packages/input/sdl3/keyboard.c @@ -0,0 +1,98 @@ +#include "arc/input/keyboard.h" +#include "keyboard.h" +#include "input.h" +#include "arc/math/point.h" +#include "arc/std/errno.h" +#include +#include +#include +#include + +void ARC_Keyboard_CreateWithInput(ARC_Keyboard **keyboard, ARC_Input *input){ + *keyboard = (ARC_Keyboard *)malloc(sizeof(ARC_Keyboard)); + (*keyboard)->event = input->event; + (*keyboard)->keys = (ARC_KeyboardState *)malloc(sizeof(ARC_KeyboardState) * ARC_KEYBOARD_BUTTON_NUM); + + (*keyboard)->released = NULL; + + for(uint8_t i = 0; i < ARC_KEYBOARD_BUTTON_NUM; i++){ + (*keyboard)->keys[i] = ARC_KEY_NONE; + } +} + +void ARC_Keyboard_Destroy(ARC_Keyboard *keyboard){ + free(keyboard->keys); + + free(keyboard); +} + +void ARC_Keyboard_Update(ARC_Keyboard *keyboard){ + if(keyboard->released){ + *keyboard->released = ARC_KEY_NONE; + keyboard->released = NULL; + } + + if(keyboard->event->type != SDL_EVENT_KEY_DOWN && keyboard->event->type != SDL_EVENT_KEY_UP){ + return; + } + + if(keyboard->event->key.key >= 239 || keyboard->event->key.key < 0){ + return; + } + + if(keyboard->event->type == SDL_EVENT_KEY_DOWN){ + keyboard->keys[keyboard->event->key.key] = ARC_KEY_PRESSED; + return; + } + + keyboard->keys[keyboard->event->key.key] = ARC_KEY_RELEASED; + keyboard->released = (keyboard->keys + keyboard->event->key.key); +} + +ARC_KeyboardState ARC_Keyboard_GetState(ARC_Keyboard *keyboard, enum ARC_KeyboardKey key){ + switch(key){ + case ARC_KEY_A: return keyboard->keys[SDLK_A]; + case ARC_KEY_B: return keyboard->keys[SDLK_B]; + case ARC_KEY_C: return keyboard->keys[SDLK_C]; + case ARC_KEY_D: return keyboard->keys[SDLK_D]; + case ARC_KEY_E: return keyboard->keys[SDLK_E]; + case ARC_KEY_F: return keyboard->keys[SDLK_F]; + case ARC_KEY_G: return keyboard->keys[SDLK_G]; + case ARC_KEY_H: return keyboard->keys[SDLK_H]; + case ARC_KEY_I: return keyboard->keys[SDLK_I]; + case ARC_KEY_J: return keyboard->keys[SDLK_J]; + case ARC_KEY_K: return keyboard->keys[SDLK_K]; + case ARC_KEY_L: return keyboard->keys[SDLK_L]; + case ARC_KEY_M: return keyboard->keys[SDLK_M]; + case ARC_KEY_N: return keyboard->keys[SDLK_N]; + case ARC_KEY_O: return keyboard->keys[SDLK_O]; + case ARC_KEY_P: return keyboard->keys[SDLK_P]; + case ARC_KEY_Q: return keyboard->keys[SDLK_Q]; + case ARC_KEY_R: return keyboard->keys[SDLK_R]; + case ARC_KEY_S: return keyboard->keys[SDLK_S]; + case ARC_KEY_T: return keyboard->keys[SDLK_T]; + case ARC_KEY_U: return keyboard->keys[SDLK_U]; + case ARC_KEY_V: return keyboard->keys[SDLK_V]; + case ARC_KEY_W: return keyboard->keys[SDLK_W]; + case ARC_KEY_X: return keyboard->keys[SDLK_X]; + case ARC_KEY_Y: return keyboard->keys[SDLK_Y]; + case ARC_KEY_Z: return keyboard->keys[SDLK_Z]; + + case ARC_KEY_0: return keyboard->keys[SDLK_0]; + case ARC_KEY_1: return keyboard->keys[SDLK_1]; + case ARC_KEY_2: return keyboard->keys[SDLK_2]; + case ARC_KEY_3: return keyboard->keys[SDLK_3]; + case ARC_KEY_4: return keyboard->keys[SDLK_4]; + case ARC_KEY_5: return keyboard->keys[SDLK_5]; + case ARC_KEY_6: return keyboard->keys[SDLK_6]; + case ARC_KEY_7: return keyboard->keys[SDLK_7]; + case ARC_KEY_8: return keyboard->keys[SDLK_8]; + case ARC_KEY_9: return keyboard->keys[SDLK_9]; + + case ARC_KEY_SPACE: return keyboard->keys[SDLK_SPACE ]; + case ARC_KEY_ESC: return keyboard->keys[SDLK_ESCAPE]; + case ARC_KEY_ENTER: return keyboard->keys[SDLK_RETURN]; + + default: return ARC_KEY_NONE; + } +} diff --git a/packages/input/sdl3/keyboard.h b/packages/input/sdl3/keyboard.h new file mode 100644 index 0000000..c46c1a5 --- /dev/null +++ b/packages/input/sdl3/keyboard.h @@ -0,0 +1,14 @@ +#ifndef ARC_SDL_KEYBOARD_H_ +#define ARC_SDL_KEYBOARD_H_ + +#include "arc/input/keyboard.h" +#include + +struct ARC_Keyboard { + SDL_Event *event; + + ARC_KeyboardState *keys; + ARC_KeyboardState *released; +}; + +#endif // !ARC_SDL_KEYBOARD_H_ diff --git a/packages/input/sdl3/mouse.c b/packages/input/sdl3/mouse.c new file mode 100644 index 0000000..3d5f084 --- /dev/null +++ b/packages/input/sdl3/mouse.c @@ -0,0 +1,105 @@ +#include "arc/input/mouse.h" + +#include "mouse.h" +#include "input.h" +#include "arc/math/point.h" +#include "arc/std/errno.h" +#include +#include +#include +#include + +void ARC_Mouse_CreateWithInput(ARC_Mouse **mouse, ARC_Input *input){ + *mouse = (ARC_Mouse *)malloc(sizeof(ARC_Mouse)); + (*mouse)->event = input->event; + (*mouse)->coords = (ARC_FPoint *)malloc(sizeof(ARC_Point)); + (*mouse)->scrollY = (int32_t *)malloc(sizeof(int32_t )); + (*mouse)->buttons = (ARC_MouseState *)malloc(sizeof(ARC_MouseState) * ARC_MOUSE_BUTTON_NUM); + + (*mouse)->buttonsReleased = (uint8_t *)malloc(sizeof(uint8_t)); + + *(*mouse)->coords = (ARC_FPoint){0, 0}; + *(*mouse)->scrollY = 0; + + for(uint8_t i = 0; i < ARC_MOUSE_BUTTON_NUM; i++){ + (*mouse)->buttons[i] = ARC_MOUSE_NONE; + } + + *(*mouse)->buttonsReleased = 0; +} + +void ARC_Mouse_Destroy(ARC_Mouse *mouse){ + free(mouse->buttonsReleased); + + free(mouse->buttons); + free(mouse->scrollY); + free(mouse->coords ); + + free(mouse); +} + +void ARC_Mouse_UpdateButton(ARC_Mouse *mouse, uint8_t button, uint32_t *buttons, uint32_t mask){ + if(*buttons & mask){ + mouse->buttons[button] = ARC_MOUSE_PRESSED; + return; + } + + if(mouse->buttons[button] == ARC_MOUSE_NONE){ + return; + } + + if(mouse->buttons[button] == ARC_MOUSE_RELEASED){ + mouse->buttons[button] = ARC_MOUSE_NONE; + --*mouse->buttonsReleased; + return; + } + + mouse->buttons[button] = ARC_MOUSE_RELEASED; + ++*mouse->buttonsReleased; +} + +void ARC_Mouse_Update(ARC_Mouse *mouse){ + *mouse->scrollY = 0; + if(mouse->event->type == SDL_EVENT_MOUSE_WHEEL){ + *mouse->scrollY = mouse->event->wheel.y; + } + + uint32_t buttons = SDL_GetMouseState(&(mouse->coords->x), &(mouse->coords->y)); + + if(mouse->event->type != SDL_EVENT_MOUSE_BUTTON_DOWN && mouse->event->type != SDL_EVENT_MOUSE_BUTTON_UP){ + if(!*mouse->buttonsReleased){ + return; + } + + for(uint8_t i = *mouse->buttonsReleased; i > 0; i--){ + if(mouse->buttons[i - 1] == ARC_MOUSE_RELEASED){ + mouse->buttons[i - 1] = ARC_MOUSE_NONE; + --*mouse->buttonsReleased; + } + } + + // if(*mouse->buttonsReleased){ + // arc_errno = ARC_ERRNO_DATA; + // ARC_DEBUG_LOG(arc_errno, "in ARC_Mouse_Update mouse->buttonsReleased == %u, it needs to be 0\n", *(mouse->buttonsReleased)); + // } + return; + } + + ARC_Mouse_UpdateButton(mouse, ARC_MOUSE_LEFT , &buttons, SDL_BUTTON_LMASK ); + ARC_Mouse_UpdateButton(mouse, ARC_MOUSE_MIDDLE, &buttons, SDL_BUTTON_MMASK ); + ARC_Mouse_UpdateButton(mouse, ARC_MOUSE_RIGHT , &buttons, SDL_BUTTON_RMASK ); + ARC_Mouse_UpdateButton(mouse, ARC_MOUSE_X1 , &buttons, SDL_BUTTON_X1MASK); + ARC_Mouse_UpdateButton(mouse, ARC_MOUSE_X2 , &buttons, SDL_BUTTON_X2MASK); +} + +ARC_FPoint *ARC_Mouse_GetCoords(ARC_Mouse *mouse){ + return mouse->coords; +} + +ARC_MouseState ARC_Mouse_GetState(ARC_Mouse *mouse, ARC_MouseButton button){ + return mouse->buttons[button]; +} + +int32_t *ARC_Mouse_GetScrollY(ARC_Mouse *mouse){ + return mouse->scrollY; +} diff --git a/packages/input/sdl3/mouse.h b/packages/input/sdl3/mouse.h new file mode 100644 index 0000000..19b29b7 --- /dev/null +++ b/packages/input/sdl3/mouse.h @@ -0,0 +1,17 @@ +#ifndef ARC_SDL_MOUSE_H_ +#define ARC_SDL_MOUSE_H_ + +#include +#include "arc/input/mouse.h" +#include "arc/math/point.h" + +struct ARC_Mouse { + SDL_Event *event; + ARC_FPoint *coords; + int32_t *scrollY; + + ARC_MouseState *buttons; + uint8_t *buttonsReleased; +}; + +#endif // !ARC_SDL_MOUSE_H_ diff --git a/src/engine/engine.c b/src/engine/engine.c index 38f1c2c..0b8bc82 100644 --- a/src/engine/engine.c +++ b/src/engine/engine.c @@ -1,7 +1,6 @@ #include "arc/engine/engine.h" //NOTE: some of this file is temporary, mostly to get smthn running so I can test out different ideas -#include #include "arc/engine/state.h" #include "arc/graphics/window.h" #include "arc/graphics/renderer.h" @@ -10,20 +9,24 @@ #include "arc/std/bool.h" #include "arc/std/errno.h" #include "arc/std/handler.h" +#include +#include -//TODO: remove this -//#include +void ARC_EngineData_VectorDestroyStateFn(void *data){ + ARC_State_Destroy((ARC_State *)data); +} -void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanFn, ARC_Point windowSize){ +void ARC_EngineData_Create(ARC_EngineData **data, ARC_Point windowSize){ *data = (ARC_EngineData *)malloc(sizeof(ARC_EngineData)); - (*data)->window = NULL; - (*data)->renderer = NULL; - (*data)->input = NULL; - (*data)->keyboard = NULL; - (*data)->mouse = NULL; + (*data)->window = NULL; + (*data)->renderer = NULL; + (*data)->input = NULL; + (*data)->keyboard = NULL; + (*data)->mouse = NULL; + (*data)->entitySystem = NULL; - //TODO: set the destroy callback - ARC_Handler_Create(&((*data)->state), NULL, cleanFn); + ARC_Vector_DestroyDataFn destroyDataFn = ARC_EngineData_VectorDestroyStateFn; + ARC_Handler_Create(&((*data)->state), &destroyDataFn); (*data)->dt = 0.0; (*data)->running = ARC_False; @@ -46,9 +49,12 @@ void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanF (*data)->keyboard = ARC_Input_GetKeyboard((*data)->input); (*data)->mouse = ARC_Input_GetMouse((*data)->input); + + ARC_EntitySystem_Create(&((*data)->entitySystem)); } void ARC_EngineData_Destroy(ARC_EngineData *data){ + ARC_EntitySystem_Destroy(data->entitySystem); ARC_Mouse_Destroy(data->mouse); ARC_Keyboard_Destroy(data->keyboard); ARC_Renderer_Destroy(data->renderer); @@ -61,13 +67,19 @@ void ARC_Engine_RunUncapped(ARC_EngineData *data){ return; } - //double lastTime = 0, currentTime; + //TODO: probably want to do this in a better way + struct timespec currentTime; + struct timespec lastTime; + + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + + lastTime = currentTime; data->running = ARC_True; while(data->running){ - //currentTime = SDL_GetTicks(); - //data->dt = currentTime - lastTime; - //lastTime = currentTime; + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + data->dt = (currentTime.tv_sec + (currentTime.tv_nsec * 0.000000001)) - (lastTime.tv_sec + (lastTime.tv_nsec * 0.000000001)); + lastTime = currentTime; data->running = ARC_Input_Update(data->input); diff --git a/src/engine/state.c b/src/engine/state.c index 5d3f707..e9f4734 100644 --- a/src/engine/state.c +++ b/src/engine/state.c @@ -1,5 +1,29 @@ #include "arc/engine/state.h" #include +#include + +void ARC_State_Create(ARC_State **state, ARC_State_UpdateFn updateFn, ARC_State_RenderFn renderFn, void *data, ARC_State_DestroyDataFn *destroyDataFn){ + *state = (ARC_State *)malloc(sizeof(ARC_State)); + + (*state)->updateFn = updateFn; + (*state)->renderFn = renderFn; + + (*state)->data = data; + + (*state)->destroyDataFn = NULL; + if(destroyDataFn != NULL){ + (*state)->destroyDataFn = (ARC_State_DestroyDataFn *)malloc(sizeof(ARC_State_DestroyDataFn)); + *((*state)->destroyDataFn) = *destroyDataFn; + } +} + +void ARC_State_Destroy(ARC_State *state){ + if(state->destroyDataFn != NULL){ + (*(state->destroyDataFn))(state->data); + } + + free(state); +} void ARC_State_Update(void *data){ ((ARC_State *)data)->updateFn(((ARC_State *)data)->data); @@ -7,4 +31,4 @@ void ARC_State_Update(void *data){ void ARC_State_Render(void *data){ ((ARC_State *)data)->renderFn(((ARC_State *)data)->data); -} \ No newline at end of file +} diff --git a/src/graphics/circle.c b/src/graphics/circle.c index ffe771b..968b3ce 100644 --- a/src/graphics/circle.c +++ b/src/graphics/circle.c @@ -3,8 +3,8 @@ #include "arc/graphics/circle.h" #include -void ARC_Circle_Render(ARC_Circle *circle, ARC_Renderer *renderer, ARC_Color *color){ +void ARC_Circle_Render(ARC_Circle circle, ARC_Renderer *renderer, ARC_Color color){ printf("No Graphics Backend Selected\n"); } -#endif // !ARC_NONE_GRAPHICS \ No newline at end of file +#endif // !ARC_NONE_GRAPHICS diff --git a/src/graphics/line.c b/src/graphics/line.c index 2f59143..e1baf22 100644 --- a/src/graphics/line.c +++ b/src/graphics/line.c @@ -3,8 +3,8 @@ #include "arc/graphics/line.h" #include -void ARC_Line_Render(int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2, ARC_Renderer *renderer, ARC_Color *color){ +void ARC_Line_Render(ARC_Point point1, ARC_Point point2, ARC_Renderer *renderer, ARC_Color color){ printf("No Graphics Backend Selected\n"); } -#endif // !ARC_NONE_GRAPHICS \ No newline at end of file +#endif // !ARC_NONE_GRAPHICS diff --git a/src/graphics/rectangle.c b/src/graphics/rectangle.c index a59b6f4..fb46d6a 100644 --- a/src/graphics/rectangle.c +++ b/src/graphics/rectangle.c @@ -3,20 +3,20 @@ #include "arc/graphics/rectangle.h" #include -void ARC_Rect_Render(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color){ +void ARC_Rect_Render(ARC_Rect rect, ARC_Renderer *renderer, ARC_Color color){ printf("No Graphics Backend Selected\n"); } -void ARC_Rect_RenderFill(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color){ +void ARC_Rect_RenderFill(ARC_Rect rect, ARC_Renderer *renderer, ARC_Color color){ printf("No Graphics Backend Selected\n"); } -void ARC_FRect_Render(ARC_FRect *rect, ARC_Renderer *renderer, ARC_Color *color){ +void ARC_FRect_Render(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color){ printf("No Graphics Backend Selected\n"); } -void ARC_FRect_RenderFill(ARC_FRect *rect, ARC_Renderer *renderer, ARC_Color *color){ +void ARC_FRect_RenderFill(ARC_FRect rect, ARC_Renderer *renderer, ARC_Color color){ printf("No Graphics Backend Selected\n"); } -#endif // !ARC_NONE_GRAPHICS \ No newline at end of file +#endif // !ARC_NONE_GRAPHICS diff --git a/src/graphics/sprite.c b/src/graphics/sprite.c index 0b3cb6f..fbf9848 100644 --- a/src/graphics/sprite.c +++ b/src/graphics/sprite.c @@ -3,7 +3,8 @@ #include "arc/graphics/sprite.h" #include -void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array *frames){ +void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array frames){ + *sprite = NULL; printf("No Graphics Backend Selected\n"); } @@ -15,19 +16,11 @@ void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite){ printf("No Graphics Backend Selected\n"); } -void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds){ +void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FRect renderBounds){ printf("No Graphics Backend Selected\n"); } -void ARC_Sprite_RenderFlip(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, enum ARC_Sprite_Axis axis){ - printf("No Graphics Backend Selected\n"); -} - -void ARC_Sprite_RenderRotated(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, ARC_Point *center, double angle){ - printf("No Graphics Backend Selected\n"); -} - -void ARC_Sprite_SetFrameIndex(ARC_Sprite *sprite, uint32_t index){ +void ARC_Sprite_RenderAt(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_FPoint point, double scale){ printf("No Graphics Backend Selected\n"); } @@ -35,14 +28,43 @@ void ARC_Sprite_IterateFrame(ARC_Sprite *sprite){ printf("No Graphics Backend Selected\n"); } -ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite){ +void ARC_Sprite_AnimateFrame(ARC_Sprite *sprite, float deltatime){ + printf("No Graphics Backend Selected\n"); +} + +void ARC_Sprite_SetFrameIndex(ARC_Sprite *sprite, uint32_t index){ + printf("No Graphics Backend Selected\n"); +} + +void ARC_Sprite_SetAngle(ARC_Sprite *sprite, double angle){ + printf("No Graphics Backend Selected\n"); +} + +void ARC_Sprite_SetOrigin(ARC_Sprite *sprite, ARC_FPoint origin){ + printf("No Graphics Backend Selected\n"); +} + +void ARC_Sprite_SetOpacity(ARC_Sprite *sprite, float opacity){ + printf("No Graphics Backend Selected\n"); +} + +void ARC_Sprite_SetFrameRate(ARC_Sprite *sprite, float rate){ + printf("No Graphics Backend Selected\n"); +} + +uint32_t ARC_Sprite_GetFrameIndex(ARC_Sprite *sprite){ + printf("No Graphics Backend Selected\n"); + return ~(uint32_t)0; +} + +ARC_FRect *ARC_Sprite_GetBounds(ARC_Sprite *sprite){ printf("No Graphics Backend Selected\n"); return NULL; } -ARC_Array *ARC_Sprite_GetAllBounds(ARC_Sprite *sprite){ +ARC_Array ARC_Sprite_GetAllBounds(ARC_Sprite *sprite){ printf("No Graphics Backend Selected\n"); - return NULL; + return (ARC_Array){ 0, NULL }; } -#endif // !ARC_NONE_GRAPHICS \ No newline at end of file +#endif // !ARC_NONE_GRAPHICS diff --git a/src/graphics/spritesheet.c b/src/graphics/spritesheet.c index a08d5ce..b916654 100644 --- a/src/graphics/spritesheet.c +++ b/src/graphics/spritesheet.c @@ -4,7 +4,24 @@ #include "arc/math/point.h" #include -void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect *sheetBounds, ARC_Renderer *renderer, ARC_Rect *renderBounds){ +void ARC_Spritesheet_CreateFromFile(ARC_Spritesheet **spritesheet, ARC_Renderer *renderer, ARC_String *path){ + *spritesheet = NULL; + printf("No Graphics Backend Selected\n"); +} + +void ARC_Spritesheet_Destroy(ARC_Spritesheet *spritesheet){ + printf("No Graphics Backend Selected\n"); +} + +void ARC_Spritesheet_Render(ARC_Spritesheet *spritesheet, ARC_Renderer *renderer, ARC_FRect renderBounds){ + printf("No Graphics Backend Selected\n"); +} + +void ARC_Spritesheet_RenderArea(ARC_Spritesheet *spritesheet, ARC_Rect sheetBounds, ARC_Renderer *renderer, ARC_FRect renderBounds){ + printf("No Graphics Backend Selected\n"); +} + +void ARC_Spritesheet_RenderTile(ARC_Spritesheet *spritesheet, ARC_Point tilePosition, ARC_Renderer *renderer, ARC_FRect renderBounds){ printf("No Graphics Backend Selected\n"); } @@ -13,9 +30,9 @@ ARC_Point ARC_Spritesheet_GetSize(ARC_Spritesheet *spritesheet){ return (ARC_Point){ 0, 0 }; } -uint32_t *ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet){ +uint32_t ARC_Spritesheet_GetTileSize(ARC_Spritesheet *spritesheet){ printf("No Graphics Backend Selected\n"); - return NULL; + return ~(uint32_t)0; } -#endif // !ARC_NONE_GRAPHICS \ No newline at end of file +#endif // !ARC_NONE_GRAPHICS diff --git a/src/input/mouse.c b/src/input/mouse.c index e9f1d9a..e3cf708 100644 --- a/src/input/mouse.c +++ b/src/input/mouse.c @@ -19,7 +19,7 @@ void ARC_Mouse_Update(ARC_Mouse *mouse){ printf("No Input Backend Selected\n"); } -ARC_Point *ARC_Mouse_GetCoords(ARC_Mouse *mouse){ +ARC_FPoint *ARC_Mouse_GetCoords(ARC_Mouse *mouse){ printf("No Input Backend Selected\n"); return NULL; } diff --git a/src/math/circle.c b/src/math/circle.c index e69de29..9a5e8d1 100644 --- a/src/math/circle.c +++ b/src/math/circle.c @@ -0,0 +1,4 @@ +#include "arc/math/circle.h" + +void TEMP_Circle_Placeholder(void){ +} diff --git a/src/math/config.c b/src/math/config.c index bb6ea9f..6cfe34a 100644 --- a/src/math/config.c +++ b/src/math/config.c @@ -1,276 +1,373 @@ #include "arc/math/config.h" #include #include -#include "arc/std/array.h" -#include "arc/std/string.h" #include "arc/std/errno.h" #include "arc/std/config.h" #include "arc/math/point.h" #include "arc/math/rectangle.h" -// #define ARC_DEFAULT_CONFIG -#include "arc/std/defaults/config.h" - -void ARC_MathConfig_Init(ARC_Config *config){ - ARC_Config_AddKeyCString(config, (char *)"ARC_Point" , 9, ARC_Point_Read , ARC_Point_Delete ); - ARC_Config_AddKeyCString(config, (char *)"ARC_Rect" , 8, ARC_Rect_Read , ARC_Rect_Delete ); - ARC_Config_AddKeyCString(config, (char *)"ARC_Rect[]", 10, ARC_RectArray_Read, ARC_RectArray_Delete); +void ARC_Config_InitMath(ARC_Config *config){ + ARC_Config_RegisterTypeWithCStr(config, "ARC_Point" , (ARC_ConfigType){ sizeof(ARC_Point) , ARC_ConfigType_PointCopyFn , ARC_ConfigType_PointDestroyFn , NULL }); + ARC_Config_RegisterTypeWithCStr(config, "ARC_FPoint", (ARC_ConfigType){ sizeof(ARC_FPoint), ARC_ConfigType_FPointCopyFn, ARC_ConfigType_FPointDestroyFn, NULL }); + ARC_Config_RegisterTypeWithCStr(config, "ARC_Rect" , (ARC_ConfigType){ sizeof(ARC_Rect) , ARC_ConfigType_RectCopyFn , ARC_ConfigType_RectDestroyFn , NULL }); + ARC_Config_RegisterTypeWithCStr(config, "ARC_FRect" , (ARC_ConfigType){ sizeof(ARC_FRect) , ARC_ConfigType_FRectCopyFn , ARC_ConfigType_FRectDestroyFn , NULL }); } -uint64_t ARC_MathConfig_GetIndexAndErrorCheck(ARC_String *string, char *search, uint64_t searchLength){ - uint64_t separator = ARC_String_FindCString(string, ",", 1); - - if(separator == ~(uint64_t)0){ +void ARC_ConfigType_PointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_NESTED_VALUE){ arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_PointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nestedValue was not passed in for ARC_Point"); + type = NULL; + return; } - return separator; -} + //get the valueArgs + ARC_ParserTagToken *valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 2); -uint8_t ARC_Point_Read(ARC_Config *config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - if(string->data[0] != '{' || string->data[string->length - 1] != '}'){ - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("in ARC_Point_Read(config, string, value); no matching curly braces: %s", string->data); + //if there is only a value with no comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ arc_errno = ARC_ERRNO_DATA; - return 0; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_PointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x } only had one value, point needs two { x, y }"); + return; } - uint64_t separator = ARC_MathConfig_GetIndexAndErrorCheck(string, ",", 1); - if(arc_errno){ - return 0; + //get the first value + ARC_ParserTagToken *valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + int32_t *pointTemp = NULL; + ARC_ConfigType_Int32CopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_PointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), first parameter was not a int32"); + return; } - ARC_String *xString, *yString; - ARC_String_CopySubstring(&xString, string, 1 , separator - 1 ); - ARC_String_CopySubstring(&yString, string, separator + 1, string->length - (separator + 2)); + //copy the xpoint value to stack and free the pointer + int32_t pointX = *pointTemp; + free(pointTemp); + pointTemp = NULL; + //get the second value + valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 4); + + //if there is an empty comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) > 1){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_PointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x, y, ... } had too many values, point needs two { x, y }"); + return; + } + + //get the second value + valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + ARC_ConfigType_Int32CopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_PointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), second parameter was not a int32"); + return; + } + + //copy the last value and free the temp value ARC_Point *point = (ARC_Point *)malloc(sizeof(ARC_Point)); - point->x = (int32_t)ARC_String_ToInt64_t(xString); - point->y = (int32_t)ARC_String_ToInt64_t(yString); + *point = (ARC_Point){ pointX, *pointTemp }; + free(pointTemp); - ARC_String_Destroy(xString); - ARC_String_Destroy(yString); - - *value = point; - return 0; + //set the type value + *type = (void *)point; } -uint8_t ARC_Rect_Read(ARC_Config *config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } +void ARC_ConfigType_PointDestroyFn(ARC_Config *config, void *type){ + free((ARC_Point *)type); +} - if(string->data[0] != '{' || string->data[string->length - 1] != '}'){ +void ARC_ConfigType_FPointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_NESTED_VALUE){ arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("in ARC_Rect_Read(config, string, value); no matching curly braces: %s", string->data); - return 0; - } - - ARC_String *current; - ARC_String_CopySubstring(¤t, string, 1, string->length - 2); - - ARC_String *temp, *tempStripped; - int32_t x, y, w, h; - int64_t separator; - - //x - separator = ARC_MathConfig_GetIndexAndErrorCheck(current, ",", 1); - if(arc_errno){ - return 0; - } - - ARC_String_CopySubstring(&temp, current, 0, separator - 1); - ARC_String_StripEndsWhitespace(&tempStripped, temp); - x = ARC_String_ToInt64_t(tempStripped); - ARC_String_Destroy(temp); - ARC_String_Destroy(tempStripped); - - temp = current; - ARC_String_CopySubstring(¤t, temp, separator + 1, temp->length - (separator + 1)); - ARC_String_Destroy(temp); - - //y - separator = ARC_MathConfig_GetIndexAndErrorCheck(current, ",", 1); - if(arc_errno){ - return 0; - } - - ARC_String_CopySubstring(&temp, current, 0, separator - 1); - ARC_String_StripEndsWhitespace(&tempStripped, temp); - y = ARC_String_ToInt64_t(tempStripped); - ARC_String_Destroy(temp); - ARC_String_Destroy(tempStripped); - - temp = current; - ARC_String_CopySubstring(¤t, temp, separator + 1, temp->length - (separator + 1)); - ARC_String_Destroy(temp); - - //w - separator = ARC_MathConfig_GetIndexAndErrorCheck(current, ",", 1); - if(arc_errno){ - return 0; - } - - ARC_String_CopySubstring(&temp, current, 0, separator - 1); - ARC_String_StripEndsWhitespace(&tempStripped, temp); - w = ARC_String_ToInt64_t(tempStripped); - ARC_String_Destroy(temp); - ARC_String_Destroy(tempStripped); - - temp = current; - ARC_String_CopySubstring(¤t, temp, separator + 1, temp->length - (separator + 1)); - ARC_String_Destroy(temp); - - //h - separator = current->length; - if(arc_errno){ - return 0; - } - - ARC_String_CopySubstring(&temp, current, 0, separator); - ARC_String_StripEndsWhitespace(&tempStripped, temp); - h = ARC_String_ToInt64_t(tempStripped); - ARC_String_Destroy(temp); - ARC_String_Destroy(tempStripped); - ARC_String_Destroy(current); - - *value = malloc(sizeof(ARC_Rect)); - ((ARC_Rect *) *value)->x = x; - ((ARC_Rect *) *value)->y = y; - ((ARC_Rect *) *value)->w = w; - ((ARC_Rect *) *value)->h = h; - return 0; -} - -void ARC_RectArray_ReadRect(ARC_Config* config, ARC_String *stripped, uint64_t index, uint64_t length, uint64_t *arrayIndex, void **value){ - ARC_String *substr, *temp; - ARC_String_CopySubstring(&temp, stripped, index, length); - ARC_String_StripEndsWhitespace(&substr, temp); - ARC_String_Destroy(temp); - - // reading in reference - ARC_Rect *tempRect; - ARC_Config_Get(config, substr, (void **) &tempRect); - if(tempRect){ - ARC_String_Destroy(substr); - - ((ARC_Rect *)((ARC_Array *) *value)->data)[*arrayIndex] = *tempRect; - ++*arrayIndex; - + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FPointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nestedValue was not passed in for ARC_FPoint"); + type = NULL; return; } - //reading in value - ARC_Rect_Read(config, substr, (void **) &tempRect); - if(arc_errno){ - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("in ARC_RectArray_ReadRect(config, string, index, length, arrayIndex, value); failed to read rect: %s", substr->data); - ARC_String_Destroy(substr); + //get the valueArgs + ARC_ParserTagToken *valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 2); + + //if there is only a value with no comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FPointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x } only had one value, fpoint needs two { x, y }"); return; } - ((ARC_Rect *)((ARC_Array *) *value)->data)[*arrayIndex] = *tempRect; - ++*arrayIndex; - - ARC_Rect_Delete(config, substr, (void *)tempRect); - ARC_String_Destroy(substr); -} - -uint8_t ARC_RectArray_Read(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - if(string->data[0] != '{' || string->data[string->length - 1] != '}'){ + //get the first value + ARC_ParserTagToken *valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + float *pointTemp = NULL; + ARC_ConfigType_FloatCopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("in ARC_RectArray_Read(config, string, value); no matching curly braces: %s", string->data); - return 0; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FPointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), first parameter was not a float"); + return; } - ARC_String *temp, *stripped; - ARC_String_CopySubstring(&temp, string, 1, string->length - 2); - ARC_String_StripEndsWhitespace(&stripped, temp); - ARC_String_Destroy(temp); + //copy the xpoint value to stack and free the pointer + float pointX = *pointTemp; + free(pointTemp); + pointTemp = NULL; - uint64_t arraySize = 1; - int64_t encapsulated = 0; - for(uint64_t i = 0; i < stripped->length; i++){ - if(stripped->data[i] == '{'){ - encapsulated++; - continue; - } + //get the second value + valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 4); - if(stripped->data[i] == '}'){ - encapsulated--; - continue; - } - - if(!encapsulated && stripped->data[i] == ','){ - arraySize++; - } - } - - if(encapsulated){ + //if there is an empty comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) > 1){ arc_errno = ARC_ERRNO_DATA; - //TODO: Fix this for windows SMFH - // ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_Read(config, data, subdata, value); after looping encapsulated was %ld", encapsulated); - ARC_String_Destroy(stripped); - return 0; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FPointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x, y, ... } had too many values, fpoint needs two { x, y }"); + return; } - *value = malloc(sizeof(ARC_Array)); - ((ARC_Array *) *value)->data = malloc(sizeof(ARC_Rect) * arraySize); - ((ARC_Array *) *value)->size = arraySize; - - uint64_t index = 0; - arraySize = 0; - encapsulated = 0; - for(uint64_t i = 0; i < stripped->length; i++){ - if(stripped->data[i] == '{'){ - encapsulated++; - continue; - } - - if(stripped->data[i] == '}'){ - encapsulated--; - continue; - } - - if(!encapsulated && stripped->data[i] == ','){ - ARC_RectArray_ReadRect(config, stripped, index, i - index, &arraySize, value); - if(arc_errno){ - return 0; - } - - index = i + 1; - - if(arraySize == ((ARC_Array *) *value)->size){ - break; - } - } + //get the second value + valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + ARC_ConfigType_FloatCopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FPointCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), second parameter was not a float"); + return; } - if(arraySize != ((ARC_Array *) *value)->size){ - ARC_RectArray_ReadRect(config, stripped, index, stripped->length - index, &arraySize, value); + //copy the last value and free the temp value + ARC_FPoint *point = (ARC_FPoint *)malloc(sizeof(ARC_FPoint)); + *point = (ARC_FPoint){ pointX, *pointTemp }; + free(pointTemp); + + //set the type value + *type = (void *)point; +} + +void ARC_ConfigType_FPointDestroyFn(ARC_Config *config, void *type){ + free((ARC_FPoint *)type); +} + +void ARC_ConfigType_RectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_NESTED_VALUE){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_RectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nestedValue was not passed in for ARC_Rect"); + type = NULL; + return; } - ARC_String_Destroy(stripped); - return 0; + + //get the valueArgs + ARC_ParserTagToken *valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 2); + + //if there is only a value with no comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_RectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x } only had one value, rect needs four { x, y, w, h }"); + return; + } + + //get the first value + ARC_ParserTagToken *valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + int32_t *pointTemp = NULL; + ARC_ConfigType_Int32CopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_RectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), first parameter was not a int32"); + return; + } + + //copy the xpoint value to stack and free the pointer + int32_t pointX = *pointTemp; + free(pointTemp); + pointTemp = NULL; + + //get the second value + valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 4); + + //if there is only a value with no comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_RectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x, y } only had two values, rect needs four { x, y, w, h }"); + return; + } + + //get the second value + valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + ARC_ConfigType_Int32CopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_RectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), second parameter was not a int32"); + return; + } + + int32_t pointY = *pointTemp; + free(pointTemp); + pointTemp = NULL; + + //get the third value + valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 4); + + //if there is an empty comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_RectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x, y, w } only had three values, rect needs four { x, y, w, h }"); + return; + } + + //get the third value + valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + ARC_ConfigType_Int32CopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_RectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), third parameter was not a int32"); + return; + } + + int32_t pointW = *pointTemp; + free(pointTemp); + pointTemp = NULL; + + //get the fourth value + valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 4); + + //if there is an empty comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) > 1){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_RectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x, y, w, h, ... } had too many values, rect needs four { x, y, w, h }"); + return; + } + + //get the fourth value + valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + ARC_ConfigType_Int32CopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_RectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), fourth parameter was not a int32"); + return; + } + + //copy the last value and free the temp value + ARC_Rect *point = (ARC_Rect *)malloc(sizeof(ARC_Point)); + *point = (ARC_Rect){ pointX, pointY, pointW, *pointTemp }; + free(pointTemp); + + //set the type value + *type = (void *)point; } -void ARC_Point_Delete(ARC_Config* config, ARC_String *string, void *value){ - free((ARC_Point *)value); +void ARC_ConfigType_RectDestroyFn(ARC_Config *config, void *type){ + free((ARC_Rect *)type); } -void ARC_Rect_Delete(ARC_Config* config, ARC_String *string, void *value){ - free((ARC_Rect *)value); +void ARC_ConfigType_FRectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_NESTED_VALUE){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FRectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nestedValue was not passed in for ARC_FRect"); + type = NULL; + return; + } + + //get the valueArgs + ARC_ParserTagToken *valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 2); + + //if there is only a value with no comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FRectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x } only had one value, frect needs four { x, y, w, h }"); + return; + } + + //get the first value + ARC_ParserTagToken *valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + float *pointTemp = NULL; + ARC_ConfigType_FloatCopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FRectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), first parameter was not a float"); + return; + } + + //copy the xpoint value to stack and free the pointer + float pointX = *pointTemp; + free(pointTemp); + pointTemp = NULL; + + //get the second value + valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 4); + + //if there is only a value with no comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FRectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x, y } only had two values, frect needs four { x, y, w, h }"); + return; + } + + //get the second value + valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + ARC_ConfigType_FloatCopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FRectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), second parameter was not a float"); + return; + } + + float pointY = *pointTemp; + free(pointTemp); + pointTemp = NULL; + + //get the third value + valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 4); + + //if there is an empty comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FRectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x, y, w } only had three values, frect needs four { x, y, w, h }"); + return; + } + + //get the third value + valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + ARC_ConfigType_FloatCopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FRectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), third parameter was not a float"); + return; + } + + float pointW = *pointTemp; + free(pointTemp); + pointTemp = NULL; + + //get the fourth value + valueArgsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 4); + + //if there is an empty comma break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) > 1){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FRectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), nested value { x, y, w, h, ... } had too many values, frect needs four { x, y, w, h }"); + return; + } + + //get the fourth value + valueTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + ARC_ConfigType_FloatCopyFn((void **)&pointTemp, valueTagToken, config, userdata); + if(pointTemp == NULL){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FRectCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), fourth parameter was not a float"); + return; + } + + //copy the last value and free the temp value + ARC_FRect *point = (ARC_FRect *)malloc(sizeof(ARC_FPoint)); + point->x = pointX; + point->y = pointY; + point->w = pointW; + point->h = *pointTemp; + free(pointTemp); + + //set the type value + *type = (void *)point; } -void ARC_RectArray_Delete(ARC_Config* config, ARC_String *string, void *value){ - //TODO free value->data - free((ARC_Array *)value); -} \ No newline at end of file +void ARC_ConfigType_FRectDestroyFn(ARC_Config *config, void *type){ + free((ARC_FRect *)type); +} diff --git a/src/math/point.c b/src/math/point.c index 7e1767c..042aff4 100644 --- a/src/math/point.c +++ b/src/math/point.c @@ -1,8 +1,26 @@ #include "arc/math/point.h" +#include "arc/math/rectangle.h" + ARC_FPoint ARC_FPoint_Lerp(ARC_FPoint *start, ARC_FPoint *end, float t){ return (ARC_FPoint){ (1.0f - t) * start->x + t * end->x, (1.0f - t) * start->y + t * end->y }; -} \ No newline at end of file +} + +void ARC_Point_CenterOn(ARC_Point *point, ARC_Rect bounds){ + *point = (ARC_Point){ + (bounds.w / 2) + bounds.x, + (bounds.h / 2) + bounds.y + }; +} + +void ARC_FPoint_CenterOn(ARC_FPoint *point, ARC_FRect bounds){ + *point = (ARC_FPoint){ + (bounds.w / 2.0f) + bounds.x, + (bounds.h / 2.0f) + bounds.y + }; +} + + diff --git a/src/math/rectangle.c b/src/math/rectangle.c index ce1a3d4..de2d90a 100644 --- a/src/math/rectangle.c +++ b/src/math/rectangle.c @@ -1,66 +1,74 @@ #include "arc/math/rectangle.h" +#include "arc/std/bool.h" -//VERY TEMP -// #include - -void ARC_Rect_CenterOn(ARC_Rect *rect, ARC_Rect *bounds){ - rect->x = (bounds->x + (bounds->w / 2)) - (rect->w / 2); - rect->y = (bounds->y + (bounds->h / 2)) - (rect->h / 2); +void ARC_Rect_CenterOn(ARC_Rect *rect, ARC_Rect bounds){ + rect->x = (bounds.x + (bounds.w / 2)) - (rect->w / 2); + rect->y = (bounds.y + (bounds.h / 2)) - (rect->h / 2); } -void ARC_FRect_CenterOn(ARC_FRect *rect, ARC_FRect *bounds){ - rect->x = (bounds->x + (bounds->w / 2.0f)) - (rect->w / 2.0f); - rect->y = (bounds->y + (bounds->h / 2.0f)) - (rect->h / 2.0f); +void ARC_FRect_CenterOn(ARC_FRect *rect, ARC_FRect bounds){ + rect->x = (bounds.x + (bounds.w / 2.0f)) - (rect->w / 2.0f); + rect->y = (bounds.y + (bounds.h / 2.0f)) - (rect->h / 2.0f); } -ARC_FRect ARC_Rect_CastToFRect(ARC_Rect *rect){ +void ARC_Rect_CenterOnPoint(ARC_Rect *rect, ARC_Point center){ + rect->x = center.x - (rect->w / 2); + rect->y = center.y - (rect->h / 2); +} + +void ARC_FRect_CenterOnPoint(ARC_FRect *rect, ARC_FPoint center){ + rect->x = center.x - (rect->w / 2.0f); + rect->y = center.y - (rect->h / 2.0f); +} + +ARC_FRect ARC_Rect_CastToFRect(ARC_Rect rect){ return (ARC_FRect){ - .x = (float)rect->x, - .y = (float)rect->y, - .w = (float)rect->w, - .h = (float)rect->h, + .x = (float)rect.x, + .y = (float)rect.y, + .w = (float)rect.w, + .h = (float)rect.h, }; } -ARC_Rect ARC_FRect_CastToRect(ARC_FRect *rect){ +ARC_Rect ARC_FRect_CastToRect(ARC_FRect rect){ return (ARC_Rect){ - .x = (int32_t)rect->x, - .y = (int32_t)rect->y, - .w = (int32_t)rect->w, - .h = (int32_t)rect->h, + .x = (int32_t)rect.x, + .y = (int32_t)rect.y, + .w = (int32_t)rect.w, + .h = (int32_t)rect.h, }; } -int32_t ARC_Rect_Intersects(ARC_Rect *rect1, ARC_Rect *rect2){ - if(rect1->x <= rect2->x + rect2->w && rect1->x + rect1->w >= rect2->x && - rect1->y <= rect2->y + rect2->h && rect1->y + rect1->h >= rect2->y){ - return 1; +ARC_Bool ARC_Rect_Intersects(ARC_Rect rect1, ARC_Rect rect2){ + if(rect1.x <= rect2.x + rect2.w && rect1.x + rect1.w >= rect2.x && + rect1.y <= rect2.y + rect2.h && rect1.y + rect1.h >= rect2.y){ + return ARC_True; } - return 0; + return ARC_False; } -int32_t ARC_FRect_Intersects(ARC_FRect *rect1, ARC_FRect *rect2){ - if(rect1->x <= rect2->x + rect2->w && rect1->x + rect1->w >= rect2->x && - rect1->y <= rect2->y + rect2->h && rect1->y + rect1->h >= rect2->y){ - return 1; +ARC_Bool ARC_FRect_Intersects(ARC_FRect rect1, ARC_FRect rect2){ + if(rect1.x <= rect2.x + rect2.w && rect1.x + rect1.w >= rect2.x && + rect1.y <= rect2.y + rect2.h && rect1.y + rect1.h >= rect2.y){ + return ARC_True; } - return 0; + return ARC_False; } -int32_t ARC_Rect_IntersectsPoint(ARC_Rect *rect, ARC_Point *point){ - if(rect->x <= point->x && rect->x + rect->w >= point->x && - rect->y <= point->y && rect->y + rect->h >= point->y){ - return 1; +ARC_Bool ARC_Rect_IntersectsPoint(ARC_Rect rect, ARC_Point point){ + if(rect.x <= point.x && rect.x + rect.w >= point.x && + rect.y <= point.y && rect.y + rect.h >= point.y){ + return ARC_True; } - return 0; + return ARC_False; } -int32_t ARC_FRect_IntersectsPoint(ARC_FRect *rect, ARC_Point *point){ - if(rect->x <= point->x && rect->x + rect->w >= point->x && - rect->y <= point->y && rect->y + rect->h >= point->y){ - return 1; +ARC_Bool ARC_FRect_IntersectsPoint(ARC_FRect rect, ARC_Point point){ + if(rect.x <= point.x && rect.x + rect.w >= point.x && + rect.y <= point.y && rect.y + rect.h >= point.y){ + return ARC_True; } - return 0; + return ARC_False; } int32_t ARC_Rect_LineIntersects(ARC_Rect *rect, int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2){ @@ -80,19 +88,19 @@ void ARC_FRect_CollideAndSlide(ARC_FRect *rect, ARC_Vector2 *velocity, ARC_FRect }; //there is no collision, return - if(!ARC_FRect_Intersects(&nextRectPosition, wall)){ + if(!ARC_FRect_Intersects(nextRectPosition, *wall)){ return; } nextRectPosition.x = rect->x + velocity->x; nextRectPosition.y = rect->y; - if(ARC_FRect_Intersects(&nextRectPosition, wall)){ + if(ARC_FRect_Intersects(nextRectPosition, *wall)){ velocity->x = 0; } nextRectPosition.x = rect->x; nextRectPosition.y = rect->y + velocity->y; - if(ARC_FRect_Intersects(&nextRectPosition, wall)){ + if(ARC_FRect_Intersects(nextRectPosition, *wall)){ velocity->y = 0; } -} \ No newline at end of file +} diff --git a/src/math/vector2.c b/src/math/vector2.c index a825903..aa80684 100644 --- a/src/math/vector2.c +++ b/src/math/vector2.c @@ -15,4 +15,16 @@ void ARC_Vector2_RotateDegree(ARC_Vector2 *vector, float angle){ ARC_Vector2 temp = *vector; vector->x = (temp.x * cos(angle)) - (temp.y * sin(angle)); vector->y = (temp.x * sin(angle)) + (temp.y * cos(angle)); -} \ No newline at end of file +} + +float ARC_Vector2_CrossProduct(ARC_Vector2 vector1, ARC_Vector2 vector2){ + return (vector1.x * vector2.y) - (vector1.y * vector2.x); +} + +ARC_Vector2 ARC_Vector2_CrossProductScalar(ARC_Vector2 vector, float scalar){ + return (ARC_Vector2){ scalar * vector.y, -scalar * vector.x }; +} + +ARC_Vector2 ARC_Vector2_ScalarCrossProduct(float scalar, ARC_Vector2 vector){ + return (ARC_Vector2){ -scalar * vector.y, scalar * vector.x }; +} diff --git a/src/std/config.c b/src/std/config.c index f27b340..6e1d2e3 100644 --- a/src/std/config.c +++ b/src/std/config.c @@ -1,9 +1,13 @@ #include "arc/std/config.h" -#include "arc/std/parser/helpers.h" + +#include "arc/std/array.h" #include "arc/std/bool.h" #include "arc/std/errno.h" #include "arc/std/hashtable.h" #include "arc/std/parser.h" +#include "arc/std/vector.h" +#include "arc/std/parser/helpers.h" +#include "arc/std/vector/inline.h" #include #include #include @@ -21,6 +25,7 @@ struct ARC_Config { }; typedef struct ARC_ConfigTypeData { + ARC_Config *config; void *data; ARC_ConfigType_DestroyFn destroyFn; } ARC_ConfigTypeData; @@ -229,6 +234,9 @@ uint32_t ARC_Config_GetStringIdFn(ARC_String *string){ if(ARC_String_EqualsCStringWithStrlen(string, "")){ return ARC_CONFIG_VALUE_ARGS; } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_CONFIG_ARRAY; + } if(ARC_String_EqualsCStringWithStrlen(string, "")){ return ARC_CONFIG_VARIABLE; } @@ -250,6 +258,9 @@ uint32_t ARC_Config_GetStringIdFn(ARC_String *string){ if(ARC_String_EqualsCStringWithStrlen(string, "")){ return ARC_CONFIG_ESCAPE_CHAR; } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_CONFIG_FLOAT; + } if(ARC_String_EqualsCStringWithStrlen(string, "")){ return ARC_CONFIG_NUMBER_SIGN; } @@ -259,7 +270,24 @@ uint32_t ARC_Config_GetStringIdFn(ARC_String *string){ if(ARC_String_EqualsCStringWithStrlen(string, "")){ return ARC_CONFIG_WHITESPACE; } - + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_CONFIG_COMMENT; + } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_CONFIG_LINE_COMMENT; + } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_CONFIG_MULTI_LINE_COMMENT; + } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_CONFIG_LINE_CHARS; + } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_CONFIG_MULTI_LINE_CHARS; + } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_CONFIG_COMMENT_CHAR; + } return ~(uint32_t)0; } @@ -285,11 +313,15 @@ void ARC_Config_GroupDataHashtableDestroyKeyValueFn(void *key, void *value){ free((char *)key); ARC_ConfigTypeData *typeData = (ARC_ConfigTypeData *)value; - typeData->destroyFn(typeData->data); + typeData->destroyFn(typeData->config, typeData->data); free(typeData); } -// -> EQUAL SEMICOLON +//private empty function to avoid removing references or data freed from an array +void ARC_ConfigType_EmptyDestroyFn(ARC_Config *config, void *type){ +} + +// -> EQUAL SEMICOLON void ARC_ConfigData_RunVariableLineTag(ARC_ParserTagToken *tagToken, ARC_Config *config){ //skip whitespace and check for group name ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 1); @@ -318,8 +350,27 @@ void ARC_ConfigData_RunVariableLineTag(ARC_ParserTagToken *tagToken, ARC_Config ARC_String_Create(&variableString, NULL, 0); ARC_ParserData_HelperRecurseStringAdd(&variableString, childTagToken); + //check if the value is an array + childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 5); + ARC_Bool isArray = (ARC_Bool)(ARC_Vector_GetSize(childTagToken->tagTokens) != 0); + //check if removing if(config->load == ARC_False){ + if(isArray == ARC_True){ + ARC_ConfigTypeData *removingType = ARC_Hashtable_Get(config->currentGroup, (void *)variableString->data); + ARC_Array *array = (ARC_Array *)removingType->data; + + for(uint32_t index = 0; index < array->size; index++){ + removingType->destroyFn(config, array->data + index); + } + + removingType->destroyFn = ARC_ConfigType_EmptyDestroyFn; + free(array->data); + free(array); + ARC_Hashtable_Remove(config->currentGroup, (void *)variableString->data); + return; + } + ARC_Hashtable_Remove(config->currentGroup, (void *)variableString->data); ARC_String_Destroy(variableString); return; @@ -342,7 +393,7 @@ void ARC_ConfigData_RunVariableLineTag(ARC_ParserTagToken *tagToken, ARC_Config ARC_String_Destroy(variableString); //get - childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 7); + childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 9); //check if is a reference ARC_String *valueString; @@ -353,20 +404,79 @@ void ARC_ConfigData_RunVariableLineTag(ARC_ParserTagToken *tagToken, ARC_Config //create where to store either the reference or type data typeData = (ARC_ConfigTypeData *)malloc(sizeof(ARC_ConfigTypeData)); + typeData->config = config; if(value != NULL){ //point to the already stored data typeData->data = value; - typeData->destroyFn = NULL; + typeData->destroyFn = ARC_ConfigType_EmptyDestroyFn; //add to the current group hashtable ARC_Hashtable_Add(config->currentGroup, (void *)nameVariableCStr, (void *)typeData); return; } - //passed the parsed value into the copy type function and set the destroy function - type->copyFn(&(typeData->data), childTagToken, config); + //set the type's destroy function typeData->destroyFn = type->destroyFn; + //if the value is an array loop through all the nested value's args + if(isArray == ARC_True){ + ARC_ParserTagToken *nestedValueTagToken = ARC_Vector_Get(childTagToken->tagTokens, 0); + if(nestedValueTagToken->id != ARC_CONFIG_NESTED_VALUE){ + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigData_RunVariableLineTag(tagToken, config), variable \"%s\" was set to be an array but did not pass in a nested value { ... }", nameVariableCStr); + return; + } + + // -> OPEN_CURLY_BRACE CLOSE_CURLY_BRACE + ARC_ParserTagToken *valueArgsTagToken = ARC_Vector_Get(nestedValueTagToken->tagTokens, 2); + + //create a temporary vector to read in the array + ARC_VectorInline *typeVector; + ARC_VectorInline_Create(&typeVector, type->size, NULL, NULL); + + // -> COMMA | + while(valueArgsTagToken->id == ARC_CONFIG_VALUE_ARGS){ + ARC_ParserTagToken *valueTagToken = ARC_Vector_Get(valueArgsTagToken->tagTokens, 0); + + //copy the type and store it in the vector + void *typeData = NULL; + type->copyFn(&typeData, valueTagToken, config, type->userdata); + ARC_VectorInline_Add(typeVector, typeData); + + //if this value args was the last one break + if(ARC_Vector_GetSize(valueArgsTagToken->tagTokens) == 1){ + break; + } + + //get the next valueArgs + valueArgsTagToken = ARC_Vector_Get(valueArgsTagToken->tagTokens, 4); + } + + //copy the data in an ARC_Array + ARC_Array typeVectorArray = ARC_VectorInline_GetData(typeVector); + ARC_Array *array = (ARC_Array *)malloc(sizeof(ARC_Array)); + array->size = typeVectorArray.size; + array->data = NULL; + + if(typeVectorArray.size != 0){ + //copy the vector into the array's data + array->data = (void *)malloc(type->size * typeVectorArray.size); + memcpy(array->data, typeVectorArray.data, type->size * typeVectorArray.size); + } + + //set the type data as an array + typeData->data = array; + + //add the array to the group hashtable + ARC_Hashtable_Add(config->currentGroup, (void *)nameVariableCStr, (void *)typeData); + + //cleanup + ARC_VectorInline_Destroy(typeVector); + return; + } + + //passed the parsed value into the copy type function and set the destroy function + type->copyFn(&(typeData->data), childTagToken, config, type->userdata); + //add to the current group hashtable ARC_Hashtable_Add(config->currentGroup, (void *)nameVariableCStr, (void *)typeData); } @@ -526,7 +636,7 @@ void ARC_ConfigData_RunLanguageTag(ARC_ParserTagToken *tagToken, ARC_Config *con } continue; - //this is for whitespace and any oddities + //this is for whitespace, comments, and any oddities default: continue; } @@ -553,34 +663,43 @@ void ARC_Config_Create(ARC_Config **config){ /* ~ define the language as a string ~ */ char *languageCString = - " -> | | \n" + " -> | | \n" - " -> OPEN_CURLY_BRACE CLOSE_CURLY_BRACE\n" - " -> \n" - " -> | LAMBDA\n" + " -> OPEN_CURLY_BRACE CLOSE_CURLY_BRACE\n" + " -> \n" + " -> | LAMBDA\n" - " -> | \n" - " -> EQUAL SEMICOLON\n" - " -> SPACE | TAB | LAMBDA\n" + " -> | | \n" + " -> EQUAL SEMICOLON\n" + " -> SPACE | TAB | LAMBDA\n" - " -> \n" - " -> | | | \n" - " -> OPEN_CURLY_BRACE CLOSE_CURLY_BRACE\n" - " -> COMMA | \n" + " -> | \n" + " -> | | | | \n" + " -> OPEN_CURLY_BRACE CLOSE_CURLY_BRACE\n" + " -> COMMA | \n" - " -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE \n" - " -> | LAMBDA\n" - " -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE | NUMBER\n" + " -> OPEN_BRACKET CLOSE_BRACKET | LAMBDA\n" + " -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE \n" + " -> | LAMBDA\n" + " -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE | NUMBER\n" - " -> QUOTE QUOTE\n" - " -> | | LAMBDA\n" - " -> TAB | SPACE | BANG | HASH | DOLLAR | PERCENT | AMPERSAND | SINGLE_QUOTE | OPEN_PAREN | CLOSE_PAREN | ASTERISK | PLUS | COMMA | MINUS | PERIOD | SLASH | NUMBER | COLON | SEMICOLON | LESS_THAN | GREATER_THAN | EQUAL | QUESTION_MARK | AT | ALPHA_UPPER_CHAR | OPEN_BRACKET | CLOSE_BRACKET | CARET | UNDERSCORE | GRAVE | ALPHA_LOWER_CHAR | OPEN_CURLY_BRACE | VERTICAL_LINE | CLOSE_CURLY_BRACE | TILDE\n" - " -> BACKSLASH BACKSLASH | BACKSLASH QUOTE | BACKSLASH ALPHA_UPPER_CHAR | BACKSLASH ALPHA_LOWER_CHAR\n" + " -> QUOTE QUOTE\n" + " -> | | LAMBDA\n" + " -> TAB | SPACE | BANG | HASH | DOLLAR | PERCENT | AMPERSAND | SINGLE_QUOTE | OPEN_PAREN | CLOSE_PAREN | ASTERISK | PLUS | COMMA | MINUS | PERIOD | SLASH | NUMBER | COLON | SEMICOLON | LESS_THAN | GREATER_THAN | EQUAL | QUESTION_MARK | AT | ALPHA_UPPER_CHAR | OPEN_BRACKET | CLOSE_BRACKET | CARET | UNDERSCORE | GRAVE | ALPHA_LOWER_CHAR | OPEN_CURLY_BRACE | VERTICAL_LINE | CLOSE_CURLY_BRACE | TILDE\n" + " -> BACKSLASH BACKSLASH | BACKSLASH QUOTE | BACKSLASH ALPHA_UPPER_CHAR | BACKSLASH ALPHA_LOWER_CHAR\n" - " -> MINUS | \n" - " -> NUMBER | NUMBER\n" + " -> PERIOD | PERIOD | PERIOD \n" + " -> MINUS | \n" + " -> NUMBER | NUMBER\n" - " -> SPACE | TAB | NEWLINE | LAMBDA\n"; + " -> SPACE | TAB | NEWLINE | LAMBDA\n" + + " -> | \n" + " -> SLASH SLASH NEWLINE\n" + " -> SLASH ASTERISK \n" + " -> | LAMBDA\n" + " -> ASTERISK SLASH | NEWLINE | \n" + " -> TAB | SPACE | BANG | QUOTE | HASH | DOLLAR | PERCENT | AMPERSAND | SINGLE_QUOTE | OPEN_PAREN | CLOSE_PAREN | ASTERISK | PLUS | COMMA | MINUS | PERIOD | SLASH | NUMBER | COLON | SEMICOLON | LESS_THAN | GREATER_THAN | EQUAL | QUESTION_MARK | AT | ALPHA_UPPER_CHAR | OPEN_BRACKET | BACKSLASH | CLOSE_BRACKET | CARET | UNDERSCORE | GRAVE | ALPHA_LOWER_CHAR | OPEN_CURLY_BRACE | VERTICAL_LINE | CLOSE_CURLY_BRACE | TILDE\n"; /* ~ define the language as a string ~ */ ARC_String *languageString; @@ -654,6 +773,171 @@ void ARC_Config_RegisterTypeWithCStr(ARC_Config *config, const char *typeNameCSt ARC_Hashtable_Add(config->types, typeNameCopy, typeCopy); } +void ARC_Config_Add(ARC_Config *config, ARC_String *type, ARC_String *name, void *value){ + //check if type exists in the types hashtable + ARC_ConfigType *typeValue = (ARC_ConfigType *)ARC_Hashtable_Get(config->types, name->data); + if(typeValue == NULL){ + //throw an error and return + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Config_Add(config, type, name, value), type \"%s\" was not registered to config", type->data); + return; + } + + //check if the group separator exists + uint64_t startSeparatorIndex = ARC_String_FindCStringWithStrlen(name, ARC_CONFIG_GROUP_SEPARATOR); + if(startSeparatorIndex == ~(uint64_t)0){ + //check to see if the current variable is already in the current group hashtable + ARC_ConfigTypeData *typeData = (ARC_ConfigTypeData *)ARC_Hashtable_Get(config->currentGroup, name->data); + if(typeData != NULL){ + //there is already a value so throw an error and return + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigData_RunVariableLineTag(tagToken, config), variable \"%s\" already registered to the current group", name->data); + return; + } + + //create where to store either the type data + typeData = (ARC_ConfigTypeData *)malloc(sizeof(ARC_ConfigTypeData)); + typeData->destroyFn = typeValue->destroyFn; + typeData->data = value; + + //copy the name into a cstring that will be stored in the hashtable + char *nameVariableCStr = malloc(sizeof(char) * (name->length + 1)); + strncpy(nameVariableCStr, name->data, name->length); + nameVariableCStr[name->length] = '\0'; + + //add to the current group hashtable + ARC_Hashtable_Add(config->currentGroup, (void *)nameVariableCStr, (void *)typeData); + return; + } + + //reset the group the the default group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)ARC_CONFIG_DEFAULT_GROUP); + + if(startSeparatorIndex != 0){ + //get the group + startSeparatorIndex--; + ARC_String *groupString; + ARC_String_CopySubstring(&groupString, name, 0, startSeparatorIndex); + + //set the group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)groupString->data); + + //cleanup + ARC_String_Destroy(groupString); + } + + //get the name + ARC_String *nameString; + startSeparatorIndex += strlen(ARC_CONFIG_GROUP_SEPARATOR); + ARC_String_CopySubstring(&nameString, name, startSeparatorIndex, name->length - startSeparatorIndex); + + //check to see if the current variable is already in the current group hashtable + ARC_ConfigTypeData *typeData = (ARC_ConfigTypeData *)ARC_Hashtable_Get(config->currentGroup, nameString->data); + if(typeData != NULL){ + //there is already a value so throw an error and return + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigData_RunVariableLineTag(tagToken, config), variable \"%s\" already registered to the current group", name->data); + return; + } + + //create where to store either the type data + typeData = (ARC_ConfigTypeData *)malloc(sizeof(ARC_ConfigTypeData)); + typeData->destroyFn = typeValue->destroyFn; + typeData->data = value; + + //copy the name into a cstring that will be stored in the hashtable + char *nameVariableCStr = malloc(sizeof(char) * (name->length + 1)); + strncpy(nameVariableCStr, name->data, name->length); + nameVariableCStr[name->length] = '\0'; + + //add to the current group hashtable + ARC_Hashtable_Add(config->currentGroup, (void *)nameVariableCStr, (void *)typeData); +} + +void ARC_Config_AddWithCStr(ARC_Config *config, const char *type, const char *name, void *value){ + //create and copy strings + ARC_String *typeString; + ARC_String *nameString; + ARC_String_CreateWithStrlen(&typeString, (char *)type); + ARC_String_CreateWithStrlen(&nameString, (char *)name); + + //add as an ARC_String + ARC_Config_Add(config, typeString, nameString, value); + + //cleanup + ARC_String_Destroy(nameString); + ARC_String_Destroy(typeString); +} + +void ARC_Config_Remove(ARC_Config *config, ARC_String *name, ARC_Bool isArray){ + //check if the group separator exists + uint64_t startSeparatorIndex = ARC_String_FindCStringWithStrlen(name, ARC_CONFIG_GROUP_SEPARATOR); + if(startSeparatorIndex == ~(uint64_t)0){ + //remove the value from the hashtable if it exists + ARC_ConfigTypeData *typeData = (ARC_ConfigTypeData *)ARC_Hashtable_Get(config->currentGroup, (void *)name->data); + if(typeData == NULL){ + return; + } + + //clean up the values in the array + if(isArray == ARC_True){ + ARC_Array *array = (ARC_Array *)typeData->data; + + for(uint32_t index = 0; index < array->size; index++){ + typeData->destroyFn(config, array->data + index); + } + + typeData->destroyFn = ARC_ConfigType_EmptyDestroyFn; + + free(array); + } + + //remove the value + ARC_Hashtable_Remove(config->currentGroup, (void *)name->data); + return; + } + + //reset the group the the default group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)ARC_CONFIG_DEFAULT_GROUP); + + if(startSeparatorIndex != 0){ + //get the group + startSeparatorIndex--; + ARC_String *groupString; + ARC_String_CopySubstring(&groupString, name, 0, startSeparatorIndex); + + //set the group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)groupString->data); + + //cleanup + ARC_String_Destroy(groupString); + } + + //get the name + ARC_String *nameString; + startSeparatorIndex += strlen(ARC_CONFIG_GROUP_SEPARATOR); + ARC_String_CopySubstring(&nameString, name, startSeparatorIndex, name->length - startSeparatorIndex); + + //remove the value from the hashtable if it exists + ARC_ConfigTypeData *typeData = (ARC_ConfigTypeData *)ARC_Hashtable_Get(config->currentGroup, (void *)name->data); + if(typeData != NULL){ + ARC_Hashtable_Remove(config->currentGroup, (void *)name->data); + } + ARC_String_Destroy(nameString); +} + +void ARC_Config_RemoveWithCStr(ARC_Config *config, const char *name, ARC_Bool isArray){ + //create and copy strings + ARC_String *nameString; + ARC_String_CreateWithStrlen(&nameString, (char *)name); + + //add as an ARC_String + ARC_Config_Remove(config, nameString, isArray); + + //cleanup + ARC_String_Destroy(nameString); +} + void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupName){ ARC_Config_SetGroupWithCStr(config, groupName->data); } @@ -677,9 +961,6 @@ void *ARC_Config_Get(ARC_Config *config, ARC_String *name){ //check if the group separator exists uint64_t startSeparatorIndex = ARC_String_FindCStringWithStrlen(name, ARC_CONFIG_GROUP_SEPARATOR); if(startSeparatorIndex == ~(uint64_t)0){ - //use empty group - config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)ARC_CONFIG_DEFAULT_GROUP); - //get the typeData and pass back the data without the cleanup function ARC_ConfigTypeData *typeData = (ARC_ConfigTypeData *)ARC_Hashtable_Get(config->currentGroup, (void *)name->data); if(typeData == NULL){ @@ -689,16 +970,21 @@ void *ARC_Config_Get(ARC_Config *config, ARC_String *name){ return typeData->data; } - //get the group - startSeparatorIndex--; - ARC_String *groupString; - ARC_String_CopySubstring(&groupString, name, 0, startSeparatorIndex); + //reset the group the the default group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)ARC_CONFIG_DEFAULT_GROUP); - //set the group - config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)groupString->data); + if(startSeparatorIndex != 0){ + //get the group + startSeparatorIndex--; + ARC_String *groupString; + ARC_String_CopySubstring(&groupString, name, 0, startSeparatorIndex); - //cleanup - ARC_String_Destroy(groupString); + //set the group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)groupString->data); + + //cleanup + ARC_String_Destroy(groupString); + } //get the name ARC_String *nameString; @@ -739,6 +1025,17 @@ void ARC_Config_LoadFromFile(ARC_Config *config, ARC_String *path){ ARC_Parser_ParseFile(config->parser, path); } +void ARC_Config_LoadFromFileWithCStr(ARC_Config *config, const char *path){ + config->load = ARC_True; + + ARC_String *pathString; + ARC_String_CreateWithStrlen(&pathString, (char *)path); + + ARC_Parser_ParseFile(config->parser, pathString); + + ARC_String_Destroy(pathString); +} + void ARC_Config_UnloadFromString(ARC_Config *config, ARC_String **string){ config->load = ARC_False; ARC_Parser_Parse(config->parser, string); @@ -749,3 +1046,402 @@ void ARC_Config_UnloadFromFile(ARC_Config *config, ARC_String *path){ ARC_Parser_ParseFile(config->parser, path); } +void ARC_Config_UnloadFromFileWithCStr(ARC_Config *config, const char *path){ + config->load = ARC_False; + + ARC_String *pathString; + ARC_String_CreateWithStrlen(&pathString, (char *)path); + + ARC_Parser_ParseFile(config->parser, pathString); + + ARC_String_Destroy(pathString); +} + +void ARC_Config_InitStd(ARC_Config *config){ + ARC_Config_RegisterTypeWithCStr(config, "bool" , (ARC_ConfigType){ sizeof(ARC_Bool) , ARC_ConfigType_BoolCopyFn , ARC_ConfigType_BoolDestroyFn , NULL }); + ARC_Config_RegisterTypeWithCStr(config, "int8" , (ARC_ConfigType){ sizeof(int8_t) , ARC_ConfigType_Int8CopyFn , ARC_ConfigType_Int8DestroyFn , NULL }); + ARC_Config_RegisterTypeWithCStr(config, "uint8" , (ARC_ConfigType){ sizeof(uint8_t) , ARC_ConfigType_Uint8CopyFn , ARC_ConfigType_Uint8DestroyFn , NULL }); + ARC_Config_RegisterTypeWithCStr(config, "int16" , (ARC_ConfigType){ sizeof(int16_t) , ARC_ConfigType_Int16CopyFn , ARC_ConfigType_Int16DestroyFn , NULL }); + ARC_Config_RegisterTypeWithCStr(config, "uint16" , (ARC_ConfigType){ sizeof(uint16_t) , ARC_ConfigType_Uint16CopyFn, ARC_ConfigType_Uint16DestroyFn, NULL }); + ARC_Config_RegisterTypeWithCStr(config, "int32" , (ARC_ConfigType){ sizeof(int32_t) , ARC_ConfigType_Int32CopyFn , ARC_ConfigType_Int32DestroyFn , NULL }); + ARC_Config_RegisterTypeWithCStr(config, "uint32" , (ARC_ConfigType){ sizeof(uint32_t) , ARC_ConfigType_Uint32CopyFn, ARC_ConfigType_Uint32DestroyFn, NULL }); + ARC_Config_RegisterTypeWithCStr(config, "int64" , (ARC_ConfigType){ sizeof(int64_t) , ARC_ConfigType_Int64CopyFn , ARC_ConfigType_Int64DestroyFn , NULL }); + ARC_Config_RegisterTypeWithCStr(config, "uint64" , (ARC_ConfigType){ sizeof(uint64_t) , ARC_ConfigType_Uint64CopyFn, ARC_ConfigType_Uint64DestroyFn, NULL }); + ARC_Config_RegisterTypeWithCStr(config, "float" , (ARC_ConfigType){ sizeof(float) , ARC_ConfigType_FloatCopyFn , ARC_ConfigType_FloatDestroyFn , NULL }); + ARC_Config_RegisterTypeWithCStr(config, "double" , (ARC_ConfigType){ sizeof(double) , ARC_ConfigType_DoubleCopyFn, ARC_ConfigType_DoubleDestroyFn, NULL }); + ARC_Config_RegisterTypeWithCStr(config, "ARC_String", (ARC_ConfigType){ sizeof(ARC_String), ARC_ConfigType_StringCopyFn, ARC_ConfigType_StringDestroyFn, NULL }); +} + +void ARC_ConfigType_BoolCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + //go into the tag + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_VARIABLE){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_BoolCopyFn(type, parsedData, config, userdata), parsed data was not a "); + *type = NULL; + return; + } + + //get the value as a string + ARC_String *value; + ARC_String_Create(&value, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&value, childTagToken); + + if(ARC_String_EqualsCStringWithStrlen(value, "true") == ARC_True){ + ARC_Bool *boolValue = (ARC_Bool *)malloc(sizeof(ARC_Bool)); + *boolValue = ARC_True; + ARC_String_Destroy(value); + + *type = boolValue; + return; + } + + if(ARC_String_EqualsCStringWithStrlen(value, "false") == ARC_True){ + ARC_Bool *boolValue = (ARC_Bool *)malloc(sizeof(ARC_Bool)); + *boolValue = ARC_False; + ARC_String_Destroy(value); + + *type = boolValue; + return; + } + + //error if true or false was not passed in + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_BoolCopyFn(type, parsedData, config, userdata), bool can only be \"true\" or \"false\" but was given \"%s\"", value->data); + ARC_String_Destroy(value); + *type = NULL; +} + +void ARC_ConfigType_BoolDestroyFn(ARC_Config *config, void *type){ + free((ARC_Bool *)type); +} + +//private function to make checking ints much easier +void ARC_ConfigType_IntNumberHelperCopyFn(void **type, ARC_ParserTagToken *parsedData, uint64_t maxSize){ + //go into the tag + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, maxSize), parsed data was not a "); + *type = NULL; + return; + } + + //get the max positive size + uint64_t maxPositiveSize = maxSize / 2; + + //set the max size to its max for positive or negative + int64_t maxSignSize = maxSize / 2; + if(childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ + maxSize *= 1; + maxSize--; + } + + //check if the first tag is a minus sign and create a string starting with that if it is + childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 0); + ARC_String *intString; + ARC_String_Create(&intString, NULL, 0); + + //get the number as a string + ARC_ParserData_HelperRecurseStringAdd(&intString, parsedData); + + //TODO: check that this gives the right number + //get the length of the max size + uint32_t maxSizeLength = 0; + for(uint32_t size = maxPositiveSize; 0 < size; size /= 10){ + maxSizeLength++; + } + + if(childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ + maxSizeLength++; + } + + //if the string is bigger than the possible size return NULL and error + if(intString->length > maxSizeLength){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, maxSize), size \"%s\" was bigger or smaller than than the max %lu or min %lu", intString->data, maxPositiveSize, (maxPositiveSize * -1) - 1); + *type = NULL; + ARC_String_Destroy(intString); + return; + } + + if(intString->length == maxSize){ + //the max size of a uint64 is -9,223,372,036,854,775,808 so 20 will be big enough for the size + char maxintCStr[20]; + sprintf(maxintCStr, "%ld", maxSignSize); + printf("value %s\n", maxintCStr); + + //check that the number is less than the max + int8_t stringIndex = maxSize; + for(int8_t index = maxSize + 1; index >= 0; index--, stringIndex--){ + if(intString->data[stringIndex] > maxintCStr[index]){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, maxSize), size \"%s\" was bigger than the max of the signed value %lu", intString->data, maxSize); + *type = NULL; + ARC_String_Destroy(intString); + return; + } + + //if the number is smaller it is safe to stop checking + if(intString->data[stringIndex] < maxintCStr[index]){ + break; + } + } + } + + //copy the int value + *type = malloc(maxSizeLength); + uint64_t valueAsUint64 = ARC_String_ToInt64_t(intString); + memcpy(*type, &valueAsUint64, maxSizeLength); + + //cleanup + ARC_String_Destroy(intString); +} + +//private function to make checking uints much easier +void ARC_ConfigType_UintNumberHelperCopyFn(void **type, ARC_ParserTagToken *parsedData, uint64_t maxSize){ + //go into the tag + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, maxSize), parsed data was not a "); + *type = NULL; + return; + } + + if(childTagToken->id == ARC_CONFIG_MINUS){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, maxSize), parsed data had a minus sign, uint numbers must be positive"); + *type = NULL; + return; + } + + //check if the first tag is a minus sign and create a string starting with that if it is + childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 0); + ARC_String *uintString; + ARC_String_Create(&uintString, NULL, 0); + + //get the number as a string + ARC_ParserData_HelperRecurseStringAdd(&uintString, parsedData); + + //TODO: check that this gives the right number + //get the length of the max size + uint32_t maxSizeLength = 0; + for(uint32_t size = maxSize; 0 < size; size /= 10){ + maxSizeLength++; + } + + //if the string is bigger than the possible size return NULL and error + if(uintString->length > maxSizeLength){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, maxSize), size \"%s\" was bigger than the max %lu", uintString->data, maxSize); + *type = NULL; + ARC_String_Destroy(uintString); + return; + } + + if(uintString->length == maxSize){ + //the max size of a uint64 is 8,446,744,073,709,551,615 so 20 will be big enough for the size + char maxuintCStr[20]; + sprintf(maxuintCStr, "%lu", maxSize); + + //check that the number is less than the max + int8_t stringIndex = maxSize; + for(int8_t index = maxSize + 1; index >= 0; index--, stringIndex--){ + if(uintString->data[stringIndex] > maxuintCStr[index]){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, maxSize), size \"%s\" was bigger than the max %lu", uintString->data, maxSize); + *type = NULL; + ARC_String_Destroy(uintString); + return; + } + + //if the number is smaller it is safe to stop checking + if(uintString->data[stringIndex] < maxuintCStr[index]){ + break; + } + } + } + + //copy the int value + *type = malloc(maxSizeLength); + uint64_t valueAsUint64 = ARC_String_ToUint64_t(uintString); + memcpy(*type, &valueAsUint64, maxSizeLength); + + //cleanup + ARC_String_Destroy(uintString); +} + +void ARC_ConfigType_Int8CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, ~(uint8_t)0); +} + +void ARC_ConfigType_Int8DestroyFn(ARC_Config *config, void *type){ + free((int8_t *)type); +} + +void ARC_ConfigType_Uint8CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, ~(uint8_t)0); +} + +void ARC_ConfigType_Uint8DestroyFn(ARC_Config *config, void *type){ + free((uint8_t *)type); +} + +void ARC_ConfigType_Int16CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, ~(uint16_t)0); +} + +void ARC_ConfigType_Int16DestroyFn(ARC_Config *config, void *type){ + free((int16_t *)type); +} + +void ARC_ConfigType_Uint16CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, ~(uint16_t)0); +} + +void ARC_ConfigType_Uint16DestroyFn(ARC_Config *config, void *type){ + free((uint16_t *)type); +} + +void ARC_ConfigType_Int32CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, ~(uint32_t)0); +} + +void ARC_ConfigType_Int32DestroyFn(ARC_Config *config, void *type){ + free((int32_t *)type); +} + +void ARC_ConfigType_Uint32CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, ~(uint32_t)0); +} + +void ARC_ConfigType_Uint32DestroyFn(ARC_Config *config, void *type){ + free((uint32_t *)type); +} + +void ARC_ConfigType_Int64CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, ~(uint64_t)0); +} + +void ARC_ConfigType_Int64DestroyFn(ARC_Config *config, void *type){ + free((int64_t *)type); +} + +void ARC_ConfigType_Uint64CopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, ~(uint64_t)0); +} + +void ARC_ConfigType_Uint64DestroyFn(ARC_Config *config, void *type){ + free((uint64_t *)type); +} + +void ARC_ConfigType_FloatCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + //go into the tag + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_FLOAT && childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FloatCopyFn(type, parsedData, config, userdata), parsed data was not a or "); + *type = NULL; + return; + } + + //get the float as a string + ARC_String *floatString; + ARC_String_Create(&floatString, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&floatString, parsedData); + + //get the value as a float + char *endptr; + float value = strtof(floatString->data, &endptr); + + //error check + if(floatString->data == endptr){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_FloatCopyFn(type, parsedData, config, userdata), parsed data \"%s\" was not a or ", floatString->data); + + //cleanup + ARC_String_Destroy(floatString); + + //set the type to NULL + *type = NULL; + return; + } + + //cleanup + ARC_String_Destroy(floatString); + + //copy the value into a new double, then pass it out through type + float *valuePointer = malloc(sizeof(float)); + *valuePointer = value; + *type = valuePointer; +} + +void ARC_ConfigType_FloatDestroyFn(ARC_Config *config, void *type){ + free((float *)type); +} + +void ARC_ConfigType_DoubleCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + //go into the tag + //note the float tag means floating point number in this context, and a double does have a flating point + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_FLOAT && childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FloatCopyFn(type, parsedData, config, userdata), parsed data was not a or "); + *type = NULL; + return; + } + + //get the double as a string + ARC_String *doubleString; + ARC_String_Create(&doubleString, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&doubleString, parsedData); + + //get the value as a double + char *endptr; + double value = strtod(doubleString->data, &endptr); + + //error check + if(doubleString->data == endptr){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_FloatCopyFn(type, parsedData, config, userdata), parsed data \"%s\" was not a or ", doubleString->data); + + //cleanup + ARC_String_Destroy(doubleString); + + //set the type to NULL + *type = NULL; + return; + } + + //cleanup + ARC_String_Destroy(doubleString); + + //copy the value into a new double, then pass it out through type + double *valuePointer = malloc(sizeof(double)); + *valuePointer = value; + *type = valuePointer; +} + +void ARC_ConfigType_DoubleDestroyFn(ARC_Config *config, void *type){ + free((double *)type); +} + +void ARC_ConfigType_StringCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_STRING){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_StringCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata), string was not passed in for ARC_String"); + type = NULL; + return; + } + + //get the string chars between the quotes + ARC_ParserTagToken *stringCharsTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 1); + ARC_String_Create((ARC_String **)type, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd((ARC_String **)type, stringCharsTagToken); +} + +void ARC_ConfigType_StringDestroyFn(ARC_Config *config, void *type){ + ARC_String_Destroy(type); +} diff --git a/src/std/defaults/config.c b/src/std/defaults/config.c deleted file mode 100644 index 780822e..0000000 --- a/src/std/defaults/config.c +++ /dev/null @@ -1,345 +0,0 @@ -#include "arc/std/string.h" -#ifdef ARC_DEFAULT_CONFIG - -#include "arc/std/defaults/config.h" - -#include "arc/std/array.h" -#include "arc/std/config.h" -#include "arc/std/errno.h" -#include -#include -#include - -void ARC_Defaults_ConfigKey_Create(ARC_Config *config){ - ARC_Config_AddKeyCString(config, "uint8_t" , 7, ARC_ConfigKey_Read_Uint8_t , ARC_ConfigKey_Delete_Uint8_t ); - ARC_Config_AddKeyCString(config, "int8_t" , 6, ARC_ConfigKey_Read_Int8_t , ARC_ConfigKey_Delete_Int8_t ); - ARC_Config_AddKeyCString(config, "uint16_t" , 8, ARC_ConfigKey_Read_Uint16_t , ARC_ConfigKey_Delete_Uint16_t ); - ARC_Config_AddKeyCString(config, "int16_t" , 7, ARC_ConfigKey_Read_Int16_t , ARC_ConfigKey_Delete_Int16_t ); - ARC_Config_AddKeyCString(config, "uint32_t" , 8, ARC_ConfigKey_Read_Uint32_t , ARC_ConfigKey_Delete_Uint32_t ); - ARC_Config_AddKeyCString(config, "int32_t" , 7, ARC_ConfigKey_Read_Int32_t , ARC_ConfigKey_Delete_Int32_t ); - ARC_Config_AddKeyCString(config, "uint64_t" , 8, ARC_ConfigKey_Read_Uint64_t , ARC_ConfigKey_Delete_Uint64_t ); - ARC_Config_AddKeyCString(config, "int64_t" , 7, ARC_ConfigKey_Read_Int64_t , ARC_ConfigKey_Delete_Int64_t ); - // ARC_Config_AddKeyCString(config, "char" , 4, ARC_ConfigKey_Read_Char , ARC_ConfigKey_Delete_Char ); - ARC_Config_AddKeyCString(config, "int" , 3, ARC_ConfigKey_Read_Int , ARC_ConfigKey_Delete_Int ); - ARC_Config_AddKeyCString(config, "long" , 4, ARC_ConfigKey_Read_Long , ARC_ConfigKey_Delete_Long ); - ARC_Config_AddKeyCString(config, "float" , 5, ARC_ConfigKey_Read_Float , ARC_ConfigKey_Delete_Float ); - ARC_Config_AddKeyCString(config, "double" , 6, ARC_ConfigKey_Read_Double , ARC_ConfigKey_Delete_Double ); - ARC_Config_AddKeyCString(config, "ARC_String", 10, ARC_ConfigKey_Read_String , ARC_ConfigKey_Delete_String ); - ARC_Config_AddKeyCString(config, "string[]" , 8, ARC_ConfigKey_Read_StringArray, ARC_ConfigKey_Delete_StringArray); -} - -uint8_t ARC_ConfigKey_Read_Uint8_t(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (uint8_t *) malloc(sizeof(uint8_t)); - *((uint8_t *)(*value)) = (uint8_t) ARC_String_ToUint64_t(string); - return 0; -} - - -uint8_t ARC_ConfigKey_Read_Int8_t(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (int8_t *) malloc(sizeof(int8_t)); - *((int8_t *)(*value)) = (int8_t) ARC_String_ToInt64_t(string); - return 0; -} - -uint8_t ARC_ConfigKey_Read_Uint16_t(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (uint16_t *) malloc(sizeof(uint16_t)); - *((uint16_t *)(*value)) = (uint16_t) ARC_String_ToUint64_t(string); - return 0; -} - -uint8_t ARC_ConfigKey_Read_Int16_t(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (int16_t *) malloc(sizeof(int16_t)); - *((int16_t *)(*value)) = (int16_t) ARC_String_ToInt64_t(string); - return 0; -} - -uint8_t ARC_ConfigKey_Read_Uint32_t(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (uint32_t *) malloc(sizeof(uint32_t)); - *((uint32_t *)(*value)) = (uint32_t) ARC_String_ToUint64_t(string); - return 0; -} - -uint8_t ARC_ConfigKey_Read_Int32_t(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (int32_t *) malloc(sizeof(int32_t)); - *((int32_t *)(*value)) = (int32_t) ARC_String_ToInt64_t(string); - return 0; -} - -uint8_t ARC_ConfigKey_Read_Uint64_t(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (uint64_t *) malloc(sizeof(uint64_t)); - *((uint64_t *)(*value)) = (uint64_t) ARC_String_ToUint64_t(string); - return 0; -} - -uint8_t ARC_ConfigKey_Read_Int64_t(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (int64_t *) malloc(sizeof(int64_t)); - *((int64_t *)(*value)) = (int64_t) ARC_String_ToInt64_t(string); - return 0; -} - -uint8_t ARC_ConfigKey_Read_Char_t(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - if(string->length != 1){ - arc_errno = ARC_ERRNO_DATA; - return 0; - } - - *value = (char *) malloc(sizeof(char)); - *((char *)(*value)) = string->data[0]; - return 0; -} - -uint8_t ARC_ConfigKey_Read_Int(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (int *) malloc(sizeof(int)); - *((int *)(*value)) = (int) ARC_String_ToInt64_t(string); - return 0; -} - -uint8_t ARC_ConfigKey_Read_Long(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (long *) malloc(sizeof(long)); - *((long *)(*value)) = (long) ARC_String_ToInt64_t(string); - return 0; -} - -uint8_t ARC_ConfigKey_Read_Float(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (float *) malloc(sizeof(float)); - *((float *)(*value)) = (float) ARC_String_ToDouble(string); - return 0; -} - -uint8_t ARC_ConfigKey_Read_Double(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - *value = (double *) malloc(sizeof(double)); - *((double *)(*value)) = (double) ARC_String_ToDouble(string); - return 0; -} - -uint8_t ARC_ConfigKey_Read_String(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - if(string->data[0] != '"' || string->data[string->length - 1] != '"'){ - arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("in ARC_ConfigKey_Read_String(config, string, value); no matching quotes: %s", string->data); - return 0; - } - - ARC_String_CopySubstring((ARC_String **)value, string, 1, string->length - 2); - return 0; -} - -void ARC_ConfigKey_StringArray_ReadString(ARC_Config* config, ARC_String *stripped, uint64_t index, uint64_t length, uint64_t *arrayIndex, void **value){ - ARC_String *substr, *temp; - ARC_String_CopySubstring(&temp, stripped, index, length); - ARC_String_StripEndsWhitespace(&substr, temp); - ARC_String_Destroy(temp); - - // reading in reference - ARC_String *tempString; - // ARC_Config_Get(config, substr, (void **) &tempString); - // if(tempString){ - // ARC_String_Destroy(substr); - - // ((ARC_String *)((ARC_Array *) *value)->data)[*arrayIndex] = *tempString; - // ++*arrayIndex; - - // return; - // } - - //reading in value - ARC_ConfigKey_Read_String(config, substr, (void **) &tempString); - if(arc_errno){ - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("in ARC_RectArray_ReadRect(config, string, index, length, arrayIndex, value); failed to read string: %s", substr->data); - ARC_String_Destroy(substr); - return; - } - - ((ARC_String **)((ARC_Array *) *value)->data)[*arrayIndex] = tempString; - ++*arrayIndex; - - ARC_String_Destroy(substr); -} - -uint8_t ARC_ConfigKey_Read_StringArray(ARC_Config* config, ARC_String *string, void **value){ - ARC_Config_Get(config, string, value); - if(*value){ - return 1; - } - - if(string->data[0] != '{' || string->data[string->length - 1] != '}'){ - arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("in ARC_ConfigKey_Read_StringArray(config, string, value); no matching curly braces: %s", string->data); - return 0; - } - - ARC_String *temp, *stripped; - ARC_String_CopySubstring(&temp, string, 1, string->length - 2); - ARC_String_StripEndsWhitespace(&stripped, temp); - ARC_String_Destroy(temp); - - uint64_t arraySize = 1; - for(uint64_t i = 0; i < stripped->length; i++){ - if(stripped->data[i] == ','){ - arraySize++; - } - } - - *value = malloc(sizeof(ARC_Array)); - ((ARC_Array *) *value)->data = malloc(sizeof(ARC_String *) * arraySize); - ((ARC_Array *) *value)->size = arraySize; - - uint64_t index = 0; - arraySize = 0; - for(uint64_t i = 0; i < stripped->length; i++){ - if(stripped->data[i] == ','){ - ARC_ConfigKey_StringArray_ReadString(config, stripped, index, i - index, &arraySize, value); - if(arc_errno){ - return 0; - } - - index = i + 1; - - if(arraySize == ((ARC_Array *) *value)->size){ - break; - } - } - } - - if(arraySize != ((ARC_Array *) *value)->size){ - ARC_ConfigKey_StringArray_ReadString(config, stripped, index, stripped->length - index, &arraySize, value); - } - ARC_String_Destroy(stripped); - return 0; -} - - - -void ARC_ConfigKey_Delete_Uint8_t(ARC_Config *config, ARC_String *string, void *value){ - free((uint8_t *)value); -} - -void ARC_ConfigKey_Delete_Int8_t(ARC_Config *config, ARC_String *string, void *value){ - free((int8_t *)value); -} - -void ARC_ConfigKey_Delete_Uint16_t(ARC_Config *config, ARC_String *string, void *value){ - free((uint16_t *)value); -} - -void ARC_ConfigKey_Delete_Int16_t(ARC_Config *config, ARC_String *string, void *value){ - free((int16_t *)value); -} - -void ARC_ConfigKey_Delete_Uint32_t(ARC_Config *config, ARC_String *string, void *value){ - free((uint32_t *)value); -} - -void ARC_ConfigKey_Delete_Int32_t(ARC_Config *config, ARC_String *string, void *value){ - free((int32_t *)value); -} - -void ARC_ConfigKey_Delete_Uint64_t(ARC_Config *config, ARC_String *string, void *value){ - free((uint64_t *)value); -} - -void ARC_ConfigKey_Delete_Int64_t(ARC_Config *config, ARC_String *string, void *value){ - free((int64_t *)value); -} - -void ARC_ConfigKey_Delete_Char(ARC_Config *config, ARC_String *string, void *value){ - free((char *)value); -} - -void ARC_ConfigKey_Delete_Int(ARC_Config *config, ARC_String *string, void *value){ - free((int *)value); -} - -void ARC_ConfigKey_Delete_Long(ARC_Config *config, ARC_String *string, void *value){ - free((long *)value); -} - -void ARC_ConfigKey_Delete_Float(ARC_Config *config, ARC_String *string, void *value){ - free((float *)value); -} - -void ARC_ConfigKey_Delete_Double(ARC_Config *config, ARC_String *string, void *value){ - free((double *)value); -} - -void ARC_ConfigKey_Delete_String(ARC_Config *config, ARC_String *string, void *value){ - ARC_String_Destroy((ARC_String *)value); -} - -void ARC_ConfigKey_Delete_StringArray(ARC_Config *config, ARC_String *string, void *value){ - for(uint32_t i = 0; i < ((ARC_Array *)value)->size; i++){ - free(((ARC_String **)((ARC_Array *)value)->data)[i]); - } - free((ARC_Array *)value); -} - -#endif //ARC_DEFAULT_CONFIG diff --git a/src/std/entity.c b/src/std/entity.c index 2673f9b..2e89603 100644 --- a/src/std/entity.c +++ b/src/std/entity.c @@ -42,6 +42,10 @@ void ARC_EntitySystem_Create(ARC_EntitySystem **entitySystem){ //init an empty query (*entitySystem)->query = NULL; + + //add the first offset as 0 + uint32_t zero = 0; + ARC_VectorInline_Add(((*entitySystem)->offsetVector), (void *)&zero); } void ARC_EntitySystem_Destroy(ARC_EntitySystem *entitySystem){ @@ -76,7 +80,7 @@ uint32_t ARC_EntitySystem_RegisterComponent(ARC_EntitySystem *entitySystem, uint //get the total component size uint32_t offsetEndIndex = ARC_VectorInline_GetSize(entitySystem->offsetVector); - uint32_t totalSize = *(uint32_t *)ARC_VectorInline_Get(entitySystem->offsetVector, offsetEndIndex); + uint32_t totalSize = *(uint32_t *)ARC_VectorInline_Get(entitySystem->offsetVector, offsetEndIndex - 1); //if the new component size would overflow, throw an error if(totalSize > (~(uint32_t)0) - componentSize){ @@ -85,16 +89,18 @@ uint32_t ARC_EntitySystem_RegisterComponent(ARC_EntitySystem *entitySystem, uint return ~(uint32_t)0; } + //add the component size to the total size for the next offset + totalSize += componentSize; + //add the component size to the total size and the offset vector array ARC_VectorInline_Add(entitySystem->offsetVector, &totalSize); ARC_VectorInline_Add(entitySystem->sizeVector , &componentSize); - totalSize += componentSize; //create the resized data vector that can now house the registered component ARC_VectorInline_Create(&(entitySystem->data), totalSize, NULL, NULL); //get the id (last index) in the offset vector - return ARC_VectorInline_GetSize(entitySystem->offsetVector) - 1; + return ARC_VectorInline_GetSize(entitySystem->sizeVector) - 1; } ARC_Entity ARC_EntitySystem_InitEntity(ARC_EntitySystem *entitySystem){ @@ -118,8 +124,10 @@ ARC_Entity ARC_EntitySystem_InitEntity(ARC_EntitySystem *entitySystem){ //get the next free entity ARC_Entity entity = (ARC_Entity)ARC_VectorInline_GetSize(entitySystem->data); - //TODO: check if this works + ARC_VectorInline_Add(entitySystem->data, NULL); + ARC_VectorInline_Add(entitySystem->flagVector, NULL); + ARC_VectorInline_Add(entitySystem->maskVector, NULL); //set the flag to make the current entity alive uint8_t *flagData = (uint8_t *)ARC_VectorInline_Get(entitySystem->flagVector, (uint32_t)entity); @@ -164,7 +172,8 @@ ARC_Bool ARC_EntitySystem_HasComponent(ARC_EntitySystem *entitySystem, ARC_Entit void *ARC_EntitySystem_GetComponentData(ARC_EntitySystem *entitySystem, ARC_Entity entity, ARC_EntityComponent component){ //get the entity row, then offset that for the component to get the component data void *data = ARC_VectorInline_Get(entitySystem->data, (uint32_t)entity); - return data + *(int32_t *)ARC_VectorInline_Get(entitySystem->offsetVector, (uint32_t)component); + int32_t temp = *(int32_t *)ARC_VectorInline_Get(entitySystem->offsetVector, (uint32_t)component); + return data + temp; } ARC_Array ARC_EntitySystem_QueryComponentsData(ARC_EntitySystem *entitySystem, ARC_Array components){ @@ -174,7 +183,7 @@ ARC_Array ARC_EntitySystem_QueryComponentsData(ARC_EntitySystem *entitySystem, A componentsMask |= (1 << ((ARC_EntityComponent *)components.data)[index]); } - //setup teh components data and get a return size + //setup the components data and get a return size uint32_t maxEntitySize = ARC_VectorInline_GetSize(entitySystem->data) - ARC_VectorInline_GetSize(entitySystem->freeEntities); //clear the query if it already exists diff --git a/src/std/handler.c b/src/std/handler.c index 78588d5..9b32584 100644 --- a/src/std/handler.c +++ b/src/std/handler.c @@ -1,21 +1,17 @@ #include "arc/std/handler.h" -#include "arc/std/errno.h" #include "arc/std/vector.h" #include struct ARC_Handler { ARC_Vector *data; ARC_Vector *trash; - - ARC_Handler_CleanDataFn cleanfn; }; -void ARC_Handler_Create(ARC_Handler **handler, ARC_Handler_CompareDataFn *compareFn, ARC_Handler_CleanDataFn cleanfn){ +void ARC_Handler_Create(ARC_Handler **handler, ARC_Vector_DestroyDataFn *destroyDataFn){ *handler = (ARC_Handler *) malloc(sizeof(ARC_Handler)); - ARC_Vector_Create(&((*handler)->data), NULL, NULL); - ARC_Vector_Create(&((*handler)->trash), compareFn, NULL); - (*handler)->cleanfn = cleanfn; + ARC_Vector_Create(&((*handler)->data) , NULL, NULL ); + ARC_Vector_Create(&((*handler)->trash), NULL, destroyDataFn); } void ARC_Handler_Destroy(ARC_Handler *handler){ @@ -32,11 +28,6 @@ void ARC_Handler_Add(ARC_Handler *handler, void *data){ ARC_Vector_Add(handler->data, data); } -void ARC_Handler_Remove(ARC_Handler *handler, void *data){ - ARC_Vector_Add(handler->trash, data); - ARC_Vector_Remove(handler->data, data); -} - void ARC_Handler_RemoveIndex(ARC_Handler *handler, uint32_t index){ if(ARC_Vector_GetSize(handler->data) == 0){ return; @@ -54,23 +45,13 @@ void ARC_Handler_Iterate(ARC_Handler *handler, ARC_Handler_DataFn datafn){ } void ARC_Handler_Clear(ARC_Handler *handler){ - uint32_t zeroIndex = 0; - while(ARC_Vector_GetSize(handler->data)){ - ARC_Handler_RemoveIndex(handler, zeroIndex); + while(ARC_Vector_GetSize(handler->data) != 0){ + ARC_Handler_RemoveIndex(handler, 0); } } void ARC_Handler_Clean(ARC_Handler *handler){ - uint32_t i = 0; - while(ARC_Vector_GetSize(handler->trash)){ - void *data = ARC_Vector_Get(handler->trash, i); - - if(handler->cleanfn){ - handler->cleanfn(data); - } - - ARC_Vector_RemoveIndex(handler->trash, i); - } + ARC_Vector_Clear(handler->trash); } uint32_t ARC_Handler_GetSize(ARC_Handler *handler){ diff --git a/src/std/hashtable.c b/src/std/hashtable.c index 8ccb06d..a8a3835 100644 --- a/src/std/hashtable.c +++ b/src/std/hashtable.c @@ -1,4 +1,5 @@ #include "arc/std/hashtable.h" + #include "arc/std/errno.h" #include #include diff --git a/src/std/lexer.c b/src/std/lexer.c index c2ee606..94b9425 100644 --- a/src/std/lexer.c +++ b/src/std/lexer.c @@ -2,9 +2,9 @@ #include "arc/std/bool.h" #include "arc/std/errno.h" +#include "arc/std/io.h" #include "arc/std/string.h" #include "arc/std/vector.h" -#include "arc/std/io.h" #include struct ARC_Lexer { @@ -208,6 +208,10 @@ void ARC_Lexer_LexString(ARC_Lexer *lexer, ARC_String **data){ //check if a token was found if it wasn't continue. I'm doing this to try to cut down on the ammount of indentation if(tokenLength == 0){ + if(tokenData != NULL){ + ARC_String_Destroy(tokenData); + } + continue; } @@ -225,6 +229,12 @@ void ARC_Lexer_LexString(ARC_Lexer *lexer, ARC_String **data){ //update the last found tokenLength to the max length lastTokenLength = tokenLength; + + continue; + } + + if(tokenData != NULL){ + ARC_String_Destroy(tokenData); } } @@ -335,7 +345,8 @@ uint32_t ARC_Lexer_AutomataMatchCharFn(ARC_String **tokenData, ARC_String *strin //check to see if there is a match with automataData as a char if(string->data[0] == *(char *)automataData){ - //return the token was found of length 1 + //return the token as token data and the token was found of length 1 + ARC_String_Create(tokenData, string->data, 1); return 1; } @@ -396,6 +407,11 @@ void ARC_LexerTokenRule_DestroyCharAutomataDataFn(void *automataData){ free((char *)automataData); } +//private function to free automataData stored as an ARC_String +void ARC_LexerTokenRule_DestroyStringAutomataDataFn(void *automataData){ + ARC_String_Destroy((ARC_String *)automataData); +} + ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchCharRule(uint32_t id, char character){ //create the token rule ARC_LexerTokenRule tokenRule; @@ -441,11 +457,6 @@ ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(uint32_t return tokenRule; } -//private function to free automataData stored as an ARC_String -void ARC_LexerTokenRule_DestroyStringAutomataDataFn(void *automataData){ - ARC_String_Destroy((ARC_String *)automataData); -} - ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchStringRule(uint32_t id, ARC_String *string){ //create the token rule ARC_LexerTokenRule tokenRule; @@ -489,39 +500,3 @@ ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(uint3 //return the created tokenRule return tokenRule; } - -void ARC_Lexer_InitBasicTokenRules(ARC_Lexer *lexer){ - //null - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_NULL, 0)); - - //number - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_NUMBER, '0', '9')); - - //alpha char - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR, 'a', 'z')); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_ALPHA_UPPER_CHAR, 'A', 'Z')); - - //whitespace - //TODO: fix this - ARC_String *whitespaceString; - ARC_String_CreateWithStrlen(&whitespaceString, " \t"); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(ARC_LEXER_TOKEN_WHITESPACE, whitespaceString)); - ARC_String_Destroy(whitespaceString); - - //single char tokens - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_NEWLINE_ID , ARC_LEXER_TOKEN_NEWLINE_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_COLON_ID , ARC_LEXER_TOKEN_COLON_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_SEMICOLON_ID , ARC_LEXER_TOKEN_SEMICOLON_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_COMMA_ID , ARC_LEXER_TOKEN_COMMA_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_PERIOD_ID , ARC_LEXER_TOKEN_PERIOD_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_FORWARD_SLASH_ID , ARC_LEXER_TOKEN_FORWARD_SLASH_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_BACK_SLASH_ID , ARC_LEXER_TOKEN_BACK_SLASH_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_LEFT_PARENTHESIS_ID , ARC_LEXER_TOKEN_LEFT_PARENTHESIS_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_ID, ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_CHAR)); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_ID , ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_ID, ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_CHAR)); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_BANG_ID , ARC_LEXER_TOKEN_BANG_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_AT_ID , ARC_LEXER_TOKEN_AT_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_HASH_ID , ARC_LEXER_TOKEN_HASH_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_PERCENT_ID , ARC_LEXER_TOKEN_PERCENT_CHAR )); -} diff --git a/src/std/parser.c b/src/std/parser.c index b52518b..b98fa1f 100644 --- a/src/std/parser.c +++ b/src/std/parser.c @@ -1,10 +1,11 @@ -#include "arc/std/parser/parserlang.h" #include "arc/std/parser.h" + #include "arc/std/bool.h" #include "arc/std/errno.h" #include "arc/std/io.h" #include "arc/std/lexer.h" #include "arc/std/vector.h" +#include "arc/std/parser/parserlang.h" #include #include #include diff --git a/src/std/parser/parserlang.c b/src/std/parser/parserlang.c index ae4d4c4..1042fb6 100644 --- a/src/std/parser/parserlang.c +++ b/src/std/parser/parserlang.c @@ -23,7 +23,7 @@ void ARC_ParserLang_InitLexerRulesFn(ARC_Lexer *lexer){ //whitespace ARC_String *whitespaceString; ARC_String_CreateWithStrlen(&whitespaceString, " \t"); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(ARC_LEXER_TOKEN_WHITESPACE, whitespaceString)); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(ARC_PARSERLANG_TOKEN_WHITESPACE, whitespaceString)); ARC_String_Destroy(whitespaceString); //single char tokens diff --git a/src/std/vector/inline.c b/src/std/vector/inline.c index fb7129e..a51a5e6 100644 --- a/src/std/vector/inline.c +++ b/src/std/vector/inline.c @@ -90,7 +90,9 @@ void ARC_VectorInline_Add(ARC_VectorInline *vectorInline, void *data){ } //add to the vectors array and increase its current size - memcpy(vectorInline->data + (vectorInline->currentSize * vectorInline->typeSize), data, vectorInline->typeSize); + if(data != NULL){ + memcpy(vectorInline->data + (vectorInline->currentSize * vectorInline->typeSize), data, vectorInline->typeSize); + } vectorInline->currentSize++; } @@ -161,7 +163,7 @@ void *ARC_VectorInline_Get(ARC_VectorInline *vectorInline, uint32_t index){ //check to make sure the given index is in bounds of the vector if(index >= vectorInline->currentSize){ arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_VectorInline_Get(vectorInline, %u), index %u bounds", index, index); + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_VectorInline_Get(vectorInline, %u), index %u out of bounds", index, index); return NULL; } diff --git a/tests/std/config.c b/tests/std/config.c index aa711e1..21a2d74 100644 --- a/tests/std/config.c +++ b/tests/std/config.c @@ -1,91 +1,15 @@ #include "../test.h" #include "arc/std/errno.h" #include "arc/std/config.h" -#include "arc/std/parser.h" -#include "arc/std/parser/helpers.h" #include -static const char *testType = "int32"; - -void TEST_configType_CopyInt32Fn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config){ - //go into the tag - ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); - if(childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ - arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR("TEST_configType_CopyInt32Fn(type, parsedData, config), parsed data was not a "); - *type = NULL; - return; - } - - //check if the first tag is a minus sign and create a string starting with that if it is - childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 0); - ARC_String *int32String; - ARC_String_Create(&int32String, NULL, 0); - if(childTagToken->id == ARC_CONFIG_MINUS){ - ARC_String_AppendCStringWithStrlen(&int32String, "-"); - } - - ARC_ParserData_HelperRecurseStringAdd(&int32String, parsedData); - - //set the max character size 2,147,483,647 (10 characters) or -2,147,483,648 (11 characters) - uint32_t maxInt32Size = 10; - if(int32String->data[0] == '-'){ - maxInt32Size++; - } - - //if the string is bigger than the possible size return NULL and error - if(int32String->length > maxInt32Size){ - arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("TEST_configType_CopyInt32Fn(type, parsedData, config), size \"%s\" was bigger or smaller than the max 2,147,483,647 or min -2,147,483,648", int32String->data); - *type = NULL; - ARC_String_Destroy(int32String); - return; - } - - if(int32String->length == maxInt32Size){ - char maxint32CStr[10] = "2147483647"; - - //offset starting index and last number if there is a negative - uint8_t stringIndex = 0; - if(int32String->data[0] == '-'){ - stringIndex++; - maxint32CStr[9]++; - } - - for(uint8_t index = 0; index < 10; index++, stringIndex++){ - if(int32String->data[stringIndex] > maxint32CStr[index]){ - arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("TEST_configType_CopyInt32Fn(type, parsedData, config), size \"%s\" was bigger or smaller than the max 2,147,483,647 or min -2,147,483,648", int32String->data); - *type = NULL; - ARC_String_Destroy(int32String); - return; - } - } - } - - //copy the int32_t - *type = malloc(sizeof(int32_t)); - *(int32_t *)(*type) = (int32_t)ARC_String_ToInt64_t(int32String); - - //cleanup - ARC_String_Destroy(int32String); -} - -void TEST_configType_DestroyInt32Fn(void *type){ - free((int32_t *)type); -} - ARC_TEST(config_BasicTest){ ARC_Config *config; ARC_Config_Create(&config); ARC_CHECK(arc_errno == 0); - ARC_ConfigType int32Type = { - TEST_configType_CopyInt32Fn, - TEST_configType_DestroyInt32Fn - }; - ARC_Config_RegisterTypeWithCStr(config, testType, int32Type); + ARC_Config_InitStd(config); char *tempCString = "tests/res/std/config/first.chemical"; ARC_String *tempString; diff --git a/tests/std/lexer.c b/tests/std/lexer.c index 30342f1..0e74db7 100644 --- a/tests/std/lexer.c +++ b/tests/std/lexer.c @@ -1,11 +1,97 @@ #include "../test.h" #include "arc/std/lexer.h" +#define ARC_LEXER_TOKEN_NULL 0 +#define ARC_LEXER_TOKEN_NUMBER 1 +#define ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR 2 +#define ARC_LEXER_TOKEN_ALPHA_UPPER_CHAR 3 +#define ARC_LEXER_TOKEN_WHITESPACE 4 +#define ARC_LEXER_TOKEN_NEWLINE_ID 5 +#define ARC_LEXER_TOKEN_NEWLINE_CHAR '\n' +#define ARC_LEXER_TOKEN_COLON_ID 6 +#define ARC_LEXER_TOKEN_COLON_CHAR ':' +#define ARC_LEXER_TOKEN_COLON_TAG "COLON" +#define ARC_LEXER_TOKEN_SEMICOLON_ID 7 +#define ARC_LEXER_TOKEN_SEMICOLON_CHAR ';' +#define ARC_LEXER_TOKEN_SEMICOLON_TAG "SEMICOLON" +#define ARC_LEXER_TOKEN_COMMA_ID 8 +#define ARC_LEXER_TOKEN_COMMA_CHAR ',' +#define ARC_LEXER_TOKEN_COMMA_TAG "COMMA" +#define ARC_LEXER_TOKEN_PERIOD_ID 9 +#define ARC_LEXER_TOKEN_PERIOD_CHAR '.' +#define ARC_LEXER_TOKEN_PERIOD_TAG "PERIOD" +#define ARC_LEXER_TOKEN_FORWARD_SLASH_ID 10 +#define ARC_LEXER_TOKEN_FORWARD_SLASH_CHAR '/' +#define ARC_LEXER_TOKEN_FORWARD_SLASH_TAG "FORWARD_SLASH" +#define ARC_LEXER_TOKEN_BACK_SLASH_ID 11 +#define ARC_LEXER_TOKEN_BACK_SLASH_CHAR '\\' +#define ARC_LEXER_TOKEN_BACK_SLASH_TAG "BACK_SLASH" +#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_ID 12 +#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_CHAR '(' +#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_TAG "LEFT_PARENTHESIS" +#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_ID 13 +#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_CHAR ')' +#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_TAG "RIGHT_PARENTHESIS" +#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_ID 14 +#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_CHAR '{' +#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_TAG "LEFT_CURLY_BRACE" +#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_ID 15 +#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_CHAR '}' +#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_TAG "RIGHT_CURLY_BRACE" +#define ARC_LEXER_TOKEN_BANG_ID 16 +#define ARC_LEXER_TOKEN_BANG_CHAR '!' +#define ARC_LEXER_TOKEN_BANG_TAG "BANG" +#define ARC_LEXER_TOKEN_AT_ID 17 +#define ARC_LEXER_TOKEN_AT_CHAR '!' +#define ARC_LEXER_TOKEN_AT_TAG "AT" +#define ARC_LEXER_TOKEN_HASH_ID 18 +#define ARC_LEXER_TOKEN_HASH_CHAR '#' +#define ARC_LEXER_TOKEN_HASH_TAG "HASH" +#define ARC_LEXER_TOKEN_PERCENT_ID 19 +#define ARC_LEXER_TOKEN_PERCENT_CHAR '%' +#define ARC_LEXER_TOKEN_PERCENT_TAG "PERCENT" + +void ARC_Test_InitBasicLexerTokenRules(ARC_Lexer *lexer){ + //null + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_NULL, 0)); + + //number + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_NUMBER, '0', '9')); + + //alpha char + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR, 'a', 'z')); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_ALPHA_UPPER_CHAR, 'A', 'Z')); + + //whitespace + //TODO: fix this + ARC_String *whitespaceString; + ARC_String_CreateWithStrlen(&whitespaceString, " \t"); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(ARC_LEXER_TOKEN_WHITESPACE, whitespaceString)); + ARC_String_Destroy(whitespaceString); + + //single char tokens + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_NEWLINE_ID , ARC_LEXER_TOKEN_NEWLINE_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_COLON_ID , ARC_LEXER_TOKEN_COLON_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_SEMICOLON_ID , ARC_LEXER_TOKEN_SEMICOLON_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_COMMA_ID , ARC_LEXER_TOKEN_COMMA_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_PERIOD_ID , ARC_LEXER_TOKEN_PERIOD_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_FORWARD_SLASH_ID , ARC_LEXER_TOKEN_FORWARD_SLASH_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_BACK_SLASH_ID , ARC_LEXER_TOKEN_BACK_SLASH_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_LEFT_PARENTHESIS_ID , ARC_LEXER_TOKEN_LEFT_PARENTHESIS_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_ID, ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_CHAR)); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_ID , ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_ID, ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_CHAR)); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_BANG_ID , ARC_LEXER_TOKEN_BANG_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_AT_ID , ARC_LEXER_TOKEN_AT_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_HASH_ID , ARC_LEXER_TOKEN_HASH_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_PERCENT_ID , ARC_LEXER_TOKEN_PERCENT_CHAR )); +} + ARC_TEST(Lexer_Char_Match){ ARC_Lexer *lexer; ARC_Lexer_Create(&lexer); - ARC_Lexer_InitBasicTokenRules(lexer); + ARC_Test_InitBasicLexerTokenRules(lexer); ARC_String *simple; ARC_String_CreateWithStrlen(&simple, "::{}!/."); diff --git a/tests/std/parser.c b/tests/std/parser.c index 60cf72a..d790613 100644 --- a/tests/std/parser.c +++ b/tests/std/parser.c @@ -2,70 +2,79 @@ #include "arc/std/bool.h" #include "arc/std/errno.h" #include "arc/std/parser.h" -#include "arc/std/parser/helpers.h" #include "arc/std/lexer.h" -#include "arc/std/vector.h" #include #include -const uint32_t TEST_PARSER_CHAR_OR_NUM = 23; -const uint32_t TEST_PARSER_VARIABLE_NAME = 24; -const uint32_t TEST_PARSER_VARIABLE = 25; +//TODO: add more tests +const char *languageCString = + " -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE \n" + " -> | LAMBDA\n" + " -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE | NUMBER\n"; -const uint32_t TEST_PARSER_ALPHA_LOWER_CHAR = 1; -const uint32_t TEST_PARSER_ALPHA_UPPER_CHAR = 2; -const uint32_t TEST_PARSER_ALPHA_CHAR = 3; +#define ARC_TEST_TAG_UNDERSCORE 1 +#define ARC_TEST_TAG_NUMBER 2 +#define ARC_TEST_TAG_ALPHA_UPPER_CHAR 3 +#define ARC_TEST_TAG_ALPHA_LOWER_CHAR 4 +#define ARC_TEST_TAG_VARIABLE 5 +#define ARC_TEST_TAG_VARIABLE_NAME 6 +#define ARC_TEST_TAG_VARIABLE_CHAR 7 -void TEST_ParserData_CreateStringFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ - ARC_String_Create((ARC_String **)data, NULL, 0); +void ARC_TEST_InitLexerRulesFn(ARC_Lexer *lexer){ + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_TEST_TAG_UNDERSCORE, '_' )); - ARC_ParserData_HelperRecurseStringAdd((ARC_String **)data, parsedData); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_TEST_TAG_NUMBER , '0', '9')); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_TEST_TAG_ALPHA_LOWER_CHAR, 'a', 'z')); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_TEST_TAG_ALPHA_UPPER_CHAR, 'A', 'Z')); } -void TEST_ParserData_DestroyStringFn(void *data, ARC_Bool clear, void *userData){ - if(data == NULL){ - return; +uint32_t ARC_TEST_GetStringIdFn(ARC_String *string){ + if(ARC_String_EqualsCStringWithStrlen(string, "LAMBDA")){ + return ARC_PARSER_TAG_LAMBDA; } - ARC_String_Destroy((ARC_String *)data); + if(ARC_String_EqualsCStringWithStrlen(string, "UNDERSCORE")){ + return ARC_TEST_TAG_UNDERSCORE; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "NUMBER")){ + return ARC_TEST_TAG_NUMBER; + } + if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_UPPER_CHAR")){ + return ARC_TEST_TAG_ALPHA_UPPER_CHAR; + } + if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_LOWER_CHAR")){ + return ARC_TEST_TAG_ALPHA_LOWER_CHAR; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_TEST_TAG_VARIABLE; + } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_TEST_TAG_VARIABLE_NAME; + } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_TEST_TAG_VARIABLE_CHAR; + } + + return ~(uint32_t)0; } -uint32_t *charOrNumTokens[] = { (uint32_t[]){ 1, ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR }, (uint32_t[]){ 1, ARC_LEXER_TOKEN_NUMBER } }; -uint32_t *variableNameTags[] = { (uint32_t[]){ 2, TEST_PARSER_CHAR_OR_NUM, TEST_PARSER_VARIABLE_NAME }, (uint32_t[]){ 1, ARC_PARSER_TAG_LAMBDA } }; -uint32_t *variableTokensOrTags[] = { (uint32_t[]){ 2, ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR, TEST_PARSER_VARIABLE_NAME } }; +void ARC_TESTData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ +} -//TODO: note how language function callbacks work, and how they use the parentData if createDataFn is NULL - -ARC_ParserTag testTags[3] = { - { - TEST_PARSER_VARIABLE, //tagId - variableTokensOrTags, //tokensOrTags - 1 //tokenOrTagsSize - }, - { - TEST_PARSER_VARIABLE_NAME, //tagId - variableNameTags, //tokensOrTags - 2 //tokenOrTagsSize - }, - { - TEST_PARSER_CHAR_OR_NUM, //tagId - charOrNumTokens, //tokensOrTags - 2 //tokenOrTagsSize - } -}; - -ARC_Array languageArray = { - 3, //size - testTags //data -}; - -void TEST_Parser_InitLexerRulesFn(ARC_Lexer *lexer){ - ARC_Lexer_InitBasicTokenRules(lexer); +void ARC_TESTData_DestroyFn(void *data, ARC_Bool clear, void *userData){ } ARC_TEST(Parser_Init){ + ARC_String *languageString; + ARC_String_CreateWithStrlen(&languageString, (char *)languageCString); + ARC_Parser *parser; - ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); + ARC_ParserData_CreateFn createCharFn = ARC_TESTData_CreateFn; + ARC_ParserData_DestroyFn destroyCharFn = ARC_TESTData_DestroyFn; + ARC_Parser_CreateFromString(&parser, languageString, ARC_TEST_InitLexerRulesFn, ARC_TEST_GetStringIdFn, &createCharFn, &destroyCharFn, NULL); + ARC_String_Destroy(languageString); ARC_Parser_Destroy(parser); @@ -73,13 +82,17 @@ ARC_TEST(Parser_Init){ } ARC_TEST(Parser_Basic_Parse){ + ARC_String *languageString; + ARC_String_CreateWithStrlen(&languageString, (char *)languageCString); + ARC_Parser *parser; - ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); - - ARC_String *tempString; - + ARC_ParserData_CreateFn createCharFn = ARC_TESTData_CreateFn; + ARC_ParserData_DestroyFn destroyCharFn = ARC_TESTData_DestroyFn; + ARC_Parser_CreateFromString(&parser, languageString, ARC_TEST_InitLexerRulesFn, ARC_TEST_GetStringIdFn, &createCharFn, &destroyCharFn, NULL); + ARC_String_Destroy(languageString); /* ~ first test ~ */ + ARC_String *tempString; ARC_String_CreateWithStrlen(&tempString, "myvar1"); //this destroys string, so no need for cleanup @@ -87,7 +100,6 @@ ARC_TEST(Parser_Basic_Parse){ ARC_CHECK(arc_errno == 0); - /* ~ second test ~ */ ARC_String_CreateWithStrlen(&tempString, "z1xwvq"); @@ -96,7 +108,6 @@ ARC_TEST(Parser_Basic_Parse){ ARC_CHECK(arc_errno == 0); - /* ~ third test ~ */ ARC_String_CreateWithStrlen(&tempString, "z1234"); @@ -105,218 +116,15 @@ ARC_TEST(Parser_Basic_Parse){ ARC_CHECK(arc_errno == 0); - /* ~ fourth test ~ */ ARC_String_CreateWithStrlen(&tempString, "aaaaa"); + //this destroys string, so no need for cleanup ARC_Parser_Parse(parser, &tempString); ARC_CHECK(arc_errno == 0); - /* ~ cleanup ~ */ ARC_Parser_Destroy(parser); } - -ARC_TEST(Parser_Basic_ParseError){ - ARC_Parser *parser; - ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); - - ARC_String *tempString; - - - /* ~ first test ~ */ - ARC_String_CreateWithStrlen(&tempString, "!myVar1"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == ARC_ERRNO_DATA); - - - /* ~ second test ~ */ - //check again with moved character - arc_errno = 0; - ARC_String_CreateWithStrlen(&tempString, "my!Var1"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == ARC_ERRNO_DATA); - - - /* ~ third test ~ */ - //check again with moved character - arc_errno = 0; - ARC_String_CreateWithStrlen(&tempString, "myVar1!"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == ARC_ERRNO_DATA); - - - /* ~ cleanup ~ */ - ARC_Parser_Destroy(parser); - - //reset for next test - arc_errno = 0; -} - -ARC_TEST(Parser_Basic_GetParsedValue){ - ARC_Parser *parser; - - ARC_ParserData_CreateFn createStringFn = TEST_ParserData_CreateStringFn; - ARC_ParserData_DestroyFn destroyStringFn = TEST_ParserData_DestroyStringFn; - - ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, &createStringFn, &destroyStringFn, NULL); - - ARC_String *tempString; - - - /* ~ first test ~ */ - ARC_String_CreateWithStrlen(&tempString, "myvar1"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == 0); - - ARC_String *checkValue = (ARC_String *)ARC_Parser_GetData(parser); - ARC_CHECK(ARC_String_EqualsCStringWithStrlen(checkValue, "myvar1")); - - - /* ~ cleanup ~ */ - ARC_Parser_Destroy(parser); -} - -ARC_TEST(Parser_ParserLang_BasicVector){ - ARC_Vector *testLanguage; - ARC_Vector_Create(&testLanguage, NULL, NULL); - - ARC_Vector_Add(testLanguage, testTags + 0); - ARC_Vector_Add(testLanguage, testTags + 1); - ARC_Vector_Add(testLanguage, testTags + 2); - - ARC_Parser *parser; - ARC_Parser_CreateFromVector(&parser, testLanguage, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); - - ARC_String *tempString; - ARC_String_CreateWithStrlen(&tempString, "variablename"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - //cleanup - ARC_Parser_Destroy(parser); - ARC_Vector_Destroy(testLanguage); - - ARC_CHECK(arc_errno == 0); -} - -/* ~ parser tests ~ */ -void TEST_Parser_InitBasicLexerTokenRules(ARC_Lexer *lexer){ - //null - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_PARSER_TAG_LAMBDA, 0)); - - //alpha char - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(TEST_PARSER_ALPHA_LOWER_CHAR, 'a', 'z')); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(TEST_PARSER_ALPHA_UPPER_CHAR, 'A', 'Z')); -} - -uint32_t TEST_Parser_GetStringIdFn(ARC_String *string){ - if(ARC_String_EqualsCStringWithStrlen(string, "")){ - return TEST_PARSER_ALPHA_CHAR; - } - - if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_LOWER_CHAR")){ - return TEST_PARSER_ALPHA_LOWER_CHAR; - } - - if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_UPPER_CHAR")){ - return TEST_PARSER_ALPHA_UPPER_CHAR; - } - - return ~(uint32_t)0; -} - -void TEST_ParserData_CreateCharFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ - if(parsedData == NULL){ - *data = NULL; - return; - } - - char *alphaChar = (char *)malloc(sizeof(char)); - - ARC_ParserTagToken *tagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); - *alphaChar = tagToken->token->data->data[0]; - - *data = (void *)alphaChar; -} - -void TEST_ParserData_DestroyCharFn(void *data, ARC_Bool clear, void *userData){ - if(data == NULL){ - return; - } - - free((char *)data); -} - -ARC_TEST(Parser_Parser_BasicCreateWithStringTest){ - ARC_Parser *parser; - - /* ~ create the language ~ */ - ARC_String *languageString; - ARC_String_CreateWithStrlen(&languageString, " -> ALPHA_LOWER_CHAR | ALPHA_UPPER_CHAR\n"); - - ARC_ParserData_CreateFn createCharFn = TEST_ParserData_CreateCharFn; - ARC_ParserData_DestroyFn destroyCharFn = TEST_ParserData_DestroyCharFn; - ARC_Parser_CreateFromString(&parser, languageString, TEST_Parser_InitBasicLexerTokenRules, TEST_Parser_GetStringIdFn, &createCharFn, &destroyCharFn, NULL); - - ARC_String_Destroy(languageString); - - ARC_CHECK(arc_errno == 0); - - - /* ~ check if a can be parsed ~ */ - ARC_String *tempString; - ARC_String_CreateWithStrlen(&tempString, "a"); - - ARC_Parser_Parse(parser, &tempString); - - char *data = (char *)ARC_Parser_GetData(parser); - - ARC_CHECK(*data == 'a'); - - ARC_Parser_ClearData(parser); - - - /* ~ check if Z can be parsed ~ */ - ARC_String_CreateWithStrlen(&tempString, "Z"); - - ARC_Parser_Parse(parser, &tempString); - - data = (char *)ARC_Parser_GetData(parser); - - ARC_CHECK(*data == 'Z'); - - ARC_Parser_ClearData(parser); - - - /* ~ check if 8 errors ~ */ - ARC_String_CreateWithStrlen(&tempString, "8"); - - ARC_Parser_Parse(parser, &tempString); - - data = (char *)ARC_Parser_GetData(parser); - - ARC_CHECK(arc_errno == ARC_ERRNO_DATA); - arc_errno = 0; - - ARC_Parser_ClearData(parser); - - - //cleanup - ARC_Parser_Destroy(parser); -}