A 3D game engine from scratch.
1// (c) 2020 Vlad-Stefan Harbuz <vlad@vladh.net>
2
3#pragma once
4
5#include "memory.hpp"
6
7template <typename T>
8class Array {
9public:
10 memory::Pool *memory_pool = nullptr;
11 const char *debug_name = nullptr;
12 u32 length = 0;
13 u32 capacity = 0;
14 bool is_sparse = false;
15 u32 starting_idx = 0;
16 T *items = nullptr;
17
18 void alloc() {
19 this->items = (T*)memory::push(this->memory_pool, sizeof(T) * this->capacity, this->debug_name);
20 }
21
22 T* push() {
23 if (!this->items) {
24 alloc();
25 }
26 assert(this->length < this->capacity);
27 u32 new_idx = this->length;
28 this->length++;
29 T* new_slot = &this->items[new_idx];
30 return new_slot;
31 }
32
33 T* push(T new_item) {
34 T* new_slot = push();
35 *new_slot = new_item;
36 return new_slot;
37 }
38
39 T* get(u32 idx) {
40 if (!this->items) {
41 alloc();
42 }
43 assert(idx >= this->starting_idx && idx < this->capacity);
44 if (idx >= this->length) {
45 assert(this->is_sparse);
46 this->length = idx + 1;
47 }
48 return &this->items[idx];
49 }
50
51 T* operator[](u32 idx) {
52 return get(idx);
53 }
54
55 template <typename F>
56 T* find(F match) {
57 for (auto item = begin(); item < end(); item++) {
58 if (match(item)) {
59 return item;
60 }
61 }
62 return nullptr;
63 }
64
65 T* begin() {
66 return &this->items[this->starting_idx];
67 }
68
69 T* end() {
70 return &this->items[this->length];
71 }
72
73 void clear() {
74 memset(this->items, 0, sizeof(T) * this->capacity);
75 this->length = 0;
76 }
77
78 void delete_elements_after_index(u32 idx) {
79 memset(&this->items[idx], 0, sizeof(T) * (this->length - idx));
80 this->length = idx;
81 }
82
83 Array(
84 memory::Pool *memory_pool,
85 u32 capacity,
86 const char *debug_name,
87 bool is_sparse = false,
88 u32 starting_idx = 0
89 ) :
90 memory_pool(memory_pool),
91 debug_name(debug_name),
92 capacity(capacity),
93 is_sparse(is_sparse),
94 starting_idx(starting_idx)
95 {
96 }
97};