Files
cell/scripts/core/engine.js
John Alanbrook bff39b0e9f
All checks were successful
Build / build-windows (push) Successful in 35s
Build / build-linux (push) Successful in 40s
Build / package-dist (push) Has been skipped
all files now have an implicit empty actor, even if there is no actor statement present
2025-02-18 19:38:24 -06:00

1685 lines
53 KiB
JavaScript

(function engine() {
prosperon.DOC = Symbol('+documentation+') // Symbol for documentation references
//
// sprite
//
prosperon.c_types.sprite[prosperon.DOC] = {}
prosperon.c_types.sprite[prosperon.DOC][prosperon.DOC] = `A 'sprite' is a simple struct for 2D drawing. It stores a rectangle (pos + size),
UV coordinates, color, and layer, as well as an associated 'image' object. The sprite
can be drawn via GPU or SDL_Renderer. Freed when no JS references remain.
`;
prosperon.c_types.sprite[prosperon.DOC].set_affine = `Update this sprite's position and size from a transform's pos and scale.
:param transform: The transform whose pos/scale will overwrite the sprite's rect.
:return: None
`;
prosperon.c_types.sprite[prosperon.DOC].set_rect = `Set the sprite's rect (x, y, w, h) directly.
:param rect: An object or array specifying x, y, width, and height.
:return: None
`;
prosperon.c_types.sprite[prosperon.DOC].set_image = `Assign or replace the sprite's underlying image. Automatically updates UV if
the image has a 'rect' property.
:param image: A JS object representing the image (with .texture, .rect, etc.).
:return: None
`;
prosperon.c_types.sprite[prosperon.DOC].layer = `Get or set the sprite's z-layer integer. Sprites with higher layers typically
draw on top of lower layers.
:param value: (when setting) An integer specifying the layer.
:return: The current layer (when getting), or None (when setting).
`;
prosperon.c_types.sprite[prosperon.DOC].color = `Get or set the sprite's color tint as [r, g, b, a].
:param value: (when setting) An array [r, g, b, a] in the 0.0..1.0 range.
:return: The current color array (when getting), or None (when setting).
`;
//
// transform
//
prosperon.c_types.transform[prosperon.DOC] = {}
prosperon.c_types.transform[prosperon.DOC][prosperon.DOC] = `A hierarchical transform storing 3D or 2D position, rotation (as a quaternion),
and scale. Can have a parent transform. Freed automatically on GC.
`;
prosperon.c_types.transform[prosperon.DOC].pos = `Get or set the transform's position as a 3D vector [x, y, z].
:param value: (when setting) [x, y, z].
:return: The current position vector (when getting), or None (when setting).
`;
prosperon.c_types.transform[prosperon.DOC].scale = `Get or set the transform's scale as a 3D vector [x, y, z].
For 2D usage, z is often 1.
:param value: (when setting) [sx, sy, sz].
:return: The current scale (when getting), or None (when setting).
`;
prosperon.c_types.transform[prosperon.DOC].rotation = `Get or set the transform's rotation as a quaternion [x, y, z, w].
Angles in degrees or radians must first be converted prior to making a quaternion.
:param value: (when setting) [qx, qy, qz, qw].
:return: The current quaternion (when getting), or None (when setting).
`;
prosperon.c_types.transform[prosperon.DOC].parent = `Get or set the transform's parent. If set, this transform becomes a child of
the parent (re-parenting). Must be another transform object or undefined.
:param value: (when setting) Another transform or undefined.
:return: The current parent transform (when getting), or None (when setting).
`;
prosperon.c_types.transform[prosperon.DOC].change_hook = `A user-supplied function that's called whenever the transform's local matrix changes.
If undefined, no hook is called.
:param value: (when setting) A function.
:return: The current function or undefined.
`;
prosperon.c_types.transform[prosperon.DOC].trs = `Set the transform's position, rotation, and scale in one call.
:param pos: [x,y,z] for position, or undefined to keep existing.
:param quat: [qx,qy,qz,qw] for rotation, or undefined.
:param scale: [sx,sy,sz] for scale, or undefined.
:return: None
`;
prosperon.c_types.transform[prosperon.DOC].phys2d = `Apply simple 2D velocity and angular velocity to this transform.
:param velocity: [vx, vy] added to 'pos' each frame.
:param angularVel: A scalar for rotation in (radians/second).
:param dt: The time delta in seconds.
:return: None
`;
prosperon.c_types.transform[prosperon.DOC].move = `Translate this transform by the specified vector.
:param delta: [dx, dy, dz] to add to .pos
:return: None
`;
prosperon.c_types.transform[prosperon.DOC].rotate = `Rotate this transform by an axis+angle.
:param axis: [ax, ay, az] the axis of rotation.
:param angle: The angle in turns or radians (depending on usage).
:return: None
`;
prosperon.c_types.transform[prosperon.DOC].angle = `Return the transform's rotation about a specified axis (x, y, or z).
For example, angle([1,0,0]) returns the roll about the X-axis.
:param axis: Which axis [1,0,0] or [0,1,0] or [0,0,1].
:return: The numeric angle in 'turns' or radians, depending on usage.
`;
prosperon.c_types.transform[prosperon.DOC].lookat = `Rotate this transform so it looks toward the given world position.
:param target: [x, y, z] position in world coords.
:return: None
`;
prosperon.c_types.transform[prosperon.DOC].direction = `Rotate a vector by this transform's rotation, effectively "transforming"
a direction from local space to world space.
:param localDir: [dx, dy, dz] in local transform coordinates.
:return: [dx', dy', dz'] direction in world space.
`;
prosperon.c_types.transform[prosperon.DOC].unit = `Reset position, rotation, and scale to [0,0,0], identity rotation, and [1,1,1].
:return: None
`;
prosperon.c_types.transform[prosperon.DOC].rect = `Set this transform's pos and scale from a 2D rect object {x, y, w, h}.
:param rect: Object with .x, .y, .w, .h
:return: None
`;
prosperon.c_types.transform[prosperon.DOC].array = `Return this transform's matrix as a 16-element float array in column-major order.
:return: An array of 16 floats.
`;
prosperon.c_types.transform[prosperon.DOC].torect = `Convert transform's 2D position/scale to a rect {x, y, w, h}.
Rotation is currently ignored.
:return: A rect object {x, y, w, h}.
`;
prosperon.c_types.transform[prosperon.DOC].children = `Return an array of child transforms belonging to this transform.
:return: An array of transform objects.
`;
//
// font
//
prosperon.c_types.font[prosperon.DOC] = {}
prosperon.c_types.font[prosperon.DOC][prosperon.DOC] = `A bitmap or TTF-based font object storing glyph data.
Used for measuring/drawing text. Freed when GC sees no references.
`;
prosperon.c_types.font[prosperon.DOC].linegap = `Get or set the font's additional line spacing above the built-in metrics.
:param value: (when setting) The new line gap.
:return: The current line gap (when getting), or None (when setting).
`;
prosperon.c_types.font[prosperon.DOC].height = `The baseline-to-baseline height in pixels.
:return: The font's total height in px.
`;
prosperon.c_types.font[prosperon.DOC].ascent = `How far above the baseline the font extends.
:return: A scalar float for ascent.
`;
prosperon.c_types.font[prosperon.DOC].descent = `How far below baseline the font extends.
:return: A scalar float for descent.
`;
prosperon.c_types.font[prosperon.DOC].text_size = `Measure a piece of text's width/height when rendered with this font.
:param text: The string to measure.
:param letterSpacing: Extra spacing between characters.
:param wrap: If nonzero, word-wrap to this maximum width.
:return: [width, height] as a float array.
`;
//
// datastream
//
prosperon.c_types.datastream[prosperon.DOC]= {}
prosperon.c_types.datastream[prosperon.DOC][prosperon.DOC] = `A streaming media handle, typically for MPEG video. Freed automatically.
`;
prosperon.c_types.datastream[prosperon.DOC].time = `Return the current playback time in seconds.
:return: Current time as a float in seconds.
`;
prosperon.c_types.datastream[prosperon.DOC].seek = `Seek to the specified time (in seconds).
:param seconds: The time to jump to in the stream.
:return: None
`;
prosperon.c_types.datastream[prosperon.DOC].advance = `Advance by a certain number of seconds, decoding video as needed.
:param seconds: The amount of time to skip forward.
:return: None
`;
prosperon.c_types.datastream[prosperon.DOC].duration = `Return the total duration of the video stream, in seconds, if known.
:return: Float seconds duration, or 0 if unknown.
`;
prosperon.c_types.datastream[prosperon.DOC].framerate = `Return the framerate (FPS) of the stream if known.
:return: Float frames per second, or 0 if unknown.
`;
prosperon.c_types.datastream[prosperon.DOC].callback = `A function to call whenever a new frame is decoded. If not set, no callback is invoked.
:param fn: (when setting) A function that receives (surface).
:return: The existing function or undefined if none.
`;
//
// timer
//
prosperon.c_types.timer[prosperon.DOC] = {}
prosperon.c_types.timer[prosperon.DOC][prosperon.DOC] = `A scheduled callback or countdown. Freed automatically once no longer referenced
or once it completes.
`;
prosperon.c_types.timer[prosperon.DOC].remain = `Get or set how many seconds remain before the timer triggers.
:param value: (when setting) A float specifying new time remaining.
:return: The current time left (when getting), or None (when setting).
`;
prosperon.c_types.timer[prosperon.DOC].fn = `Get or set the function called when the timer expires.
:param value: (when setting) The function.
:return: The function or undefined if none is set.
`;
//
// rtree
//
prosperon.c_types.rtree[prosperon.DOC] = {}
prosperon.c_types.rtree[prosperon.DOC][prosperon.DOC] = `An R-tree for spatial lookups. Insert bounding boxes, query by bounding box, etc.
`;
prosperon.c_types.rtree[prosperon.DOC].add = `Insert an object that has a 'rect' property {x, y, w, h} into the tree.
:param obj: The object to add (must have rectAtom).
:return: None
`;
prosperon.c_types.rtree[prosperon.DOC].delete = `Remove an object from the tree. Must match the same rect as used when adding.
:param obj: The object to remove.
:return: None
`;
prosperon.c_types.rtree[prosperon.DOC].query = `Return an array of objects whose bounding boxes intersect the given rect.
:param rect: {x, y, w, h} bounding region to query.
:return: Array of objects that overlap that region.
`;
prosperon.c_types.rtree[prosperon.DOC].size = `Indicates how many items are stored in the rtree.
:return: Integer count of items in the tree.
`;
prosperon.c_types.rtree[prosperon.DOC].forEach = `Call a function for every item in the rtree.
:param callback: A function called with no arguments, or possibly (item).
:return: None
`;
prosperon.c_types.rtree[prosperon.DOC].has = `Return true if the specified object is in the tree, false otherwise.
:param obj: The object to check.
:return: True if found, else false.
`;
prosperon.c_types.rtree[prosperon.DOC].values = `Return an array of all items currently in the rtree.
:return: Array of all stored objects.
`;
//
// PHYSFS_File
//
prosperon.c_types.PHYSFS_File[prosperon.DOC] = {}
prosperon.c_types.PHYSFS_File[prosperon.DOC][prosperon.DOC] = `A file handle opened via PhysFS for writing or reading. Freed automatically when references go away.
`;
prosperon.c_types.PHYSFS_File[prosperon.DOC].close = `Close this file handle. Throws on error.
:return: None
`;
prosperon.c_types.PHYSFS_File[prosperon.DOC].write = `Write data (string or ArrayBuffer) to the file. Throws on error.
:param data: The data to write (string or ArrayBuffer).
:return: None
`;
prosperon.c_types.PHYSFS_File[prosperon.DOC].buffer = `Enable an internal write buffer of the given size on this file.
:param size: Size in bytes of the buffer.
:return: None
`;
prosperon.c_types.PHYSFS_File[prosperon.DOC].tell = `Return the current position in the file.
:return: A numeric offset.
`;
prosperon.c_types.PHYSFS_File[prosperon.DOC].eof = `Return whether the file pointer is at end-of-file.
:return: True if at EOF, false otherwise.
`;
//
// SDL_Camera
//
prosperon.c_types.SDL_Camera[prosperon.DOC] = {}
prosperon.c_types.SDL_Camera[prosperon.DOC][prosperon.DOC] = `A handle to a physical camera device. Freed when references drop or camera is closed.
`;
prosperon.c_types.SDL_Camera[prosperon.DOC].frame = `Acquire the latest camera frame (as an SDL_Surface). Returns undefined if no
new frame is available yet. Throws on error.
:return: SDL_Surface or undefined.
`;
prosperon.c_types.SDL_Camera[prosperon.DOC].release_frame = `Release a frame surface previously acquired via camera.frame(). Must be
done for each acquired frame.
:param surface: The surface to release.
:return: None
`;
//
// SDL_Cursor
//
prosperon.c_types.SDL_Cursor[prosperon.DOC] = {}
prosperon.c_types.SDL_Cursor[prosperon.DOC][prosperon.DOC] = `An SDL cursor handle. Freed automatically on GC. No direct methods.
`;
//
// SDL_Thread
//
prosperon.c_types.SDL_Thread[prosperon.DOC] = {}
prosperon.c_types.SDL_Thread[prosperon.DOC][prosperon.DOC] = `A handle to an SDL-created thread. Freed on GC after join.
Note: The engine generally doesn't expose custom usage for threads.
`;
prosperon.c_types.SDL_Thread[prosperon.DOC].wait = `Block until this thread terminates.
:return: None
`;
//
// SDL_Window
//
prosperon.c_types.SDL_Window[prosperon.DOC] = {}
prosperon.c_types.SDL_Window[prosperon.DOC][prosperon.DOC] = `An application window, created via prosperon.engine_start or SDL calls. Freed on GC.
`;
prosperon.c_types.SDL_Window[prosperon.DOC].fullscreen = `Toggle fullscreen mode for this window (SDL_WINDOW_FULLSCREEN).
:return: None
`;
prosperon.c_types.SDL_Window[prosperon.DOC].make_renderer = `Create an SDL_Renderer for 2D rendering tied to this window.
:param name: The renderer driver name, e.g. "opengl" (may be optional).
:return: An SDL_Renderer object.
`;
prosperon.c_types.SDL_Window[prosperon.DOC].make_gpu = `Create an SDL_GPUDevice for low-level GPU rendering on this window.
:param debug: If true, enable debugging in the GPU device.
:param driverName: The GPU back-end driver, e.g. "opengl".
:return: An SDL_GPUDevice.
`;
prosperon.c_types.SDL_Window[prosperon.DOC].keyboard_shown = `Return whether the on-screen keyboard is visible (mobile/tablet).
:return: True if shown, false otherwise.
`;
prosperon.c_types.SDL_Window[prosperon.DOC].theme = `Currently returns undefined. Placeholder for retrieving OS window theme info.
:return: undefined
`;
prosperon.c_types.SDL_Window[prosperon.DOC].safe_area = `Return a rect describing any OS-specific "safe" region for UI, e.g. on iPhone with a notch.
:return: A rect object {x, y, w, h}.
`;
prosperon.c_types.SDL_Window[prosperon.DOC].bordered = `Enable or disable window borders.
:param flag: True to show borders, false to hide.
:return: None
`;
prosperon.c_types.SDL_Window[prosperon.DOC].set_icon = `Set the window's icon from an SDL_Surface.
:param surface: An SDL_Surface holding the icon.
:return: None
`;
prosperon.c_types.SDL_Window[prosperon.DOC].mouse_grab = `Grab or ungrab the mouse for this window (so the pointer won't leave).
:param flag: True to grab mouse input, false to release.
:return: None
`;
prosperon.c_types.SDL_Window[prosperon.DOC].title = `Get or set the window's title text in the title bar.
:param newTitle: (when setting) A string title.
:return: The current title if getting, or None if setting.
`;
prosperon.c_types.SDL_Window[prosperon.DOC].size = `Get or set the window's size as [width, height].
:param newSize: (when setting) e.g. [640, 480]
:return: The current [width, height] or None if setting.
`;
//
// SDL_Renderer
//
prosperon.c_types.SDL_Renderer[prosperon.DOC] = {}
prosperon.c_types.SDL_Renderer[prosperon.DOC][prosperon.DOC] = `A 2D rendering context using the SDL renderer API. Freed automatically.
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].draw_color = `Set the render draw color for subsequent primitive calls (rect, line, etc.).
:param color: [r, g, b, a] in 0..1.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].present = `Display whatever has been rendered (swap buffers). Must be called each frame.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].clear = `Clear the current render target with the renderer's draw color.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].rect = `Draw one or more outlines of rectangles.
:param rectOrArray: A single rect {x,y,w,h} or an array of rects.
:param color: Optional [r,g,b,a]. If provided, overrides current draw color.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].fillrect = `Fill one or more rectangles with the renderer's current color or an optional override.
:param rectOrArray: A single rect {x,y,w,h} or an array of rects.
:param color: Optional [r,g,b,a].
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].line = `Draw a sequence of lines connecting points in an array.
:param points: An array of [x,y] points. Lines connect consecutive points.
:param color: Optional [r,g,b,a].
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].point = `Draw a list of points (pixels).
:param points: An array of [x,y] positions.
:param color: Optional [r,g,b,a].
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].load_texture = `Create an SDL_Texture from a given SDL_Surface for use with this renderer.
:param surface: An SDL_Surface.
:return: An SDL_Texture object.
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].texture = `Draw a texture onto the render target.
:param tex: The SDL_Texture to draw.
:param dstRect: The destination rect {x, y, w, h}.
:param srcRect: Optional portion of the texture to draw {x, y, w, h}.
:param color: Optional color mod [r,g,b,a].
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].slice9 = `Draw a texture with 9-slice scaling. The argument includes edges {l, r, t, b}
for the corners/borders that remain unscaled. The rest is tiled or stretched.
:param tex: The SDL_Texture.
:param dstRect: Destination region {x, y, w, h}.
:param edges: {l, r, t, b} for corner sizes in pixels.
:param srcRect: Optional portion in the texture.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].tile = `Tile a texture repeatedly within the specified region. Optionally use a srcRect.
:param tex: The SDL_Texture to tile.
:param dstRect: The region to fill {x, y, w, h}.
:param srcRect: Optional portion of texture.
:param scale: A float scale factor for each tile.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].get_image = `Read back the rendered pixels into a new SDL_Surface. If rect is undefined, capture entire output.
:param rect: Optional {x,y,w,h}.
:return: An SDL_Surface with the requested region's pixels.
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].fasttext = `Draw debug text using an internal fast path. Typically used for quick debugging overlays.
:param text: The string to draw.
:param pos: The [x, y] position to draw text.
:param color: Optional [r,g,b,a].
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].geometry = `Render custom geometry from a mesh object {pos, uv, color, indices, count} with an optional texture.
:param texture: The SDL_Texture or undefined.
:param meshObject: The geometry data with typed arrays.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].scale = `Set a scaling factor for all subsequent rendering on this renderer.
:param scaleVec2: [sx, sy] scaling factors.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].logical_size = `Set a "logical" size that the renderer will scale to.
For example, (320, 240) can auto-scale up to the window resolution.
:param size: [width, height].
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].viewport = `Set the clipping viewport for rendering. Pass undefined to use the full render target.
:param rect: {x, y, w, h}, or undefined.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].clip = `Set or clear the clipping rectangle for drawing. Pass undefined to clear.
:param rect: {x, y, w, h} or undefined.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].vsync = `Enable or disable vertical sync. This may have no effect depending on the driver.
:param flag: True or false.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].coords = `Convert window coordinates to this renderer's coordinate space.
:param pos: [x, y] in window space.
:return: [x, y] in renderer coordinate space.
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].camera = `Set up a basic 2D camera matrix from a given transform. If 'centered' is true,
the origin is the center of the viewport, else top-left.
:param cameraTransform: The transform whose pos is used.
:param centered: Boolean true or false.
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].get_viewport = `Return the current viewport rect.
:return: {x, y, w, h}
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].screen2world = `Convert a screen coordinate to world space based on the current camera transform.
:param pos: [x, y] screen coords
:return: [wx, wy] in world space
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].target = `Set or clear the current render target texture. Pass undefined to reset to the default/window.
:param texture: An SDL_Texture or undefined
:return: None
`;
prosperon.c_types.SDL_Renderer[prosperon.DOC].make_sprite_mesh = `Generate a mesh from an array of sprite objects, combining their positions, UVs,
and colors into a single geometry block.
:param sprites: An array of sprite-like objects.
:return: A 'mesh' object with pos, uv, color, indices, etc.
`;
//
// SDL_Texture
//
prosperon.c_types.SDL_Texture[prosperon.DOC] = {}
prosperon.c_types.SDL_Texture[prosperon.DOC][prosperon.DOC] = `A 2D GPU-accelerated texture for rendering with SDL_Renderer. Freed automatically.
`;
prosperon.c_types.SDL_Texture[prosperon.DOC].mode = `Set texture scale mode or filtering mode (nearest/linear).
:param mode: A string or numeric mode to set (e.g., 'linear').
:return: None
`;
//
// SDL_Surface
//
prosperon.c_types.SDL_Surface[prosperon.DOC] = {}
prosperon.c_types.SDL_Surface[prosperon.DOC][prosperon.DOC] = `A software (CPU) image in memory. Freed when references vanish. Typically converted
to SDL_Texture for drawing, or used as raw pixel data.
`;
prosperon.c_types.SDL_Surface[prosperon.DOC].blit = `Blit (copy) another surface onto this surface, scaling if needed.
:param dstRect: Destination {x, y, w, h}
:param srcSurface: The source SDL_Surface
:param srcRect: {x, y, w, h} portion from source
:return: None
`;
prosperon.c_types.SDL_Surface[prosperon.DOC].scale = `Return a new SDL_Surface scaled to [width, height] using linear filtering.
:param newSize: [width, height]
:return: A new SDL_Surface with the scaled result.
`;
prosperon.c_types.SDL_Surface[prosperon.DOC].fill = `Fill the entire surface with a single color.
:param color: [r, g, b, a] in 0..1
:return: None
`;
prosperon.c_types.SDL_Surface[prosperon.DOC].rect = `Fill a sub-rectangle of the surface with a color.
:param rect: {x, y, w, h}
:param color: [r, g, b, a]
:return: None
`;
prosperon.c_types.SDL_Surface[prosperon.DOC].dup = `Make a copy of this surface in RGBA format.
:return: A new SDL_Surface copy.
`;
//
// SDL_GPUDevice
//
prosperon.c_types.SDL_GPUDevice[prosperon.DOC] = {}
prosperon.c_types.SDL_GPUDevice[prosperon.DOC][prosperon.DOC] = `A handle for low-level GPU operations via SDL GPU. Freed on GC.
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].claim_window = `Claim an existing SDL_Window so this GPU device can render to it.
:param window: The SDL_Window to attach.
:return: None
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].make_pipeline = `Create a new graphics pipeline from a descriptor object specifying shaders,
blend states, vertex format, etc.
:param pipelineDesc: An object containing pipeline fields (vertexShader, blend, etc.).
:return: A SDL_GPUGraphicsPipeline handle.
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].compute_pipeline = `Create a compute pipeline from a descriptor (shader code, threadgroup sizes, etc.).
:param desc: An object with shader code, thread counts, etc.
:return: SDL_GPUComputePipeline handle.
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].set_swapchain = `Specify how the swapchain (final rendered image) is composed, e.g. 'sdr', 'hdr',
and present mode like 'vsync' or 'immediate'.
:param composition: E.g. 'sdr', 'linear', or 'hdr'.
:param presentMode: E.g. 'vsync', 'immediate', 'mailbox'.
:return: None
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].sort_sprite = `A comparator function used for sorting sprite objects by layer, y, and texture.
Usually used internally.
:param a: A sprite object.
:param b: Another sprite object.
:return: <0, 0, or >0 for sort ordering.
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].make_sampler = `Create a sampler object specifying filtering, wrapping, anisotropy, etc.
:param samplerDesc: An object with min_filter, mag_filter, etc.
:return: SDL_GPUSampler handle.
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].load_texture = `Upload an SDL_Surface into a GPU texture, optionally compressing with DXT. Freed automatically.
:param surface: An SDL_Surface.
:param compressionLevel: 0=none, 1=DXT1 or DXT5, 2=high quality, etc.
:return: SDL_GPUTexture
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].texture = `Create a GPU texture with the specified format usage.
:param desc: Object with {width, height, layers, type, format, usage, etc.}
:return: SDL_GPUTexture
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].make_quad = `Return a simple 2-triangle quad geometry covering [0,1]x[0,1].
Useful for post-processing passes.
:return: A mesh {pos, uv, color, indices}.
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].driver = `Return the name of the underlying GPU driver in use (e.g. 'OpenGL').
:return: A string with driver name.
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].make_shader = `Compile raw shader code (vertex or fragment) in e.g. SPIR-V, MSL, or DXIL format.
:param desc: {code:ArrayBuffer, stage:'vertex'|'fragment', format:'spv'|..., entrypoint:'main', ...}
:return: SDL_GPUShader object
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].acquire_cmd_buffer = `Obtain a new command buffer for recording GPU commands. Must be submitted or canceled.
:return: SDL_GPUCommandBuffer handle
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].upload = `Upload CPU data into a list of GPU buffers, optionally reusing or returning a
transfer buffer. Typically you provide (cmdBuf, arrayOfTypedArrays, [transferBuffer]).
:param cmdBuffer: The command buffer in which to record copy commands.
:param buffers: An array of typed-array data to upload, each must have a 'gpu' property or so.
:param transferBuffer: Optional existing GPU transfer buffer to reuse.
:return: The transfer buffer used or newly created.
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].wait_for_fences = `Wait on an array of GPU fence objects, optionally requiring all or any.
:param fences: An array of SDL_GPUFence objects.
:param waitAll: Boolean, true to wait for all fences, false for any.
:return: True if fences signaled, false on timeout or error.
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].query_fence = `Check if the given fence has been signaled yet. Non-blocking.
:param fence: SDL_GPUFence handle
:return: True if signaled, false if still pending
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].shader_format = `Return an array of supported GPU shader binary formats (like 'spv', 'dxbc', etc.).
:return: Array of strings naming supported formats.
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].slice9 = `Generate a 9-slice tiling geometry in one shot. For advanced usage with GPU pipeline.
:param texture: An SDL_GPUTexture
:param dstRect: The rectangle {x, y, w, h}
:param edges: {l, r, t, b} edge sizes
:return: A mesh object
`;
prosperon.c_types.SDL_GPUDevice[prosperon.DOC].tile = `Generate geometry to tile a texture portion inside a dest rect.
Often used for repeating backgrounds.
:param texture: The SDL_GPUTexture
:param srcRect: The portion to tile in pixels
:param dstRect: Where to fill
:param tileInfo: e.g. {repeat_x:true, repeat_y:true}
:return: A mesh object
`;
//
// SDL_GPUCommandBuffer
//
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC] = {}
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC][prosperon.DOC] = `A command buffer that accumulates rendering, copy, and compute operations. Freed after submission or GC.
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].render_pass = `Begin a render pass with color/depth attachments. Provide an object with
'color_targets' and optional 'depth_stencil'. Returns an SDL_GPURenderPass handle.
:param passDesc: {color_targets:[...], depth_stencil:...}
:return: SDL_GPURenderPass
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].compute_pass = `Begin a compute pass reading/writing given arrays of textures and buffers.
:param storageTextures: array of read/write textures
:param storageBuffers: array of read/write buffers
:return: SDL_GPUComputePass
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].swapchain_pass = `Begin a render pass that directly targets the swapchain (the window). Clears
with the specified color.
:param clearColor: [r,g,b,a]
:return: SDL_GPURenderPass
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].acquire_swapchain = `Acquire the current swapchain texture from the window. Internal usage.
:return: SDL_GPUTexture handle
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].bind_vertex_buffer = `Bind a GPU buffer as the vertex buffer at a given slot.
:param slot: Integer slot index.
:param buffer: The SDL_GPUBuffer.
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].bind_index_buffer = `Bind a GPU buffer as the index buffer (16-bit or 32-bit).
:param buffer: The SDL_GPUBuffer.
:param offset: Optional offset in bytes.
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].bind_fragment_sampler = `Bind a texture+sampler pair to a particular fragment shader slot.
:param slot: Index of the sampler binding.
:param texture: The SDL_GPUTexture
:param sampler: The SDL_GPUSampler
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].push_vertex_uniform_data = `Push raw data to a vertex shader uniform block.
:param slot: The uniform buffer slot.
:param data: An ArrayBuffer with the data to upload.
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].push_fragment_uniform_data = `Push raw data to a fragment shader uniform block.
:param slot: The uniform buffer slot index.
:param data: An ArrayBuffer with uniform data.
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].push_compute_uniform_data = `Push raw data to a compute shader uniform buffer.
:param slot: The uniform buffer slot.
:param data: An ArrayBuffer with the data.
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].submit = `Submit this command buffer to the GPU and return a fence for synchronization.
:return: An SDL_GPUFence
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].cancel = `Cancel (discard) this command buffer without submitting.
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].camera = `Write a camera transform (projection/view) to a uniform slot for 3D or 2D usage.
:param cameraTransform: A camera object or transform with .pos, fov, etc.
:param uniformSlot: The integer uniform buffer slot to which data is pushed.
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].hud = `Write an orthographic full-screen "HUD" matrix to a uniform slot. Typically used
for 2D overlays.
:param sizeVec2: [width, height] of the viewport area.
:param uniformSlot: The integer uniform buffer slot.
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].push_debug_group = `Push a named debug group marker onto the GPU command list (for debuggers/profilers).
:param name: The debug label string.
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].pop_debug_group = `Pop the most recent debug group marker.
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].debug_label = `Insert a one-off debug label at the current spot in the command list.
:param label: The debug label string
:return: None
`;
prosperon.c_types.SDL_GPUCommandBuffer[prosperon.DOC].blit = `Blit one GPU texture to another with optional flip mode, filter, and clear operations.
:param blitDesc: { src:{texture,mip_level, etc}, dst:{texture,...}, load_op, flip, filter, clear_color:[r,g,b,a] }
:return: None
`;
//
// SDL_GPURenderPass
//
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC] = {}
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC][prosperon.DOC] = `A single pass of drawing commands with color/depth attachments. Freed after end() or GC.
`;
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC].bind_pipeline = `Bind a previously created graphics pipeline (shaders, states, vertex layouts, etc.).
:param pipeline: The SDL_GPUGraphicsPipeline
:return: None
`;
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC].viewport = `Set the viewport for clipping or scaling draws, in pass-local coordinates.
:param rect: {x,y,w,h}
:return: None
`;
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC].scissor = `Set a scissor rectangle for discarding pixels outside it.
:param rect: {x,y,w,h}
:return: None
`;
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC].draw = `Issue a non-indexed draw call.
:param primitiveType: e.g. SDL_GPU_PRIMITIVETYPE_TRIANGLELIST
:param baseVertex: Starting vertex offset.
:param firstVertex: The first vertex to draw.
:param vertexCount: How many vertices to draw.
:return: None
`;
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC].draw_indexed = `Issue an indexed draw call from the bound index buffer.
:param primitiveType: The primitive type constant.
:param baseVertex: Offset in the vertex buffer.
:param firstIndex: Which index to start from.
:param indexCount: Number of indices to draw.
:param instanceCount: For instanced drawing, or 1 if normal.
:return: None
`;
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC].end = `End this render pass, finalizing the draw operations.
:return: None
`;
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC].bind_index_buffer = `Bind an index buffer inside this pass, possibly overriding the global one.
:param buffer: The SDL_GPUBuffer
:param elementSize16bit: If 2, uses 16-bit indices; if 4, uses 32-bit indices
:return: None
`;
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC].bind_buffers = `Bind multiple vertex buffers at consecutive slots.
:param firstSlot: The starting vertex buffer slot.
:param arrayOfBuffers: An array of GPUBuffer objects
:return: None
`;
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC].bind_samplers = `Bind multiple texture/sampler pairs to either vertex or fragment slots.
:param vertexOrFragment: Boolean, true for vertex stage, false for fragment.
:param firstSlot: The first sampler slot to bind.
:param samplerBindings: An array of {texture, sampler}.
:return: None
`;
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC].bind_storage_buffers = `Bind one or more storage buffers for read/write in the pipeline.
:param firstSlot: Starting buffer slot index.
:param buffers: An array of SDL_GPUBuffer objects.
:return: None
`;
prosperon.c_types.SDL_GPURenderPass[prosperon.DOC].bind_storage_textures = `Bind one or more storage textures for read/write in the pipeline.
:param firstSlot: Starting texture slot index.
:param textures: An array of SDL_GPUTexture objects.
:return: None
`;
//
// SDL_GPUComputePass
//
prosperon.c_types.SDL_GPUComputePass[prosperon.DOC] = {}
prosperon.c_types.SDL_GPUComputePass[prosperon.DOC][prosperon.DOC] = `A compute pass for dispatching compute pipelines. Freed after end() or GC.
`;
prosperon.c_types.SDL_GPUComputePass[prosperon.DOC].dispatch = `Dispatch the compute pipeline with the specified threadgroup counts.
:param x: Number of groups in X dimension
:param y: Number of groups in Y dimension
:param z: Number of groups in Z dimension
:return: None
`;
prosperon.c_types.SDL_GPUComputePass[prosperon.DOC].end = `End this compute pass.
:return: None
`;
prosperon.c_types.SDL_GPUComputePass[prosperon.DOC].pipeline = `Bind a compute pipeline in this pass.
:param computePipeline: The SDL_GPUComputePipeline
:return: None
`;
prosperon.c_types.SDL_GPUComputePass[prosperon.DOC].samplers = `Bind a set of texture/sampler pairs for compute usage.
:param arrayOfSamplerBindings: e.g. [ {texture, sampler}, ...]
:param firstSlot: The starting sampler slot.
:return: None
`;
prosperon.c_types.SDL_GPUComputePass[prosperon.DOC].storage_buffers = `Bind an array of storage buffers for the compute shader.
:param arrayOfBuffers: The buffers
:param firstSlot: Starting binding slot.
:return: None
`;
prosperon.c_types.SDL_GPUComputePass[prosperon.DOC].storage_textures = `Bind an array of storage textures for the compute shader.
:param arrayOfTextures: The textures
:param firstSlot: Starting binding slot
:return: None
`;
//
// SDL_GPUCopyPass
//
prosperon.c_types.SDL_GPUCopyPass[prosperon.DOC] = {}
prosperon.c_types.SDL_GPUCopyPass[prosperon.DOC][prosperon.DOC] = `A pass for CPU<->GPU or GPU<->GPU copy operations. No direct JS API besides internal usage.
`;
//
// SDL_GPUFence
//
prosperon.c_types.SDL_GPUFence[prosperon.DOC] = {}
prosperon.c_types.SDL_GPUFence[prosperon.DOC][prosperon.DOC] = `A GPU fence for synchronization. Created upon commandBuffer.submit().
Wait or query it with device.wait_for_fences or device.query_fence.
`;
//
// SDL_GPUTransferBuffer
//
prosperon.c_types.SDL_GPUTransferBuffer[prosperon.DOC] = {}
prosperon.c_types.SDL_GPUTransferBuffer[prosperon.DOC][prosperon.DOC] = `A staging buffer used for copying data to or from GPU buffers/textures. Typically
allocated/used internally by device.upload(...).
`;
//
// SDL_GPUShader
//
prosperon.c_types.SDL_GPUShader[prosperon.DOC] = {}
prosperon.c_types.SDL_GPUShader[prosperon.DOC][prosperon.DOC] = `A single compiled shader (vertex or fragment) in a GPU-friendly format
(e.g., SPIR-V, MSL). Combined into a pipeline for drawing.
`;
//
// SDL_GPUSampler
//
prosperon.c_types.SDL_GPUSampler[prosperon.DOC] = {}
prosperon.c_types.SDL_GPUSampler[prosperon.DOC][prosperon.DOC] = `Defines how a texture is sampled (filter mode, address mode, anisotropy, compare op, etc.).
`;
//
// SDL_GPUGraphicsPipeline
//
prosperon.c_types.SDL_GPUGraphicsPipeline[prosperon.DOC] = {}
prosperon.c_types.SDL_GPUGraphicsPipeline[prosperon.DOC][prosperon.DOC] = `Encapsulates vertex+fragment shaders, blend/cull states, and vertex attribute layouts.
Created via device.make_pipeline(...).
`;
//
// SDL_GPUComputePipeline
//
prosperon.c_types.SDL_GPUComputePipeline[prosperon.DOC] = {}
prosperon.c_types.SDL_GPUComputePipeline[prosperon.DOC][prosperon.DOC] = `Encapsulates a compute shader program plus associated resource layouts.
Created via device.compute_pipeline(...).
`;
var listeners = new Map()
prosperon.on = function(type, callback) {
if (!listeners.has(type)) listeners.set(type, [])
listeners.get(type).push(callback)
return function() {
var arr = listeners.get(type)
if (!arr) return
var idx = arr.indexOf(callback)
if (idx >= 0) arr.splice(idx,1)
}
}
prosperon.dispatch = function(type, data) {
var arr = listeners.get(type)
if (!arr) return
for (var callback of arr) callback(data)
}
var os = use_embed('os')
var js = use_embed('js')
prosperon.on('SIGINT', function() {
os.exit(1)
})
prosperon.on('SIGABRT', function() {
console.error(new Error('SIGABRT'))
os.exit(1)
})
prosperon.on('SIGSEGV', function() {
console.error(new Error('SIGSEGV'))
os.exit(1)
})
var use_cache = {}
Object.defineProperty(Function.prototype, "hashify", {
value: function () {
var hash = new Map()
var fn = this
function hashified(...args) {
var key = args[0]
if (!hash.has(key)) hash.set(key, fn(...args))
return hash.get(key)
}
return hashified
},
})
var io = use_embed('io')
var tracy = use_embed('tracy')
var RESPATH = 'scripts/modules/resources.js'
var canonical = io.realdir(RESPATH) + 'resources.js'
var content = io.slurp(RESPATH)
var resources = js.eval(RESPATH, `(function setup_resources(){${content}})`).call({})
use_cache[resources.canonical('resources.js')] = resources
function print_api(obj) {
for (var prop in obj) {
if (!obj.hasOwnProperty(prop)) continue
var val = obj[prop]
console.log(prop)
if (typeof val === 'function') {
var m = val.toString().match(/\(([^)]*)\)/)
if (m) console.log(' function: ' + prop + '(' + m[1].trim() + ')')
}
}
}
prosperon.PATH = [
"/",
"scripts/modules/",
"scripts/modules/ext/",
]
// path is the path of a module or script to resolve
var script_fn = function script_fn(path) {
var parsed = {}
var file = resources.find_script(path)
if (!file) {
parsed.module_ret = bare_load(path)
if (!parsed.module_ret) throw new Error(`Module ${path} could not be created`)
return parsed
}
var content = io.slurp(file)
var parsed = parse_file(content)
var module_name = file.name()
parsed.module_ret = bare_load(path)
parsed.module_ret ??= {}
if (parsed.module) {
var mod_script = `(function setup_${module_name}_module(){ var self = this; var $ = this; var exports = {}; var module = {exports: exports}; var define = undefined; ${parsed.module}})`
var module_fn = js.eval(file, mod_script)
parsed.module_ret = module_fn.call(parsed.module_ret)
if (parsed.module_ret === undefined || parsed.module_ret === null)
throw new Error(`Module ${module_name} must return a value`)
parsed.module_fn = module_fn
}
parsed.program ??= ""
var prog_script = `(function use_${module_name}() { var self = this; var $ = this.__proto__; ${parsed.program}})`
parsed.prog_fn = js.eval(file, prog_script)
return parsed
}.hashify()
function bare_load(file) {
try {
return use_embed(file)
} catch (e) { }
try {
return use_dyn(file + so_ext)
} catch(e) { }
return undefined
}
var res_cache = {}
function console_rec(category, priority, line, file, msg) {
return `${file}:${line}: [${category} ${priority}]: ${msg}\n`
}
io.mkdir('.prosperon')
var logfile = io.open('.prosperon/log.txt')
function pprint(msg, lvl = 0) {
if (!logfile) return
if (typeof msg === "object") msg = JSON.stringify(msg, null, 2)
var file = "nofile"
var line = 0
var caller = new Error().stack.split("\n")[2]
if (caller) {
var md = caller.match(/\((.*)\:/)
var m = md ? md[1] : "SCRIPT"
if (m) file = m
md = caller.match(/\:(\d*)\)/)
m = md ? md[1] : 0
if (m) line = m
}
var fmt = console_rec("script", lvl, line, file, msg)
console.print(fmt)
if (logfile)
logfile.write(fmt)
if (tracy) tracy.message(fmt)
}
console.spam = function(msg) {
pprint(msg, 0)
}
console.debug = function(msg) {
pprint(msg, 1)
}
console.info = function(msg) {
pprint(msg, 2)
}
console.warn = function(msg) {
pprint(msg, 3)
}
console.log = function(msg) {
pprint(msg, 2)
}
console.error = function(e) {
if (!e) e = new Error()
pprint(`${e.name} : ${e.message}
${e.stack}`, 4)
}
console.panic = function(e) {
pprint(e, 5)
os.quit()
}
console.assert = function(op, str = `assertion failed [value '${op}']`) {
if (!op) console.panic(str)
}
os.on('uncaught_exception', function(e) { console.error(e) })
console[prosperon.DOC] = {
doc: "The console object provides various logging, debugging, and output methods.",
spam: "Output a spam-level message for very verbose logging.",
debug: "Output a debug-level message.",
info: "Output info level message.",
warn: "Output warn level message.",
error: "Output error level message, and print stacktrace.",
panic: "Output a panic-level message and exit the program.",
assert: "If the condition is false, print an error and panic.",
critical: "Output critical level message, and exit game immediately.",
write: "Write raw text to console.",
say: "Write raw text to console, plus a newline.",
log: "Output directly to in game console.",
level: "Set level to output logging to console.",
stack: "Output a stacktrace to console.",
clear: "Clear console."
}
var BASEPATH = 'scripts/core/base.js'
var script = io.slurp(BASEPATH)
var fnname = "base"
script = `(function ${fnname}() { ${script}; })`
js.eval(BASEPATH, script)()
function add_timer(obj, fn, seconds) {
var timers = obj[TIMERS]
var stop = function () {
if (!timer) return
timers.delete(stop)
timer.fn = undefined
timer = undefined
}
function execute() {
if (fn) timer.remain = fn(stop.seconds)
if (!timer) return
if (!timer.remain) stop()
else stop.seconds = timer.remain
}
var timer = os.make_timer(execute)
timer.remain = seconds
stop.remain = seconds
stop.seconds = seconds
timers.push(stop)
return stop
}
var DEAD = Symbol()
var GARBAGE = Symbol()
var FILE = Symbol()
var TIMERS = Symbol()
var REGGIES = Symbol()
var UNDERLINGS = Symbol()
var OVERLING = Symbol()
var actor = {}
globalThis.actor = actor
var so_ext
switch(os.platform()) {
case 'Windows':
so_ext = '.dll'
break
default:
so_ext = '.so'
break
}
globalThis.use = function use(file) {
if (use_cache[file]) return use_cache[file]
var mod = script_fn(file)
use_cache[file] = mod.module_ret
return use_cache[file]
}
//use[prosperon.DOC] = 'Return the value from the provided path to a module'.
globalThis.json = use('json')
function parse_file(content) {
if (!content) return {}
var parts = content.split(/\n\s*---\s*\n/)
if (parts.length === 1) {
var part = parts[0]
if (part.match(/return\s+[^;]+;?\s*$/))
return { module: part }
return { program: part }
}
var module = parts[0]
if (!module.match(/return\s+[^;]+;?\s*$/))
throw new Error("Module section must end with a return statement")
var pad = '\n'.repeat(module.split('\n').length+2)
return {
module,
program: pad+parts[1]
}
}
//////////////////
// REGISTRANT
/////////////////
globalThis.Register = {
registries: [],
add_cb(name) {
var n = {}
var fns = []
n.register = function (fn, oname) {
if (typeof fn !== 'function') return
var dofn = function (...args) {
fn(...args)
}
Object.defineProperty(dofn, 'name', {value:`do_${oname}`})
var left = 0
var right = fns.length - 1
dofn.layer = fn.layer
dofn.layer ??= 0
while (left <= right) {
var mid = Math.floor((left + right) / 2)
if (fns[mid] === dofn.layer) {
left = mid
break
} else if (fns[mid].layer < dofn.layer) left = mid + 1
else right = mid - 1
}
fns.splice(left, 0, dofn)
return function () {
fns.delete(dofn)
}
}
prosperon[name] = function (...args) {
fns.forEach(fn => {
fn(...args)
})
}
Object.defineProperty(prosperon[name], 'name', {value:name})
prosperon[name].fns = fns
n.clear = function () {
fns = []
}
Register[name] = n
Register.registries[name] = n
return n
},
}
Register.pull_registers = function pull_registers(obj) {
var reggies = []
for (var reg in Register.registries) {
if (typeof obj[reg] === "function")
reggies.push(reg)
}
return reggies
}
Register.register_obj = function register_obj(obj, reg) {
var fn = obj[reg].bind(obj)
fn.layer = obj[reg].layer
var name = obj.ur ? obj.ur.name : obj.toString()
obj[TIMERS].push(Register.registries[reg].register(fn, name))
if (!obj[reg].name) Object.defineProperty(obj[reg], 'name', {value:`${obj._file}_${reg}`})
}
Register.check_registers = function check_registers(obj) {
if (obj[REGGIES]) {
if (obj[REGGIES].length == 0) return
for (var reg of obj[REGGIES])
Register.register_obj(obj,reg)
return
}
for (var reg in Register.registries) {
if (typeof obj[reg] === "function")
Register.register_obj(obj,reg)
}
}
Register.add_cb("appupdate")
Register.add_cb("update").doc = "Called once per frame."
Register.add_cb("physupdate")
Register.add_cb("gui")
Register.add_cb("hud")
Register.add_cb("draw")
Register.add_cb("imgui")
Register.add_cb("app")
function cant_kill() {
throw Error("Can't kill an object in its spawning code. Move the kill command to awake.")
}
actor.toString = function() { return this[FILE] }
actor.spawn = function spawn(script, config, callback) {
if (this[DEAD]) throw Error("Attempting to spawn on a dead actor")
var prog
if (!script) {
prog = {}
prog.module_ret = {}
prog.prog_fn = function() {}
} else {
prog = script_fn(script)
if (!prog.prog_fn) throw new Error(`Script ${script} is not an actor script or has no actor component`)
}
var underling
prog.module_ret.__proto__ = actor
underling = Object.create(prog.module_ret)
underling[OVERLING] = this
underling[FILE] = script
underling[TIMERS] = []
underling[UNDERLINGS] = new Set()
Object.defineProperty(underling, 'overling', {
get() { return this[OVERLING] },
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'underlings', {
get() { return new Set(this[UNDERLINGS]) },
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'spawn', {
value: actor.spawn,
writable:false,
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'kill', {
value: actor.kill,
writable:false,
enumerable:true,
configurable:false
})
Object.defineProperty(underling, 'delay', {
value: actor.delay,
writable:false,
enumerable:true,
configurable:false
})
if (callback) callback(underling, { message:"created" })
try {
prog.prog_fn.call(underling)
} catch(e) { throw e }
if (underling[DEAD]) return undefined
if (typeof config === 'object') Object.assign(underling, config)
if (!underling[REGGIES])
underling.__proto__[REGGIES] = Register.pull_registers(underling)
Register.check_registers(underling)
if (underling.awake) underling.awake()
this[UNDERLINGS].add(underling)
if (underling.tag) act.tag_add(underling.tag, underling)
underling[GARBAGE] = underling.garbage
return underling
}
actor.clear = function actor_clear() {
this[UNDERLINGS].forEach(p => {
p.kill()
})
this[UNDERLINGS].clear()
}
var input = use('input')
actor.kill = function kill() {
if (this[DEAD]) return
this[DEAD] = true
this[TIMERS].slice().forEach(t => t())
delete this[TIMERS]
input.do_uncontrol(this)
this.clear()
this[OVERLING][UNDERLINGS].delete(this)
delete this[UNDERLINGS]
if (typeof this.garbage === "function") this.garbage()
if (typeof this.then === "function") this.then()
act.tag_clear_guid(this)
}
actor.kill.doc = `Remove this actor and all its underlings from existence.`
actor.delay = function(fn, seconds) {
add_timer(this, fn, seconds)
}
actor.delay.doc = `Call 'fn' after 'seconds' with 'this' set to the actor.`
var act = use('actor')
actor[UNDERLINGS] = new Set()
globalThis.mixin("color")
use('cmd')(prosperon.argv)
// ---------------------------------------------------------------------------
// Documentation blocks following the style shown in time.js
// ---------------------------------------------------------------------------
// Document the main prosperon object
prosperon[prosperon.DOC] = {
doc: `The main prosperon object providing event dispatch, signal handling, and engine management.`,
DOC: `Symbol used to store documentation references on objects.`,
on: `Register a callback function for a given event type. Returns a function to remove the callback.`,
dispatch: `Dispatch an event of the given type, calling all registered callbacks with the provided data.`,
PATH: `Array of directory paths that Prosperon will search to find scripts or modules.`,
c_types: `Prototype objects for all present defined c-types (like sprite, transform, etc)`
}
// Document the actor object/prototype
actor[prosperon.DOC] = {
doc: `The actor object/prototype, serving as a base for all game actors or entities.`,
spawn: `Create a new actor from a script, optionally applying a config object, then call the new actor's 'awake' method.`,
kill: `Destroy this actor, removing it from the game along with all underlings. Frees resources and triggers garbage if defined.`,
clear: `Remove all child (underling) actors by calling kill on each.`,
delay: `Schedule a function to be called after a specified delay (in seconds) on this actor.`,
toString: `Return the script filename associated with this actor instance.`
}
// Expand console.doc to document the console object and missing methods
console[prosperon.DOC] = {}
console[prosperon.DOC][prosperon.DOC] = `The console object provides various logging, debugging, and output methods.`
console[prosperon.DOC].spam = `Output a spam-level message for very verbose logging.`
console[prosperon.DOC].debug = `Output a debug-level message.`
console[prosperon.DOC].panic = `Output a panic-level message and exit the program.`
console[prosperon.DOC].assert = `If the condition is false, print an error and panic.`
// Document the Register object
Register[prosperon.DOC] = {
doc: `Factory for creating and managing event registries (e.g. update, draw, etc.) within Prosperon.`,
add_cb: `Create or retrieve a registry for an event type, exposing a 'register' method for callbacks.`,
pull_registers: `Gather the names of all recognized event methods implemented by an object.`,
register_obj: `Bind an object's event method to the relevant registry. The unregistration handle goes in the actor's timers.`,
check_registers: `Automatically register recognized events (like 'update', 'gui', etc.) on an object.`,
}
})()