Browse Source

Update package reflect

gingerBill 4 years ago
parent
commit
aed63a6e8b
2 changed files with 63 additions and 29 deletions
  1. 52 28
      core/reflect/reflect.odin
  2. 11 1
      core/time/time.odin

+ 52 - 28
core/reflect/reflect.odin

@@ -344,24 +344,29 @@ index :: proc(val: any, i: int, loc := #caller_location) -> any {
 
 
 
-
+// Struct_Tag represents the type of the string of a struct field
+//
+// Through convention, tags are the concatenation of optionally space separationed key:"value" pairs.
+// Each key is a non-empty string which contains no control characters other than space, quotes, and colon.
 Struct_Tag :: distinct string;
 
 Struct_Field :: struct {
-	name:   string,
-	type:   typeid,
-	tag:    Struct_Tag,
-	offset: uintptr,
+	name:     string,
+	type:     typeid,
+	tag:      Struct_Tag,
+	offset:   uintptr,
+	is_using: bool,
 }
 
 struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) {
 	ti := runtime.type_info_base(type_info_of(T));
 	if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
 		if 0 <= i && i < len(s.names) {
-			field.name   = s.names[i];
-			field.type   = s.types[i].id;
-			field.tag    = Struct_Tag(s.tags[i]);
-			field.offset = s.offsets[i];
+			field.name     = s.names[i];
+			field.type     = s.types[i].id;
+			field.tag      = Struct_Tag(s.tags[i]);
+			field.offset   = s.offsets[i];
+			field.is_using = s.usings[i];
 		}
 	}
 	return;
@@ -372,10 +377,11 @@ struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) {
 	if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
 		for fname, i in s.names {
 			if fname == name {
-				field.name   = s.names[i];
-				field.type   = s.types[i].id;
-				field.tag    = Struct_Tag(s.tags[i]);
-				field.offset = s.offsets[i];
+				field.name     = s.names[i];
+				field.type     = s.types[i].id;
+				field.tag      = Struct_Tag(s.tags[i]);
+				field.offset   = s.offsets[i];
+				field.is_using = s.usings[i];
 				break;
 			}
 		}
@@ -531,23 +537,41 @@ enum_string :: proc(a: any) -> string {
 
 // Given a enum type and a value name, get the enum value.
 enum_from_name :: proc($EnumType: typeid, name: string) -> (value: EnumType, ok: bool) {
-    ti := type_info_base(type_info_of(EnumType));
-    if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
-        for value_name, i in eti.names {
-            if value_name != name {
-            	continue;
-            }
-            v := eti.values[i];
-            value = EnumType(v);
-            ok = true;
-            return;
-        }
-    } else {
-        panic("expected enum type to reflect.enum_from_name");
-    }
-    return;
+	ti := type_info_base(type_info_of(EnumType));
+	if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
+		for value_name, i in eti.names {
+			if value_name != name {
+				continue;
+			}
+			v := eti.values[i];
+			value = EnumType(v);
+			ok = true;
+			return;
+		}
+	} else {
+		panic("expected enum type to reflect.enum_from_name");
+	}
+	return;
+}
+
+enum_from_name_any :: proc(EnumType: typeid, name: string) -> (value: runtime.Type_Info_Enum_Value, ok: bool) {
+	ti := runtime.type_info_base(type_info_of(EnumType));
+	if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
+		for value_name, i in eti.names {
+			if value_name != name {
+				continue;
+			}
+			value = eti.values[i];
+			ok = true;
+			return;
+		}
+	} else {
+		panic("expected enum type to reflect.enum_from_name_any");
+	}
+	return;
 }
 
+
 union_variant_type_info :: proc(a: any) -> ^runtime.Type_Info {
 	id := union_variant_typeid(a);
 	return type_info_of(id);

+ 11 - 1
core/time/time.odin

@@ -108,7 +108,6 @@ duration_truncate :: proc(d, m: Duration) -> Duration {
 	return d if m <= 0 else d - d%m;
 }
 
-
 date :: proc(t: Time) -> (year: int, month: Month, day: int) {
 	year, month, day, _ = _abs_date(_time_abs(t), true);
 	return;
@@ -160,6 +159,17 @@ unix :: proc(sec: i64, nsec: i64) -> Time {
 	return Time{(sec*1e9 + nsec) + UNIX_TO_INTERNAL};
 }
 
+time_to_unix :: proc(t: Time) -> i64 {
+	return t._nsec/1e9;
+}
+
+time_to_unix_nano :: proc(t: Time) -> i64 {
+	return t._nsec;
+}
+
+time_add :: proc(t: Time, d: Duration) -> Time {
+	return Time{t._nsec + i64(d)};
+}
 
 
 ABSOLUTE_ZERO_YEAR :: i64(-292277022399); // Day is chosen so that 2001-01-01 is Monday in the calculations