From 664c2cd7a587feb18f02378506bdade2503343d3 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Wed, 21 Sep 2016 23:26:31 +0100 Subject: Fix enum type comparison; Start demo 003 code --- code/demo.odin | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- code/game.odin | 2 +- code/math.odin | 8 +- code/test.odin | 35 ++++++- 4 files changed, 318 insertions(+), 25 deletions(-) (limited to 'code') diff --git a/code/demo.odin b/code/demo.odin index 08f3dedde..19d997c33 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -2,34 +2,294 @@ #import "os.odin" + main :: proc() { - Fruit :: enum { - APPLE, - BANANA, - GRAPE, - MELON, - PEACH, - TOMATO, + // struct_padding() + // bounds_checking() + // type_introspection() + // any_type() + crazy_introspection() + // namespaces_and_files() + // miscellany() +} + +struct_padding :: proc() { + { + A :: struct { + a: u8 + b: u32 + c: u16 + } + + B :: struct { + a: [7]u8 + b: [3]u16 + c: u8 + d: u16 + } + + fmt.println("size_of(A):", size_of(A)) + fmt.println("size_of(B):", size_of(B)) + + // n.b. http://cbloomrants.blogspot.co.uk/2012/07/07-23-12-structs-are-not-what-you-want.html + } + { + A :: struct #ordered { + a: u8 + b: u32 + c: u16 + } + + B :: struct #ordered { + a: [7]u8 + b: [3]u16 + c: u8 + d: u16 + } + + fmt.println("size_of(A):", size_of(A)) + fmt.println("size_of(B):", size_of(B)) + + // C-style structure layout + } + { + A :: struct #packed { + a: u8 + b: u32 + c: u16 + } + + B :: struct #packed { + a: [7]u8 + b: [3]u16 + c: u8 + d: u16 + } + + fmt.println("size_of(A):", size_of(A)) + fmt.println("size_of(B):", size_of(B)) + + // Useful for explicit layout + } + + // Member sorting by priority + // Alignment desc. + // Size desc. + // source order asc. + + /* + A :: struct { + a: u8 + b: u32 + c: u16 + } + + B :: struct { + a: [7]u8 + b: [3]u16 + c: u8 + d: u16 + } + + Equivalent too + + A :: struct #ordered { + b: u32 + c: u16 + a: u8 + } + + B :: struct #ordered { + b: [3]u16 + d: u16 + a: [7]u8 + c: u8 + } + */ +} + +bounds_checking :: proc() { + x: [4]int + // x[-1] = 0; // Compile Time + // x[4] = 0; // Compile Time + + /*{ + a, b := -1, 4; + x[a] = 0; // Runtime Time + x[b] = 0; // Runtime Time + }*/ + + // Works for arrays, strings, slices, and related procedures & operations + + { + base: [10]int + s := base[2:6] + a, b := -1, 6 + + #no_bounds_check { + s[a] = 0; + // #bounds_check s[b] = 0; + } + + #no_bounds_check + if s[a] == 0 { + // Do whatever + } + + // Bounds checking can be toggled explicit + // on a per statement basis. + // _any statement_ + } +} + +type_introspection :: proc() { + + info: ^Type_Info + x: int + + info = type_info(int) // by type + info = type_info(x) // by value + // See: runtime.odin + + match type i : info { + case Type_Info.Integer: + fmt.println("integer!") + case Type_Info.Float: + fmt.println("float!") + default: + fmt.println("potato!") + } + + // Unsafe cast + integer_info := info as ^Type_Info.Integer +} + +any_type :: proc() { + a: any + + x := 123 + y := 6.28 + z := "Yo-Yo Ma" + // All types can be implicit cast to `any` + a = x + a = y + a = z + a = a + + // any has two members + // data - rawptr to the data + // type_info - pointer to the type info + + fmt.println(x, y, z) + // See: Implementation +} + +crazy_introspection :: proc() { + { + Fruit :: enum { + APPLE, + BANANA, + GRAPE, + MELON, + PEACH, + TOMATO, + } + + s: string + s = enum_to_string(Fruit.PEACH) + fmt.println(s) + + f := Fruit.GRAPE + s = enum_to_string(f) + fmt.println(s) + + fmt.println(f) } - fruit_ti := type_info(Fruit) - name := (fruit_ti as ^Type_Info.Named).name // Unsafe casts - info := type_info_base(fruit_ti) as ^Type_Info.Enum // Unsafe casts - fmt.printf("% :: enum ", name); - fmt.fprint_type(os.stdout, info.base) - fmt.printf(" {\n") - for i := 0; i < info.values.count; i++ { - fmt.printf("\t%\t= %,\n", info.names[i], info.values[i]) + { + // NOTE(bill): This is not safe code and I would not recommend this at all + // I'd recommend you use `match type` to get the subtype rather than + // casting pointers + + Fruit :: enum { + APPLE, + BANANA, + GRAPE, + MELON, + PEACH, + TOMATO, + } + + fruit_ti := type_info(Fruit) + name := (fruit_ti as ^Type_Info.Named).name // Unsafe casts + info := type_info_base(fruit_ti) as ^Type_Info.Enum // Unsafe casts + + fmt.printf("% :: enum ", name); + fmt.fprint_type(os.stdout, info.base) + fmt.printf(" {\n") + for i := 0; i < info.values.count; i++ { + fmt.printf("\t%\t= %,\n", info.names[i], info.values[i]) + } + fmt.printf("}\n") } - fmt.printf("}\n") - Vector3 :: struct {x, y, z: f32} - v := Vector3{x = 1, y = 4, z = 9} - fmt.println(v) + { + Vector3 :: struct {x, y, z: f32} + + a := Vector3{x = 1, y = 4, z = 9} + fmt.println(a) + b := Vector3{x = 9, y = 3, z = 1} + fmt.println(b) + + // NOTE(bill): See fmt.odin + } + + // n.b. This pretty much "solves" serialization (to strings) } +namespaces_and_files :: proc() { + /* + // Non-exporting import + #import "file.odin" + #import "file.odin" as file + #import "file.odin" as . + #import "file.odin" as _ + + // Exporting import + #load "file.odin" + */ + + // Talk about scope rules and diagram +} + +miscellany :: proc() { + /* + win32 `__imp__` prefix + #dll_import + #dll_export + + Change exported name/symbol for linking + #link_name + + Custom calling conventions + #stdcall + #fastcall + + Runtime stuff + #shared_global_scope + */ + + // assert(false) + // compile_assert(false) + // panic("Panic message goes here") +} + + + + + // #import "fmt.odin" as fmt // #foreign_system_library "Ws2_32" diff --git a/code/game.odin b/code/game.odin index fd1bcfa70..123f89982 100644 --- a/code/game.odin +++ b/code/game.odin @@ -206,7 +206,7 @@ run :: proc() { display_window(^window) ms_to_sleep := (16 - 1000*dt) as i32 if ms_to_sleep > 0 { - sleep_ms(ms_to_sleep) + win32.Sleep(ms_to_sleep) } } } diff --git a/code/math.odin b/code/math.odin index 5fea41adc..e9554f6b5 100644 --- a/code/math.odin +++ b/code/math.odin @@ -96,7 +96,7 @@ remainder :: proc(x, y: f32) -> f32 { fmod :: proc(x, y: f32) -> f32 { y = abs(y) result := remainder(abs(x), y) - if fsign(result) < 0 { + if sign32(result) < 0 { result += y } return copy_sign(result, x) @@ -120,9 +120,9 @@ cross :: proc(x, y: Vec3) -> Vec3 { } -vec2_mag :: proc(v: Vec2) -> f32 { return fsqrt(dot2(v, v)) } -vec3_mag :: proc(v: Vec3) -> f32 { return fsqrt(dot3(v, v)) } -vec4_mag :: proc(v: Vec4) -> f32 { return fsqrt(dot4(v, v)) } +vec2_mag :: proc(v: Vec2) -> f32 { return sqrt32(dot2(v, v)) } +vec3_mag :: proc(v: Vec3) -> f32 { return sqrt32(dot3(v, v)) } +vec4_mag :: proc(v: Vec4) -> f32 { return sqrt32(dot4(v, v)) } vec2_norm :: proc(v: Vec2) -> Vec2 { return v / Vec2{vec2_mag(v)} } vec3_norm :: proc(v: Vec3) -> Vec3 { return v / Vec3{vec3_mag(v)} } diff --git a/code/test.odin b/code/test.odin index b99a832c1..48f992ffa 100644 --- a/code/test.odin +++ b/code/test.odin @@ -1,5 +1,38 @@ #import "fmt.odin" -thing :: proc() #link_name "frankerooney" { +thing :: proc() { fmt.println("Hello!") } + +/* +#import "fmt.odin" as fmt + +thing :: proc() { + fmt.println("Hello!") +} +*/ + +/* +#import "fmt.odin" as . + +thing :: proc() { + println("Hello!") +} +*/ + +/* +#import "fmt.odin" as _ + +thing :: proc() { + // println("Hello!") +} +*/ + + +/* +#load "fmt.odin" + +thing :: proc() { + println("Hello!") +} +*/ -- cgit v1.2.3