# api_types.h ## Overview
Standard types and macros that are always available.
## Index
Types
`struct tm_vec2_t`
`struct tm_vec3_t`
`struct tm_vec4_t`
`struct tm_mat44_t`
`struct tm_transform_t`
`struct tm_rect_t`
`struct tm_str_t`
`tm_str()`
`tm_str_range()`
`struct tm_clock_o`
`struct tm_uuid_t`
`struct tm_color_srgb_t`
`TM_RGB()`
`struct tm_tt_type_t`
`struct tm_tt_id_t`
`tm_tt_type()`
`struct tm_tt_id_t`
`struct tm_tt_undo_scope_t`

Build configuration
`TM_OS_WINDOWS`
`TM_OS_MACOSX`
`TM_OS_LINUX`
`TM_OS_POSIX`
`TM_NO_MAIN_FIBER`
`TM_CONFIGURATION_DEBUG`
`TM_CONFIGURATION_RELEASE`

String hashes
`struct tm_strhash_t`
`TM_STRHASH()`
`TM_STRHASH_U64()`
`TM_STRHASH_EQUAL()`
`TM_STATIC_HASH()`

Macros
`TM_LITERAL()`
`TM_DLL_EXPORT`
`TM_ATOMIC`
`TM_CONCAT()`
`TM_MACRO_VAR()`
`TM_PAD()`
`TM_DISABLE_PADDING_WARNINGS`
`TM_RESTORE_PADDING_WARNINGS`
`TM_INHERITS()`
## API

Types

### `struct tm_vec2_t`
Represents a 2D vector. ~~~c typedef struct tm_vec2_t { float x, y; } tm_vec2_t; ~~~
### `struct tm_vec3_t`
Represents a 3D vector. ~~~c typedef struct tm_vec3_t { float x, y, z; } tm_vec3_t; ~~~
### `struct tm_vec4_t`
Represents a 4D vector. ~~~c typedef struct tm_vec4_t { float x, y, z, w; } tm_vec4_t; ~~~
### `struct tm_mat44_t`
Represents a 4x4 matrix. ~~~c typedef struct tm_mat44_t { float xx, xy, xz, xw; float yx, yy, yz, yw; float zx, zy, zz, zw; float wx, wy, wz, ww; } tm_mat44_t; ~~~
### `struct tm_transform_t`
Represents a transform in TRS form. ~~~c typedef struct tm_transform_t { tm_vec3_t pos; tm_vec4_t rot; tm_vec3_t scl; } tm_transform_t; ~~~
### `struct tm_rect_t`
Represents a rectangle. ~~~c typedef struct tm_rect_t { float x, y, w, h; } tm_rect_t; ~~~
### `struct tm_str_t`
Used to represent a string slice with pointer and length. This lets you reason about parts of a string, which you are not able to do with standard NULL-terminated strings. ~~~c typedef struct tm_str_t { // Pointer to string bytes. const char *data; // Length of the string. uint32_t size; // If set to *true*, indicates that there is an allocated NULL-byte after the string data. I.e. // `data[size] == 0`. This means that `data` can be used immediately as a C string without // needing to copy it to a separate memory area. // // If *false*, there may or may not be a NULL-byte at the end of the string and accessing // `data[size]` may cause an access violation, so if you want to use it as a C-string you have // to copy it to a new memory area and append a NULL byte. // // Note that the NULL-byte is never included in the `size`. uint32_t null_terminated; } tm_str_t; ~~~
### `tm_str()`
~~~c #define tm_str(s) ~~~ Creates a `tm_str_t` from a static string `s`.
### `tm_str_range()`
~~~c #define tm_str_range(s, e) ~~~ Creates a `tm_str_t` from a start pointer `s` and end pointer `e`.
### `struct tm_clock_o`
Represents a time from the system clock. You can assume the clock to be monotonically increasing, i.e. a larger `opaque` value represents a later time, but you shouldn't assume anything else about what the `opaque` value represents or the resolution of the timer. Instead, use `tm_os_time_api->delta()` to convert elapsed time to seconds. ~~~c typedef struct tm_clock_o { uint64_t opaque; } tm_clock_o; ~~~
### `struct tm_uuid_t`
Represents a unique 128-bit identifier. ~~~c typedef struct tm_uuid_t { uint64_t a; uint64_t b; } tm_uuid_t; ~~~
### `struct tm_color_srgb_t`
Represents an 8-bit per channel RGBA color in sRGB color space (Note: alpha is always linear.) ~~~c typedef struct tm_color_srgb_t { uint8_t r, g, b, a; } tm_color_srgb_t; ~~~
### `TM_RGB()`
~~~c #define TM_RGB(c) ~~~ Converts an `uint32_t` to an `tm_color_srgb_t` color. The nibbles in the `uint32_t` hex representation specify TRGB, where T is transparancy (0x00 means fully opaque and 0xff fully transparent, i.e. it is the invert of alpha). This lets you leave the highest nibble out for an opaque color (the most common case), but specify it if you want transparency. Hex | Color ---------- | ------------------- 0x00 | Black 0xff0000 | Red 0xff000000 | Transparent black 0x80ffff00 | 50 % transparent yellow
### `struct tm_tt_type_t`
Type representing a type in The Truth. ~~~c typedef struct tm_tt_type_t { uint64_t u64; } tm_tt_type_t; ~~~
### `struct tm_tt_id_t`
ID representing an object in The Truth. ~~~c typedef struct tm_tt_id_t { union { // Used for comparing objects or storing them in hash tables. uint64_t u64; struct { // Type of the object. uint64_t type : 10; // Generation of the object, used to distinguish objects created at the same index. uint64_t generation : 22; // Index of the object. uint64_t index : 32; }; }; } tm_tt_id_t; ~~~
### `tm_tt_type()`
~~~c static inline tm_tt_type_t tm_tt_type(tm_tt_id_t id) ~~~ Returns the type of `id`.
### `struct tm_tt_id_t`
~~~c typedef struct tm_tt_id_t { uint64_t u64; } tm_tt_id_t; ~~~
### `struct tm_tt_undo_scope_t`
Type representing an undo scope in The Truth. ~~~c typedef struct tm_tt_undo_scope_t { uint64_t u64; } tm_tt_undo_scope_t; ~~~

Build configuration

These macros are defined in the build file `premake5.lua`, but listed here for documentation purposes. ### `TM_OS_WINDOWS`
~~~c #define TM_OS_WINDOWS ~~~ Defined for Windows builds.
### `TM_OS_MACOSX`
~~~c #define TM_OS_MACOSX ~~~ Defined for OS X builds.
### `TM_OS_LINUX`
~~~c #define TM_OS_LINUX ~~~ Defined for Linux builds.
### `TM_OS_POSIX`
~~~c #define TM_OS_POSIX ~~~ Defined for POSIX builds (OS X or Linux).
### `TM_NO_MAIN_FIBER`
~~~c #define TM_NO_MAIN_FIBER ~~~ If defined, the main job runs on a thread, not a fiber.
### `TM_CONFIGURATION_DEBUG`
~~~c #define TM_CONFIGURATION_DEBUG ~~~ Defined for debug builds.
### `TM_CONFIGURATION_RELEASE`
~~~c #define TM_CONFIGURATION_RELEASE ~~~ Defined for release builds.

String hashes

`#define TM_USE_STRHASH_TYPE` controls whether we should use a custom type `tm_strhash_t` for string hashes, or if they should just be `uint64_t`. Currently, it is set to `0` when compiling using MSVC and `1` otherwise. We cannot use the `tm_strhash_t` type with the Visual Studio compiler, because it doesn't see our `TM_STATIC_HASH()` macro as a constant, and thus will generate [C2099](https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2099?view=msvc-160) compiler error. errors whenever it is used to initialize a global variable. This is unfortunate, because it means we can't get type safe string hashes in Visual Studio. Hopefully, this will be fixed in a future Visual Studio release and we can transition fully to the `tm_strhash_t` type. ### `struct tm_strhash_t`
Type-safe representation of a hashed string. !!! WARNING: WARNING In Visual Studio, string hashes won't use this string type, instead `tm_strhash_t` will be typedefed to `uint64_t`. The reason for this is that the `TM_STATIC_HASH()` macro is not seen as a constant by the MSVC compiler and thus using it to initialize global variables yields the [C2099](https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2099?view=msvc-160) compiler error. This means that the type safety of string hashes won't be checked when compiling with MSVC. Make sure you build your code under clang too, with `tmbuild --clang` to check the type safety of string hashes. Also, always use the macros `TM_STRHASH()` and `TM_STRHASH_U64()` to convert between `tm_strhash_t` and `uint64_t`. This ensures that the conversions work on all platforms. ~~~c typedef struct tm_strhash_t { uint64_t u64; } tm_strhash_t; ~~~
### `TM_STRHASH()`
~~~c #define TM_STRHASH(x) ~~~ Converts a `uint64_t` to a `tm_strhash_t`.
### `TM_STRHASH_U64()`
~~~c #define TM_STRHASH_U64(x) ~~~ Extracts the `uint64_t` of a `tm_strhash_t` value `x`.
### `TM_STRHASH_EQUAL()`
~~~c #define TM_STRHASH_EQUAL(a, b) ~~~ Returns true if the the two `tm_strhash_t` are equal.
### `TM_STATIC_HASH()`
~~~c #define TM_STATIC_HASH(s, v) ~~~ Used for static string hashes. The `hash.exe` utility checks the entire source code and makes sure that wherever you use `TM_STATIC_HASH()`, the numeric value `v` matches the actual hash of the string `s` (if not, the code is updated). When you create a new static hash, don't enter the numeric value, just the string: `TM_STATIC_HASH<!-- -->("bla")`. This ensures that the macro fails to compile until you run `hash.exe` to generate a numeric value. `TM_STATIC_HASH()` returns a constant value of type `tm_strhash_t`. <!-- `(sizeof("" s "") ? v : v)` is a trick to get an expression that evaluates to `v` but produces a compile error if `s` is anything other than a static string. -->

Macros

### `TM_LITERAL()`
~~~c #define TM_LITERAL(T) ~~~ Macro for creating a struct literal of type `T` that works both in C and C++. Use as: ~~~c x = TM_LITERAL(tm_vec2_t) {x, y} ~~~ In C, this turns into `(tm_vec2_t){0, 0}` and in C++ to `tm_vec2_t{0, 0}`. Note that use of `TM_LITERAL()` is only needed in .h and .inl files that might be included from both C and C++. In .c and .cpp file you should just use the native literal format instead of relying on `TM_LITERAL()`.
### `TM_DLL_EXPORT`
~~~c #define TM_DLL_EXPORT ~~~ Marks a function to be exported to DLLs.
### `TM_ATOMIC`
~~~c #define TM_ATOMIC ~~~ Mark struct fields in header files as atomic.
### `TM_CONCAT()`
~~~c #define TM_CONCAT(a, b) ~~~ Concatenates `a` and `b` , allowing you to expand macros before doing the concatenation. This is useful when used with builtin macros like `__LINE__` or `__COUNTER__`. `x##__COUNTER__` doesn't expand to `x1` since a macro is not expanded if preceded by `#` or `##`, but `TM_CONCAT(x, __COUNTER__)` works.
### `TM_MACRO_VAR()`
~~~c #define TM_MACRO_VAR(name) ~~~ Generates a unique name for a macro variable, based on `name`.
### `TM_PAD()`
~~~c #define TM_PAD(n) ~~~ Declares a field that pads a struct with the specified number of bytes. To ensure that structs are completely zero-initialized by designated initializers, we require all struct padding to be explicitly declared using this macro. (We enable warnings that trigger if there is undeclared padding in a struct.) Example: ~~~c struct x { uint32_t a; // This padding is needed since `b` needs to be aligned to a 64-bit boundary. TM_PAD(4); uint64_t b; }; ~~~ Note that in situations where types have different sizes on different platforms you may need to pad with different amounts: ~~~c TM_PAD(8 - sizeof(x)); ~~~
### `TM_DISABLE_PADDING_WARNINGS`
~~~c #define TM_DISABLE_PADDING_WARNINGS ~~~ Disable warnings about padding inserted into structs. Use this before including external headers that do not explicitly declare padding. Restore the padding warning afterwards with `TM_RESTORE_PADDING_WARNINGS`.
### `TM_RESTORE_PADDING_WARNINGS`
~~~c #define TM_RESTORE_PADDING_WARNINGS ~~~ Restore padding warnings disabled by `TM_DISABLE_PADDING_WARNINGS`.
### `TM_INHERITS()`
~~~c #define TM_INHERITS(TYPE) ~~~ Used to implement "inheritance" -- inserting the members of one struct into another, with a construct like: ~~~c struct tm_class_t { TM_INHERITS(struct tm_super_t); ... } ~~~ In a compiler that supports anonymous structs, (`-Wno-microsoft-anon-tag`, `-fms-extensions`), this will be expanded to just `struct tm_super_t;`, otherwise to `struct tm_super_t super;`. !!! note A struct should never have more than one `TM_INHERITS()` and it should always be placed at the top of the struct.