diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index ed50d658b..f27ed570e 100644 --- a/core/reflect/reflect.odin +++ b/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); diff --git a/core/time/time.odin b/core/time/time.odin index 6eb4d7cb2..740a0df5b 100644 --- a/core/time/time.odin +++ b/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