Skip to content

Commit

Permalink
feat: phase out @rbxts/gamejoy in favor of @rbxts/mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
R-unic committed Dec 27, 2024
1 parent 8575da0 commit b0a4c21
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 54 deletions.
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,16 @@
"@rbxts/firebase": "^1.0.1",
"@rbxts/flamework-binary-serializer": "^0.6.0",
"@rbxts/flamework-meta-utils": "^1.0.1",
"@rbxts/gamejoy": "^1.1.4",
"@rbxts/id": "^1.0.0",
"@rbxts/instance-utility": "^1.0.1",
"@rbxts/iris": "^2.2.0-ts.0",
"@rbxts/janitor": "^1.15.7-ts.0",
"@rbxts/lazy": "^1.0.1",
"@rbxts/lazy-iterator": "^1.0.1",
"@rbxts/mechanism": "^1.0.0",
"@rbxts/mechanism": "^1.0.6",
"@rbxts/object-utils": "^1.0.4",
"@rbxts/quaternion": "^1.0.0",
"@rbxts/runit": "^1.1.1",
"@rbxts/runit": "^1.2.0",
"@rbxts/signal": "^1.1.1",
"@rbxts/strict-map": "^1.0.2",
"@rbxts/string-builder": "^1.0.0",
Expand All @@ -63,4 +62,4 @@
"@rbxts/wave": "^1.0.0",
"node": "^18.20.1"
}
}
}
5 changes: 3 additions & 2 deletions src/client/controllers/control-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { createMappingDecorator } from "shared/utility/meta";
import type { ControlPanelDropdownRenderer } from "shared/structs/control-panel";

import type { MouseController } from "./mouse";
import { StandardActionBuilder } from "@rbxts/mechanism";

const [renderableMeta, ControlPanelRenderable] = createMappingDecorator<ControlPanelDropdownRenderer, never[], [dropdownName: string, order?: number]>();
export { ControlPanelRenderable };
Expand Down Expand Up @@ -43,13 +44,13 @@ export class ControlPanelController implements OnStart, LogStart {
Iris.Connect(() => this.render());
}

@OnInput("Comma")
@OnInput(new StandardActionBuilder(Enum.KeyCode.Comma))
public open(): void {
if (!isDeveloper(Player)) return;
this.windowOpened.set(!this.windowOpened.get());
}

@OnInput("P")
@OnInput(new StandardActionBuilder(Enum.KeyCode.P))
public unlockMouse(): void {
if (!isDeveloper(Player)) return;
this.mouseUnlocked = !this.mouseUnlocked;
Expand Down
16 changes: 14 additions & 2 deletions src/client/controllers/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,30 @@ import { Controller } from "@flamework/core";

import type { LogStart } from "shared/hooks";
import { OnInput, OnInputRelease } from "client/decorators";
import { StandardActionBuilder } from "@rbxts/mechanism";

export const enum ActionID {
LMB,
RMB,
MMB,
LeftTrigger,
RightTrigger,
Crouch
}

/** Handles all game input */
@Controller()
export class InputController implements LogStart {
@OnInput("C", "crouch")
@OnInput(
new StandardActionBuilder(Enum.KeyCode.C)
.setID(ActionID.Crouch)
)
public crouch(): void {
// code for crouching
print("crouched")
}

@OnInputRelease("crouch")
@OnInputRelease(ActionID.Crouch)
public stand(): void {
// code for standing
print("stood")
Expand Down
69 changes: 44 additions & 25 deletions src/client/controllers/mouse.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Controller, type OnInit, type OnRender } from "@flamework/core";
import { UserInputService as UserInput, Workspace as World } from "@rbxts/services";
import { RaycastParamsBuilder } from "@rbxts/builders";
import { Context as InputContext } from "@rbxts/gamejoy";
import { Axis } from "@rbxts/gamejoy/out/Actions";
import Charm, { atom } from "@rbxts/charm";
import Signal from "@rbxts/signal";

import { OnInput, OnAxisInput, OnInputRelease } from "client/decorators";
import { OnInput, OnAxisInput, OnInputRelease, inputManager } from "client/decorators";
import { Player } from "client/utility";
import { AxisAction, AxisActionBuilder, StandardActionBuilder } from "@rbxts/mechanism";
import { ActionID } from "./input";

const { abs } = math;

Expand All @@ -24,14 +24,17 @@ export class MouseController implements OnInit, OnRender {
public readonly behavior = atom<Enum.MouseBehavior>(Enum.MouseBehavior.Default);

private readonly playerMouse = Player.GetMouse();
private readonly rightThumbstickAxis = new Axis("Thumbstick2");
private readonly rightThumbstickAxis = new AxisActionBuilder(Enum.KeyCode.Thumbstick2);
private readonly thumbstickDeadzone = 0.1;

private lastInput?: Enum.UserInputType;
private delta = new Vector2;

public onInit(): void {
new InputContext().Bind(this.rightThumbstickAxis, () => { /* this is only so that the Position property computes */ });
inputManager
.bind(this.rightThumbstickAxis)
.bind(new StandardActionBuilder(Enum.KeyCode.ButtonL2).setID(ActionID.LeftTrigger))
.bind(new StandardActionBuilder(Enum.KeyCode.ButtonR2).setID(ActionID.RightTrigger));

// Touch controls
UserInput.TouchPinch.Connect((_, scale) => this.scrolled.Fire((scale < 1 ? 1 : -1) * abs(scale - 2)));
Expand All @@ -51,8 +54,15 @@ export class MouseController implements OnInit, OnRender {
this.delta = UserInput.GetMouseDelta();
break;
}
case Enum.UserInputType.Gamepad1: {
const { X, Y } = this.rightThumbstickAxis.Position;
case Enum.UserInputType.Gamepad1:
case Enum.UserInputType.Gamepad2:
case Enum.UserInputType.Gamepad3:
case Enum.UserInputType.Gamepad4:
case Enum.UserInputType.Gamepad5:
case Enum.UserInputType.Gamepad6:
case Enum.UserInputType.Gamepad7:
case Enum.UserInputType.Gamepad8: {
const { X, Y } = this.rightThumbstickAxis.position;
this.delta = new Vector2(
this.applyThumbstickDeadzone(X),
this.applyThumbstickDeadzone(-Y)
Expand Down Expand Up @@ -90,74 +100,83 @@ export class MouseController implements OnInit, OnRender {
}

/** @hidden */
@OnAxisInput("MouseWheel")
public onScroll(axis: Axis<"MouseWheel">): void {
this.scrolled.Fire(-axis.Position.Z);
@OnAxisInput(new AxisActionBuilder(Enum.UserInputType.MouseWheel))
public onScroll(axis: AxisAction): void {
this.scrolled.Fire(-axis.position.Z);
}

/** @hidden */
@OnAxisInput("ButtonR2", "axisR2")
public onR2AxisChange(axis: Axis<"ButtonR2">): void {
@OnAxisInput(new AxisActionBuilder(Enum.KeyCode.ButtonR2))
public onR2AxisChange(axis: AxisAction): void {
this.triggerAxesChange(axis, this.isLmbDown);
}

/** @hidden */
@OnAxisInput("ButtonL2", "axisL2")
public onL2AxisChange(axis: Axis<"ButtonL2">): void {
@OnAxisInput(new AxisActionBuilder(Enum.KeyCode.ButtonL2))
public onL2AxisChange(axis: AxisAction): void {
this.triggerAxesChange(axis, this.isLmbDown);
}

/** @hidden */
@OnInputRelease("axisR2")
@OnInputRelease(ActionID.RightTrigger)
public onR2Release(): void {
this.rmbUp();
}

/** @hidden */
@OnInputRelease("axisL2")
@OnInputRelease(ActionID.LeftTrigger)
public onL2Release(): void {
this.lmbUp();
}

/** @hidden */
@OnInputRelease("mmb")
@OnInputRelease(ActionID.MMB)
public mmbUp(): void {
this.isMmbDown(false);
}

/** @hidden */
@OnInput("MouseButton3", "mmb")
@OnInput(
new StandardActionBuilder(Enum.KeyCode.MouseMiddleButton)
.setID(ActionID.MMB)
)
public mmbDown(): void {
this.isMmbDown(true);
}

/** @hidden */
@OnInputRelease("rmb")
@OnInputRelease(ActionID.RMB)
public rmbUp(): void {
this.isRmbDown(false);
}

/** @hidden */
@OnInput("MouseButton2", "rmb")
@OnInput(
new StandardActionBuilder(Enum.KeyCode.MouseRightButton)
.setID(ActionID.RMB)
)
public rmbDown(): void {
this.isRmbDown(true);
}

/** @hidden */
@OnInputRelease("lmb")
@OnInputRelease(ActionID.LMB)
public lmbUp(): void {
this.isLmbDown(false);
}

/** @hidden */
@OnInput("MouseButton1", "lmb")
@OnInput(
new StandardActionBuilder(Enum.KeyCode.MouseLeftButton)
.setID(ActionID.LMB)
)
public lmbDown(): void {
this.isLmbDown(true);
}

private triggerAxesChange(axis: Axis<"ButtonL2" | "ButtonR2">, isDown: Charm.Atom<boolean>): void {
if (axis.Delta.Z < 0) return void isDown(false);
if (axis.Delta.Z < 0.05) return;
private triggerAxesChange(axis: AxisAction, isDown: Charm.Atom<boolean>): void {
if (axis.delta.Z < 0) return void isDown(false);
if (axis.delta.Z < 0.05) return;
isDown(true);
}

Expand Down
36 changes: 15 additions & 21 deletions src/client/decorators.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Modding } from "@flamework/core";
import { InputManager } from "@rbxts/mechanism";
import { BaseAction } from "@rbxts/mechanism/out/base-action";
import { InputManager, StandardAction, AxisAction } from "@rbxts/mechanism";
import { callMethodOnDependency } from "@rbxts/flamework-meta-utils";
import type { ClientReceiver as ClientEventReceiver } from "@flamework/networking/out/events/types";
import type { ClientReceiver as ClientFunctionReceiver } from "@flamework/networking/out/functions/types";
Expand All @@ -9,31 +8,27 @@ import type { Serializer } from "@rbxts/flamework-binary-serializer";
import { FlameworkIgnited } from "shared/constants";
import Log from "shared/log";

const inputManager = new InputManager;
export const inputManager = new InputManager;

export const OnInput = Modding.createDecorator<[binding: BaseAction]>(
export const OnInput = Modding.createDecorator<[binding: StandardAction]>(
"Method",
(descriptor, [action]) => {
FlameworkIgnited.Once(() => {
inputManager.bind(action)
context.Bind(<ActionLike<RawActionEntry>>action, () => {
inputManager.bind(action);
action.activated.Connect(() => {
const object = <Record<string, Callback>>Modding.resolveSingleton(descriptor.constructor!);
void task.spawn(object[descriptor.property], object, action);
});
});
}
);

export const OnAxisInput = Modding.createDecorator<[binding: AxisActionEntry, actionName?: string, process?: boolean]>(
export const OnAxisInput = Modding.createDecorator<[binding: AxisAction]>(
"Method",
(descriptor, [rawAction, actionName, process]) => {
const axis = new Axis(rawAction);
if (actionName !== undefined)
inputActions[actionName] = axis;

(descriptor, [axis]) => {
FlameworkIgnited.Once(() => {
const context = process ? processedContext : inputContext;
context.Bind(axis, () => {
inputManager.bind(axis);
axis.updated.Connect(() => {
const object = <Record<string, Callback>>Modding.resolveSingleton(descriptor.constructor!);
void task.spawn(object[descriptor.property], object, axis);
});
Expand All @@ -42,21 +37,20 @@ export const OnAxisInput = Modding.createDecorator<[binding: AxisActionEntry, ac
);

/** **Note:** You need to provide an action name to the OnInput decorator to use this decorator, with which you will use the same action name. */
export const OnInputRelease = Modding.createDecorator<[actionName: string, process?: boolean]>(
export const OnInputRelease = Modding.createDecorator<[actionID: string | number]>(
"Method",
(descriptor, [actionName, process]) => task.spawn(() => {
(descriptor, [actionID]) => task.spawn(() => {
FlameworkIgnited.Once(() => {
let action = inputActions[actionName];
let action = inputManager.getActionByID(actionID, StandardAction);
if (action === undefined) {
task.wait(0.1);
action = inputActions[actionName];
action = inputManager.getActionByID(actionID, StandardAction);
}

if (action === undefined)
throw Log.fatal(`Failed to bind method "${descriptor.property}" using @OnInputRelease decorator: No input action "${actionName}" exists`);
throw Log.fatal(`Failed to bind method "${descriptor.property}" using @OnInputRelease decorator: No input action with ID "${actionID}" exists`);

const context = process ? processedContext : inputContext;
context.BindEvent(actionName, action.Released, () => {
action.deactivated.Connect(() => {
const object = <Record<string, Callback>>Modding.resolveSingleton(descriptor.constructor!);
void task.spawn(object[descriptor.property], object, action);
});
Expand Down

0 comments on commit b0a4c21

Please sign in to comment.