remove mouse sensitivity value, improve type strictness

This commit is contained in:
Brian Beck 2026-03-14 00:27:22 -07:00
parent 8542e07259
commit d47d3adc27
3 changed files with 53 additions and 26 deletions

View file

@ -265,9 +265,6 @@ export function InspectorControls({
Mouse sensitivity Mouse sensitivity
</label> </label>
<div className={styles.Control}> <div className={styles.Control}>
<output htmlFor="mouseSensitivityInput">
{Math.round(mouseSensitivity * 8000) / 64}
</output>
<input <input
id="mouseSensitivityInput" id="mouseSensitivityInput"
type="range" type="range"

View file

@ -87,15 +87,33 @@ type PersistedSettings = {
}; };
export function useSettings() { export function useSettings() {
return useContext(SettingsContext); const context = useContext(SettingsContext);
if (!context) {
throw new Error(
"No SettingsContext found. Did you remember to add a <SettingsProvider>?",
);
}
return context;
} }
export function useDebug() { export function useDebug() {
return useContext(DebugContext); const context = useContext(DebugContext);
if (!context) {
throw new Error(
"No DebugContext found. Did you remember to add a <SettingsProvider>?",
);
}
return context;
} }
export function useControls() { export function useControls() {
return useContext(ControlsContext); const context = useContext(ControlsContext);
if (!context) {
throw new Error(
"No ControlsContext found. Did you remember to add a <SettingsProvider>?",
);
}
return context;
} }
export function SettingsProvider({ children }: { children: ReactNode }) { export function SettingsProvider({ children }: { children: ReactNode }) {

View file

@ -3,6 +3,22 @@ import { createRuntime } from "./runtime";
import type { TorqueRuntimeOptions } from "./types"; import type { TorqueRuntimeOptions } from "./types";
import { parse, transpile } from "./index"; import { parse, transpile } from "./index";
// Mock pino logger so log.warn() calls are capturable in Node.js (pino's
// browser write function only applies in browsers, not in vitest/Node).
const mockLogger = vi.hoisted(() => ({
warn: vi.fn(),
info: vi.fn(),
error: vi.fn(),
debug: vi.fn(),
trace: vi.fn(),
fatal: vi.fn(),
child: vi.fn(),
}));
vi.mock("../logger", () => ({
createLogger: () => mockLogger,
}));
function run(script: string, options?: TorqueRuntimeOptions) { function run(script: string, options?: TorqueRuntimeOptions) {
const { $, $f, $g, state } = createRuntime(options); const { $, $f, $g, state } = createRuntime(options);
const { code } = transpile(script); const { code } = transpile(script);
@ -1658,19 +1674,17 @@ describe("TorqueScript Runtime", () => {
it("returns false when exec called without loadScript", async () => { it("returns false when exec called without loadScript", async () => {
const runtime = createRuntime(); const runtime = createRuntime();
// Warn about missing loader during load // Warn about missing loader during load (via pino logger)
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); mockLogger.warn.mockClear();
const script = await runtime.loadFromSource( const script = await runtime.loadFromSource(
'$Result = exec("scripts/test.cs");', '$Result = exec("scripts/test.cs");',
); );
expect(warnSpy).toHaveBeenCalled(); expect(mockLogger.warn).toHaveBeenCalled();
warnSpy.mockRestore();
// Execution should warn and set $Result to false // Execution should warn and set $Result to false (via console.warn in builtins)
const warnSpy2 = vi.spyOn(console, "warn").mockImplementation(() => {}); const warnSpy2 = vi.spyOn(console, "warn").mockImplementation(() => {});
script.execute(); script.execute();
expect(warnSpy2).toHaveBeenCalledWith( expect(warnSpy2).toHaveBeenCalledWith(
"[runtime]",
'exec("scripts/test.cs"): script not found', 'exec("scripts/test.cs"): script not found',
); );
warnSpy2.mockRestore(); warnSpy2.mockRestore();
@ -1763,15 +1777,14 @@ describe("TorqueScript Runtime", () => {
const runtime = createRuntime({ const runtime = createRuntime({
loadScript: async () => null, loadScript: async () => null,
}); });
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); mockLogger.warn.mockClear();
await runtime.loadFromSource('exec("scripts/missing.cs");'); await runtime.loadFromSource('exec("scripts/missing.cs");');
expect(warnSpy).toHaveBeenCalledWith( expect(mockLogger.warn).toHaveBeenCalledWith(
"[runtime]", "Script not found: %s",
"Script not found: scripts/missing.cs", "scripts/missing.cs",
); );
warnSpy.mockRestore();
}); });
}); });
@ -2925,7 +2938,7 @@ describe("TorqueScript Runtime", () => {
} }
it("skips scripts matching glob patterns", async () => { it("skips scripts matching glob patterns", async () => {
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); mockLogger.warn.mockClear();
const runtime = createRuntime({ const runtime = createRuntime({
loadScript: createLoader({ loadScript: createLoader({
@ -2940,11 +2953,10 @@ describe("TorqueScript Runtime", () => {
expect(runtime.$g.get("Main")).toBe(1); expect(runtime.$g.get("Main")).toBe(1);
expect(runtime.$g.get("AI")).toBe(""); // Not loaded expect(runtime.$g.get("AI")).toBe(""); // Not loaded
expect(warnSpy).toHaveBeenCalledWith( expect(mockLogger.warn).toHaveBeenCalledWith(
"[runtime]", "Ignoring script: %s",
"Ignoring script: scripts/ai/brain.cs", "scripts/ai/brain.cs",
); );
warnSpy.mockRestore();
}); });
it("is case insensitive", async () => { it("is case insensitive", async () => {
@ -2990,7 +3002,7 @@ describe("TorqueScript Runtime", () => {
it("marks ignored scripts as failed (not retried)", async () => { it("marks ignored scripts as failed (not retried)", async () => {
let loadCount = 0; let loadCount = 0;
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); mockLogger.warn.mockClear();
const runtime = createRuntime({ const runtime = createRuntime({
loadScript: async (path) => { loadScript: async (path) => {
@ -3011,13 +3023,13 @@ describe("TorqueScript Runtime", () => {
// Should only warn once (second exec sees it's already in failedScripts) // Should only warn once (second exec sees it's already in failedScripts)
expect( expect(
warnSpy.mock.calls.filter( mockLogger.warn.mock.calls.filter(
(c) => c[1] === "Ignoring script: scripts/ignored.cs", (c) =>
c[0] === "Ignoring script: %s" && c[1] === "scripts/ignored.cs",
).length, ).length,
).toBe(1); ).toBe(1);
// Loader should only be called for main.cs, not for ignored.cs // Loader should only be called for main.cs, not for ignored.cs
expect(loadCount).toBe(1); expect(loadCount).toBe(1);
warnSpy.mockRestore();
}); });
it("matches exact filenames with glob", async () => { it("matches exact filenames with glob", async () => {