Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions examples/2d/solar2d.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Application, Vector2, Palette } from "vectorjs";
import { Application, Vector2, Palette, Keyboard } from "vectorjs";

const screenWidth = 800;
const screenHeight = 800;
Expand All @@ -16,13 +16,33 @@ const planets = [

const app = new Application(screenWidth, screenHeight, "Solar System Simulation");

// Simulation State
let isRunning = true;
let time = 0;

app.run({

onUpdate(ctx) {
// Toggle running state when Spacebar is pressed (fires once per press)
if (ctx.isKeyPressed(Keyboard.KEY_SPACE)) {
isRunning = !isRunning;
}

// Reset the animation
if (ctx.isKeyPressed(Keyboard.KEY_R)) {
time = 0;
}

// Advance simulation time only while running (assuming ~60 FPS)
if (isRunning) {
time += 1 / 60;
}
},

onDraw(render) {
render.withLayer2D((ctx) => {
ctx.drawFPS(fpsPos);

const time = Date.now() * 0.001;

// 1. Draw the central Sun
ctx.shapes.drawCircle(sunPos, 35, {
color: Palette.YELLOW
Expand Down
69 changes: 68 additions & 1 deletion src/api/api_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,74 @@ namespace HostApi {
}

JSValue create_update_context_object(JSContext* ctx) {
return JS_NewObject(ctx);
Utils::ScopedJSValue update_obj(ctx, JS_NewObject(ctx));

JS_SetPropertyStr(ctx, update_obj, "isKeyPressed", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int argc, JSValueConst* argv) -> JSValue {
int key;
if (argc < 1 || JS_ToInt32(c, &key, argv[0]) < 0) return JS_ThrowTypeError(c, "isKeyPressed requires a Keyboard key enum");
return JS_NewBool(c, ::IsKeyPressed(key));
}, "isKeyPressed", 1));

JS_SetPropertyStr(ctx, update_obj, "isKeyDown", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int argc, JSValueConst* argv) -> JSValue {
int key;
if (argc < 1 || JS_ToInt32(c, &key, argv[0]) < 0) return JS_ThrowTypeError(c, "isKeyDown requires a Keyboard key enum");
return JS_NewBool(c, ::IsKeyDown(key));
}, "isKeyDown", 1));

JS_SetPropertyStr(ctx, update_obj, "isKeyReleased", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int argc, JSValueConst* argv) -> JSValue {
int key;
if (argc < 1 || JS_ToInt32(c, &key, argv[0]) < 0) return JS_ThrowTypeError(c, "isKeyReleased requires a Keyboard key enum");
return JS_NewBool(c, ::IsKeyReleased(key));
}, "isKeyReleased", 1));

JS_SetPropertyStr(ctx, update_obj, "isKeyUp", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int argc, JSValueConst* argv) -> JSValue {
int key;
if (argc < 1 || JS_ToInt32(c, &key, argv[0]) < 0) return JS_ThrowTypeError(c, "isKeyUp requires a Keyboard key enum");
return JS_NewBool(c, ::IsKeyUp(key));
}, "isKeyUp", 1));

JS_SetPropertyStr(ctx, update_obj, "isMouseButtonPressed", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int argc, JSValueConst* argv) -> JSValue {
int button;
if (argc < 1 || JS_ToInt32(c, &button, argv[0]) < 0) return JS_ThrowTypeError(c, "isMouseButtonPressed requires a MouseButton enum");
return JS_NewBool(c, ::IsMouseButtonPressed(button));
}, "isMouseButtonPressed", 1));

JS_SetPropertyStr(ctx, update_obj, "isMouseButtonDown", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int argc, JSValueConst* argv) -> JSValue {
int button;
if (argc < 1 || JS_ToInt32(c, &button, argv[0]) < 0) return JS_ThrowTypeError(c, "isMouseButtonDown requires a MouseButton enum");
return JS_NewBool(c, ::IsMouseButtonDown(button));
}, "isMouseButtonDown", 1));

JS_SetPropertyStr(ctx, update_obj, "isMouseButtonReleased", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int argc, JSValueConst* argv) -> JSValue {
int button;
if (argc < 1 || JS_ToInt32(c, &button, argv[0]) < 0) return JS_ThrowTypeError(c, "isMouseButtonReleased requires a MouseButton enum");
return JS_NewBool(c, ::IsMouseButtonReleased(button));
}, "isMouseButtonReleased", 1));

JS_SetPropertyStr(ctx, update_obj, "isMouseButtonUp", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int argc, JSValueConst* argv) -> JSValue {
int button;
if (argc < 1 || JS_ToInt32(c, &button, argv[0]) < 0) return JS_ThrowTypeError(c, "isMouseButtonUp requires a MouseButton enum");
return JS_NewBool(c, ::IsMouseButtonUp(button));
}, "isMouseButtonUp", 1));

JS_SetPropertyStr(ctx, update_obj, "getMousePosition", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int, JSValueConst*) -> JSValue {
Vector2 pos = ::GetMousePosition();
return Utils::create_class_instance<JSVector2>(c, js_vector2_class_id, pos.x, pos.y);
}, "getMousePosition", 0));

JS_SetPropertyStr(ctx, update_obj, "getMouseX", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int, JSValueConst*) -> JSValue {
return JS_NewInt32(c, ::GetMouseX());
}, "getMouseX", 0));

JS_SetPropertyStr(ctx, update_obj, "getMouseY", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int, JSValueConst*) -> JSValue {
return JS_NewInt32(c, ::GetMouseY());
}, "getMouseY", 0));

JS_SetPropertyStr(ctx, update_obj, "getMouseWheelMove", JS_NewCFunction(ctx, [](JSContext* c, JSValueConst, int, JSValueConst*) -> JSValue {
return JS_NewFloat64(c, ::GetMouseWheelMove());
}, "getMouseWheelMove", 0));

return update_obj.release();
}

static JSValue create_shapes_object(JSContext* ctx) {
Expand Down
256 changes: 196 additions & 60 deletions src/api/api_enums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,73 +4,209 @@

namespace HostApi {

void register_hapi_enums(JSContext* ctx, JSModuleDef* m) {

static auto export_object = []<typename... Pairs>(JSContext* js_context, JSModuleDef* js_module_def, const char* obj_name, Pairs&&... pairs) {
template <typename... Pairs>
static void export_object(JSContext* js_context, JSModuleDef* js_module_def, const char* obj_name, Pairs&&... pairs) {
const JSValue obj = JS_NewObject(js_context);
Utils::set_object_properties(js_context, obj, std::forward<Pairs>(pairs)...);
JS_SetModuleExport(js_context, js_module_def, obj_name, obj);
};
}

void register_hapi_enums(JSContext* ctx, JSModuleDef* m) {

// --- Palette Object ---
export_object(ctx, m, "Palette",
std::pair{"LIGHTGRAY", LIGHTGRAY},
std::pair{"GRAY", GRAY},
std::pair{"DARKGRAY", DARKGRAY},
std::pair{"YELLOW", YELLOW},
std::pair{"GOLD", GOLD},
std::pair{"ORANGE", ORANGE},
std::pair{"PINK", PINK},
std::pair{"RED", RED},
std::pair{"MAROON", MAROON},
std::pair{"GREEN", GREEN},
std::pair{"LIME", LIME},
std::pair{"DARKGREEN", DARKGREEN},
std::pair{"SKYBLUE", SKYBLUE},
std::pair{"BLUE", BLUE},
std::pair{"DARKBLUE", DARKBLUE},
std::pair{"PURPLE", PURPLE},
std::pair{"VIOLET", VIOLET},
std::pair{"DARKPURPLE", DARKPURPLE},
std::pair{"BEIGE", BEIGE},
std::pair{"BROWN", BROWN},
std::pair{"DARKBROWN", DARKBROWN},
std::pair{"WHITE", WHITE},
std::pair{"BLACK", BLACK},
std::pair{"BLANK", BLANK},
std::pair{"MAGENTA", MAGENTA},
std::pair{"RAYWHITE", RAYWHITE}
);

// --- Info Object ---
export_object(ctx, m, "Info",
std::pair{"RAYLIB_VERSION", RAYLIB_VERSION_STR},
std::pair{"QUICKJS_VERSION", QUICKJS_VERSION_STR}
);

constexpr static auto P = []<typename V>(const char* name, V&& val) {
return std::pair{name, std::forward<V>(val)};
};
// --- ConfigFlags Object ---
export_object(ctx, m, "ConfigFlags",
std::pair{"FLAG_VSYNC_HINT", FLAG_VSYNC_HINT},
std::pair{"FLAG_FULLSCREEN_MODE", FLAG_FULLSCREEN_MODE},
std::pair{"FLAG_WINDOW_RESIZABLE", FLAG_WINDOW_RESIZABLE},
std::pair{"FLAG_WINDOW_UNDECORATED", FLAG_WINDOW_UNDECORATED},
std::pair{"FLAG_WINDOW_HIDDEN", FLAG_WINDOW_HIDDEN},
std::pair{"FLAG_WINDOW_MINIMIZED", FLAG_WINDOW_MINIMIZED},
std::pair{"FLAG_WINDOW_MAXIMIZED", FLAG_WINDOW_MAXIMIZED},
std::pair{"FLAG_WINDOW_UNFOCUSED", FLAG_WINDOW_UNFOCUSED},
std::pair{"FLAG_WINDOW_TOPMOST", FLAG_WINDOW_TOPMOST},
std::pair{"FLAG_WINDOW_ALWAYS_RUN", FLAG_WINDOW_ALWAYS_RUN},
std::pair{"FLAG_WINDOW_TRANSPARENT", FLAG_WINDOW_TRANSPARENT},
std::pair{"FLAG_WINDOW_HIGHDPI", FLAG_WINDOW_HIGHDPI},
std::pair{"FLAG_WINDOW_MOUSE_PASSTHROUGH", FLAG_WINDOW_MOUSE_PASSTHROUGH},
std::pair{"FLAG_BORDERLESS_WINDOWED_MODE", FLAG_BORDERLESS_WINDOWED_MODE},
std::pair{"FLAG_MSAA_4X_HINT", FLAG_MSAA_4X_HINT},
std::pair{"FLAG_INTERLACED_HINT", FLAG_INTERLACED_HINT}
);

// --- Palette Object ---
export_object(ctx, m, "Palette",
P("LIGHTGRAY", LIGHTGRAY),
P("GRAY", GRAY),
P("DARKGRAY", DARKGRAY),
P("YELLOW", YELLOW),
P("GOLD", GOLD),
P("ORANGE", ORANGE),
P("PINK", PINK),
P("RED", RED),
P("MAROON", MAROON),
P("GREEN", GREEN),
P("LIME", LIME),
P("DARKGREEN", DARKGREEN),
P("SKYBLUE", SKYBLUE),
P("BLUE", BLUE),
P("DARKBLUE", DARKBLUE),
P("PURPLE", PURPLE),
P("VIOLET", VIOLET),
P("DARKPURPLE", DARKPURPLE),
P("BEIGE", BEIGE),
P("BROWN", BROWN),
P("DARKBROWN", DARKBROWN),
P("WHITE", WHITE),
P("BLACK", BLACK),
P("BLANK", BLANK),
P("MAGENTA", MAGENTA),
P("RAYWHITE", RAYWHITE)
);
export_object(ctx, m, "Keyboard",
std::pair{"KEY_NULL", KEY_NULL},
std::pair{"KEY_APOSTROPHE", KEY_APOSTROPHE},
std::pair{"KEY_COMMA", KEY_COMMA},
std::pair{"KEY_MINUS", KEY_MINUS},
std::pair{"KEY_PERIOD", KEY_PERIOD},
std::pair{"KEY_SLASH", KEY_SLASH},
std::pair{"KEY_ZERO", KEY_ZERO},
std::pair{"KEY_ONE", KEY_ONE},
std::pair{"KEY_TWO", KEY_TWO},
std::pair{"KEY_THREE", KEY_THREE},
std::pair{"KEY_FOUR", KEY_FOUR},
std::pair{"KEY_FIVE", KEY_FIVE},
std::pair{"KEY_SIX", KEY_SIX},
std::pair{"KEY_SEVEN", KEY_SEVEN},
std::pair{"KEY_EIGHT", KEY_EIGHT},
std::pair{"KEY_NINE", KEY_NINE},
std::pair{"KEY_SEMICOLON", KEY_SEMICOLON},
std::pair{"KEY_EQUAL", KEY_EQUAL},
std::pair{"KEY_A", KEY_A},
std::pair{"KEY_B", KEY_B},
std::pair{"KEY_C", KEY_C},
std::pair{"KEY_D", KEY_D},
std::pair{"KEY_E", KEY_E},
std::pair{"KEY_F", KEY_F},
std::pair{"KEY_G", KEY_G},
std::pair{"KEY_H", KEY_H},
std::pair{"KEY_I", KEY_I},
std::pair{"KEY_J", KEY_J},
std::pair{"KEY_K", KEY_K},
std::pair{"KEY_L", KEY_L},
std::pair{"KEY_M", KEY_M},
std::pair{"KEY_N", KEY_N},
std::pair{"KEY_O", KEY_O},
std::pair{"KEY_P", KEY_P},
std::pair{"KEY_Q", KEY_Q},
std::pair{"KEY_R", KEY_R},
std::pair{"KEY_S", KEY_S},
std::pair{"KEY_T", KEY_T},
std::pair{"KEY_U", KEY_U},
std::pair{"KEY_V", KEY_V},
std::pair{"KEY_W", KEY_W},
std::pair{"KEY_X", KEY_X},
std::pair{"KEY_Y", KEY_Y},
std::pair{"KEY_Z", KEY_Z},
std::pair{"KEY_LEFT_BRACKET", KEY_LEFT_BRACKET},
std::pair{"KEY_BACKSLASH", KEY_BACKSLASH},
std::pair{"KEY_RIGHT_BRACKET", KEY_RIGHT_BRACKET},
std::pair{"KEY_GRAVE", KEY_GRAVE},
std::pair{"KEY_SPACE", KEY_SPACE},
std::pair{"KEY_ESCAPE", KEY_ESCAPE},
std::pair{"KEY_ENTER", KEY_ENTER},
std::pair{"KEY_TAB", KEY_TAB},
std::pair{"KEY_BACKSPACE", KEY_BACKSPACE},
std::pair{"KEY_INSERT", KEY_INSERT},
std::pair{"KEY_DELETE", KEY_DELETE},
std::pair{"KEY_RIGHT", KEY_RIGHT},
std::pair{"KEY_LEFT", KEY_LEFT},
std::pair{"KEY_DOWN", KEY_DOWN},
std::pair{"KEY_UP", KEY_UP},
std::pair{"KEY_PAGE_UP", KEY_PAGE_UP},
std::pair{"KEY_PAGE_DOWN", KEY_PAGE_DOWN},
std::pair{"KEY_HOME", KEY_HOME},
std::pair{"KEY_END", KEY_END},
std::pair{"KEY_CAPS_LOCK", KEY_CAPS_LOCK},
std::pair{"KEY_SCROLL_LOCK", KEY_SCROLL_LOCK},
std::pair{"KEY_NUM_LOCK", KEY_NUM_LOCK},
std::pair{"KEY_PRINT_SCREEN", KEY_PRINT_SCREEN},
std::pair{"KEY_PAUSE", KEY_PAUSE},
std::pair{"KEY_F1", KEY_F1},
std::pair{"KEY_F2", KEY_F2},
std::pair{"KEY_F3", KEY_F3},
std::pair{"KEY_F4", KEY_F4},
std::pair{"KEY_F5", KEY_F5},
std::pair{"KEY_F6", KEY_F6},
std::pair{"KEY_F7", KEY_F7},
std::pair{"KEY_F8", KEY_F8},
std::pair{"KEY_F9", KEY_F9},
std::pair{"KEY_F10", KEY_F10},
std::pair{"KEY_F11", KEY_F11},
std::pair{"KEY_F12", KEY_F12},
std::pair{"KEY_LEFT_SHIFT", KEY_LEFT_SHIFT},
std::pair{"KEY_LEFT_CONTROL", KEY_LEFT_CONTROL},
std::pair{"KEY_LEFT_ALT", KEY_LEFT_ALT},
std::pair{"KEY_LEFT_SUPER", KEY_LEFT_SUPER},
std::pair{"KEY_RIGHT_SHIFT", KEY_RIGHT_SHIFT},
std::pair{"KEY_RIGHT_CONTROL", KEY_RIGHT_CONTROL},
std::pair{"KEY_RIGHT_ALT", KEY_RIGHT_ALT},
std::pair{"KEY_RIGHT_SUPER", KEY_RIGHT_SUPER},
std::pair{"KEY_KB_MENU", KEY_KB_MENU},
std::pair{"KEY_KP_0", KEY_KP_0},
std::pair{"KEY_KP_1", KEY_KP_1},
std::pair{"KEY_KP_2", KEY_KP_2},
std::pair{"KEY_KP_3", KEY_KP_3},
std::pair{"KEY_KP_4", KEY_KP_4},
std::pair{"KEY_KP_5", KEY_KP_5},
std::pair{"KEY_KP_6", KEY_KP_6},
std::pair{"KEY_KP_7", KEY_KP_7},
std::pair{"KEY_KP_8", KEY_KP_8},
std::pair{"KEY_KP_9", KEY_KP_9},
std::pair{"KEY_KP_DECIMAL", KEY_KP_DECIMAL},
std::pair{"KEY_KP_DIVIDE", KEY_KP_DIVIDE},
std::pair{"KEY_KP_MULTIPLY", KEY_KP_MULTIPLY},
std::pair{"KEY_KP_SUBTRACT", KEY_KP_SUBTRACT},
std::pair{"KEY_KP_ADD", KEY_KP_ADD},
std::pair{"KEY_KP_ENTER", KEY_KP_ENTER},
std::pair{"KEY_KP_EQUAL", KEY_KP_EQUAL},
std::pair{"KEY_BACK", KEY_BACK},
std::pair{"KEY_MENU", KEY_MENU},
std::pair{"KEY_VOLUME_UP", KEY_VOLUME_UP},
std::pair{"KEY_VOLUME_DOWN", KEY_VOLUME_DOWN}
);

// --- Info Object ---
export_object(ctx, m, "Info",
P("RAYLIB_VERSION", RAYLIB_VERSION_STR),
P("QUICKJS_VERSION", QUICKJS_VERSION_STR)
);
// Enum: MouseButton
export_object(ctx, m, "MouseButton",
std::pair{"MOUSE_BUTTON_LEFT", MOUSE_BUTTON_LEFT},
std::pair{"MOUSE_BUTTON_RIGHT", MOUSE_BUTTON_RIGHT},
std::pair{"MOUSE_BUTTON_MIDDLE", MOUSE_BUTTON_MIDDLE},
std::pair{"MOUSE_BUTTON_SIDE", MOUSE_BUTTON_SIDE},
std::pair{"MOUSE_BUTTON_EXTRA", MOUSE_BUTTON_EXTRA},
std::pair{"MOUSE_BUTTON_FORWARD", MOUSE_BUTTON_FORWARD},
std::pair{"MOUSE_BUTTON_BACK", MOUSE_BUTTON_BACK}
);

// --- ConfigFlags Object ---
export_object(ctx, m, "ConfigFlags",
P("FLAG_VSYNC_HINT", FLAG_VSYNC_HINT),
P("FLAG_FULLSCREEN_MODE", FLAG_FULLSCREEN_MODE),
P("FLAG_WINDOW_RESIZABLE", FLAG_WINDOW_RESIZABLE),
P("FLAG_WINDOW_UNDECORATED", FLAG_WINDOW_UNDECORATED),
P("FLAG_WINDOW_HIDDEN", FLAG_WINDOW_HIDDEN),
P("FLAG_WINDOW_MINIMIZED", FLAG_WINDOW_MINIMIZED),
P("FLAG_WINDOW_MAXIMIZED", FLAG_WINDOW_MAXIMIZED),
P("FLAG_WINDOW_UNFOCUSED", FLAG_WINDOW_UNFOCUSED),
P("FLAG_WINDOW_TOPMOST", FLAG_WINDOW_TOPMOST),
P("FLAG_WINDOW_ALWAYS_RUN", FLAG_WINDOW_ALWAYS_RUN),
P("FLAG_WINDOW_TRANSPARENT", FLAG_WINDOW_TRANSPARENT),
P("FLAG_WINDOW_HIGHDPI", FLAG_WINDOW_HIGHDPI),
P("FLAG_WINDOW_MOUSE_PASSTHROUGH", FLAG_WINDOW_MOUSE_PASSTHROUGH),
P("FLAG_BORDERLESS_WINDOWED_MODE", FLAG_BORDERLESS_WINDOWED_MODE),
P("FLAG_MSAA_4X_HINT", FLAG_MSAA_4X_HINT),
P("FLAG_INTERLACED_HINT", FLAG_INTERLACED_HINT)
);
// Enum: MouseCursor
export_object(ctx, m, "MouseCursor",
std::pair{"MOUSE_CURSOR_DEFAULT", MOUSE_CURSOR_DEFAULT},
std::pair{"MOUSE_CURSOR_ARROW", MOUSE_CURSOR_ARROW},
std::pair{"MOUSE_CURSOR_IBEAM", MOUSE_CURSOR_IBEAM},
std::pair{"MOUSE_CURSOR_CROSSHAIR", MOUSE_CURSOR_CROSSHAIR},
std::pair{"MOUSE_CURSOR_POINTING_HAND", MOUSE_CURSOR_POINTING_HAND},
std::pair{"MOUSE_CURSOR_RESIZE_EW", MOUSE_CURSOR_RESIZE_EW},
std::pair{"MOUSE_CURSOR_RESIZE_NS", MOUSE_CURSOR_RESIZE_NS},
std::pair{"MOUSE_CURSOR_RESIZE_NWSE", MOUSE_CURSOR_RESIZE_NWSE},
std::pair{"MOUSE_CURSOR_RESIZE_NESW", MOUSE_CURSOR_RESIZE_NESW},
std::pair{"MOUSE_CURSOR_RESIZE_ALL", MOUSE_CURSOR_RESIZE_ALL},
std::pair{"MOUSE_CURSOR_NOT_ALLOWED", MOUSE_CURSOR_NOT_ALLOWED}
);
}

} // namespace HostApi
3 changes: 3 additions & 0 deletions src/api/hostapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ namespace HostApi {
JS_AddModuleExport(ctx, m, "Vector2");
JS_AddModuleExport(ctx, m, "Rectangle");
JS_AddModuleExport(ctx, m, "Palette");
JS_AddModuleExport(ctx, m, "Keyboard");
JS_AddModuleExport(ctx, m, "MouseButton");
JS_AddModuleExport(ctx, m, "MouseCursor");
JS_AddModuleExport(ctx, m, "Font");
JS_AddModuleExport(ctx, m, "Info");
JS_AddModuleExport(ctx, m, "ConfigFlags");
Expand Down
Loading