Retype out the entire bindings for Orca

This commit is contained in:
gingerBill
2024-03-19 22:36:56 +00:00
parent 5714ea4ea3
commit fdc48a242d
15 changed files with 1255 additions and 2089 deletions

View File

@@ -1,58 +0,0 @@
package orca
import "core:math"
// TODO use orcas or native?
@(default_calling_convention="c", link_prefix="oc_")
foreign {
mat2x3_mul_m :: proc(lhs, rhs: mat2x3) -> mat2x3 ---
mat2x3_inv :: proc(x: mat2x3) -> mat2x3 ---
mat2x3_mul :: proc(m: mat2x3, p: vec2) -> vec2 ---
mat2x3_rotate :: proc(radians: f32) -> mat2x3 ---
mat2x3_translate :: proc(x, y: f32) -> mat2x3 ---
}
// mat2x3_mul_m :: proc "contextless" (lhs, rhs: mat2x3) -> (res: mat2x3) {
// res[0] = lhs[0] * rhs[0] + lhs[1] * rhs[3]
// res[1] = lhs[0] * rhs[1] + lhs[1] * rhs[4]
// res[2] = lhs[0] * rhs[2] + lhs[1] * rhs[5] + lhs[2]
// res[3] = lhs[3] * rhs[0] + lhs[4] * rhs[3]
// res[4] = lhs[3] * rhs[1] + lhs[4] * rhs[4]
// res[5] = lhs[3] * rhs[2] + lhs[4] * rhs[5] + lhs[5]
// return
// }
// mat2x3_inv :: proc "contextless" (x: mat2x3) -> (res: mat2x3) {
// res[0] = x[4] / (x[0] * x[4] - x[1] * x[3])
// res[1] = x[1] / (x[1] * x[3] - x[0] * x[4])
// res[3] = x[3] / (x[1] * x[3] - x[0] * x[4])
// res[4] = x[0] / (x[0] * x[4] - x[1] * x[3])
// res[2] = -(x[2] * res[0] + x[5] * res[1])
// res[5] = -(x[2] * res[3] + x[5] * res[4])
// return
// }
// mat2x3_mul :: proc "contextless" (m: mat2x3, p: vec2) -> vec2 {
// return {
// p.x * m[0] + p.y * m[1] + m[2],
// p.x * m[3] + p.y * m[4] + m[5],
// }
// }
// mat2x3_rotate :: proc "contextless" (radians: f32) -> mat2x3 {
// sinRot := math.sin(radians)
// cosRot := math.cos(radians)
// rot := mat2x3 {
// cosRot, -sinRot, 0,
// sinRot, cosRot, 0,
// }
// return rot
// }
// mat2x3_translate :: proc "contextless" (x, y: f32) -> mat2x3 {
// return {
// 1, 0, x,
// 0, 1, y,
// }
// }

View File

@@ -1,366 +0,0 @@
package orca
import "core:c"
window :: distinct u64
mouse_cursor :: enum c.int {
ARROW,
RESIZE_0,
RESIZE_90,
RESIZE_45,
RESIZE_135,
TEXT,
}
window_style :: enum u32 {
NO_TITLE = 0x01 << 0,
FIXED_SIZE = 0x01 << 1,
NO_CLOSE = 0x01 << 2,
NO_MINIFY = 0x01 << 3,
NO_FOCUS = 0x01 << 4,
FLOAT = 0x01 << 5,
POPUPMENU = 0x01 << 6,
NO_BUTTONS = 0x01 << 7
}
event_type :: enum c.int {
NONE,
KEYBOARD_MODS, //TODO: remove, keep only key?
KEYBOARD_KEY,
KEYBOARD_CHAR,
MOUSE_BUTTON,
MOUSE_MOVE,
MOUSE_WHEEL,
MOUSE_ENTER,
MOUSE_LEAVE,
CLIPBOARD_PASTE,
WINDOW_RESIZE,
WINDOW_MOVE,
WINDOW_FOCUS,
WINDOW_UNFOCUS,
WINDOW_HIDE, // rename to minimize?
WINDOW_SHOW, // rename to restore?
WINDOW_CLOSE,
PATHDROP,
FRAME,
QUIT
}
key_action :: enum c.int {
NO_ACTION,
PRESS,
RELEASE,
REPEAT
}
key_code :: enum c.int {
KEY_UNKNOWN = '\x00',
KEY_SPACE = ' ',
KEY_APOSTROPHE = '\'',
KEY_COMMA = ',',
KEY_MINUS = '-',
KEY_PERIOD = '.',
KEY_SLASH = '/',
KEY_0 = '0',
KEY_1 = '1',
KEY_2 = '2',
KEY_3 = '3',
KEY_4 = '4',
KEY_5 = '5',
KEY_6 = '6',
KEY_7 = '7',
KEY_8 = '8',
KEY_9 = '9',
KEY_SEMICOLON = ';',
KEY_EQUAL = '=',
KEY_LEFT_BRACKET = '[',
KEY_BACKSLASH = '\\',
KEY_RIGHT_BRACKET = ']',
KEY_GRAVE_ACCENT = '`',
KEY_A = 'a',
KEY_B = 'b',
KEY_C = 'c',
KEY_D = 'd',
KEY_E = 'e',
KEY_F = 'f',
KEY_G = 'g',
KEY_H = 'h',
KEY_I = 'i',
KEY_J = 'j',
KEY_K = 'k',
KEY_L = 'l',
KEY_M = 'm',
KEY_N = 'n',
KEY_O = 'o',
KEY_P = 'p',
KEY_Q = 'q',
KEY_R = 'r',
KEY_S = 's',
KEY_T = 't',
KEY_U = 'u',
KEY_V = 'v',
KEY_W = 'w',
KEY_X = 'x',
KEY_Y = 'y',
KEY_Z = 'z',
KEY_WORLD_1 = 161,
KEY_WORLD_2 = 162,
KEY_ESCAPE = 256,
KEY_ENTER = 257,
KEY_TAB = 258,
KEY_BACKSPACE = 259,
KEY_INSERT = 260,
KEY_DELETE = 261,
KEY_RIGHT = 262,
KEY_LEFT = 263,
KEY_DOWN = 264,
KEY_UP = 265,
KEY_PAGE_UP = 266,
KEY_PAGE_DOWN = 267,
KEY_HOME = 268,
KEY_END = 269,
KEY_CAPS_LOCK = 280,
KEY_SCROLL_LOCK = 281,
KEY_NUM_LOCK = 282,
KEY_PRINT_SCREEN = 283,
KEY_PAUSE = 284,
KEY_F1 = 290,
KEY_F2 = 291,
KEY_F3 = 292,
KEY_F4 = 293,
KEY_F5 = 294,
KEY_F6 = 295,
KEY_F7 = 296,
KEY_F8 = 297,
KEY_F9 = 298,
KEY_F10 = 299,
KEY_F11 = 300,
KEY_F12 = 301,
KEY_F13 = 302,
KEY_F14 = 303,
KEY_F15 = 304,
KEY_F16 = 305,
KEY_F17 = 306,
KEY_F18 = 307,
KEY_F19 = 308,
KEY_F20 = 309,
KEY_F21 = 310,
KEY_F22 = 311,
KEY_F23 = 312,
KEY_F24 = 313,
KEY_F25 = 314,
KEY_KP_0 = 320,
KEY_KP_1 = 321,
KEY_KP_2 = 322,
KEY_KP_3 = 323,
KEY_KP_4 = 324,
KEY_KP_5 = 325,
KEY_KP_6 = 326,
KEY_KP_7 = 327,
KEY_KP_8 = 328,
KEY_KP_9 = 329,
KEY_KP_DECIMAL = 330,
KEY_KP_DIVIDE = 331,
KEY_KP_MULTIPLY = 332,
KEY_KP_SUBTRACT = 333,
KEY_KP_ADD = 334,
KEY_KP_ENTER = 335,
KEY_KP_EQUAL = 336,
KEY_LEFT_SHIFT = 340,
KEY_LEFT_CONTROL = 341,
KEY_LEFT_ALT = 342,
KEY_LEFT_SUPER = 343,
KEY_RIGHT_SHIFT = 344,
KEY_RIGHT_CONTROL = 345,
KEY_RIGHT_ALT = 346,
KEY_RIGHT_SUPER = 347,
KEY_MENU = 348,
}
scan_code :: enum c.int {
SCANCODE_UNKNOWN = 0,
SCANCODE_SPACE = 32,
SCANCODE_APOSTROPHE = 39,
SCANCODE_COMMA = 44,
SCANCODE_MINUS = 45,
SCANCODE_PERIOD = 46,
SCANCODE_SLASH = 47,
SCANCODE_0 = 48,
SCANCODE_1 = 49,
SCANCODE_2 = 50,
SCANCODE_3 = 51,
SCANCODE_4 = 52,
SCANCODE_5 = 53,
SCANCODE_6 = 54,
SCANCODE_7 = 55,
SCANCODE_8 = 56,
SCANCODE_9 = 57,
SCANCODE_SEMICOLON = 59,
SCANCODE_EQUAL = 61,
SCANCODE_LEFT_BRACKET = 91,
SCANCODE_BACKSLASH = 92,
SCANCODE_RIGHT_BRACKET = 93,
SCANCODE_GRAVE_ACCENT = 96,
SCANCODE_A = 97,
SCANCODE_B = 98,
SCANCODE_C = 99,
SCANCODE_D = 100,
SCANCODE_E = 101,
SCANCODE_F = 102,
SCANCODE_G = 103,
SCANCODE_H = 104,
SCANCODE_I = 105,
SCANCODE_J = 106,
SCANCODE_K = 107,
SCANCODE_L = 108,
SCANCODE_M = 109,
SCANCODE_N = 110,
SCANCODE_O = 111,
SCANCODE_P = 112,
SCANCODE_Q = 113,
SCANCODE_R = 114,
SCANCODE_S = 115,
SCANCODE_T = 116,
SCANCODE_U = 117,
SCANCODE_V = 118,
SCANCODE_W = 119,
SCANCODE_X = 120,
SCANCODE_Y = 121,
SCANCODE_Z = 122,
SCANCODE_WORLD_1 = 161,
SCANCODE_WORLD_2 = 162,
SCANCODE_ESCAPE = 256,
SCANCODE_ENTER = 257,
SCANCODE_TAB = 258,
SCANCODE_BACKSPACE = 259,
SCANCODE_INSERT = 260,
SCANCODE_DELETE = 261,
SCANCODE_RIGHT = 262,
SCANCODE_LEFT = 263,
SCANCODE_DOWN = 264,
SCANCODE_UP = 265,
SCANCODE_PAGE_UP = 266,
SCANCODE_PAGE_DOWN = 267,
SCANCODE_HOME = 268,
SCANCODE_END = 269,
SCANCODE_CAPS_LOCK = 280,
SCANCODE_SCROLL_LOCK = 281,
SCANCODE_NUM_LOCK = 282,
SCANCODE_PRINT_SCREEN = 283,
SCANCODE_PAUSE = 284,
SCANCODE_F1 = 290,
SCANCODE_F2 = 291,
SCANCODE_F3 = 292,
SCANCODE_F4 = 293,
SCANCODE_F5 = 294,
SCANCODE_F6 = 295,
SCANCODE_F7 = 296,
SCANCODE_F8 = 297,
SCANCODE_F9 = 298,
SCANCODE_F10 = 299,
SCANCODE_F11 = 300,
SCANCODE_F12 = 301,
SCANCODE_F13 = 302,
SCANCODE_F14 = 303,
SCANCODE_F15 = 304,
SCANCODE_F16 = 305,
SCANCODE_F17 = 306,
SCANCODE_F18 = 307,
SCANCODE_F19 = 308,
SCANCODE_F20 = 309,
SCANCODE_F21 = 310,
SCANCODE_F22 = 311,
SCANCODE_F23 = 312,
SCANCODE_F24 = 313,
SCANCODE_F25 = 314,
SCANCODE_KP_0 = 320,
SCANCODE_KP_1 = 321,
SCANCODE_KP_2 = 322,
SCANCODE_KP_3 = 323,
SCANCODE_KP_4 = 324,
SCANCODE_KP_5 = 325,
SCANCODE_KP_6 = 326,
SCANCODE_KP_7 = 327,
SCANCODE_KP_8 = 328,
SCANCODE_KP_9 = 329,
SCANCODE_KP_DECIMAL = 330,
SCANCODE_KP_DIVIDE = 331,
SCANCODE_KP_MULTIPLY = 332,
SCANCODE_KP_SUBTRACT = 333,
SCANCODE_KP_ADD = 334,
SCANCODE_KP_ENTER = 335,
SCANCODE_KP_EQUAL = 336,
SCANCODE_LEFT_SHIFT = 340,
SCANCODE_LEFT_CONTROL = 341,
SCANCODE_LEFT_ALT = 342,
SCANCODE_LEFT_SUPER = 343,
SCANCODE_RIGHT_SHIFT = 344,
SCANCODE_RIGHT_CONTROL = 345,
SCANCODE_RIGHT_ALT = 346,
SCANCODE_RIGHT_SUPER = 347,
SCANCODE_MENU = 348,
}
keymod_flags :: enum c.int {
NONE = 0x00,
ALT = 0x01,
SHIFT = 0x02,
CTRL = 0x04,
CMD = 0x08,
MAIN_MODIFIER = 0x10 /* CMD on Mac, CTRL on Win32 */
}
mouse_button :: enum c.int {
LEFT = 0x00,
RIGHT = 0x01,
MIDDLE = 0x02,
EXT1 = 0x03,
EXT2 = 0x04,
}
// keyboard and mouse buttons input
key_event :: struct {
action: key_action,
scanCode: scan_code,
keyCode: key_code,
button: mouse_button,
mods: keymod_flags,
clickCount: u8,
}
// character input
char_event :: struct {
codepoint: utf32,
sequence: [8]c.char,
seqLen: u8,
}
// mouse move/scroll
mouse_event :: struct {
x: f32,
y: f32,
deltaX: f32,
deltaY: f32,
mods: keymod_flags,
}
// window resize / move
move_event :: struct {
frame: rect,
content: rect,
}
event :: struct {
//TODO clipboard and path drop
window: window,
type: event_type,
_: struct #raw_union {
key: key_event,
character: char_event,
mouse: mouse_event,
move: move_event,
paths: str8_list,
}
}

View File

@@ -1,247 +0,0 @@
package orca
import "core:c"
// types
color :: distinct [4]f32
utf32 :: rune
// handles
surface :: distinct u32
font :: distinct u64
image :: distinct u64
canvas :: distinct u64
joint_type :: enum c.int {
MITER,
BEVEL,
NONE,
}
cap_type :: enum c.int {
NONE,
SQUARE,
}
font_metrics :: struct {
ascent: f32, // the extent above the baseline (by convention a positive value extends above the baseline)
descent: f32, // the extent below the baseline (by convention, positive value extends below the baseline)
lineGap: f32, // spacing between one row's descent and the next row's ascent
xHeight: f32, // height of the lower case letter 'x'
capHeight: f32, // height of the upper case letter 'M'
width: f32, // maximum width of the font
}
glyph_metrics :: struct {
ink: rect,
advance: vec2,
}
text_metrics :: struct {
ink: rect,
logical: rect,
advance: vec2,
}
rect_atlas :: struct {
arena: ^arena,
size: vec2i,
pos: vec2i,
lineHeight: u32,
}
image_region :: struct {
image: image,
rect: rect,
}
//------------------------------------------------------------------------------------------
// graphics surface
//------------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_", link_suffix="_argptr_stub")
foreign {
surface_nil :: proc() -> surface ---
surface_is_nil :: proc() -> c.bool ---
surface_canvas :: proc(s: ^surface) ---
surface_destroy :: proc(surface: surface) ---
surface_get_size :: proc(surface: surface) -> vec2 ---
surface_contents_scaling :: proc(surface: surface) -> vec2 ---
surface_bring_to_front :: proc(surface: surface) ---
surface_send_to_back :: proc(surface: surface) ---
surface_gles :: proc(surface: ^surface) ---
surface_select :: proc(surface: surface) ---
surface_deselect :: proc() ---
surface_present :: proc(surface: surface) ---
}
//------------------------------------------------------------------------------------------
// 2D canvas command buffer
//------------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
canvas_nil :: proc() -> canvas ---
canvas_is_nil :: proc(canvas: canvas) -> c.bool ---
canvas_create :: proc() -> canvas ---
canvas_destroy :: proc(canvas: canvas) ---
canvas_set_current :: proc(_canvas: canvas) -> canvas ---
canvas_select :: proc(_canvas: canvas) -> canvas ---
render :: proc(canvas: canvas) ---
}
//------------------------------------------------------------------------------------------
// transform and clipping
//------------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
matrix_push :: proc(mat: mat2x3) ---
matrix_multiply_push :: proc(mat: mat2x3) ---
matrix_pop :: proc() ---
matrix_top :: proc() -> mat2x3 ---
clip_push :: proc(x, y, w, h: f32) ---
clip_pop :: proc() ---
clip_top :: proc() -> rect ---
}
//------------------------------------------------------------------------------------------
// graphics attributes setting/getting
//------------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
set_color :: proc(color: color) ---
set_color_rgba :: proc(r, g, b, a: f32) ---
set_width :: proc(width: f32) ---
set_tolerance :: proc(tolerance: f32) ---
set_joint :: proc(joint: joint_type) ---
set_max_joint_excursion :: proc(maxJointExcursion: f32) ---
set_cap :: proc(cap: cap_type) ---
set_font :: proc(font: font) ---
set_font_size :: proc(size: f32) ---
set_text_flip :: proc(flip: c.bool) ---
set_image :: proc(image: image) ---
set_image_source_region :: proc(region: rect) ---
get_color :: proc() -> color ---
get_width :: proc() -> f32 ---
get_tolerance :: proc() -> f32 ---
get_joint :: proc() -> joint_type ---
get_max_joint_excursion :: proc() -> f32 ---
get_cap :: proc() -> cap_type ---
get_font :: proc() -> font ---
get_font_size :: proc() -> f32 ---
get_text_flip :: proc() -> bool ---
get_image :: proc() -> image ---
}
//------------------------------------------------------------------------------------------
// path construction
//------------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
get_position :: proc() -> vec2 ---
move_to :: proc(x, y: f32) ---
line_to :: proc(x, y: f32) ---
quadratic_to :: proc(x1, y1, x2, y2: f32) ---
cubic_to :: proc(x1, y1, x2, y2, x3, y3: f32) ---
close_path :: proc() ---
glyph_outlines :: proc(glyphIndices: str32) -> rect ---
codepoints_outlines :: proc(str: str32) ---
text_outlines :: proc(str: str8) ---
}
//------------------------------------------------------------------------------------------
// clear/fill/stroke
//------------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
clear :: proc() ---
fill :: proc() ---
stroke :: proc() ---
}
//------------------------------------------------------------------------------------------
// shapes helpers
//------------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
rectangle_fill :: proc(x, y, w, h: f32) ---
rectangle_stroke :: proc(x, y, w, h: f32) ---
rounded_rectangle_fill :: proc(x, y, w, h, r: f32) ---
rounded_rectangle_stroke :: proc(x, y, w, h, r: f32) ---
ellipse_fill :: proc(x, y, rx, ry: f32) ---
ellipse_stroke :: proc(x, y, rx, ry: f32) ---
circle_fill :: proc(x, y, r: f32) ---
circle_stroke :: proc(x, y, r: f32) ---
arc :: proc(x, y, r, arcAngle, startAngle: f32) ---
image_draw :: proc(image: image, rect: rect) ---
image_draw_region :: proc(image: image, srcRegion, dstRegion: rect) ---
text_fill :: proc(x, y: f32, text: str8) ---
}
//------------------------------------------------------------------------------------------
// fonts
//------------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
font_nil :: proc() -> font ---
font_is_nil :: proc(font: font) -> c.bool ---
font_create_from_memory :: proc(mem: str8, rangeCount: u32, ranges: [^]unicode_range) -> font ---
font_create_from_file :: proc(file: file, rangeCount: u32, ranges: [^]unicode_range) -> font ---
font_create_from_path :: proc(path: str8, rangeCount: u32, ranges: [^]unicode_range) -> font ---
font_destroy :: proc(font: font) ---
font_get_glyph_indices :: proc(font: font, codePoints: str32, backing: str32) -> str32 ---
font_push_glyph_indices :: proc(arena: ^arena, font: font, codePoints: str32) -> str32 ---
font_get_glyph_index :: proc(font: font, codePoint: utf32) -> u32 ---
font_get_metrics :: proc(font: font, emSize: f32) -> font_metrics ---
font_get_metrics_unscaled :: proc(font: font) -> font_metrics ---
font_get_scale_for_em_pixels :: proc(font: font, emSize: f32) -> f32 ---
font_text_metrics_utf32 :: proc(font: font, fontSize: f32, codepoints: str32) -> text_metrics ---
font_text_metrics :: proc(font: font, fontSize: f32, text: str8) -> text_metrics ---
}
//------------------------------------------------------------------------------------------
// images
//------------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
image_nil :: proc() -> image ---
image_is_nil :: proc(a: image) -> c.bool ---
image_create :: proc(surface: surface, width, height: u32) -> image ---
image_create_from_rgba8 :: proc(surface: surface, width, height: u32, pixels: [^]u8) -> image ---
image_create_from_memory :: proc(surface: surface, mem: str8, flip: c.bool) -> image ---
image_create_from_file :: proc(surface: surface, file: file, flip: c.bool) -> image ---
image_create_from_path :: proc(surface: surface, path: str8, flip: c.bool) -> image ---
image_destroy :: proc(image: image) ---
image_upload_region_rgba8 :: proc(image: image, region: rect, pixels: [^]u8) ---
image_size :: proc(image: image) -> vec2 ---
}
//------------------------------------------------------------------------------------------
// image atlas
//------------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
rect_atlas_create :: proc(arena: ^arena, width, height: i32) -> ^rect_atlas ---
rect_atlas_alloc :: proc(atlas: ^rect_atlas, width, height: i32) -> rect ---
rect_atlas_recycle :: proc(atlas: ^rect_atlas, rect: rect) ---
image_atlas_allfrom_rgba8 :: proc(atlas: ^rect_atlas, backingImage: image, width, height: u32, pixels: [^]u8) -> image_region ---
image_atlas_allfrom_memory :: proc(atlas: ^rect_atlas, backingImage: image, mem: str8, flip: c.bool) -> image_region ---
image_atlas_allfrom_file :: proc(atlas: ^rect_atlas, backingImage: image, file: file, flip: c.bool) -> image_region ---
image_atlas_allfrom_path :: proc(atlas: ^rect_atlas, backingImage: image, path: str8, flip: c.bool) -> image_region ---
image_atlas_recycle :: proc(atlas: ^rect_atlas, imageRgn: image_region) ---
}

View File

@@ -1,59 +0,0 @@
package orca
import "core:c"
key_state :: struct {
lastUpdate: u64,
transitionCount: u32,
repeatCount: u32,
down: c.bool,
sysClicked: c.bool,
sysDoubleClicked: c.bool,
sysTripleClicked: c.bool,
}
keyboard_state :: struct {
keys: [len(key_code)]key_state,
mods: keymod_flags,
}
mouse_state :: struct {
lastUpdate: u64,
posValid: c.bool,
pos: vec2,
delta: vec2,
wheel: vec2,
_: struct #raw_union {
buttons: [len(mouse_button)]key_state,
_: struct {
left: key_state,
right: key_state,
middle: key_state,
ext1: key_state,
ext2: key_state,
}
}
}
INPUT_TEXT_BACKING_SIZE :: 64
text_state :: struct {
lastUpdate: u64,
backing: [INPUT_TEXT_BACKING_SIZE]utf32,
codePoints: str32,
}
clipboard_state :: struct {
lastUpdate: u64,
pastedText: str8,
}
input_state :: struct {
frameCounter: u64,
keyboard: keyboard_state,
mouse: mouse_state,
text: text_state,
clipboard: clipboard_state,
}

View File

@@ -1,159 +0,0 @@
package orca
import "core:c"
file :: distinct u64 // handle
file_access :: enum u16 {
NONE = 0,
READ = 1 << 1,
WRITE = 1 << 2,
}
file_open_flags :: enum u16 {
NONE = 0,
APPEND = 1 << 1,
TRUNCATE = 1 << 2,
CREATE = 1 << 3,
SYMLINK = 1 << 4,
NO_FOLLOW = 1 << 5,
RESTRICT = 1 << 6,
}
file_whence :: enum c.int {
SEEK_SET,
SEEK_END,
SEEK_CURRENT,
}
io_error :: enum i32 {
OK = 0,
ERR_UNKNOWN,
ERR_OP, // unsupported operation
ERR_HANDLE, // invalid handle
ERR_PREV, // previously had a fatal error (last error stored on handle)
ERR_ARG, // invalid argument or argument combination
ERR_PERM, // access denied
ERR_SPACE, // no space left
ERR_NO_ENTRY, // file or directory does not exist
ERR_EXISTS, // file already exists
ERR_NOT_DIR, // path element is not a directory
ERR_DIR, // attempted to write directory
ERR_MAX_FILES, // max open files reached
ERR_MAX_LINKS, // too many symbolic links in path
ERR_PATH_LENGTH, // path too long
ERR_FILE_SIZE, // file too big
ERR_OVERFLOW, // offset too big
ERR_NOT_READY, // no data ready to be read/written
ERR_MEM, // failed to allocate memory
ERR_INTERRUPT, // operation interrupted by a signal
ERR_PHYSICAL, // physical IO error
ERR_NO_DEVICE, // device not found
ERR_WALKOUT, // attempted to walk out of root directory
}
//----------------------------------------------------------------
// File System wrapper API
//----------------------------------------------------------------
file_type :: enum c.int {
UNKNOWN,
REGULAR,
DIRECTORY,
SYMLINK,
BLOCK,
CHARACTER,
FIFO,
SOCKET,
}
file_perm :: enum u16 {
OTHER_EXEC = 1 << 0,
OTHER_WRITE = 1 << 1,
OTHER_READ = 1 << 2,
GROUP_EXEC = 1 << 3,
GROUP_WRITE = 1 << 4,
GROUP_READ = 1 << 5,
OWNER_EXEC = 1 << 6,
OWNER_WRITE = 1 << 7,
OWNER_READ = 1 << 8,
STICKY_BIT = 1 << 9,
SET_GID = 1 << 10,
SET_UID = 1 << 11,
}
datestamp :: struct {
seconds: i64, // seconds relative to NTP epoch.
fraction: u64, // fraction of seconds elapsed since the time specified by seconds.
}
file_status :: struct {
uid: u64,
type: file_type,
perm: file_perm,
size: u64,
creationDate: datestamp,
accessDate: datestamp,
modificationDate: datestamp,
}
// TODO file dialogs
// typedef struct oc_file_open_with_dialog_elt
// {
// oc_list_elt listElt;
// oc_file file;
// } oc_file_open_with_dialog_elt;
// typedef struct oc_file_open_with_dialog_result
// {
// oc_file_dialog_button button;
// oc_file file;
// oc_list selection;
// } oc_file_open_with_dialog_result;
// file_open_with_dialog_result :: u64 // TODO
// file_dialog_desc :: u64 // TODO
//----------------------------------------------------------------
// Low-level File IO API
//----------------------------------------------------------------
// @(default_calling_convention="c", link_prefix="oc_")
// foreign {
// oc_io_cmp oc_io_wait_single_req(oc_io_req* req);
// }
//----------------------------------------------------------------
// High-level File IO API
//----------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
file_nil :: proc() -> file ---
file_is_nil :: proc(handle: file) -> c.bool ---
file_open :: proc(path: str8, rights: file_access, flags: file_open_flags) -> file ---
file_open_at :: proc(dir: file, path: str8, rights: file_access, flags: file_open_flags) -> file ---
file_close :: proc(file: file) ---
file_last_error :: proc(handle: file) -> io_error ---
file_pos :: proc(file: file) -> i64 ---
file_seek :: proc(file: file, offset: i64, whence: file_whence) -> i64 ---
file_write :: proc(file: file, size: u64, buffer: [^]byte) -> u64 ---
file_read :: proc(file: file, size: u64, buffer: [^]byte) -> u64 ---
file_get_status :: proc(file: file) -> file_status ---
file_size :: proc(file: file) -> u64 ---
}
//----------------------------------------------------------------
// Asking users for file capabilities
//----------------------------------------------------------------
// @(default_calling_convention="c", link_prefix="oc_")
// foreign {
// file_open_with_request :: proc(path: str8, rights: file_access, flags: file_open_flags) -> file ---
// file_open_with_dialog :: proc(arena: ^arena, rights: file_access, flags: file_open_flags, desc: ^file_dialog_desc) -> file_open_with_dialog_result ---
// }

View File

@@ -1,117 +0,0 @@
package orca
// TODO could check if container/intrusive/list/intrusive_list.odin can be used
//----------------------------------------------------------------
// Lists
//----------------------------------------------------------------
list_elt :: struct {
prev: ^list_elt,
next: ^list_elt,
}
list :: struct {
first: ^list_elt,
last: ^list_elt,
}
list_init :: proc "c" (list: ^list) {
list.first = nil
list.last = nil
}
list_insert :: proc "c" (list: ^list, afterElt, elt: ^list_elt) {
elt.prev = afterElt
elt.next = afterElt.next
if afterElt.next != nil {
afterElt.next.prev = elt
} else {
list.last = elt
}
afterElt.next = elt
// OC_DEBUG_ASSERT(elt.next != elt, "list_insert(): can't insert an element into itself")
}
list_insert_before :: proc "c" (list: ^list, beforeElt, elt: ^list_elt) {
elt.next = beforeElt
elt.prev = beforeElt.prev
if beforeElt.prev != nil {
beforeElt.prev.next = elt
} else {
list.first = elt
}
beforeElt.prev = elt
// OC_DEBUG_ASSERT(elt.next != elt, "list_insert_before(): can't insert an element into itself")
}
list_remove :: proc "c" (list: ^list, elt: ^list_elt) {
if elt.prev != nil {
elt.prev.next = elt.next
} else {
// OC_DEBUG_ASSERT(list.first == elt)
list.first = elt.next
}
if elt.next != nil {
elt.next.prev = elt.prev
} else {
// OC_DEBUG_ASSERT(list.last == elt)
list.last = elt.prev
}
elt.prev = nil
elt.next = nil
}
list_push :: proc "c" (list: ^list, elt: ^list_elt) {
elt.next = list.first
elt.prev = nil
if list.first != nil {
list.first.prev = elt
} else {
list.last = elt
}
list.first = elt
}
list_pop :: proc "c" (list: ^list) -> ^list_elt {
elt := list.first
if elt != list.last {
list_remove(list, elt)
return elt
} else {
return nil
}
}
list_push_back :: proc "c" (list: ^list, elt: ^list_elt) {
elt.prev = list.last
elt.next = nil
if list.last != nil {
list.last.next = elt
} else {
list.first = elt
}
list.last = elt
}
list_append :: list_push_back
list_pop_back :: proc "c" (list: ^list) -> ^list_elt {
elt := list.last
if elt != nil {
list_remove(list, elt)
return elt
} else {
return nil
}
}
list_empty :: proc "c" (list: ^list) -> bool {
return list.first == nil || list.last == nil
}

View File

@@ -0,0 +1,332 @@
package orca
import "core:c"
surface_data :: struct {}
canvas_backend :: struct {}
surface_destroy_proc :: proc "c" (surface: ^surface_data)
surface_select_proc :: proc "c" (surface: ^surface_data)
surface_deselect_proc :: proc "c" (surface: ^surface_data)
surface_present_proc :: proc "c" (surface: ^surface_data)
surface_swap_interval_proc :: proc "c" (surface: ^surface_data, swap: c.int)
surface_get_size_proc :: proc "c" (surface: ^surface_data) -> vec2
surface_contents_scaling_proc :: proc "c" (surface: ^surface_data) -> vec2
surface_get_hidden_proc :: proc "c" (surface: ^surface_data) -> bool
surface_set_hidden_proc :: proc "c" (surface: ^surface_data, hidden: bool);
surface_native_layer_proc :: proc "c" (surface: ^surface_data) -> rawptr
surface_bring_to_front_proc :: proc "c" (surface: ^surface_data)
surface_send_to_back_proc :: proc "c" (surface: ^surface_data)
//------------------------------------------------------------------------
// canvas structs
//------------------------------------------------------------------------
path_elt_type :: enum c.int {
MOVE,
LINE,
QUADRATIC,
CUBIC,
}
path_elt :: struct {
type: path_elt_type,
p: [3]vec2,
}
path_descriptor :: struct {
startIndex: u32,
count: u32,
startPoint: vec2,
}
attributes :: struct {
width: f32,
tolerance: f32,
color: color,
joint: joint_type,
maxJointExcursion: f32,
cap: cap_type,
font: font,
fontSize: f32,
image: image,
srcRegion: rect,
transform: mat2x3,
clip: rect,
}
primitive_cmd :: enum {
FILL,
STROKE,
JUMP,
}
primitive :: struct {
cmd: primitive_cmd,
attributes: attributes,
using _: struct #raw_union {
path: path_descriptor,
rect: rect,
jump: u32,
},
}
surface_api :: enum c.int {
NONE,
METAL,
GL,
GLES,
CANVAS,
HOST,
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
is_surface_api_available :: proc(api: surface_api) -> bool ---
}
//------------------------------------------------------------------------------------------
//SECTION: graphics surface
//------------------------------------------------------------------------------------------
surface :: struct {
h: u64,
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
oc_surface_nil :: proc() -> surface --- //DOC: returns a nil surface
oc_surface_is_nil :: proc(surface: surface) -> bool --- //DOC: true if surface is nil
oc_surface_canvas :: proc() -> surface --- //DOC: creates a surface for use with the canvas API
oc_surface_gles :: proc() -> surface --- //DOC: create a surface for use with GLES API
oc_surface_destroy :: proc(surface: surface) --- //DOC: destroys the surface
oc_surface_select :: proc(surface: surface) --- //DOC: selects the surface in the current thread before drawing
oc_surface_deselect :: proc() --- //DOC: deselects the current thread's previously selected surface
oc_surface_get_selected :: proc() -> surface ---
oc_surface_present :: proc(surface: surface) --- //DOC: presents the surface to its window
oc_surface_get_size :: proc(surface: surface) -> vec2 ---
oc_surface_contents_scaling:: proc(surface: surface) -> vec2 --- //DOC: returns the scaling of the surface (pixels = points * scale)
oc_surface_bring_to_front :: proc(surface: surface) --- //DOC: puts surface on top of the surface stack
oc_surface_send_to_back :: proc(surface: surface) --- //DOC: puts surface at the bottom of the surface stack
}
//------------------------------------------------------------------------------------------
//SECTION: graphics canvas structs
//------------------------------------------------------------------------------------------
canvas :: struct {h: u64}
font :: struct {h: u64}
image :: struct {h: u64}
joint_type :: enum c.int {
MITER = 0,
BEVEL,
NONE,
}
cap_type :: enum c.int {
NONE = 0,
SQUARE,
}
font_metrics :: struct {
ascent: f32, // the extent above the baseline (by convention a positive value extends above the baseline)
descent: f32, // the extent below the baseline (by convention, positive value extends below the baseline)
lineGap: f32, // spacing between one row's descent and the next row's ascent
xHeight: f32, // height of the lower case letter 'x'
capHeight: f32, // height of the upper case letter 'M'
width: f32, // maximum width of the font
}
glyph_metrics :: struct {
ink: rect,
advance: vec2,
}
text_metrics :: struct {
ink: rect,
logical: rect,
advance: vec2,
}
//NOTE: image atlas helpers
image_region :: struct {
image: image,
rect: rect,
}
/*
@(default_calling_convention="c", link_prefix="oc_")
foreign {
//------------------------------------------------------------------------------------------
//SECTION: graphics canvas
//------------------------------------------------------------------------------------------
ORCA_API oc_canvas oc_canvas_nil(); //DOC: returns a nil canvas
ORCA_API bool oc_canvas_is_nil(oc_canvas canvas); //DOC: true if canvas is nil
ORCA_API oc_canvas oc_canvas_create(); //DOC: create a new canvas
ORCA_API void oc_canvas_destroy(oc_canvas canvas); //DOC: destroys canvas
ORCA_API oc_canvas oc_canvas_select(oc_canvas canvas); //DOC: selects canvas in the current thread
ORCA_API void oc_render(oc_canvas canvas); //DOC: renders all canvas commands onto surface
//------------------------------------------------------------------------------------------
//SECTION: fonts
//------------------------------------------------------------------------------------------
ORCA_API oc_font oc_font_nil();
ORCA_API bool oc_font_is_nil(oc_font font);
ORCA_API oc_font oc_font_create_from_memory(oc_str8 mem, u32 rangeCount, oc_unicode_range* ranges);
ORCA_API oc_font oc_font_create_from_file(oc_file file, u32 rangeCount, oc_unicode_range* ranges);
ORCA_API oc_font oc_font_create_from_path(oc_str8 path, u32 rangeCount, oc_unicode_range* ranges);
ORCA_API void oc_font_destroy(oc_font font);
ORCA_API oc_str32 oc_font_get_glyph_indices(oc_font font, oc_str32 codePoints, oc_str32 backing);
ORCA_API oc_str32 oc_font_push_glyph_indices(oc_arena* arena, oc_font font, oc_str32 codePoints);
ORCA_API u32 oc_font_get_glyph_index(oc_font font, oc_utf32 codePoint);
// metrics
ORCA_API oc_font_metrics oc_font_get_metrics(oc_font font, f32 emSize);
ORCA_API oc_font_metrics oc_font_get_metrics_unscaled(oc_font font);
ORCA_API f32 oc_font_get_scale_for_em_pixels(oc_font font, f32 emSize);
ORCA_API oc_text_metrics oc_font_text_metrics_utf32(oc_font font, f32 fontSize, oc_str32 codepoints);
ORCA_API oc_text_metrics oc_font_text_metrics(oc_font font, f32 fontSize, oc_str8 text);
//------------------------------------------------------------------------------------------
//SECTION: images
//------------------------------------------------------------------------------------------
ORCA_API oc_image oc_image_nil();
ORCA_API bool oc_image_is_nil(oc_image a);
ORCA_API oc_image oc_image_create(oc_surface surface, u32 width, u32 height);
ORCA_API oc_image oc_image_create_from_rgba8(oc_surface surface, u32 width, u32 height, u8* pixels);
ORCA_API oc_image oc_image_create_from_memory(oc_surface surface, oc_str8 mem, bool flip);
ORCA_API oc_image oc_image_create_from_file(oc_surface surface, oc_file file, bool flip);
ORCA_API oc_image oc_image_create_from_path(oc_surface surface, oc_str8 path, bool flip);
ORCA_API void oc_image_destroy(oc_image image);
ORCA_API void oc_image_upload_region_rgba8(oc_image image, oc_rect region, u8* pixels);
ORCA_API oc_vec2 oc_image_size(oc_image image);
//------------------------------------------------------------------------------------------
//SECTION: atlasing
//------------------------------------------------------------------------------------------
//NOTE: rectangle allocator
typedef struct oc_rect_atlas oc_rect_atlas;
ORCA_API oc_rect_atlas* oc_rect_atlas_create(oc_arena* arena, i32 width, i32 height);
ORCA_API oc_rect oc_rect_atlas_alloc(oc_rect_atlas* atlas, i32 width, i32 height);
ORCA_API void oc_rect_atlas_recycle(oc_rect_atlas* atlas, oc_rect rect);
ORCA_API oc_image_region oc_image_atlas_alloc_from_rgba8(oc_rect_atlas* atlas, oc_image backingImage, u32 width, u32 height, u8* pixels);
ORCA_API oc_image_region oc_image_atlas_alloc_from_memory(oc_rect_atlas* atlas, oc_image backingImage, oc_str8 mem, bool flip);
ORCA_API oc_image_region oc_image_atlas_alloc_from_file(oc_rect_atlas* atlas, oc_image backingImage, oc_file file, bool flip);
ORCA_API oc_image_region oc_image_atlas_alloc_from_path(oc_rect_atlas* atlas, oc_image backingImage, oc_str8 path, bool flip);
ORCA_API void oc_image_atlas_recycle(oc_rect_atlas* atlas, oc_image_region imageRgn);
//------------------------------------------------------------------------------------------
//SECTION: transform, viewport and clipping
//------------------------------------------------------------------------------------------
ORCA_API void oc_matrix_push(oc_mat2x3 matrix);
ORCA_API void oc_matrix_multiply_push(oc_mat2x3 matrix);
ORCA_API void oc_matrix_pop();
ORCA_API oc_mat2x3 oc_matrix_top();
ORCA_API void oc_clip_push(f32 x, f32 y, f32 w, f32 h);
ORCA_API void oc_clip_pop();
ORCA_API oc_rect oc_clip_top();
//------------------------------------------------------------------------------------------
//SECTION: graphics attributes setting/getting
//------------------------------------------------------------------------------------------
ORCA_API void oc_set_color(oc_color color);
ORCA_API void oc_set_color_rgba(f32 r, f32 g, f32 b, f32 a);
ORCA_API void oc_set_width(f32 width);
ORCA_API void oc_set_tolerance(f32 tolerance);
ORCA_API void oc_set_joint(oc_joint_type joint);
ORCA_API void oc_set_max_joint_excursion(f32 maxJointExcursion);
ORCA_API void oc_set_cap(oc_cap_type cap);
ORCA_API void oc_set_font(oc_font font);
ORCA_API void oc_set_font_size(f32 size);
ORCA_API void oc_set_text_flip(bool flip);
ORCA_API void oc_set_image(oc_image image);
ORCA_API void oc_set_image_source_region(oc_rect region);
ORCA_API oc_color oc_get_color();
ORCA_API f32 oc_get_width();
ORCA_API f32 oc_get_tolerance();
ORCA_API oc_joint_type oc_get_joint();
ORCA_API f32 oc_get_max_joint_excursion();
ORCA_API oc_cap_type oc_get_cap();
ORCA_API oc_font oc_get_font();
ORCA_API f32 oc_get_font_size();
ORCA_API bool oc_get_text_flip();
ORCA_API oc_image oc_get_image();
ORCA_API oc_rect oc_get_image_source_region();
//------------------------------------------------------------------------------------------
//SECTION: path construction
//------------------------------------------------------------------------------------------
ORCA_API oc_vec2 oc_get_position();
ORCA_API void oc_move_to(f32 x, f32 y);
ORCA_API void oc_line_to(f32 x, f32 y);
ORCA_API void oc_quadratic_to(f32 x1, f32 y1, f32 x2, f32 y2);
ORCA_API void oc_cubic_to(f32 x1, f32 y1, f32 x2, f32 y2, f32 x3, f32 y3);
ORCA_API void oc_close_path();
ORCA_API oc_rect oc_glyph_outlines(oc_str32 glyphIndices);
ORCA_API void oc_codepoints_outlines(oc_str32 string);
ORCA_API void oc_text_outlines(oc_str8 string);
//------------------------------------------------------------------------------------------
//SECTION: clear/fill/stroke
//------------------------------------------------------------------------------------------
ORCA_API void oc_clear();
ORCA_API void oc_fill();
ORCA_API void oc_stroke();
//------------------------------------------------------------------------------------------
//SECTION: shapes helpers
//------------------------------------------------------------------------------------------
ORCA_API void oc_rectangle_fill(f32 x, f32 y, f32 w, f32 h);
ORCA_API void oc_rectangle_stroke(f32 x, f32 y, f32 w, f32 h);
ORCA_API void oc_rounded_rectangle_fill(f32 x, f32 y, f32 w, f32 h, f32 r);
ORCA_API void oc_rounded_rectangle_stroke(f32 x, f32 y, f32 w, f32 h, f32 r);
ORCA_API void oc_ellipse_fill(f32 x, f32 y, f32 rx, f32 ry);
ORCA_API void oc_ellipse_stroke(f32 x, f32 y, f32 rx, f32 ry);
ORCA_API void oc_circle_fill(f32 x, f32 y, f32 r);
ORCA_API void oc_circle_stroke(f32 x, f32 y, f32 r);
ORCA_API void oc_arc(f32 x, f32 y, f32 r, f32 arcAngle, f32 startAngle);
ORCA_API void oc_text_fill(f32 x, f32 y, oc_str8 text);
//NOTE: image helpers
ORCA_API void oc_image_draw(oc_image image, oc_rect rect);
ORCA_API void oc_image_draw_region(oc_image image, oc_rect srcRegion, oc_rect dstRegion);
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
egl_surface_create_for_window :: proc(window: window) -> ^surface_data ---
egl_surface_create_remote :: proc(width, height: u32) -> ^surface_data ---
}
*/

View File

@@ -0,0 +1,40 @@
package orca
import "core:c"
import ilist "core:container/intrusive/list"
@(default_calling_convention="c", link_prefix="oc_")
foreign {
str8_push_buffer :: proc(arena: ^arena, len: u64, buffer: rawptr) -> str8 ---
str8_push_cstring :: proc(arena: ^arena, str: cstring) -> str8 ---
str8_push_copy :: proc(arena: ^arena, s: string) -> str8 ---
str8_to_cstring :: proc(arena: ^arena, s: str8) -> cstring ---
}
// string lists
//----------------------------------------------------------------------------------
str8_elt :: struct {
listElt: list_elt,
string: str8,
}
str8_list :: struct {
list: list,
eltCount: u64,
len: u64,
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
str8_list_push :: proc(arena: ^arena, list: ^str8_list, str: string) ---
str8_list_collate :: proc(arena: ^arena, list: str8_list, prefix, separator, postfix: string) -> str8 ---
str8_list_join :: proc(arena: ^arena, list: str8_list) -> str8 ---
str8_split :: proc(arena: ^arena, str: string, separators: str8_list) -> str8_list ---
win32_utf8_to_wide :: proc(arena: ^arena, s: str8) -> str16 ---
win32_wide_to_utf8 :: proc(arena: ^arena, s: str16) -> str8 ---
win32_path_normalize_slash_in_place :: proc(path: []byte) ---
}

View File

@@ -0,0 +1,75 @@
package orca
import "core:c"
THREAD_NAME_MAX_SIZE :: 64 // including null terminator
thread :: struct {}
thread_start_proc :: proc "c" (userPointer: rawptr) -> i32
@(default_calling_convention="c", link_prefix="oc_")
foreign {
thread_create :: proc(start: thread_start_proc, userPointer: rawptr) -> ^thread ---
thread_create_with_name :: proc(start: thread_start_proc, userPointer: rawptr, name: string) -> ^thread ---
thread_get_name :: proc(thread: ^thread) -> string ---
thread_unique_id :: proc(thread: ^thread) -> u64 ---
thread_self_id :: proc() -> u64 ---
thread_signal :: proc(thread: ^thread, sig: c.int) -> c.int ---
thread_join :: proc(thread: ^thread, exitCode: ^i64) -> c.int ---
thread_detach :: proc(thread: ^thread) -> c.int ---
}
//---------------------------------------------------------------
// Platform Mutex API
//---------------------------------------------------------------
mutex :: struct {}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
mutex_create :: proc() -> ^mutex ---
mutex_destroy :: proc(mutex: ^mutex) -> c.int ---
mutex_lock :: proc(mutex: ^mutex) -> c.int ---
mutex_unlock :: proc(mutex: ^mutex) -> c.int ---
}
//---------------------------------------------------------------
// Lightweight ticket mutex API
//---------------------------------------------------------------
ticket :: struct {
nextTicket: u64, // volatile and atomic
serving: u64, // volatile and atomic
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
ticket_init :: proc(mutex: ^ticket) ---
ticket_lock :: proc(mutex: ^ticket) ---
ticket_unlock :: proc(mutex: ^ticket) ---
}
//---------------------------------------------------------------
// Platform condition variable API
//---------------------------------------------------------------
condition :: struct {}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
condition_create :: proc() -> ^condition ---
condition_destroy :: proc(cond: ^condition) -> c.int ---
condition_wait :: proc(cond: ^condition, mutex: ^mutex) -> c.int ---
condition_timedwait :: proc(cond: ^condition, mutex: ^mutex, seconds: f64) -> c.int ---
condition_signal :: proc(cond: ^condition) -> c.int ---
condition_broadcast :: proc(cond: ^condition) -> c.int ---
}
//---------------------------------------------------------------
// Putting threads to sleep
//---------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
sleep_nano :: proc(nanoseconds: u64) --- // sleep for a given number of nanoseconds
}

View File

@@ -0,0 +1,807 @@
package orca
import "core:c"
import ilist "core:container/intrusive/list"
list_elt :: ilist.Node
list :: ilist.List
vec2 :: [2]f32
vec3 :: [3]f32
vec4 :: [4]f32
vec2i :: [2]i32
mat2x3 :: #row_major matrix[2, 3]f32
rect :: struct {
x, y: f32,
w, h: f32,
}
color :: distinct [4]f32
str8 :: string
str16 :: []u16
str32 :: []rune
clock_kind :: enum c.int {
MONOTONIC, // clock that increment monotonically
UPTIME, // clock that increment monotonically during uptime
DATE // clock that is driven by the platform time
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
clock_time :: proc(clock: clock_kind) -> f64 ---
}
//----------------------------------------------------------------
// Assert / Abort
//----------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
abort_ext :: proc(file: cstring, function: cstring, line: c.int, fmt: cstring, #c_vararg args: ..any) -> ! ---
assert_fail :: proc(file: cstring, function: cstring, line: c.int, src: cstring, fmt: cstring, #c_vararg args: ..any) -> ! ---
}
//----------------------------------------------------------------
// Logging
//----------------------------------------------------------------
log_level :: enum c.int {
ERROR,
WARNING,
INFO,
}
log_output :: struct {}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
@(link_name="OC_LOG_DEFAULT_OUTPUT")
LOG_DEFAULT_OUTPUT: ^log_output
log_set_level :: proc(level: log_level) ---
log_set_output :: proc(output: ^log_output) ---
log_ext :: proc(level: log_level,
function: cstring,
file: cstring,
line: c.int,
fmt: cstring,
#c_vararg args: ..any) ---
}
//--------------------------------------------------------------------------------
//NOTE(martin): base allocator
//--------------------------------------------------------------------------------
mem_reserve_proc :: proc "c" (ctx: ^base_allocator, size: u64) -> rawptr
mem_modify_proc :: proc "c" (ctx: ^base_allocator, ptr: rawptr, size: u64)
base_allocator :: struct {
reserve: mem_reserve_proc,
commit: mem_modify_proc,
decommit: mem_modify_proc,
release: mem_modify_proc,
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
base_allocator_default :: proc() -> ^base_allocator ---
}
//--------------------------------------------------------------------------------
//NOTE(martin): memory arena
//--------------------------------------------------------------------------------
arena_chunk :: struct {
listElt: list_elt,
ptr: [^]byte,
offset: u64,
committed: u64,
cap: u64,
}
arena :: struct {
base: ^base_allocator,
chunks: list,
currentChunk: ^arena_chunk,
}
arena_scope :: struct {
arena: ^arena,
chunk: ^arena_chunk,
offset: u64,
}
arena_options :: struct {
base: ^base_allocator,
reserve: u64,
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
arena_init :: proc(arena: ^arena) ---
arena_init_with_options :: proc(arena: ^arena, #by_ptr options: arena_options) ---
arena_cleanup :: proc(arena: ^arena) ---
arena_push :: proc(arena: ^arena, size: u64) -> rawptr ---
arena_push_aligned :: proc(arena: ^arena, size: u64, alignment: u32) -> rawptr ---
arena_clear :: proc(arena: ^arena) ---
arena_scope_begin :: proc(arena: ^arena) -> arena_scope ---
arena_scope_end :: proc(scope: arena_scope) ---
}
arena_push_type :: proc "c" (arena: ^arena, $T: typeid) -> ^T {
return (^T)(arena_push_aligned(arena, size_of(type), align_of(type)))
}
arena_push_array :: proc "c" (arena: ^arena, $T: typeid, #any_int count: int) -> []T {
return ([^]T)(arena_push_aligned(arena, size_of(type)*u64(count), align_of(type)))[:count]
}
//----------------------------------------------------------------
// IO API
//----------------------------------------------------------------
file :: struct {
h: u64,
}
file_open_flags :: distinct bit_set[file_open_flags_enum; u16]
file_open_flags_enum :: enum u16 {
APPEND = 1,
TRUNCATE = 2,
CREATE = 3,
SYMLINK = 4,
NO_FOLLOW = 5,
RESTRICT = 6,
}
file_access :: distinct bit_set[file_access_enum; u16]
file_access_enum :: enum u16 {
READ = 1,
WRITE = 2,
}
file_whence :: enum c.int {
SET,
END,
CURRENT,
}
io_req_id :: distinct u64
io_op :: enum u32 {
OPEN_AT = 0,
CLOSE,
FSTAT,
SEEK,
READ,
WRITE,
ERROR,
};
io_req :: struct {
id: io_req_id,
op: io_op,
handle: file,
offset: i64,
size: u64,
using _: struct #raw_union {
buffer: [^]byte,
_: u64,
},
using _: struct #raw_union {
open: struct {
rights: file_access,
flags: file_open_flags,
},
whence: file_whence,
},
}
io_error :: enum u32 {
NONE = 0,
UNKNOWN,
OP, // unsupported operation
HANDLE, // invalid handle
PREV, // previously had a fatal error (last error stored on handle)
ARG, // invalid argument or argument combination
PERM, // access denied
SPACE, // no space left
NO_ENTRY, // file or directory does not exist
EXISTS, // file already exists
NOT_DIR, // path element is not a directory
DIR, // attempted to write directory
MAX_FILES, // max open files reached
MAX_LINKS, // too many symbolic links in path
PATH_LENGTH, // path too long
FILE_SIZE, // file too big
OVERFLOW, // offset too big
NOT_READY, // no data ready to be read/written
MEM, // failed to allocate memory
INTERRUPT, // operation interrupted by a signal
PHYSICAL, // physical IO error
NO_DEVICE, // device not found
WALKOUT, // attempted to walk out of root directory
}
io_cmp :: struct {
id: io_req_id,
error: io_error,
using _: struct #raw_union {
result: i64,
size: u64,
offset: i64,
handle: file,
}
}
@(default_calling_convention="c", link_prefix="oc_", link_suffix="_argptr_stub")
foreign {
//----------------------------------------------------------------
//TODO: complete io queue api
//----------------------------------------------------------------
io_wait_single_req :: proc(req: ^io_req) -> io_cmp ---
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
//----------------------------------------------------------------
// File IO wrapper API
//----------------------------------------------------------------
file_nil :: proc() -> file ---
file_is_nil :: proc(handle: file) -> bool ---
file_open :: proc(path: string, rights: file_access, flags: file_open_flags) -> file ---
file_open_at :: proc(dir: file, path: string, rights: file_access, flags: file_open_flags) -> file ---
file_close :: proc(file: file) ---
file_pos :: proc(file: file) -> i64 ---
file_seek :: proc(file: file, offset: i64, whence: file_whence) -> i64 ---
file_write :: proc(file: file, size: u64, buffer: rawptr) -> u64 ---
file_read :: proc(file: file, size: u64, buffer: rawptr) -> u64 ---
file_last_error :: proc(handle: file) -> io_error ---
}
//----------------------------------------------------------------
// File System wrapper API
//----------------------------------------------------------------
file_type :: enum c.int {
UNKNOWN,
REGULAR,
DIRECTORY,
SYMLINK,
BLOCK,
CHARACTER,
FIFO,
SOCKET,
}
file_perm :: distinct bit_set[file_perm_enum; u16]
file_perm_enum :: enum u16 {
OTHER_EXEC = 0,
OTHER_WRITE = 1,
OTHER_READ = 2,
GROUP_EXEC = 3,
GROUP_WRITE = 4,
GROUP_READ = 5,
OWNER_EXEC = 6,
OWNER_WRITE = 7,
OWNER_READ = 8,
STICKY_BIT = 9,
SET_GID = 10,
SET_UID = 11,
}
datestamp :: struct {
seconds: i64, // seconds relative to NTP epoch.
fraction: u64, // fraction of seconds elapsed since the time specified by seconds.
}
file_status :: struct {
uid: u64,
type: file_type,
perm: file_perm,
size: u64,
creationDate: datestamp,
accessDate: datestamp,
modificationDate: datestamp,
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
file_get_status :: proc(file: file) -> file_status ---
file_size :: proc(file: file) -> u64 ---
}
file_open_with_dialog_elt :: struct {
listElt: list_elt,
file: file,
}
file_open_with_dialog_result :: struct {
button: file_dialog_button,
file: file,
selection: list,
}
@(default_calling_convention="c", link_prefix="oc_", link_suffix="_argptr_stub")
foreign {
file_open_with_request :: proc(path: string, rights: file_access, flags: file_open_flags) -> file ---
file_open_with_dialog :: proc(arena: ^arena, rights: file_access, flags: file_open_flags, #by_ptr desc: file_dialog_desc) -> file_open_with_dialog_result ---
}
//--------------------------------------------------------------------
// App typedefs, enums and constants
//--------------------------------------------------------------------
window :: struct {
h: u64,
}
mouse_cursor :: enum c.int {
ARROW,
RESIZE_0,
RESIZE_90,
RESIZE_45,
RESIZE_135,
TEXT,
}
window_style :: distinct bit_set[window_style_enum; u32]
window_style_enum :: enum u32 {
NO_TITLE = 0,
FIXED_SIZE = 1,
NO_CLOSE = 2,
NO_MINIFY = 3,
NO_FOCUS = 4,
FLOAT = 5,
POPUPMENU = 6,
NO_BUTTONS = 7,
}
event_type :: enum c.int {
NONE,
KEYBOARD_MODS, //TODO: remove, keep only key?
KEYBOARD_KEY,
KEYBOARD_CHAR,
MOUSE_BUTTON,
MOUSE_MOVE,
MOUSE_WHEEL,
MOUSE_ENTER,
MOUSE_LEAVE,
CLIPBOARD_PASTE,
WINDOW_RESIZE,
WINDOW_MOVE,
WINDOW_FOCUS,
WINDOW_UNFOCUS,
WINDOW_HIDE, // rename to minimize?
WINDOW_SHOW, // rename to restore?
WINDOW_CLOSE,
PATHDROP,
FRAME,
QUIT,
}
key_action :: enum c.int {
NO_ACTION,
PRESS,
RELEASE,
REPEAT,
}
scan_code :: enum c.int {
UNKNOWN = 0,
SPACE = 32,
APOSTROPHE = 39,
COMMA = 44,
MINUS = 45,
PERIOD = 46,
SLASH = 47,
_0 = 48,
_1 = 49,
_2 = 50,
_3 = 51,
_4 = 52,
_5 = 53,
_6 = 54,
_7 = 55,
_8 = 56,
_9 = 57,
SEMICOLON = 59,
EQUAL = 61,
LEFT_BRACKET = 91,
BACKSLASH = 92,
RIGHT_BRACKET = 93,
GRAVE_ACCENT = 96,
A = 97,
B = 98,
C = 99,
D = 100,
E = 101,
F = 102,
G = 103,
H = 104,
I = 105,
J = 106,
K = 107,
L = 108,
M = 109,
N = 110,
O = 111,
P = 112,
Q = 113,
R = 114,
S = 115,
T = 116,
U = 117,
V = 118,
W = 119,
X = 120,
Y = 121,
Z = 122,
WORLD_1 = 161,
WORLD_2 = 162,
ESCAPE = 256,
ENTER = 257,
TAB = 258,
BACKSPACE = 259,
INSERT = 260,
DELETE = 261,
RIGHT = 262,
LEFT = 263,
DOWN = 264,
UP = 265,
PAGE_UP = 266,
PAGE_DOWN = 267,
HOME = 268,
END = 269,
CAPS_LOCK = 280,
SCROLL_LOCK = 281,
NUM_LOCK = 282,
PRINT_SCREEN = 283,
PAUSE = 284,
F1 = 290,
F2 = 291,
F3 = 292,
F4 = 293,
F5 = 294,
F6 = 295,
F7 = 296,
F8 = 297,
F9 = 298,
F10 = 299,
F11 = 300,
F12 = 301,
F13 = 302,
F14 = 303,
F15 = 304,
F16 = 305,
F17 = 306,
F18 = 307,
F19 = 308,
F20 = 309,
F21 = 310,
F22 = 311,
F23 = 312,
F24 = 313,
F25 = 314,
KP_0 = 320,
KP_1 = 321,
KP_2 = 322,
KP_3 = 323,
KP_4 = 324,
KP_5 = 325,
KP_6 = 326,
KP_7 = 327,
KP_8 = 328,
KP_9 = 329,
KP_DECIMAL = 330,
KP_DIVIDE = 331,
KP_MULTIPLY = 332,
KP_SUBTRACT = 333,
KP_ADD = 334,
KP_ENTER = 335,
KP_EQUAL = 336,
LEFT_SHIFT = 340,
LEFT_CONTROL = 341,
LEFT_ALT = 342,
LEFT_SUPER = 343,
RIGHT_SHIFT = 344,
RIGHT_CONTROL = 345,
RIGHT_ALT = 346,
RIGHT_SUPER = 347,
MENU = 348,
}
key_code :: enum c.int {
UNKNOWN = 0,
SPACE = ' ',
APOSTROPHE = '\'',
COMMA = ',',
MINUS = '-',
PERIOD = '.',
SLASH = '/',
_0 = '0',
_1 = '1',
_2 = '2',
_3 = '3',
_4 = '4',
_5 = '5',
_6 = '6',
_7 = '7',
_8 = '8',
_9 = '9',
SEMICOLON = ';',
EQUAL = '=',
LEFT_BRACKET = '[',
BACKSLASH = '\\',
RIGHT_BRACKET = ']',
GRAVE_ACCENT = '`',
A = 'a',
B = 'b',
C = 'c',
D = 'd',
E = 'e',
F = 'f',
G = 'g',
H = 'h',
I = 'i',
J = 'j',
K = 'k',
L = 'l',
M = 'm',
N = 'n',
O = 'o',
P = 'p',
Q = 'q',
R = 'r',
S = 's',
T = 't',
U = 'u',
V = 'v',
W = 'w',
X = 'x',
Y = 'y',
Z = 'z',
WORLD_1,
WORLD_2,
ESCAPE,
ENTER,
TAB,
BACKSPACE,
INSERT,
DELETE,
RIGHT,
LEFT,
DOWN,
UP,
PAGE_UP,
PAGE_DOWN,
HOME,
END,
CAPS_LOCK,
SCROLL_LOCK,
NUM_LOCK,
PRINT_SCREEN,
PAUSE,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16,
F17,
F18,
F19,
F20,
F21,
F22,
F23,
F24,
F25,
KP_0,
KP_1,
KP_2,
KP_3,
KP_4,
KP_5,
KP_6,
KP_7,
KP_8,
KP_9,
KP_DECIMAL,
KP_DIVIDE,
KP_MULTIPLY,
KP_SUBTRACT,
KP_ADD,
KP_ENTER,
KP_EQUAL,
LEFT_SHIFT,
LEFT_CONTROL,
LEFT_ALT,
LEFT_SUPER,
RIGHT_SHIFT,
RIGHT_CONTROL,
RIGHT_ALT,
RIGHT_SUPER,
MENU,
}
keymod_flags :: distinct bit_set[keymod_flags_enum; c.int]
keymod_flags_enum :: enum c.int {
ALT = 0,
SHIFT = 1,
CTRL = 2,
CMD = 3,
MAIN_MODIFIER = 4, // CMD on Mac, CTRL on Win32
}
mouse_button :: enum {
LEFT = 0x00,
RIGHT = 0x01,
MIDDLE = 0x02,
EXT1 = 0x03,
EXT2 = 0x04,
}
key_event :: struct { // keyboard and mouse buttons input
action: key_action,
scanCode: scan_code,
keyCode: key_code,
button: mouse_button,
mods: keymod_flags,
clickCount: u8,
}
char_event :: struct { // character input
codepoint: rune,
sequence: [8]u8 `fmt:"s,seqLen"`,
seqLen: u8,
}
mouse_event :: struct { // mouse move/scroll
x: f32,
y: f32,
deltaX: f32,
deltaY: f32,
mods: keymod_flags,
}
move_event :: struct { // window resize / move
frame: rect,
content: rect,
}
event :: struct {
//TODO clipboard and path drop
window: window,
type: event_type,
using _: struct #raw_union {
key: key_event,
character: char_event,
mouse: mouse_event,
move: move_event,
paths: str8_list,
},
}
file_dialog_kind :: enum c.int {
SAVE,
OPEN,
}
file_dialog_flags :: distinct bit_set[file_dialog_flags_enum; u32]
file_dialog_flags_enum :: enum u32 {
FILES = 0,
DIRECTORIES = 1,
MULTIPLE = 2,
CREATE_DIRECTORIES = 3,
}
file_dialog_desc :: struct {
kind: file_dialog_kind,
flags: file_dialog_flags,
title: str8,
okLabel: str8,
startAt: file,
startPath: str8,
filters: str8_list,
//... later customization options with checkboxes / radiobuttons
}
file_dialog_button :: enum c.int {
CANCEL = 0,
OK,
}
file_dialog_result :: struct {
button: file_dialog_button,
path: str8,
selection: str8_list,
}
@(default_calling_convention="c", link_prefix="oc_", link_suffix="_argptr_stub")
foreign {
window_set_title :: proc(title: str8) ---
window_set_size :: proc(size: vec2) ---
clipboard_set_string :: proc(string: str8) ---
}
@(default_calling_convention="c", link_prefix="oc_", link_suffix="_argptr_stub")
foreign {
request_quit :: proc() ---
scancode_to_keycode :: proc(scanCode: scan_code) -> key_code ---
}
/*NOTE:
by convention, functions that take an arena and return a path
allocated on that arena allocate 1 more character and null-terminate
the string.
*/
@(default_calling_convention="c", link_prefix="oc_")
foreign {
path_slice_directory :: proc(path: string) -> string ---
path_slice_filename :: proc(path: string) -> string ---
path_split :: proc(arena: ^arena, path: string) -> str8_list ---
path_join :: proc(arena: ^arena, elements: str8_list) -> string ---
path_append :: proc(arena: ^arena, parent, relPath: string) -> string ---
path_is_absolute :: proc(path: string) -> bool ---
}

View File

@@ -1,685 +0,0 @@
package orca
import "core:c"
ui_key :: struct {
hash: u64
}
ui_axis :: enum c.int {
X,
Y,
}
ui_align :: enum c.int {
START,
END,
CENTER,
}
ui_layout_align :: [2]ui_align
ui_layout :: struct {
axis: ui_axis,
spacing: f32,
margin: [2]f32,
align: ui_layout_align,
}
ui_size_kind :: enum c.int {
TEXT,
PIXELS,
CHILDREN,
PARENT,
PARENT_MINUS_PIXELS,
}
ui_size :: struct {
kind: ui_size_kind,
value: f32,
relax: f32,
minSize: f32,
}
ui_box_size :: [2]ui_size
ui_box_floating :: [2]c.bool
//NOTE: flags for axis-dependent properties (e.g. UI_STYLE_FLOAT_X/Y) need to be consecutive bits
// in order to play well with axis agnostic functions
ui_style_mask :: enum u64 {
NONE = 0,
SIZE_WIDTH = 1 << 1,
SIZE_HEIGHT = 1 << 2,
LAYOUT_AXIS = 1 << 3,
LAYOUT_ALIGN_X = 1 << 4,
LAYOUT_ALIGN_Y = 1 << 5,
LAYOUT_SPACING = 1 << 6,
LAYOUT_MARGIN_X = 1 << 7,
LAYOUT_MARGIN_Y = 1 << 8,
FLOAT_X = 1 << 9,
FLOAT_Y = 1 << 10,
COLOR = 1 << 11,
BG_COLOR = 1 << 12,
BORDER_COLOR = 1 << 13,
BORDER_SIZE = 1 << 14,
ROUNDNESS = 1 << 15,
FONT = 1 << 16,
FONT_SIZE = 1 << 17,
ANIMATION_TIME = 1 << 18,
ANIMATION_MASK = 1 << 19,
//masks
SIZE = SIZE_WIDTH | SIZE_HEIGHT,
LAYOUT_MARGINS = LAYOUT_MARGIN_X | LAYOUT_MARGIN_Y,
LAYOUT = LAYOUT_AXIS | LAYOUT_ALIGN_X | LAYOUT_ALIGN_Y | LAYOUT_SPACING | LAYOUT_MARGIN_X | LAYOUT_MARGIN_Y,
FLOAT = FLOAT_X | FLOAT_Y,
MASK_INHERITED = COLOR | FONT | FONT_SIZE | ANIMATION_TIME | ANIMATION_MASK,
}
ui_style :: struct {
size: ui_box_size,
layout: ui_layout,
floating: ui_box_floating,
floatTarget: vec2,
_color: color,
bgColor: color,
borderColor: color,
font: font,
fontSize: f32,
borderSize: f32,
roundness: f32,
animationTime: f32,
animationMask: ui_style_mask,
}
ui_palette :: struct {
red0: color,
red1: color,
red2: color,
red3: color,
red4: color,
red5: color,
red6: color,
red7: color,
red8: color,
red9: color,
orange0: color,
orange1: color,
orange2: color,
orange3: color,
orange4: color,
orange5: color,
orange6: color,
orange7: color,
orange8: color,
orange9: color,
amber0: color,
amber1: color,
amber2: color,
amber3: color,
amber4: color,
amber5: color,
amber6: color,
amber7: color,
amber8: color,
amber9: color,
yellow0: color,
yellow1: color,
yellow2: color,
yellow3: color,
yellow4: color,
yellow5: color,
yellow6: color,
yellow7: color,
yellow8: color,
yellow9: color,
lime0: color,
lime1: color,
lime2: color,
lime3: color,
lime4: color,
lime5: color,
lime6: color,
lime7: color,
lime8: color,
lime9: color,
lightGreen0: color,
lightGreen1: color,
lightGreen2: color,
lightGreen3: color,
lightGreen4: color,
lightGreen5: color,
lightGreen6: color,
lightGreen7: color,
lightGreen8: color,
lightGreen9: color,
green0: color,
green1: color,
green2: color,
green3: color,
green4: color,
green5: color,
green6: color,
green7: color,
green8: color,
green9: color,
teal0: color,
teal1: color,
teal2: color,
teal3: color,
teal4: color,
teal5: color,
teal6: color,
teal7: color,
teal8: color,
teal9: color,
cyan0: color,
cyan1: color,
cyan2: color,
cyan3: color,
cyan4: color,
cyan5: color,
cyan6: color,
cyan7: color,
cyan8: color,
cyan9: color,
lightBlue0: color,
lightBlue1: color,
lightBlue2: color,
lightBlue3: color,
lightBlue4: color,
lightBlue5: color,
lightBlue6: color,
lightBlue7: color,
lightBlue8: color,
lightBlue9: color,
blue0: color,
blue1: color,
blue2: color,
blue3: color,
blue4: color,
blue5: color,
blue6: color,
blue7: color,
blue8: color,
blue9: color,
indigo0: color,
indigo1: color,
indigo2: color,
indigo3: color,
indigo4: color,
indigo5: color,
indigo6: color,
indigo7: color,
indigo8: color,
indigo9: color,
violet0: color,
violet1: color,
violet2: color,
violet3: color,
violet4: color,
violet5: color,
violet6: color,
violet7: color,
violet8: color,
violet9: color,
purple0: color,
purple1: color,
purple2: color,
purple3: color,
purple4: color,
purple5: color,
purple6: color,
purple7: color,
purple8: color,
purple9: color,
pink0: color,
pink1: color,
pink2: color,
pink3: color,
pink4: color,
pink5: color,
pink6: color,
pink7: color,
pink8: color,
pink9: color,
grey0: color,
grey1: color,
grey2: color,
grey3: color,
grey4: color,
grey5: color,
grey6: color,
grey7: color,
grey8: color,
grey9: color,
black: color,
white: color,
}
// TODO exteern
// ui_palette: UI_DARK_PALETTE
// ui_palette: UI_LIGHT_PALETTE
ui_theme :: struct {
white: color,
primary: color,
primaryHover: color,
primaryActive: color,
border: color,
fill0: color,
fill1: color,
fill2: color,
bg0: color,
bg1: color,
bg2: color,
bg3: color,
bg4: color,
text0: color,
text1: color,
text2: color,
text3: color,
sliderThumbBorder: color,
elevatedBorder: color,
roundnessSmall: f32,
roundnessMedium: f32,
roundnessLarge: f32,
palette: ^ui_palette,
}
@export UI_DARK_THEME: ui_theme
@export UI_LIGHT_THEME: ui_theme
ui_tag :: struct {
hash: u64,
}
ui_selector_kind :: enum c.int {
ANY,
OWNER,
TEXT,
TAG,
STATUS,
KEY,
}
ui_status :: enum u8 {
NONE = 0,
HOVER = 1 << 1,
HOT = 1 << 2,
ACTIVE = 1 << 3,
DRAGGING = 1 << 4,
}
ui_selector_op :: enum c.int {
DESCENDANT = 0,
AND = 1,
}
ui_selector :: struct {
listElt: list_elt,
kind: ui_selector_kind,
op: ui_selector_op,
type: struct #raw_union {
text: str8,
key: ui_key,
tag: ui_tag,
status: ui_status,
}
}
ui_pattern :: struct {
l: list,
}
ui_style_rule :: struct {
boxElt: list_elt,
buildElt: list_elt,
tmpElt: list_elt,
owner: ^ui_box,
pattern: ui_pattern,
mask: ui_style_mask,
style: ^ui_style,
}
ui_sig :: struct {
box: ^ui_box,
mouse: vec2,
delta: vec2,
wheel: vec2,
pressed: c.bool,
released: c.bool,
clicked: c.bool,
doubleClicked: c.bool,
tripleClicked: c.bool,
rightPressed: c.bool,
dragging: c.bool,
hovering: c.bool,
pasted: c.bool,
}
ui_box_draw_proc :: proc "c" (box: ^ui_box, data: rawptr)
ui_flags :: enum c.int {
NONE = 0,
CLICKABLE = (1 << 0),
SCROLL_WHEEL_X = (1 << 1),
SCROLL_WHEEL_Y = (1 << 2),
BLOCK_MOUSE = (1 << 3),
HOT_ANIMATION = (1 << 4),
ACTIVE_ANIMATION = (1 << 5),
//WARN: these two following flags need to be kept as consecutive bits to
// play well with axis-agnostic functions
OVERFLOW_ALLOW_X = (1 << 6),
OVERFLOW_ALLOW_Y = (1 << 7),
CLIP = (1 << 8),
DRAW_BACKGROUND = (1 << 9),
DRAW_FOREGROUND = (1 << 10),
DRAW_BORDER = (1 << 11),
DRAW_TEXT = (1 << 12),
DRAW_PROC = (1 << 13),
OVERLAY = (1 << 16),
}
ui_box :: struct {
// hierarchy
listElt: list_elt,
children: list,
parent: ^ui_box,
overlayElt: list_elt,
// keying and caching
bucketElt: list_elt,
key: ui_key,
frameCounter: u64,
// builder-provided info
flags: ui_flags,
string: str8,
tags: list,
drawProc: ui_box_draw_proc,
drawData: rawptr,
// styling
beforeRules: list,
afterRules: list,
//ui_style_tag tag
targetStyle: ^ui_style,
style: ui_style,
z: u32,
floatPos: vec2,
childrenSum: [2]f32,
spacing: [2]f32,
minSize: [2]f32,
rect: rect,
// signals
sig: ^ui_sig,
// stateful behaviour
fresh: c.bool,
closed: c.bool,
parentClosed: c.bool,
dragging: c.bool,
hot: c.bool,
active: c.bool,
scroll: vec2,
pressedMouse: vec2,
// animation data
hotTransition: f32,
activeTransition: f32,
}
UI_MAX_INPUT_CHAR_PER_FRAME :: 64
ui_input_text :: struct {
count: u8,
codePoints: [UI_MAX_INPUT_CHAR_PER_FRAME]utf32,
}
ui_stack_elt :: struct {
parent: ^ui_stack_elt,
_: struct #raw_union {
box: ^ui_box,
size: ui_size,
clip: rect,
}
}
ui_tag_elt :: struct {
listElt: list_elt,
tag: ui_tag,
}
UI_BOX_MAP_BUCKET_COUNT :: 1024
ui_edit_move :: enum c.int {
NONE,
CHAR,
WORD,
LINE,
}
ui_context :: struct {
init: c.bool,
input: input_state,
frameCounter: u64,
frameTime: f64,
lastFrameDuration: f64,
frameArena: arena,
boxPool: pool,
boxMap: [UI_BOX_MAP_BUCKET_COUNT]list,
root: ^ui_box,
overlay: ^ui_box,
overlayList: list,
boxStack: ^ui_stack_elt,
clipStack: ^ui_stack_elt,
nextBoxBeforeRules: list,
nextBoxAfterRules: list,
nextBoxTags: list,
z: u32,
hovered: ^ui_box,
focus: ^ui_box,
editCursor: i32,
editMark: i32,
editFirstDisplayedChar: i32,
editCursorBlinkStart: f64,
editSelectionMode: ui_edit_move,
editWordSelectionInitialCursor: i32,
editWordSelectionInitialMark: i32,
clipboardRegistered: c.bool,
theme: ^ui_theme,
}
ui_text_box_result :: struct {
changed: c.bool,
accepted: c.bool,
text: str8,
}
ui_select_popup_info :: struct {
changed: bool,
selectedIndex: int, // -1 if nothing is selected
optionCount: int,
options: [^]str8,
placeholder: str8,
}
ui_radio_group_info :: struct {
changed: bool,
selectedIndex: int, // -1 if nothing is selected
optionCount: int,
options: [^]str8,
}
//----------------------------------------------------------------
// Context and frame lifecycle
//----------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
ui_init :: proc(ctx: ^ui_context) ---
ui_get_context :: proc() -> ^ui_context ---
ui_set_context :: proc(ctx: ^ui_context) ---
ui_process_event :: proc(event: ^event) ---
ui_begin_frame :: proc(size: vec2, defaultStyle: ^ui_style, mask: ui_style_mask) ---
ui_end_frame :: proc() ---
ui_draw :: proc() ---
}
@(deferred_none=ui_end_frame)
ui_frame :: proc "c" (size: vec2, defaultStyle: ^ui_style, mask: ui_style_mask) {
ui_begin_frame(size, defaultStyle, mask)
}
ui_frame_scoped :: ui_frame
//----------------------------------------------------------------
// Common widget helpers
//----------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
ui_label :: proc(label: cstring) -> ui_sig ---
ui_label_str8 :: proc(label: str8) -> ui_sig ---
ui_button :: proc(label: cstring) -> ui_sig ---
ui_checkbox :: proc(name: cstring, checked: ^c.bool) -> ui_sig ---
ui_slider :: proc(label: cstring, value: ^f32) -> ^ui_box ---
ui_scrollbar :: proc(label: cstring, thumbRatio: f32, scrollValue: ^f32) -> ^ui_box ---
ui_text_box :: proc(name: cstring, arena: ^arena, text: str8) -> ui_text_box_result ---
ui_select_popup :: proc(name: cstring, info: ^ui_select_popup_info) -> ui_select_popup_info ---
ui_radio_group :: proc(name: cstring, info: ^ui_radio_group_info) -> ui_radio_group_info ---
ui_panel_begin :: proc(name: cstring, flags: ui_flags) ---
ui_panel_end :: proc() ---
ui_menu_bar_begin :: proc(label: cstring) ---
ui_menu_bar_end :: proc() ---
ui_menu_begin :: proc(label: cstring) ---
ui_menu_end :: proc() ---
ui_menu_button :: proc(name: cstring) -> ui_sig ---
ui_tooltip_begin :: proc(name: cstring) -> ui_sig ---
ui_tooltip_end :: proc() ---
}
@(deferred_none=ui_panel_end)
ui_panel :: proc "c" (name: cstring, flags: ui_flags) {
ui_panel_begin(name, flags)
}
ui_panel_scoped :: ui_panel
@(deferred_none=ui_menu_bar_end)
ui_menu_bar :: proc "c" (label: cstring) {
ui_menu_bar_begin(label)
}
ui_menu_bar_scoped :: ui_menu_bar
@(deferred_none=ui_menu_end)
ui_menu :: proc "c" (label: cstring) {
ui_menu_begin(label)
}
ui_menu_scoped :: ui_menu
@(deferred_none=ui_tooltip_end)
ui_tooltip :: proc "c" (label: cstring) -> ui_sig {
return ui_tooltip_begin(label)
}
ui_tooltip_scoped :: ui_menu
//-------------------------------------------------------------------------------------
// Styling
//-------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
ui_style_next :: proc(style: ^ui_style, mask: ui_style_mask) ---
ui_pattern_push :: proc(arena: ^arena, pattern: ^ui_pattern, selector: ui_selector) ---
ui_pattern_all :: proc() -> ui_pattern ---
ui_pattern_owner :: proc() -> ui_pattern ---
ui_style_match_before :: proc(pattern: ui_pattern, style: ^ui_style, mask: ui_style_mask) ---
ui_style_match_after :: proc(pattern: ui_pattern, style: ^ui_style, mask: ui_style_mask) ---
}
//-------------------------------------------------------------------------------------
// BOX
//-------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
ui_box_make_str8 :: proc(str: str8, flags: ui_flags) -> ^ui_box ---
ui_box_begin_str8 :: proc(str: str8, flags: ui_flags) -> ^ui_box ---
ui_box_end :: proc() -> ^ui_box ---
}
@(deferred_none=ui_box_end)
ui_container :: proc "c" (str: string, flags: ui_flags) -> ^ui_box {
return ui_box_begin_str8(str, flags)
}
@(deferred_none=ui_box_end)
ui_container_str8 :: proc "c" (str: str8, flags: ui_flags) -> ^ui_box {
return ui_box_begin_str8(str, flags)
}
ui_box_make :: proc "c" (str: string, flags: ui_flags) -> ^ui_box {
return ui_box_make_str8(str, flags)
}
ui_box_begin :: proc "c" (str: string, flags: ui_flags) -> ^ui_box {
return ui_box_begin_str8(str, flags)
}
//-------------------------------------------------------------------------------------
// BOX
//-------------------------------------------------------------------------------------
@(default_calling_convention="c", link_prefix="oc_")
foreign {
ui_tag_make_str8 :: proc(str: str8) -> ui_tag ---
ui_tag_box_str8 :: proc(box: ^ui_box, str: str8) ---
ui_tag_next_str8 :: proc(str: str8) ---
}
ui_tag_make :: proc "c" (s: string) -> ui_tag {
return ui_tag_make_str8(s)
}
ui_tag_box :: proc "c" (b: ^ui_box, s: string) {
ui_tag_box_str8(b, s)
}
ui_tag_next :: proc "c" (s: string) {
ui_tag_next_str8(s)
}

View File

@@ -1,131 +0,0 @@
package orca
unicode_range :: struct {
firstCodePoint: utf32,
count: u32,
}
UNICODE_BASIC_LATIN :: unicode_range { 0x0000, 127 }
UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT :: unicode_range { 0x0080, 127 }
UNICODE_LATIN_EXTENDED_A :: unicode_range { 0x0100, 127 }
UNICODE_LATIN_EXTENDED_B :: unicode_range { 0x0180, 207 }
UNICODE_IPA_EXTENSIONS :: unicode_range { 0x0250, 95 }
UNICODE_SPACING_MODIFIER_LETTERS :: unicode_range { 0x02b0, 79 }
UNICODE_COMBINING_DIACRITICAL_MARKS :: unicode_range { 0x0300, 111 }
UNICODE_GREEK_COPTIC :: unicode_range { 0x0370, 143 }
UNICODE_CYRILLIC :: unicode_range { 0x0400, 255 }
UNICODE_CYRILLIC_SUPPLEMENT :: unicode_range { 0x0500, 47 }
UNICODE_ARMENIAN :: unicode_range { 0x0530, 95 }
UNICODE_HEBREW :: unicode_range { 0x0590, 111 }
UNICODE_ARABIC :: unicode_range { 0x0600, 255 }
UNICODE_SYRIAC :: unicode_range { 0x0700, 79 }
UNICODE_THAANA :: unicode_range { 0x0780, 63 }
UNICODE_DEVANAGARI :: unicode_range { 0x0900, 127 }
UNICODE_BENGALI_ASSAMESE :: unicode_range { 0x0980, 127 }
UNICODE_GURMUKHI :: unicode_range { 0x0a00, 127 }
UNICODE_GUJARATI :: unicode_range { 0x0a80, 127 }
UNICODE_ORIYA :: unicode_range { 0x0b00, 127 }
UNICODE_TAMIL :: unicode_range { 0x0b80, 127 }
UNICODE_TELUGU :: unicode_range { 0x0c00, 127 }
UNICODE_KANNADA :: unicode_range { 0x0c80, 127 }
UNICODE_MALAYALAM :: unicode_range { 0x0d00, 255 }
UNICODE_SINHALA :: unicode_range { 0x0d80, 127 }
UNICODE_THAI :: unicode_range { 0x0e00, 127 }
UNICODE_LAO :: unicode_range { 0x0e80, 127 }
UNICODE_TIBETAN :: unicode_range { 0x0f00, 255 }
UNICODE_MYANMAR :: unicode_range { 0x1000, 159 }
UNICODE_GEORGIAN :: unicode_range { 0x10a0, 95 }
UNICODE_HANGUL_JAMO :: unicode_range { 0x1100, 255 }
UNICODE_ETHIOPIC :: unicode_range { 0x1200, 383 }
UNICODE_CHEROKEE :: unicode_range { 0x13a0, 95 }
UNICODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS :: unicode_range { 0x1400, 639 }
UNICODE_OGHAM :: unicode_range { 0x1680, 31 }
UNICODE_RUNIC :: unicode_range { 0x16a0, 95 }
UNICODE_TAGALOG :: unicode_range { 0x1700, 31 }
UNICODE_HANUNOO :: unicode_range { 0x1720, 31 }
UNICODE_BUHID :: unicode_range { 0x1740, 31 }
UNICODE_TAGBANWA :: unicode_range { 0x1760, 31 }
UNICODE_KHMER :: unicode_range { 0x1780, 127 }
UNICODE_MONGOLIAN :: unicode_range { 0x1800, 175 }
UNICODE_LIMBU :: unicode_range { 0x1900, 79 }
UNICODE_TAI_LE :: unicode_range { 0x1950, 47 }
UNICODE_KHMER_SYMBOLS :: unicode_range { 0x19e0, 31 }
UNICODE_PHONETIC_EXTENSIONS :: unicode_range { 0x1d00, 127 }
UNICODE_LATIN_EXTENDED_ADDITIONAL :: unicode_range { 0x1e00, 255 }
UNICODE_GREEK_EXTENDED :: unicode_range { 0x1f00, 255 }
UNICODE_GENERAL_PUNCTUATION :: unicode_range { 0x2000, 111 }
UNICODE_SUPERSCRIPTS_AND_SUBSCRIPTS :: unicode_range { 0x2070, 47 }
UNICODE_CURRENCY_SYMBOLS :: unicode_range { 0x20a0, 47 }
UNICODE_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS :: unicode_range { 0x20d0, 47 }
UNICODE_LETTERLIKE_SYMBOLS :: unicode_range { 0x2100, 79 }
UNICODE_NUMBER_FORMS :: unicode_range { 0x2150, 63 }
UNICODE_ARROWS :: unicode_range { 0x2190, 111 }
UNICODE_MATHEMATICAL_OPERATORS :: unicode_range { 0x2200, 255 }
UNICODE_MISCELLANEOUS_TECHNICAL :: unicode_range { 0x2300, 255 }
UNICODE_CONTROL_PICTURES :: unicode_range { 0x2400, 63 }
UNICODE_OPTICAL_CHARACTER_RECOGNITION :: unicode_range { 0x2440, 31 }
UNICODE_ENCLOSED_ALPHANUMERICS :: unicode_range { 0x2460, 159 }
UNICODE_BOX_DRAWING :: unicode_range { 0x2500, 127 }
UNICODE_BLOCK_ELEMENTS :: unicode_range { 0x2580, 31 }
UNICODE_GEOMETRIC_SHAPES :: unicode_range { 0x25a0, 95 }
UNICODE_MISCELLANEOUS_SYMBOLS :: unicode_range { 0x2600, 255 }
UNICODE_DINGBATS :: unicode_range { 0x2700, 191 }
UNICODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A :: unicode_range { 0x27c0, 47 }
UNICODE_SUPPLEMENTAL_ARROWS_A :: unicode_range { 0x27f0, 15 }
UNICODE_BRAILLE_PATTERNS :: unicode_range { 0x2800, 255 }
UNICODE_SUPPLEMENTAL_ARROWS_B :: unicode_range { 0x2900, 127 }
UNICODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B :: unicode_range { 0x2980, 127 }
UNICODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS :: unicode_range { 0x2a00, 255 }
UNICODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS :: unicode_range { 0x2b00, 255 }
UNICODE_CJK_RADICALS_SUPPLEMENT :: unicode_range { 0x2e80, 127 }
UNICODE_KANGXI_RADICALS :: unicode_range { 0x2f00, 223 }
UNICODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS :: unicode_range { 0x2ff0, 15 }
UNICODE_CJK_SYMBOLS_AND_PUNCTUATION :: unicode_range { 0x3000, 63 }
UNICODE_HIRAGANA :: unicode_range { 0x3040, 95 }
UNICODE_KATAKANA :: unicode_range { 0x30a0, 95 }
UNICODE_BOPOMOFO :: unicode_range { 0x3100, 47 }
UNICODE_HANGUL_COMPATIBILITY_JAMO :: unicode_range { 0x3130, 95 }
UNICODE_KANBUN_KUNTEN :: unicode_range { 0x3190, 15 }
UNICODE_BOPOMOFO_EXTENDED :: unicode_range { 0x31a0, 31 }
UNICODE_KATAKANA_PHONETIC_EXTENSIONS :: unicode_range { 0x31f0, 15 }
UNICODE_ENCLOSED_CJK_LETTERS_AND_MONTHS :: unicode_range { 0x3200, 255 }
UNICODE_CJK_COMPATIBILITY :: unicode_range { 0x3300, 255 }
UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A :: unicode_range { 0x3400, 6591 }
UNICODE_YIJING_HEXAGRAM_SYMBOLS :: unicode_range { 0x4dc0, 63 }
UNICODE_CJK_UNIFIED_IDEOGRAPHS :: unicode_range { 0x4e00, 20911 }
UNICODE_YI_SYLLABLES :: unicode_range { 0xa000, 1167 }
UNICODE_YI_RADICALS :: unicode_range { 0xa490, 63 }
UNICODE_HANGUL_SYLLABLES :: unicode_range { 0xac00, 11183 }
UNICODE_HIGH_SURROGATE_AREA :: unicode_range { 0xd800, 1023 }
UNICODE_LOW_SURROGATE_AREA :: unicode_range { 0xdc00, 1023 }
UNICODE_PRIVATE_USE_AREA :: unicode_range { 0xe000, 6399 }
UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS :: unicode_range { 0xf900, 511 }
UNICODE_ALPHABETIC_PRESENTATION_FORMS :: unicode_range { 0xfb00, 79 }
UNICODE_ARABIC_PRESENTATION_FORMS_A :: unicode_range { 0xfb50, 687 }
UNICODE_VARIATION_SELECTORS :: unicode_range { 0xfe00, 15 }
UNICODE_COMBINING_HALF_MARKS :: unicode_range { 0xfe20, 15 }
UNICODE_CJK_COMPATIBILITY_FORMS :: unicode_range { 0xfe30, 31 }
UNICODE_SMALL_FORM_VARIANTS :: unicode_range { 0xfe50, 31 }
UNICODE_ARABIC_PRESENTATION_FORMS_B :: unicode_range { 0xfe70, 143 }
UNICODE_HALFWIDTH_AND_FULLWIDTH_FORMS :: unicode_range { 0xff00, 239 }
UNICODE_SPECIALS :: unicode_range { 0xfff0, 15 }
UNICODE_LINEAR_B_SYLLABARY :: unicode_range { 0x10000, 127 }
UNICODE_LINEAR_B_IDEOGRAMS :: unicode_range { 0x10080, 127 }
UNICODE_AEGEAN_NUMBERS :: unicode_range { 0x10100, 63 }
UNICODE_OLD_ITALIC :: unicode_range { 0x10300, 47 }
UNICODE_GOTHIC :: unicode_range { 0x10330, 31 }
UNICODE_UGARITIC :: unicode_range { 0x10380, 31 }
UNICODE_DESERET :: unicode_range { 0x10400, 79 }
UNICODE_SHAVIAN :: unicode_range { 0x10450, 47 }
UNICODE_OSMANYA :: unicode_range { 0x10480, 47 }
UNICODE_CYPRIOT_SYLLABARY :: unicode_range { 0x10800, 63 }
UNICODE_BYZANTINE_MUSICAL_SYMBOLS :: unicode_range { 0x1d000, 255 }
UNICODE_MUSICAL_SYMBOLS :: unicode_range { 0x1d100, 255 }
UNICODE_TAI_XUAN_JING_SYMBOLS :: unicode_range { 0x1d300, 95 }
UNICODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS :: unicode_range { 0x1d400, 1023 }
UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B :: unicode_range { 0x20000, 42719 }
UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT :: unicode_range { 0x2f800, 543 }
UNICODE_TAGS :: unicode_range { 0xe0000, 127 }
UNICODE_VARIATION_SELECTORS_SUPPLEMENT :: unicode_range { 0xe0100, 239 }
UNICODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A :: unicode_range { 0xf0000, 65533 }
UNICODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B :: unicode_range { 0x100000, 65533 }

View File

@@ -1,266 +0,0 @@
package orca
import "core:c"
import "core:fmt"
import "core:runtime"
import "core:intrinsics"
//----------------------------------------------------------------
// Arenas
//----------------------------------------------------------------
mem_reserve_proc :: proc "c" (ctx: ^base_allocator, size: u64)
mem_modify_proc :: proc "c" (ctx: ^base_allocator, ptr: rawptr, size: u64)
base_allocator :: struct {
reserve: mem_reserve_proc,
commit: mem_modify_proc,
decommit: mem_modify_proc,
release: mem_modify_proc,
}
arena_chunk :: struct {
listElt: list_elt,
ptr: [^]byte,
offset: u64,
committed: u64,
cap: u64,
}
arena :: struct {
base: ^base_allocator,
chunks: list,
currentChunk: ^arena_chunk,
}
arena_scope :: struct {
arena: ^arena,
chunk: ^arena_chunk,
offset: u64,
}
arena_options :: struct {
base: ^base_allocator,
reserve: u64,
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
arena_init :: proc(arena: ^arena) ---
arena_init_with_options :: proc(arena: ^arena, options: ^arena_options) ---
arena_cleanup :: proc(arena: ^arena) ---
arena_push :: proc(arena: ^arena, size: u64) -> rawptr ---
arena_clear :: proc(arena: ^arena) ---
arena_scope_begin :: proc(arena: ^arena) -> arena_scope ---
arena_scope_end :: proc(scope: arena_scope) ---
scratch_begin :: proc() -> arena_scope ---
scratch_begin_next :: proc(used: ^arena) -> arena_scope ---
}
arena_push_type :: proc "c" (arena: ^arena, $T: typeid) -> ^T {
return cast(^T) arena_push(arena, size_of(T))
}
arena_push_array :: proc "c" (arena: ^arena, $T: typeid, count: int) -> []T {
return ([^]T)(arena_push(arena, size_of(T)))[:count]
}
scratch_end :: arena_scope_end
//----------------------------------------------------------------
// Pool
//----------------------------------------------------------------
pool :: struct {
arena: arena,
freeList: list,
blockSize: u64,
}
pool_options :: struct {
base: ^base_allocator,
reserve: u64,
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
pool_init :: proc(pool: ^pool, blockSize: u64) ---
pool_init_with_options :: proc(pool: ^pool, blockSize: u64, options: ^pool_options) ---
pool_cleanup :: proc(pool: ^pool) ---
pool_alloc :: proc(pool: ^pool) -> rawptr ---
pool_recycle :: proc(pool: ^pool, ptr: rawptr) ---
pool_clear :: proc(pool: ^pool) ---
}
pool_alloc_type :: proc "c" (arena: ^arena, $T: typeid) -> ^T {
return cast(^T) pool_alloc(arena)
}
// TODO support list macros?
// #define list_entry :: proc(ptr, type, member)
// #define list_next_entry :: proc(list, elt, type, member)
// #define list_prev_entry :: proc(list, elt, type, member)
// #define list_first_entry :: proc(list, type, member)
// #define list_last_entry :: proc(list, type, member)
// #define list_pop_entry :: proc(list, type, member)
// @(default_calling_convention="c", link_prefix="oc_")
// foreign {
// list_init :: proc(list: ^list) ---
// list_empty :: proc(list: ^list) -> c.bool ---
// list_begin :: proc(list: ^list) -> ^list_elt ---
// list_end :: proc(list: ^list) -> ^list_elt ---
// list_last :: proc(list: ^list) -> ^list_elt ---
// list_insert :: proc(list: ^list, afterElt: ^list_elt, elt: ^list_elt) ---
// list_insert_before :: proc(list: ^list, beforeElt: ^list_elt, elt: ^list_elt) ---
// list_remove :: proc(list: ^list, elt: ^list_elt) ---
// list_push :: proc(list: ^list, elt: ^list_elt) ---
// list_pop :: proc(list: ^list) -> ^list_elt ---
// list_push_back :: proc(list: ^list, elt: ^list_elt) ---
// list_pop_back :: proc(list: ^list) -> ^list_elt ---
// }
//------------------------------------------------------------------------------------------
// for iterators
//------------------------------------------------------------------------------------------
List_Iterator :: struct($T: typeid) {
iterate: ^list,
curr: ^list_elt,
index: int,
offset: uintptr,
}
// NOTE(Skytrias): intrusive list iterator
list_iter_init :: proc "c" (iterate: ^list, $T: typeid, $field_name: string) -> (res: List_Iterator(T))
where intrinsics.type_has_field(T, field_name),
intrinsics.type_field_type(T, field_name) == list_elt {
res.iterate = iterate
res.curr = list_begin(iterate)
res.offset = offset_of_by_string(T, field_name)
return
}
list_iterate :: proc "c" (iter: ^List_Iterator($T)) -> (ptr: ^T, ok: bool) {
node := iter.curr
if node == nil {
return nil, false
}
iter.index += 1
iter.curr = node.next
return (^T)(uintptr(node) - iter.offset), true
}
//----------------------------------------------------------------
// Strings / string lists / path strings
//----------------------------------------------------------------
str8 :: string
str32 :: []rune
str8_list :: struct {
list: list,
eltCount: u64,
len: u64,
}
str8_elt :: struct {
str: str8,
listElt: list_elt,
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
str8_push_buffer :: proc(arena: ^arena, len: u64, buffer: [^]c.char) -> str8 ---
str8_push_cstring :: proc(arena: ^arena, str: cstring) -> str8 ---
str8_push_copy :: proc(arena: ^arena, s: str8) -> str8 ---
str8_push_slice :: proc(arena: ^arena, s: str8, start: u64, end: u64) -> str8 ---
// TODO get rid of these or wrap them
str8_pushfv :: proc(arena: ^arena, format: cstring, args: c.va_list) -> str8 ---
str8_pushf :: proc(arena: ^arena, format: cstring, #c_vararg args: ..any) -> str8 ---
str8_to_cstring :: proc(arena: ^arena, string: str8) -> cstring ---
str8_list_push :: proc(arena: ^arena, list: ^str8_list, str: str8) ---
str8_list_pushf :: proc(arena: ^arena, list: ^str8_list, format: cstring, #c_vararg args: ..any) ---
str8_list_collate :: proc(arena: ^arena, list: str8_list, prefix: str8, separator: str8, postfix: str8) -> str8 ---
str8_list_join :: proc(arena: ^arena, list: str8_list) -> str8 ---
str8_split :: proc(arena: ^arena, str: str8, separators: str8_list) -> str8_list ---
path_slice_directory :: proc(path: str8) -> str8 ---
path_slice_filename :: proc(path: str8) -> str8 ---
path_split :: proc(arena: ^arena, path: str8) -> str8_list ---
path_join :: proc(arena: ^arena, elements: str8_list) -> str8 ---
path_append :: proc(arena: ^arena, parent: str8, relPath: str8) -> str8 ---
path_is_absolute :: proc(path: str8) -> bool ---
}
//----------------------------------------------------------------
// Logging
//----------------------------------------------------------------
// TODO proper odin formatted strings
log_level :: enum c.int {
ERROR,
WARNING,
INFO,
}
@(default_calling_convention="c", link_prefix="oc_")
foreign {
bridge_log :: proc(
level: log_level,
functionLen: c.int,
function: [^]byte,
fileLen: c.int,
file: [^]byte,
line: c.int,
msgLen: c.int,
msg: [^]byte,
) ---
}
@(private)
log_position :: proc "contextless" (loc: runtime.Source_Code_Location) -> (functionLen: c.int, function: [^]byte,
fileLen: c.int, file: [^]byte,
line: c.int) {
functionLen = c.int(len(loc.procedure))
function = raw_data(loc.procedure)
fileLen = c.int(len(loc.file_path))
file = raw_data(loc.file_path)
line = c.int(loc.line)
return
}
log_ext :: proc "contextless" (level: log_level, format: string, args: ..any, loc := #caller_location) {
@(thread_local) buffer: [256]byte
context = runtime.default_context()
s := fmt.bprintf(buffer[:], format, ..args)
bridge_log(level, log_position(loc), c.int(len(s)), raw_data(s))
}
log_info :: proc "contextless" (format: string, args: ..any, loc := #caller_location) {
log_ext(.INFO, format, ..args, loc=loc)
}
log_warning :: proc "contextless" (format: string, args: ..any, loc := #caller_location) {
log_ext(.WARNING, format, ..args, loc=loc)
}
log_error :: proc "contextless" (format: string, args: ..any, loc := #caller_location) {
log_ext(.ERROR, format, ..args, loc=loc)
}

View File

@@ -1279,7 +1279,7 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast
error(e->token, "A foreign variable declaration cannot have a default value");
}
init_entity_foreign_library(ctx, e);
if (is_arch_wasm()) {
if (is_arch_wasm() && build_context.metrics.os != TargetOs_orca) {
error(e->token, "A foreign variable declaration are not allowed for the '%.*s' architecture", LIT(target_arch_names[build_context.metrics.arch]));
}
}