### Project Setup with npm Source: https://github.com/robloach/node-raylib/blob/master/README.md Steps to set up a new Node.js project, install node-raylib as a dependency, and configure a start script in `package.json`. ```bash mkdir myexample cd myexample ``` ```json { "dependencies": { "raylib": "*" }, "scripts": { "start": "node index.js" } } ``` ```bash npm install npm start ``` -------------------------------- ### Development Setup and Testing Source: https://github.com/robloach/node-raylib/blob/master/README.md Instructions for cloning the repository, installing dependencies, and running the test suite for node-raylib development. ```bash git clone https://github.com/RobLoach/node-raylib.git cd node-raylib npm i npm t ``` -------------------------------- ### Install and Run node-raylib Game Source: https://github.com/robloach/node-raylib/blob/master/templates/simple_game/README.md Instructions to install project dependencies using npm and start the node-raylib game. ```bash npm i npm start ``` -------------------------------- ### Basic Window Creation in Node.js Source: https://github.com/robloach/node-raylib/blob/master/README.md Demonstrates how to initialize a window, set the frame rate, and draw text using node-raylib. This is a fundamental example for starting graphical applications. ```javascript const r = require('raylib') const screenWidth = 800 const screenHeight = 450 r.InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window") r.SetTargetFPS(60) while (!r.WindowShouldClose()) { r.BeginDrawing(); r.ClearBackground(r.RAYWHITE) r.DrawText("Congrats! You created your first node-raylib window!", 120, 200, 20, r.LIGHTGRAY) r.EndDrawing() } r.CloseWindow() ``` -------------------------------- ### Usage Commands Source: https://github.com/robloach/node-raylib/blob/master/templates/typescript_game/README.md Standard npm commands to install project dependencies and start the application. ```bash npm i npm start ``` -------------------------------- ### Complete Node-Addon-API Binding Example for Raylib Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/function_bindings.md A comprehensive example combining the concepts discussed, showing a full C++ node-addon-api binding for a Raylib function (`InitWindow`). It includes necessary headers, the function binding, the initialization function for exporting, and the `NODE_API_MODULE` registration. ```cpp #include #include using namespace Napi; void BindInitWindow(const Napi::CallbackInfo& info) { return InitWindow( info[0].As(), info[1].As(), info[2].As().Utf8Value().c_str() ); } Napi::Object Init(Napi::Env env, Napi::Object exports) { exports.Set( Napi::String::New(env, "InitWindow"), Napi::Function::New(env, BindInitWindow) ); return exports; } NODE_API_MODULE(addon, Init); ``` -------------------------------- ### CLI Tool Usage Source: https://github.com/robloach/node-raylib/blob/master/README.md Demonstrates how to use the `node-raylib` command-line interface tool to execute Node.js files directly, and how to install it globally. ```bash # Unix ./bin/node-raylib core_basic_window.js # Windows node bin/node-raylib core_basic_window.js ``` ```bash # Global installation and usage npm install raylib --global node-raylib --version npx -y raylib --version ``` -------------------------------- ### DRM Mode Import Example Source: https://github.com/robloach/node-raylib/blob/master/README.md Illustrates how to import the DRM (Direct Rendering Manager) specific module for node-raylib, typically used on ARM devices like Raspberry Pi for rendering without an X11 window. ```javascript import * as rl from 'raylib/drm/index.js' // or const rl = require('raylib/drm') ``` -------------------------------- ### JavaScript Memory Leak Example Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/optimization/pointer_accessible_structs.md This JavaScript example demonstrates a common pitfall where reloading a texture without first unloading the previous instance leads to a C++ memory leak. It advises users to explicitly call r.UnloadTexture before loading the same texture again. ```javascript let texture = r.LoadTexture('sprite.png') // expect user to make some change to sprite.png on disk // ... then later texture = r.LoadTexture('sprite.png') // C++ memory leak!! user should call r.UnloadTexture(texture) first ``` -------------------------------- ### Bind raylib InitWindow function Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/function_bindings.md Demonstrates binding the C++ raylib function `InitWindow` to JavaScript. It shows how to receive arguments from JavaScript via `Napi::CallbackInfo`, convert them from `Napi::Value` to C++ types (int, const char*), and then call the original raylib function. ```cpp void BindInitWindow(const Napi::CallbackInfo& info) { int width = info[0].As(); int height = info[1].As(); const char * title = info[2].As().Utf8Value().c_str(); // now we can call our raylib function! InitWindow(width, height, title); } ``` -------------------------------- ### Instantiate Color Object in JavaScript Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/raylib_api_json.md Shows how to create a Color object using a constructor function or a plain JavaScript object, highlighting the flexibility in handling color data. ```javascript let color_a = r.Color(128, 128, 128, 255) let color_b = {r: 128, g: 128, b: 128, a: 255} console.log(color_a) // => {r: 128, g: 128, b: 128, a: 255} ``` -------------------------------- ### Configure node-raylib Build with CMake Source: https://github.com/robloach/node-raylib/blob/master/CMakeLists.txt This CMakeLists.txt file configures the build process for node-raylib, a Node.js binding for the raylib game development library. It handles fetching raylib, setting compiler flags for different environments (GCC, MSVC), and defining the shared library target with necessary include directories and linked libraries. ```cmake include(FetchContent) # 2025-02-15: based on https://github.com/raysan5/raylib/blob/master/src/external/glfw/CMakeLists.txt, make sure the CMake version are between 3.4 and 3.28 or the whole raylib lib will face fatal errors cmake_minimum_required(VERSION 3.4...3.28 FATAL_ERROR) project (node-raylib VERSION 0.10.0 DESCRIPTION "Node.js bindings for raylib" HOMEPAGE_URL "https://github.com/RobLoach/node-raylib" LANGUAGES C CXX) if ( CMAKE_COMPILER_IS_GNUCC ) set(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS} -Wno-unused-result") set(CMAKE_CXX_FLAGS "-Wall -Wextra") endif() # 2025-02-15: based on @link: https://learn.microsoft.com/en-us/cpp/build/reference/o-options-optimize-code?view=msvc-170. MSVC only accept O2 and don't have O3 optimization flag if ( MSVC ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /w") set(CMAKE_CXX_FLAGS_RELEASE "-O2") else() set(CMAKE_CXX_FLAGS_RELEASE "-O3") endif() if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() set(CMAKE_CXX_FLAGS_DEBUG "-g") # version doesn't seem to pick correct version #find_package(raylib 5.5 QUIET EXACT) if (NOT raylib_FOUND) include(FetchContent) FetchContent_Declare( raylib GIT_REPOSITORY https://github.com/raysan5/raylib.git GIT_TAG 5.5 GIT_SHALLOW TRUE ) FetchContent_GetProperties(raylib) if (NOT raylib_POPULATED) set(FETCHCONTENT_QUIET NO) FetchContent_MakeAvailable(raylib) set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) endif() endif() set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(BUILD_GAMES OFF CACHE BOOL "" FORCE) # Add all the include directories. include_directories(${PROJECT_NAME} "${CMAKE_JS_INC}" "${CMAKE_SOURCE_DIR}/node_modules/node-addon-api" "${CMAKE_CURRENT_SOURCE_DIR}/node_modules/node-addon-api" "${CMAKE_SOURCE_DIR}/node_modules/node-addon-api/src" "${CMAKE_CURRENT_SOURCE_DIR}/node_modules/node-addon-api/src" "${CMAKE_CURRENT_SOURCE_DIR}/../node-addon-api" "${CMAKE_CURRENT_SOURCE_DIR}/../node-addon-api/src" ) # This is hardcoded so that updates force a re-compile. add_library(${PROJECT_NAME} SHARED # src/lib/AddDefine.h # src/lib/AddFunction.h # src/lib/CleanUp.h # src/lib/GetArgFromParam.h # src/lib/ValidArgs.h # src/addon.cc # src/node-raymath.h # src/node-rlgl.h # src/lib/WrappedFunctions.h src/generated/node-raylib.cc ) ## Suffix the node module with .node. set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node" ) target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20) target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_JS_INC}" "${CMAKE_SOURCE_DIR}/node_modules/node-addon-api" "${CMAKE_CURRENT_SOURCE_DIR}/node_modules/node-addon-api" "${CMAKE_SOURCE_DIR}/node_modules/node-addon-api/src" "${CMAKE_CURRENT_SOURCE_DIR}/node_modules/node-addon-api/src" "${CMAKE_CURRENT_SOURCE_DIR}/../node-addon-api" "${CMAKE_CURRENT_SOURCE_DIR}/../node-addon-api/src" ) # Link raylib. target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB} raylib ) ``` -------------------------------- ### Exporting Functions and Modules with Node-Addon-API Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/function_bindings.md Explains the final steps to make native C++ functions available in Node.js. This involves creating an `Init` function that populates an `exports` object with bound functions using `exports.Set()` and registering the addon with `NODE_API_MODULE`. ```cpp // note that `exports` is one of the arguments to this function: Napi::Object Init(Napi::Env env, Napi::Object exports) { exports.Set( // this is what the name of the function will be in Javascript Napi::String::New(env, "InitWindow"), // create an Napi::Function out of the function binding you wrote somewhere Napi::Function::New(env, BindInitWindow) ); return exports; } // you don't need to declare `addon` anywhere - it comes from the node-addon-api namespace NODE_API_MODULE(addon, Init); ``` -------------------------------- ### Create Camera2D Object in JavaScript Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/raylib_api_json.md Demonstrates how to create and initialize a Camera2D object in JavaScript, mirroring the structure defined by raylib's API. ```javascript let myCamera = { offset: {x: 0, y: 0}, target: {x: 50, y: 50}, rotation: 0, zoom: 1 } ``` -------------------------------- ### Handling Nested Structs in Node-Addon-API Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/function_bindings.md Illustrates a common challenge when binding C++ libraries: handling nested structs. It shows that `Napi::Object::Set` cannot directly convert C++ struct instances, requiring them to be explicitly converted into `Napi::Object` first before being set as properties. ```cpp Vector2 vec2 = {0.0, 0.0}; // instantiate c++ vector2 (maybe some function returns this) Napi::Object out = Napi::Object::New(info.Env()); // out.Set("position", vec2); // ERROR! can't convert vec2 to Napi::Value // instead lets convert the vec2 into a JS object: Napi::Object napi_vec2 = Napi::Object::New(info.Env()); napi_vec2.Set("x", vec2.x); napi_vec2.Set("y", vec2.y); // NOW we can set it onto our output object: out.Set("position", napi_vec2); return out; ``` -------------------------------- ### Bind raylib GetFPS function with return value Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/function_bindings.md Illustrates binding the C++ raylib function `GetFPS` which returns an integer. The binding function returns a `Napi::Number` to JavaScript, using `Napi::Number::New` and `info.Env()` to create the JavaScript number within the correct NodeJS environment. ```cpp Napi::Number BindGetFPS(const Napi::CallbackInfo& info) { int fps = GetFPS(); return Napi::Number::New(info.Env(), fps); } ``` -------------------------------- ### C++ DrawTexture Binding with Flattened Arguments Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/flattening_arguments.md This C++ code shows a Node.js addon binding for the `DrawTexture` function. It demonstrates how struct arguments like `Texture2D` and `Color` are constructed from individual JavaScript number arguments passed via `Napi::CallbackInfo`, bypassing direct `Napi::Object` conversion for performance. ```cpp void BindDrawTexture(const Napi::CallbackInfo& info) { DrawTexture( (Texture2D) { info[0].As(), info[1].As(), info[2].As(), info[3].As(), info[4].As(), }, info[5].As(), info[6].As(), (Color){ (int)info[7].As(), (int)info[8].As(), (int)info[9].As(), (int)info[10].As() } ); } ``` -------------------------------- ### Binding Raylib LoadTexture to Node.js Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/function_bindings.md Demonstrates how to bind the C++ Raylib function `LoadTexture` to Node.js. It converts the C++ `Texture` struct, which has integer properties (id, width, height, mipmaps, format), into a JavaScript `Napi::Object` using node-addon-api. ```cpp #include #include Napi::Object BindLoadTexture(const Napi::CallbackInfo& info) { Texture texture = LoadTexture( // convert our function argument to a string! info[0].As().Utf8Value().c_str() ); Napi::Object out = Napi::Object::New(info.Env()); out.Set("id", texture.id); out.Set("width", texture.width); out.Set("height", texture.height); out.Set("mipmaps", texture.mipmaps); out.Set("format", texture.format); return out; } ``` -------------------------------- ### Generated JavaScript Wrapper for DrawTexture Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/flattening_arguments.md Shows a generated JavaScript wrapper function that simplifies calling `DrawTexture`. It accepts the original object-based arguments (`Texture`, `Color`) and uses helper functions (`processTextureInput`, `processColorInput`) to flatten them before passing them to the native `raylib.DrawTexture` function. ```javascript export function DrawTexture(texture: Texture, posX: Number, posY: Number, tint: Color) { raylib.DrawTexture(...processTextureInput(texture), posX, posY, ...processColorInput(color)) } // Helper function to flatten Color object properties function processColorInput(color: Color) { return [color.r, color.g, color.b, color.a] } // Helper function to flatten Texture object properties function processTextureInput(texture: Texture) { return [texture.id, texture.width, texture.height, texture.mipmaps, texture.format] } ``` -------------------------------- ### DrawTexture with Inline Color Conversion in C++ Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/optimization/colors_as_integers.md Illustrates the integration of color integer conversion within a C++ function, specifically `DrawTexture`. It shows how `GetColor` can be used inline to process an integer color argument passed from JavaScript, optimizing data transfer. ```cpp void BindDrawTexture(const Napi::CallbackInfo& info) { DrawTexture( *(Texture2D*)info[0].As().Int64Value(), info[1].As(), info[2].As(), // convert a color inline GetColor(info[3].As()) ); } ``` -------------------------------- ### C++ Binding for LoadTexture Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/optimization/pointer_accessible_structs.md Demonstrates the C++ binding for raylib's LoadTexture function. It allocates memory for the texture, copies the data, and returns a pointer to the texture data along with its properties to the NodeJS environment. ```cpp Napi::Object BindLoadTexture(const Napi::CallbackInfo& info) { // call raylib function and store result Texture texture = LoadTexture(info[0].As().Utf8Value().c_str()); // assign memory in the raylib memory pool for the texture void* ptr = MemAlloc(sizeof(Texture2D)); // copy the texture data to that memory location *(Texture2D*)ptr = tex; // return a JS object to NodeJS containing the texture, with the pointer included Napi::Object out = Napi::Object::New(env); out.Set("id", texture.id); out.Set("width", texture.width); out.Set("height", texture.height); out.Set("mipmaps", texture.mipmaps); out.Set("format", texture.format); // a void* needs to be cast as an integer to convert to a Javascript number out.Set("pointer", (int64_t) ptr); return out; } ``` -------------------------------- ### BindWindowShouldClose N-API C++ Function Source: https://github.com/robloach/node-raylib/blob/master/docs/generator/example_function_binding.md Binds the C++ raylib function `WindowShouldClose` to Node.js using N-API. This function checks if the user has requested to close the window. It returns a boolean value indicating the window's close status, converted to a JavaScript value using `ToValue`. ```cpp Napi::Value BindWindowShouldClose(const Napi::CallbackInfo& info) { int index = -1; // unused since no arguments are needed - maybe only conditionally add this line return ToValue(info.Env(), WindowShouldClose() ); // if the function is not void, pass it's result into a ToValue() call } ``` -------------------------------- ### JavaScript Usage of Flattened DrawTexture Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/flattening_arguments.md Illustrates how the `DrawTexture` function must be called from JavaScript when arguments are flattened. Instead of passing `Texture` and `Color` objects, their properties are provided as individual arguments in a specific order, matching the C++ binding. ```javascript let myTexture = { id: 0, width: 128, height: 128, mipmaps: 1, format: 7 // default format for PNGs } let myTextureColor = { r: 255, g: 255, b: 255, a: 255 } // Called with 11 arguments due to flattening: raylib.DrawTexture( // texture properties myTexture.id, myTexture.width, myTexture.height, myTexture.mipmaps, myTexture.format, // position 10, 10, // color properties myTextureColor.r, myTextureColor.g, myTextureColor.b, myTextureColor.a ) ``` -------------------------------- ### BindDrawPixelV N-API C++ Function Source: https://github.com/robloach/node-raylib/blob/master/docs/generator/example_function_binding.md Binds the C++ raylib function `DrawPixelV` to Node.js using N-API. This function draws a single pixel at a specified 2D coordinate with a given color. It expects arguments to be converted from JavaScript values using helper functions like `Vector2FromValue` and `ColorFromValue`. ```cpp void BindDrawPixelV(const Napi::CallbackInfo& info, int& index) { // create an index variable to index into info[] with int index = -1; DrawPixelV( Vector2FromValue(info, index), // for each function argument, call ${arg.type}FromValue(info, index) ColorFromValue(info, index) ); // no return type on this function } ``` -------------------------------- ### TypeScript Wrapper for DrawTexture with Color Conversion Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/optimization/colors_as_integers.md Provides a TypeScript wrapper function for `DrawTexture` that handles the conversion of a `Color` object to an integer before passing it to the underlying Raylib C++ function. This maintains a clean API for JavaScript/TypeScript users. ```typescript function process_color(color: Color) { var cr = color.r & 0xFF; var cg = color.g & 0xFF; var cb = color.b & 0xFF; var ca = color.a & 0xFF; return (cr << 24) + (cg << 16) + (cb << 8) + (ca) } export function DrawTexture(texture: Texture, x: number, y: number, color: Color) { raylib.DrawTexture(texture.pointer, x, y, process_color(color)) } ``` -------------------------------- ### BindLoadTexture N-API C++ Function Source: https://github.com/robloach/node-raylib/blob/master/docs/generator/example_function_binding.md Binds the C++ raylib function `LoadTexture` to Node.js using N-API. This function loads a texture from a file path provided as a string. The file path is converted from a JavaScript string using `StringFromValue`, and the resulting texture object is converted to a JavaScript object using `ToValue`. ```cpp Napi::Object BindLoadTexture(const Napi::CallbackInfo& info) { int index = -1; return ToValue(info.Env(), LoadTexture( StringFromValue(info, index) ) ); } ``` -------------------------------- ### Raylib Struct Definitions (JSON Schema) Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/raylib_api_json.md Defines the structure of raylib data types like Vector2 and Camera2D using JSON schema. These schemas map native C++ types to their JavaScript object representations. ```json [ { "name": "Vector2", "description": "Vector2, 2 components", "fields": [ { "type": "float", "name": "x", "description": "Vector x component" }, { "type": "float", "name": "y", "description": "Vector y component" } ] }, { "name": "Camera2D", "description": "Camera2D, defines position/orientation in 2d space", "fields": [ { "type": "Vector2", "name": "offset", "description": "Camera offset (displacement from target)" }, { "type": "Vector2", "name": "target", "description": "Camera target (rotation and zoom origin)" }, { "type": "float", "name": "rotation", "description": "Camera rotation in degrees" }, { "type": "float", "name": "zoom", "description": "Camera zoom (scaling), should be 1.0f by default" } ] } ] ``` -------------------------------- ### Decode Integer to Raylib Color in C++ Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/optimization/colors_as_integers.md Shows how to use the Raylib function `GetColor` within C++ (specifically with `node-addon-api`) to convert a 32-bit integer representation back into a Raylib `Color` struct. This is useful for processing colors passed from JavaScript. ```cpp Napi::Number num = info[0].As(); Color color = GetColor(num); ``` -------------------------------- ### NodeJS API for LoadTexture Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/optimization/pointer_accessible_structs.md Shows the JavaScript implementation for LoadTexture in node-raylib. It wraps the C++ binding, processes the returned texture object to hide the pointer property using Object.defineProperty, and makes all texture properties immutable. ```js export function LoadTexture(path) { let texture = raylib.LoadTexture(path) return processTextureOutput(texture) } function processTextureOutput(texture) { const ob = { id: texture.id, width: texture.width, height: texture.height, mipmaps: texture.mipmaps, format: texture.format } // pointer property will not appear in console.log() // or when iterating values of the texture Object.defineProperty(obj, 'pointer', { enumerable: false, writable: false, value: texture.pointer }) // make all properties of the texture readonly (immutable) Object.freeze(ob) return ob } ``` -------------------------------- ### Convert C++ Types to Napi::Value with N-API Source: https://github.com/robloach/node-raylib/blob/master/docs/generator/example_type_converters.md These C++ functions serialize common C++ data types like float, int, Vector2, and Texture2D into Napi::Value objects. This is essential for passing data from C++ to JavaScript environments when using N-API for Node.js bindings. ```cpp Napi::Value ToValue(napi_env env, float obj) { return Napi::Number::New(env, obj); } Napi::Value ToValue(napi_env env, int obj) { return Napi::Number::New(env, obj); } Napi::Value ToValue(napi_env env, Vector2 obj) { Napi::Object out = Napi::Object::New(env); out.Set("x", ToValue(env, obj.x)); // float out.Set("y", ToValue(env, obj.y)); // float return out; } Napi::Value ToValue(napi_env env, Texture2D obj) { Napi::Object out = Napi::Object::New(env); out.Set("id", ToValue(env, obj.x)); // int out.Set("width", ToValue(env, obj.y)); // int out.Set("height", ToValue(env, obj.x)); // int out.Set("mipmaps", ToValue(env, obj.y)); // int out.Set("format", ToValue(env, obj.x)); // int // future: texture.pointer return out; } ``` -------------------------------- ### Encode Color to Integer in JavaScript Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/optimization/colors_as_integers.md Demonstrates how to use bitwise operators in JavaScript to convert a color object (with r, g, b, a channels) into a single 32-bit integer. This is a common technique for performance optimization in graphics programming. ```javascript let c = {r: 255, g: 128, b: 0, a: 255} var cr = c.r & 0xFF; var cg = c.g & 0xFF; var cb = c.b & 0xFF; var ca = c.a & 0xFF; var rgba = (cr << 24) + (cg << 16) + (cb << 8) + (ca) ``` -------------------------------- ### TypeScript Wrapper for ImageDrawPixel Source: https://github.com/robloach/node-raylib/blob/master/docs/generator/pass_by_reference.md This TypeScript wrapper function provides a convenient way for JavaScript developers to use raylib's pass-by-reference functions. It calls the native addon, receives the updated object, and copies its properties back to the original JavaScript object. ```ts export function ImageDrawPixel(image: Image, posX: number, posY: number, color: Color) { // store updated copy let new_image = raylib.ImageDrawPixel(image, posX, posY, color) for (let key in image) { // copy each value over to the original image[key] = new_image[key] } } ``` -------------------------------- ### Convert Napi::Value to C++ Types with N-API Source: https://github.com/robloach/node-raylib/blob/master/docs/generator/example_type_converters.md These C++ functions deserialize Napi::Value objects received from JavaScript into native C++ types such as float and Vector2. They are crucial for handling arguments passed from Node.js to C++ functions within N-API modules. ```cpp float FloatFromValue(const Napi::CallbackInfo& info, int& index) { return info[index += 1].As(); } Vector2 Vector2FromValue(const Napi::CallbackInfo& info, int& index) { return (Vector2) { FloatFromValue(info, index += 1), FloatFromValue(info, index += 1) }; } ``` -------------------------------- ### C++ Binding for Pass-By-Reference ImageDrawPixel Source: https://github.com/robloach/node-raylib/blob/master/docs/generator/pass_by_reference.md This C++ binding demonstrates how to handle raylib functions that modify arguments passed by reference. Since C++ modifications are on a copy in Node.js, the binding must return the modified object to JavaScript. ```cpp Napi::Value BindImageDrawPixel(const Napi::CallbackInfo& info) { Image obj = //convert from info[0] to Image // this function is void because it is pass-by-reference ImageDrawPixel(obj/* <- Image reference */, ...); // now we must reference the updated values, // and build a new Napi::Object to return to the user return ToValue(info.Env(), obj); // assume there is some function Napi::Value ToValue(napi_env env, Image obj) {} } ``` -------------------------------- ### NodeJS API for DrawTexture Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/optimization/pointer_accessible_structs.md Presents the TypeScript API wrapper for DrawTexture in node-raylib. It abstracts the pointer management by accepting a Texture object (which contains the hidden pointer) and passing this pointer to the underlying C++ binding. ```ts export function DrawTexture(texture: Texture, x: number, y: number, color: Color) { raylib.DrawTexture(texture.pointer, x, y, color) } ``` -------------------------------- ### C++ Binding for DrawTexture (Pointer Input) Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/optimization/pointer_accessible_structs.md Illustrates a C++ binding function, likely for DrawTexture, that accepts a JavaScript Number representing a memory pointer. It casts this number back to a Texture2D pointer to use with the raylib DrawTexture function. ```cpp void BindDrawTexturePointer(const Napi::CallbackInfo& info) { DrawTexture( // convert the JS Number to a pointer. // Then cast that pointer as a Texture pointer and access the texture *(Texture2D*)info[0].As().Int64Value(), info[1].As(), info[2].As(), GetColor(info[3].As()) ); } ``` -------------------------------- ### TypeScript UnloadTexture Wrapper Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/optimization/pointer_accessible_structs.md A TypeScript wrapper function for unloading textures. It takes a Texture object and calls the underlying raylib.UnloadTexture function using the texture's pointer. The note suggests potential improvements like unfreezing the JavaScript object and nullifying its pointer properties after unloading. ```typescript export function UnloadTexture(texture: Texture) { raylib.UnloadTexture(texture.pointer) } ``` -------------------------------- ### C++ BindUnloadTexture for Memory Management Source: https://github.com/robloach/node-raylib/blob/master/docs/bindings/optimization/pointer_accessible_structs.md This C++ function serves as a binding for unloading textures. It dereferences a pointer to a Texture2D struct, calls the raylib UnloadTexture function, and then frees the memory allocated for the struct using MemFree to prevent memory leaks. ```cpp void BindUnloadTexture(const Napi::CallbackInfo& info) { UnloadTexture(*(Texture2D*)info[0].As().Int64Value()); MemFree((void*)info[0].As().Int64Value()); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.