feat: implemented variant_from_str, Drop, and Mirror
This commit is contained in:
parent
aec965f3f6
commit
1d919fef38
69
core/src/variant.c
Normal file
69
core/src/variant.c
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#include "variant.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
impl_Drop_for(Variant,
|
||||||
|
destroy_variant
|
||||||
|
)
|
||||||
|
|
||||||
|
START_REFLECT(Variant)
|
||||||
|
REFLECT_TYPECLASS(Variant, Drop)
|
||||||
|
END_REFLECT(Variant)
|
||||||
|
|
||||||
|
Variant variant_from_str(const char* str) {
|
||||||
|
size_t length = strlen(str);
|
||||||
|
if(isdigit(str[0])) {
|
||||||
|
// variant is a number
|
||||||
|
// convert to double
|
||||||
|
return NumberVariant(atof(str));
|
||||||
|
} else if(str[0] == '"') {
|
||||||
|
// variant should be a string
|
||||||
|
// format: "<content>"
|
||||||
|
// copy the input string without the quotes
|
||||||
|
size_t result_length = strfirst(str+1, str+length, '"');
|
||||||
|
char* string = malloc(result_length);
|
||||||
|
strncpy(string, str+1, result_length-1);
|
||||||
|
string[result_length] = '\0';
|
||||||
|
return StringVariant(string, result_length);
|
||||||
|
} else if(strncmp(str, "Vector(", 7) == 0) {
|
||||||
|
// variant is a vector
|
||||||
|
// format: Vector(<x>, <y>)
|
||||||
|
// get the location of the brackets
|
||||||
|
long close_bracket = strfirst(str, str + length, ')');
|
||||||
|
if(close_bracket == -1) goto variant_from_str_err;
|
||||||
|
char buf[24]; buf[23] = '\0';
|
||||||
|
// copy what is within the brackets
|
||||||
|
// 7 is the number of characters in "Vector(", which should be skipped
|
||||||
|
strncpy(buf, str + 7, close_bracket - 7);
|
||||||
|
length = strlen(buf);
|
||||||
|
long comma_ind = strfirst(buf, buf+length, ',');
|
||||||
|
if(comma_ind == -1) goto variant_from_str_err;
|
||||||
|
// split the string at the comma by inserting a null terminator
|
||||||
|
buf[comma_ind] = '\0';
|
||||||
|
return VectorVariant(MakeVector(atof(buf), atof(buf + comma_ind + 1)));
|
||||||
|
}
|
||||||
|
variant_from_str_err:
|
||||||
|
return UndefinedVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_variant(Variant* self) {
|
||||||
|
destroy_contained(self);
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_contained(Variant* self) {
|
||||||
|
switch(self->type) {
|
||||||
|
default: break;
|
||||||
|
case Variant_String:
|
||||||
|
if(self->as_string != NULL)
|
||||||
|
free(self->as_string);
|
||||||
|
break;
|
||||||
|
case Variant_Object:
|
||||||
|
if(TC_MIRRORS(self->as_object, Drop)) {
|
||||||
|
Drop drop = TC_CAST(self->as_object, Drop);
|
||||||
|
drop.tc->drop(drop.data);
|
||||||
|
} else {
|
||||||
|
LOG_ERROR("Deallocating Object Variant that does not mirror Drop, pointer will be orphaned");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
#define _fencer_variant_h
|
#define _fencer_variant_h
|
||||||
|
|
||||||
#include "vmath.h"
|
#include "vmath.h"
|
||||||
|
#include "drop.h"
|
||||||
#include "mirror.h"
|
#include "mirror.h"
|
||||||
|
|
||||||
typedef enum VariantType {
|
typedef enum VariantType {
|
||||||
|
@ -23,10 +24,17 @@ typedef struct Variant {
|
||||||
};
|
};
|
||||||
} Variant;
|
} Variant;
|
||||||
|
|
||||||
|
extern Variant variant_from_str(const char* str);
|
||||||
|
extern void destroy_variant(Variant* self);
|
||||||
|
extern void destroy_contained(Variant* self);
|
||||||
|
|
||||||
#define NumberVariant(Value_) (Variant){.type = Variant_Number, .as_number = Value_}
|
#define NumberVariant(Value_) (Variant){.type = Variant_Number, .as_number = Value_}
|
||||||
#define VectorVariant(Value_) (Variant){.type = Variant_Vector, .as_vector = Value_}
|
#define VectorVariant(Value_) (Variant){.type = Variant_Vector, .as_vector = Value_}
|
||||||
#define ObjectVariant(Value_) (Variant){.type = Variant_Object, .as_object = Value_}
|
#define ObjectVariant(Value_) (Variant){.type = Variant_Object, .as_object = Value_}
|
||||||
#define StringVariant(Value_, BufSize_) (Variant){.type = Variant_String, .as_string = Value_, .string_size = BufSize_}
|
#define StringVariant(Value_, BufSize_) (Variant){.type = Variant_String, .as_string = Value_, .string_size = BufSize_}
|
||||||
#define UndefinedVariant() (Variant){.type = Variant_Undefined }
|
#define UndefinedVariant() (Variant){.type = Variant_Undefined }
|
||||||
|
|
||||||
|
decl_typeclass_impl(Drop, Variant);
|
||||||
|
decl_typeclass_impl(Mirror, Variant);
|
||||||
|
|
||||||
#endif // !_fencer_variant_h
|
#endif // !_fencer_variant_h
|
||||||
|
|
Loading…
Reference in a new issue