diff --git a/include/arc/std/chemical.h b/include/arc/std/chemical.h index 394aff8..6fc9162 100644 --- a/include/arc/std/chemical.h +++ b/include/arc/std/chemical.h @@ -39,16 +39,6 @@ extern "C" { -> SPACE | TAB | NEWLINE | LAMBDA */ -/** - * @brief TODO: write this -*/ -typedef void (* ARC_ChemicalData_CopyToTypeFn)(void **data, ARC_ParserTagToken *parsedData); - -/** - * @brief TODO: write this -*/ -typedef void (* ARC_ParserCSV_DestroyTypeFn)(void *data); - /** * @brief a function to read a key from string to a ARC_ConfigTypeTemplate * @@ -79,6 +69,24 @@ typedef void (* ARC_ParserCSV_DestroyTypeFn)(void *data); */ typedef struct ARC_Chemical ARC_Chemical; +/** + * @brief +*/ +typedef void (* ARC_ChemicalType_CopyFn)(void **type, ARC_ParserTagToken *parsedData, ARC_Chemical *chemical); + +/** + * @brief +*/ +typedef void (* ARC_ChemicalType_DestroyFn)(void *type); + +/** + * @brief +*/ +typedef struct ARC_ChemicalType { + ARC_ChemicalType_CopyFn copyFn; + ARC_ChemicalType_DestroyFn destroyFn; +} ARC_ChemicalType; + /** * @brief TODO: write this */ @@ -92,7 +100,12 @@ void ARC_Chemical_Destroy(ARC_Chemical *chemical); /** * @brief TODO: write this */ -void ARC_Chemical_RegisterType(ARC_Chemical *chemical, ARC_String *typeName, ARC_ChemicalData_CopyToTypeFn *copyToTypeFn, ARC_ParserCSV_DestroyTypeFn destroyTypeFn); +void ARC_Chemical_RegisterType(ARC_Chemical *chemical, ARC_String *typeName, ARC_ChemicalType type); + +/** + * @brief TODO: write this +*/ +void ARC_Chemical_RegisterTypeWithCStr(ARC_Chemical *chemical, const char *typeNameCStr, ARC_ChemicalType type); /** * @brief sets current group in config diff --git a/include/arc/std/hashtable.h b/include/arc/std/hashtable.h index e79d15f..f68bfd8 100644 --- a/include/arc/std/hashtable.h +++ b/include/arc/std/hashtable.h @@ -38,10 +38,11 @@ typedef void (* ARC_Hashtable_DestroyKeyValueFn)(void *key, void *value); /** * @brief a callback to be used by ARC_Hashtable_RunIteration * - * @param[in] key a key at the current iteration - * @param[in] value a value that matches the key at the current iteration + * @param[in] key a key at the current iteration + * @param[in] value a value that matches the key at the current iteration + * @param[in] userData any data passed into the function that uses this callback to be used in this callback */ -typedef void (* ARC_Hashtable_IteratorFn)(void *key, void *value); +typedef void (* ARC_Hashtable_IteratorFn)(void *key, void *value, void *userData); /** * @brief a resizable hashtable data type (will find next open slot before resizing) @@ -109,8 +110,9 @@ void *ARC_Hashtable_Get(ARC_Hashtable *hashtable, void *key); * * @param[in] hashtable the hashtable to iterate through * @param[in] iteratorFn the callback which will can use the iterated key value pairs + * @patam[in] userData anything to be used within the ARC_Hashtable_IteratorFn callback, can be NULL */ -void ARC_Hashtable_RunIteration(ARC_Hashtable *hashtable, ARC_Hashtable_IteratorFn iteratorFn); +void ARC_Hashtable_RunIteration(ARC_Hashtable *hashtable, ARC_Hashtable_IteratorFn iteratorFn, void *userData); #ifdef __cplusplus } diff --git a/src/std/chemical.c b/src/std/chemical.c index 977702d..dae4b3e 100644 --- a/src/std/chemical.c +++ b/src/std/chemical.c @@ -11,8 +11,16 @@ struct ARC_Chemical { ARC_Parser *parser; ARC_Hashtable *groups; + ARC_Hashtable *types; + + ARC_Hashtable *currentGroup; }; +typedef struct ARC_ChemicalTypeData { + void *data; + ARC_ChemicalType_DestroyFn *destroyFn; +} ARC_ChemicalTypeData; + //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) static const uint32_t ARC_CHEMICAL_TAB = 0x01; static const uint32_t ARC_CHEMICAL_NEWLINE = 0x02; @@ -307,11 +315,13 @@ uint32_t ARC_Chemical_GetStringIdFn(ARC_String *string){ void ARC_ChemicalData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ *data = NULL; - if(data == NULL || userData == NULL){ + if(parsedData == NULL || userData == NULL){ //TODO: error here? *data = NULL; return; } + + } void ARC_ChemicalData_DestroyFn(void *data, ARC_Bool clear, void *userData){ @@ -368,10 +378,34 @@ void ARC_Chemical_Destroy(ARC_Chemical *chemical){ free(chemical); } -void ARC_Chemical_RegisterType(ARC_Chemical *chemical, ARC_String *typeName, ARC_ChemicalData_CopyToTypeFn *copyToTypeFn, ARC_ParserCSV_DestroyTypeFn destroyTypeFn){ +void ARC_Chemical_HashtableCheckKeyIteratorFn(void *key, void *value){ + +} + +void ARC_Chemical_RegisterType(ARC_Chemical *chemical, ARC_String *typeName, ARC_ChemicalType type){ + //TODO: check if name currently exists + ARC_String *typeNameCopy; + ARC_String_Copy(&typeNameCopy, typeName); + + ARC_ChemicalType *typeCopy = (ARC_ChemicalType *)malloc(sizeof(ARC_ChemicalType)); + *typeCopy = type; + + ARC_Hashtable_Add(chemical->types, typeName, typeCopy); +} + +void ARC_Chemical_RegisterTypeWithCStr(ARC_Chemical *chemical, const char *typeNameCStr, ARC_ChemicalType type){ + //TODO: check if name currently exists + ARC_String *typeName; + ARC_String_CreateWithStrlen(&typeName, (char *)typeNameCStr); + + ARC_ChemicalType *typeCopy = (ARC_ChemicalType *)malloc(sizeof(ARC_ChemicalType)); + *typeCopy = type; + + ARC_Hashtable_Add(chemical->types, typeName, typeCopy); } void ARC_Chemical_SetGroup(ARC_Chemical *chemical, ARC_String *groupName){ + } void *ARC_Chemical_Get(ARC_Chemical *chemical, ARC_String *element){ diff --git a/src/std/hashtable.c b/src/std/hashtable.c index acd4c21..e22fa9f 100644 --- a/src/std/hashtable.c +++ b/src/std/hashtable.c @@ -343,10 +343,17 @@ void ARC_Hashtable_Remove(ARC_Hashtable *hashtable, void *key){ free(oldNodes); } +//private callback function to delete all the key value pairs in the hashtable +void ARC_Hashtable_DestroyKeyValueIteratorFn(void *key, void *value, void *userData){ + ARC_Hashtable *hashtable = (ARC_Hashtable *)userData; + + (*(hashtable->destroyKeyValueFn))(key, value); +} + void ARC_Hashtable_Clear(ARC_Hashtable *hashtable){ - //NOTE: this recasts ARC_Hashtable_DestroyKeyValueFn because it matches ARC_Hashtable_IteratorFn, if either is changed, this needs updated + //if the destroyKeyValueFn exists, run iterations to clear the table if(hashtable->destroyKeyValueFn != NULL){ - ARC_Hashtable_RunIteration(hashtable, *(hashtable->destroyKeyValueFn)); + ARC_Hashtable_RunIteration(hashtable, ARC_Hashtable_DestroyKeyValueIteratorFn, hashtable); } //delete the array holding all the nodes @@ -399,7 +406,7 @@ void *ARC_Hashtable_Get(ARC_Hashtable *hashtable, void *key){ return NULL; } -void ARC_Hashtable_RunIteration(ARC_Hashtable *hashtable, ARC_Hashtable_IteratorFn iteratorFn){ +void ARC_Hashtable_RunIteration(ARC_Hashtable *hashtable, ARC_Hashtable_IteratorFn iteratorFn, void *userData){ //pass each non NULL nodes into an iteratorFn callback for(uint32_t index = 0; index < hashtable->currentCapacity; index++){ //get the current node @@ -411,6 +418,6 @@ void ARC_Hashtable_RunIteration(ARC_Hashtable *hashtable, ARC_Hashtable_Iterator } //passes current iteration into the callback function - iteratorFn(node.key, node.value); + iteratorFn(node.key, node.value, userData); } } diff --git a/tests/std/hashtable.c b/tests/std/hashtable.c index 9d4878a..8a24890 100644 --- a/tests/std/hashtable.c +++ b/tests/std/hashtable.c @@ -9,18 +9,17 @@ //TODO: add hash function for testing -void TEST_Hashtable_PrintIter(void *key, void *value){ - //printf("%s, %d\n", (char *)key, *(int32_t *)value); +void TEST_Hashtable_PrintIter(void *key, void *value, void *userData){ + printf("%s, %d\n", (char *)key, *(int32_t *)value); } void TEST_Hashtable_Print(void *hashtable){ printf("hashtable:\n"); - ARC_Hashtable_RunIteration(hashtable, TEST_Hashtable_PrintIter); + ARC_Hashtable_RunIteration(hashtable, TEST_Hashtable_PrintIter, NULL); printf("\n"); } ARC_Bool TEST_Hashtable_KeyCompareDataFn(void *dataA, void *dataB){ - //printf("%s : %s\n", (char *)dataA, (char *)dataB); return (ARC_Bool)strcmp((const char *)dataA, (const char *)dataB) == 0; }