// [..] T == Array(T)
// where
// Array :: struct (T: type_expr) {
-// data : T;
+// data : ^T;
// count : u32;
// capacity : u32;
// allocator : Allocator;
return arr.data[arr.count];
}
-transplant :: (arr: ^[..] $T, old_index: i32, new_index: i32) -> bool {
+concat :: (arr: ^[..] $T, other: [..] T) {
+ for ^o: other do push(arr, *o);
+}
+
+
+fold_idx_elem :: #match {
+ (arr: ^[..] $T, cmp: (T, T) -> bool) -> (i32, T) {
+ return fold_idx_elem(arr.data, arr.count, cmp);
+ },
+
+ (arr: ^$T, count: i32, cmp: (T, T) -> bool) -> (i32, T) {
+ idx := 0;
+ elem := arr[0];
+
+ for i: 1 .. count {
+ if cmp(arr[i], elem) {
+ idx = i;
+ elem = arr[i];
+ }
+ }
+
+ return idx, elem;
+ },
+}
+
+#private_file cmp_greater :: (x: $T, y: T) -> bool do return x > y;
+#private_file cmp_less :: (x: $T, y: T) -> bool do return x < y;
+
+greatest :: #match {
+ (arr: [..] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_greater); },
+ (arr: [] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_greater); },
+ (arr: [$N] $T) -> (i32, T) { return fold_idx_elem(cast(^T) arr, N, cmp_greater); },
+}
+
+least :: #match {
+ (arr: [..] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_less); },
+ (arr: [] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_less); },
+ (arr: [$N] $T) -> (i32, T) { return fold_idx_elem(cast(^T) arr, N, cmp_less); },
+}
+
+
+// Useful structure when talking about dynamic arrays where you don't know of what
+// type they store. For example, when passing a dynamic array as an 'any' argument.
+Untyped_Array :: struct {
+ data: rawptr;
+ count: u32;
+ capacity: u32;
+ allocator: Allocator;
+}
+
+
+
+// Things that work with slices and arrays
+
+transplant :: (arr: [] $T, old_index: i32, new_index: i32) -> bool {
if old_index < 0 || old_index >= arr.count do return false;
if new_index < 0 || new_index >= arr.count do return false;
if old_index == new_index do return true;
return true;
}
-get :: (arr: ^[..] $T, idx: i32) -> T {
+get :: (arr: [] $T, idx: i32) -> T {
if arr.count == 0 do return __zero_value(T);
while idx < 0 do idx += arr.count;
return arr.data[idx];
}
-get_ptr :: (arr: ^[..] $T, idx: i32) -> ^T {
+get_ptr :: (arr: [] $T, idx: i32) -> ^T {
if arr.count == 0 do return null;
while idx < 0 do idx += arr.count;
return ^arr.data[idx];
}
-set :: (arr: ^[..] $T, idx: i32, value: T) {
+set :: (arr: [] $T, idx: i32, value: T) {
if arr.count == 0 do return;
while idx < 0 do idx += arr.count;
arr.data[idx] = value;
}
-concat :: (arr: ^[..] $T, other: [..] T) {
- for ^o: other do push(arr, *o);
-}
-
// Uses '==' to compare for equality.
-contains :: #match {
- (arr: ^[..] $T, x: T) -> bool {
- for it: *arr do if it == x do return true;
- return false;
- },
-
- (arr: [] $T, x: T) -> bool {
- for it: arr do if it == x do return true;
- return false;
- }
+contains :: (arr: [] $T, x: T) -> bool {
+ for it: arr do if it == x do return true;
+ return false;
}
// Uses '+' to sum.
-sum :: #match {
- (arr: ^[..] $T, start: T = 0) -> T {
- sum := start;
- for it: *arr do sum += it;
- return sum;
- },
-
- (arr: [] $T, start: T = 0) -> T {
- sum := start;
- for it: arr do sum += it;
- return sum;
- }
+sum :: (arr: [] $T, start: T = 0) -> T {
+ sum := start;
+ for it: arr do sum += it;
+ return sum;
}
-product :: #match {
- (arr: ^[..] $T, start: T = 1) -> T {
- sum := start;
- for it: *arr do sum *= it;
- return sum;
- },
-
- (arr: [] $T, start: T = 1) -> T {
- sum := start;
- for it: arr do sum *= it;
- return sum;
- }
+product :: (arr: [] $T, start: T = 1) -> T {
+ prod := start;
+ for it: arr do prod *= it;
+ return prod;
}
-average :: (arr: ^[..] $T) -> T {
+average :: (arr: [] $T) -> T {
sum := cast(T) 0;
for it: *arr do sum += it;
return sum / cast(T) arr.count;
}
-to_slice :: #match {
- (arr: [..] $T) -> [] T {
- return arr.data[0 .. arr.count];
- },
-
- (arr: ^[..] $T) -> [] T {
- return arr.data[0 .. arr.count];
- },
-}
-
-/*
-** Simple insertion sort
-** cmp should return >0 if left > right
-*/
+//
+// Simple insertion sort
+// cmp should return >0 if left > right
+//
sort :: #match {
- (arr: ^[..] $T, cmp: (T, T) -> i32) {
+ (arr: [] $T, cmp: (T, T) -> i32) {
for i: 1 .. arr.count {
x := arr.data[i];
j := i - 1;
}
},
- (arr: ^[..] $T, cmp: (^T, ^T) -> i32) {
+ (arr: [] $T, cmp: (^T, ^T) -> i32) {
for i: 1 .. arr.count {
j := i;
}
}
-fold :: #match {
- (arr: ^[..] $T, init: $R, f: (T, R) -> R) -> R {
- val := init;
- for it: *arr do val = f(it, val);
- return val;
- },
-
- (arr: [] $T, init: $R, f: (T, R) -> R) -> R {
- val := init;
- for it: arr do val = f(it, val);
- return val;
- }
+fold :: (arr: [] $T, init: $R, f: (T, R) -> R) -> R {
+ val := init;
+ for it: arr do val = f(it, val);
+ return val;
}
map :: #match {
- macro (arr: [..] $T, f: (^T) -> void) do for ^it: arr do f(it);,
- macro (arr: [..] $T, f: (T) -> T) do for ^it: arr do *it = f(*it);,
- macro (arr: [..] $T, body: Code) do for ^it: arr do #insert body;,
- macro (arr: [..] $T, data: $R, f: (^T, R) -> void) do for ^it: arr do f(it, data);,
- macro (arr: [..] $T, data: $R, f: (T, R) -> T) do for ^it: arr do *it = f(*it, data);,
macro (arr: [] $T, f: (^T) -> void) do for ^it: arr do f(it);,
macro (arr: [] $T, f: (T) -> T) do for ^it: arr do *it = f(*it);,
macro (arr: [] $T, body: Code) do for ^it: arr do #insert body;,
macro (arr: [] $T, data: $R, f: (T, R) -> T) do for ^it: arr do *it = f(*it, data);,
}
-every :: (arr: ^[..] $T, predicate: (T) -> bool) -> bool {
+every :: (arr: [] $T, predicate: (T) -> bool) -> bool {
val := true;
- for ^it: *arr do val = val && predicate(*it);
+ for ^it: arr do val = val && predicate(*it);
return val;
}
-some :: (arr: ^[..] $T, predicate: (T) -> bool) -> bool {
+some :: (arr: [] $T, predicate: (T) -> bool) -> bool {
val := false;
- for ^it: *arr {
+ for ^it: arr {
val = val || predicate(*it);
if val do break;
}
return val;
}
-fill :: (arr: ^[..] $T, value: T) {
+fill :: (arr: [] $T, value: T) {
for i: arr.count {
- arr.data[i] = value;
+ arr[i] = value;
}
}
-fill_range :: (arr: ^[..] $T, r: range, value: T) {
+fill_range :: (arr: [] $T, r: range, value: T) {
for i: r {
if i >= arr.count || i < 0 do continue;
- arr.data[i] = value;
+ arr[i] = value;
}
}
-to_list :: (arr: ^[..] $T, allocator := context.allocator) -> List(T) {
+to_list :: (arr: [] $T, allocator := context.allocator) -> List(T) {
new_list := list.make(T, allocator);
- for ^it: *arr {
+ for ^it: arr {
list.push_end(^new_list, *it);
}
return new_list;
}
-find :: (arr: ^[..] $T, value: T) -> i32 {
+find :: (arr: [] $T, value: T) -> i32 {
for i: arr.count {
if value == arr.data[i] do return i;
}
return -1;
}
-find_ptr :: (arr: ^[..] $T, value: T) -> ^T {
- for ^it: *arr {
+find_ptr :: (arr: [] $T, value: T) -> ^T {
+ for ^it: arr {
if value == *it do return it;
}
return null;
}
-first :: #match {
- (arr: ^[..] $T, predicate: (T) -> bool) -> ^T {
- first((#type [] T).{ arr.data, arr.count }, predicate);
- },
-
- (arr: [] $T, predicate: (T) -> bool) -> ^T {
- for ^it: arr {
- if predicate(*it) do return it;
- }
+first :: (arr: [] $T, predicate: (T) -> bool) -> ^T {
+ for ^it: arr {
+ if predicate(*it) do return it;
+ }
- return null;
- },
+ return null;
}
count_where :: #match {
- (arr: ^[..] $T, predicate: $Pred) -> u32 {
- return count_where((#type [] T).{ arr.data, arr.count }, predicate);
- },
-
(arr: [] $T, predicate: (T) -> bool) -> u32 {
count: u32 = 0;
for ^it: arr do if predicate(*it) do count += 1;
},
}
-fold_idx_elem :: #match {
- (arr: ^[..] $T, cmp: (T, T) -> bool) -> (i32, T) {
- return fold_idx_elem(arr.data, arr.count, cmp);
- },
-
- (arr: ^$T, count: i32, cmp: (T, T) -> bool) -> (i32, T) {
- idx := 0;
- elem := arr[0];
-
- for i: 1 .. count {
- if cmp(arr[i], elem) {
- idx = i;
- elem = arr[i];
- }
- }
-
- return idx, elem;
- },
-}
-
-#private_file cmp_greater :: (x: $T, y: T) -> bool do return x > y;
-#private_file cmp_less :: (x: $T, y: T) -> bool do return x < y;
-
-greatest :: #match {
- (arr: [..] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_greater); },
- (arr: [] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_greater); },
- (arr: [$N] $T) -> (i32, T) { return fold_idx_elem(cast(^T) arr, N, cmp_greater); },
-}
-
-least :: #match {
- (arr: [..] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_less); },
- (arr: [] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_less); },
- (arr: [$N] $T) -> (i32, T) { return fold_idx_elem(cast(^T) arr, N, cmp_less); },
-}
-
-
-// Useful structure when talking about dynamic arrays where you don't know of what
-// type they store. For example, when passing a dynamic array as an 'any' argument.
-Untyped_Array :: struct {
- data: rawptr;
- count: u32;
- capacity: u32;
- allocator: Allocator;
-}
world_transform_stack = array.make(Transform, capacity=1);
array.insert_empty(^world_transform_stack, 0);
- transform_identity(array.get_ptr(^world_transform_stack, -1));
+ transform_identity(array.get_ptr(world_transform_stack, -1));
scissor_stack = array.make(Scissor_State);
gl.bindBuffer(gl.ARRAY_BUFFER, -1);
- world_transform := array.get_ptr(^world_transform_stack, -1);
+ world_transform := array.get_ptr(world_transform_stack, -1);
world_matrix := transform_to_matrix(world_transform);
gl.uniformMatrix4(shader.world_uniform, false, world_matrix);
if world_transform_dirty {
world_transform_dirty = false;
- world_transform := array.get_ptr(^world_transform_stack, -1);
+ world_transform := array.get_ptr(world_transform_stack, -1);
world_matrix := transform_to_matrix(world_transform);
for shader: (#type ^Shader).[ ^simple_shader, ^textured_shader, ^alpha_shader ] {
world_transform_dirty = true;
array.push(^world_transform_stack, world_transform_stack[world_transform_stack.count - 1]);
- *array.get_ptr(^world_transform_stack, -1) = *array.get_ptr(^world_transform_stack, -2);
+ *array.get_ptr(world_transform_stack, -1) = *array.get_ptr(world_transform_stack, -2);
// transform_identity(array.get_ptr(^world_transform_stack, -1));
}
}
identity :: (use ir: ^Immediate_Renderer) {
- transform_identity(array.get_ptr(^world_transform_stack, -1));
+ transform_identity(array.get_ptr(world_transform_stack, -1));
}
get_transform :: (use ir: ^Immediate_Renderer) -> ^Transform {
- return array.get_ptr(^world_transform_stack, -1);
+ return array.get_ptr(world_transform_stack, -1);
}
apply_transform :: (use ir: ^Immediate_Renderer, transform: Transform) {
- transform_apply(array.get_ptr(^world_transform_stack, -1), transform);
+ transform_apply(array.get_ptr(world_transform_stack, -1), transform);
world_transform_dirty = true;
}
I.push_matrix();
defer I.pop_matrix();
-}
\ No newline at end of file
+}