130 lines
6.6 KiB
TypeScript
130 lines
6.6 KiB
TypeScript
|
|
import React from 'react';
|
|
import { ContentPage } from '../../components/ContentPage';
|
|
import { ApiSection } from '../../types';
|
|
|
|
const reactorApi: ApiSection[] = [
|
|
{
|
|
title: 'Chemical.Reactor',
|
|
description: 'A Reactor is a server-side factory for creating and managing `Reaction` objects. Reactions are stateful objects whose state is automatically replicated from the server to specified clients.',
|
|
entries: [
|
|
{
|
|
signature: 'Chemical.Reactor<T, U...>(config: ReactorConfig, constructor: (key: string, ...args: U) => T): ReactorInstance<T, U>',
|
|
description: 'Creates a new Reactor factory.',
|
|
parameters: [
|
|
{ name: 'config', type: 'ReactorConfig', description: 'Configuration for the Reactor. Must include a unique `Name`. Optionally, `Subjects` can specify which players receive updates (defaults to all players).' },
|
|
{ name: 'constructor', type: '(key: string, ...args: U) => T', description: "A function that returns the initial state structure for a new Reaction. This function receives the `key` of the Reaction (e.g., a player's ID) and any additional arguments passed to `reactor:create()`. The provided `key` is primarily for the Reactor system's internal identification and typically does not need to be stored as a field in the state object returned by this constructor, as the Reaction instance will have `.Name` and `.Key` properties managed by Chemical." },
|
|
],
|
|
returns: { type: 'ReactorInstance<T, U>', description: 'A new Reactor instance.' },
|
|
notes: 'ReactorConfig: `{ Name: string, Subjects?: Player[] | Symbol }`. The `Symbol` can be `Chemical.Symbols.All("Players")`. `T` is the type of the state structure returned by the constructor. `U...` are the types of additional arguments for the constructor.',
|
|
example: `
|
|
local Chemical = require(game.ReplicatedStorage.Chemical)
|
|
local Value = Chemical.Value
|
|
local Table = Chemical.Table
|
|
local Reactor = Chemical.Reactor
|
|
local Symbols = Chemical.Symbols
|
|
|
|
-- Define a Reactor for player game data
|
|
local PlayerGameDataReactor = Reactor({
|
|
Name = "PlayerGameData",
|
|
-- Subjects = {player1, player2} -- Optional: replicate only to specific players
|
|
-- Subjects = Symbols.All("Players") -- Default: replicate to all
|
|
}, function(playerIdString, initialLives, initialScore)
|
|
-- This constructor defines the structure of each Reaction.
|
|
-- Note: 'playerIdString' (the key) is passed here but typically
|
|
-- not stored directly in this returned table, as the Reaction object
|
|
-- will have .Key and .Name properties managed by Chemical.
|
|
return {
|
|
lives = Value(initialLives or 3),
|
|
score = Value(initialScore or 0),
|
|
inventory = Table({})
|
|
}
|
|
end)
|
|
`,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: 'ReactorInstance Methods',
|
|
entries: [
|
|
{
|
|
signature: 'reactor:create(key: string, ...args: U): Reaction<T> -- Server-Only',
|
|
description: 'Creates a new `Reaction` instance managed by this Reactor. The Reaction\'s state will be initialized using the constructor function provided when the Reactor was defined. This method can only be called on the server.',
|
|
parameters: [
|
|
{ name: 'key', type: 'string', description: 'A unique key to identify this Reaction instance (e.g., a player\'s UserId).' },
|
|
{ name: '...args', type: 'U', description: 'Additional arguments to pass to the Reaction\'s constructor function.' },
|
|
],
|
|
returns: { type: 'Reaction<T>', description: 'The newly created (and replicating) Reaction object.' },
|
|
example: `
|
|
local Chemical = require(game.ReplicatedStorage.Chemical)
|
|
local Value = Chemical.Value -- Assuming Value is used in constructor
|
|
local Table = Chemical.Table -- Assuming Table is used in constructor
|
|
-- Assuming PlayerGameDataReactor is defined as in the previous example
|
|
|
|
-- Server-side:
|
|
local player1Data = PlayerGameDataReactor:create("player1_id", 5, 1000)
|
|
-- player1Data.lives:get() would be 5
|
|
-- player1Data.score:get() would be 1000
|
|
|
|
player1Data.score:set(1500) -- Access directly; this change will be replicated.
|
|
player1Data.inventory:insert("Sword") -- Access directly
|
|
`,
|
|
},
|
|
{
|
|
signature: 'reactor:await(key: string): Reaction<T> -- Client-Only',
|
|
description: 'Yields (waits) until a `Reaction` instance, created on the server and managed by this Reactor, becomes available on the client. It then returns the Reaction object directly.',
|
|
parameters: [
|
|
{ name: 'key', type: 'string', description: 'The unique key of the Reaction instance to await.' },
|
|
],
|
|
returns: { type: 'Reaction<T>', description: 'The Reaction object, once available.' },
|
|
example: `
|
|
local Chemical = require(game.ReplicatedStorage.Chemical)
|
|
local Effect = Chemical.Effect
|
|
-- Assuming PlayerGameDataReactor is defined and available on the client
|
|
-- and its constructor creates { lives = Value(), score = Value(), inventory = Table() }
|
|
|
|
-- Client-side:
|
|
local player1Data = PlayerGameDataReactor:await("player1_id") -- Yields until data is ready
|
|
|
|
-- Now player1Data is the actual Reaction object
|
|
if player1Data then
|
|
print("Player 1 score:", player1Data.score:get())
|
|
|
|
Effect(function()
|
|
print("Player 1 lives updated to:", player1Data.lives:get())
|
|
print("Player 1 inventory count:", #player1Data.inventory:get())
|
|
end)
|
|
else
|
|
warn("Failed to get player data for player1_id")
|
|
end
|
|
`,
|
|
},
|
|
{
|
|
signature: 'reactor:onCreate(callback: (key: string, reaction: Reaction<T>) -> ()): Connection -- Client-Only',
|
|
description: 'Registers a callback function that will be invoked whenever a new `Reaction` instance managed by this Reactor is created and replicated to the client. This is useful for reacting to dynamically created Reactions.',
|
|
parameters: [
|
|
{ name: 'callback', type: '(key: string, reaction: Reaction<T>) -> ()', description: 'The function to call. It receives the `key` of the new Reaction and the Reaction object itself.' },
|
|
],
|
|
returns: { type: 'Connection', description: 'A connection object with a `:Disconnect()` method to stop listening.' },
|
|
example: `
|
|
local Chemical = require(game.ReplicatedStorage.Chemical)
|
|
-- Assuming PlayerGameDataReactor is defined and available on the client
|
|
|
|
-- Client-side:
|
|
local connection = PlayerGameDataReactor:onCreate(function(playerId, playerData)
|
|
print("New player data received for:", playerId)
|
|
-- Access properties directly:
|
|
-- print("Initial score for new player:", playerData.score:get())
|
|
end)
|
|
|
|
-- To stop listening:
|
|
-- connection:Disconnect()
|
|
`,
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
export const ReactorPage: React.FC = () => {
|
|
return <ContentPage title="Chemical.Reactor" sections={reactorApi} />;
|
|
};
|