Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions .github/workflows/auto-assign.yml

This file was deleted.

2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
.then((root) =>
{
const { Shape } = next2d.display;


const rects = [];
for (let i = 0; i < count; i++) {
Expand Down
449 changes: 226 additions & 223 deletions package-lock.json

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next2d/player",
"version": "3.6.0",
"version": "3.7.0",
"description": "Experience the fast and beautiful anti-aliased rendering of WebGL/WebGPU. You can create rich, interactive graphics, cross-platform applications and games without worrying about browser or device compatibility.",
"author": "Toshiyuki Ienaga<ienaga@next2d.app> (https://github.com/ienaga/)",
"license": "MIT",
Expand Down Expand Up @@ -50,22 +50,22 @@
"devDependencies": {
"@eslint/eslintrc": "^3.3.5",
"@eslint/js": "^10.0.1",
"@playwright/test": "^1.60.0",
"@playwright/test": "^1.61.0",
"@rollup/plugin-commonjs": "^29.0.3",
"@rollup/plugin-node-resolve": "^16.0.3",
"@rollup/plugin-terser": "^1.0.0",
"@rollup/plugin-typescript": "^12.3.0",
"@typescript-eslint/eslint-plugin": "^8.61.0",
"@typescript-eslint/parser": "^8.61.0",
"@typescript-eslint/eslint-plugin": "^8.61.1",
"@typescript-eslint/parser": "^8.61.1",
"@webgpu/types": "^0.1.70",
"eslint": "^10.4.1",
"eslint": "^10.5.0",
"eslint-plugin-unused-imports": "^4.4.1",
"globals": "^17.6.0",
"jsdom": "^29.1.1",
"rollup": "^4.61.1",
"rollup": "^4.62.0",
"typescript": "^6.0.3",
"vite": "^8.0.16",
"vitest": "^4.1.8",
"vitest": "^4.1.9",
"vitest-webgl-canvas-mock": "^1.1.0"
},
"peerDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/Events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
EventDispatcher,
EventPhase,
FocusEvent,
GamepadEvent,
HTTPStatusEvent,
IOErrorEvent,
PointerEvent,
Expand All @@ -17,6 +18,7 @@ const events: IEvents = {
EventDispatcher,
EventPhase,
FocusEvent,
GamepadEvent,
HTTPStatusEvent,
IOErrorEvent,
PointerEvent,
Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/GamepadState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @description ゲームパッドの前フレームのボタン押下状態 (gamepadIndex => boolean[])
* Previous frame button pressed state per gamepad (gamepadIndex => boolean[])
*
* @type {Map<number, boolean[]>}
* @protected
*/
export const $gamepadButtonStates: Map<number, boolean[]> = new Map();

/**
* @description ゲームパッドの前フレームの軸値 (gamepadIndex => number[])
* Previous frame axis values per gamepad (gamepadIndex => number[])
*
* @type {Map<number, number[]>}
* @protected
*/
export const $gamepadAxisStates: Map<number, number[]> = new Map();
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { execute } from "./PlayerGamepadConnectService";
import { $gamepadButtonStates, $gamepadAxisStates } from "../../GamepadState";
import { stage } from "@next2d/display";
import { GamepadEvent } from "@next2d/events";
import { describe, expect, it, vi, beforeEach } from "vitest";

describe("PlayerGamepadConnectService.js test", () =>
{
beforeEach(() =>
{
$gamepadButtonStates.clear();
$gamepadAxisStates.clear();
});

it("execute test case: gamepad is null", () =>
{
const mockEvent = { "gamepad": null } as unknown as GamepadEvent;

stage.hasEventListener = vi.fn().mockReturnValue(true);
stage.dispatchEvent = vi.fn();

execute(mockEvent);
expect(stage.dispatchEvent).not.toHaveBeenCalled();
});

it("execute test case: no stage listener", () =>
{
const mockEvent = {
"gamepad": { "index": 0, "buttons": [{}], "axes": [0] }
} as unknown as GamepadEvent;

let result = "";
stage.hasEventListener = vi.fn().mockReturnValue(false);
stage.dispatchEvent = vi.fn((event) =>
{
result = event.type;
});

execute(mockEvent);
expect($gamepadButtonStates.has(0)).toBe(true);
expect($gamepadAxisStates.has(0)).toBe(true);
expect(result).toBe("");
});

it("execute test case: dispatches GAMEPAD_CONNECTED", () =>
{
const mockEvent = {
"gamepad": { "index": 1, "buttons": [{}, {}, {}], "axes": [0, 0] }
} as unknown as GamepadEvent;

let result = "";
let gamepadIndex = -1;
stage.hasEventListener = vi.fn().mockReturnValue(true);
stage.dispatchEvent = vi.fn((event: GamepadEvent) =>
{
result = event.type;
gamepadIndex = event.gamepadIndex;
});

execute(mockEvent);
expect($gamepadButtonStates.get(1)).toEqual([false, false, false]);
expect($gamepadAxisStates.get(1)).toEqual([0, 0]);
expect(result).toBe("gamepadconnected");
expect(gamepadIndex).toBe(1);
});
});
37 changes: 37 additions & 0 deletions packages/core/src/Player/service/PlayerGamepadConnectService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { $gamepadButtonStates, $gamepadAxisStates } from "../../GamepadState";
import { stage } from "@next2d/display";
import { GamepadEvent } from "@next2d/events";

/**
* @description ゲームパッド接続イベントを実行する
* Execute the gamepad connected event
*
* @param {GamepadEvent} event
* @return {void}
* @method
* @protected
*/
export const execute = (event: GamepadEvent): void =>
{
const gamepad = event.gamepad;
if (!gamepad) {
return ;
}

$gamepadButtonStates.set(
gamepad.index,
Array.from({ "length": gamepad.buttons.length }, () => false)
);
$gamepadAxisStates.set(
gamepad.index,
Array.from({ "length": gamepad.axes.length }, () => 0)
);

if (!stage.hasEventListener(GamepadEvent.GAMEPAD_CONNECTED)) {
return ;
}

const gamepadEvent = new GamepadEvent(GamepadEvent.GAMEPAD_CONNECTED);
gamepadEvent.gamepadIndex = gamepad.index;
stage.dispatchEvent(gamepadEvent);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { execute } from "./PlayerGamepadDisconnectService";
import { $gamepadButtonStates, $gamepadAxisStates } from "../../GamepadState";
import { stage } from "@next2d/display";
import { GamepadEvent } from "@next2d/events";
import { describe, expect, it, vi, beforeEach } from "vitest";

describe("PlayerGamepadDisconnectService.js test", () =>
{
beforeEach(() =>
{
$gamepadButtonStates.clear();
$gamepadAxisStates.clear();
});

it("execute test case: gamepad is null", () =>
{
const mockEvent = { "gamepad": null } as unknown as GamepadEvent;

stage.hasEventListener = vi.fn().mockReturnValue(true);
stage.dispatchEvent = vi.fn();

execute(mockEvent);
expect(stage.dispatchEvent).not.toHaveBeenCalled();
});

it("execute test case: no stage listener", () =>
{
$gamepadButtonStates.set(0, [false, false]);
$gamepadAxisStates.set(0, [0, 0]);

const mockEvent = {
"gamepad": { "index": 0, "buttons": [{}, {}], "axes": [0, 0] }
} as unknown as GamepadEvent;

let result = "";
stage.hasEventListener = vi.fn().mockReturnValue(false);
stage.dispatchEvent = vi.fn((event) =>
{
result = event.type;
});

execute(mockEvent);
expect($gamepadButtonStates.has(0)).toBe(false);
expect($gamepadAxisStates.has(0)).toBe(false);
expect(result).toBe("");
});

it("execute test case: dispatches GAMEPAD_DISCONNECTED", () =>
{
$gamepadButtonStates.set(2, [false]);
$gamepadAxisStates.set(2, [0]);

const mockEvent = {
"gamepad": { "index": 2, "buttons": [{}], "axes": [0] }
} as unknown as GamepadEvent;

let result = "";
let gamepadIndex = -1;
stage.hasEventListener = vi.fn().mockReturnValue(true);
stage.dispatchEvent = vi.fn((event: GamepadEvent) =>
{
result = event.type;
gamepadIndex = event.gamepadIndex;
});

execute(mockEvent);
expect($gamepadButtonStates.has(2)).toBe(false);
expect($gamepadAxisStates.has(2)).toBe(false);
expect(result).toBe("gamepaddisconnected");
expect(gamepadIndex).toBe(2);
});
});
31 changes: 31 additions & 0 deletions packages/core/src/Player/service/PlayerGamepadDisconnectService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { $gamepadButtonStates, $gamepadAxisStates } from "../../GamepadState";
import { stage } from "@next2d/display";
import { GamepadEvent } from "@next2d/events";

/**
* @description ゲームパッド切断イベントを実行する
* Execute the gamepad disconnected event
*
* @param {GamepadEvent} event
* @return {void}
* @method
* @protected
*/
export const execute = (event: GamepadEvent): void =>
{
const gamepad = event.gamepad;
if (!gamepad) {
return ;
}

$gamepadButtonStates.delete(gamepad.index);
$gamepadAxisStates.delete(gamepad.index);

if (!stage.hasEventListener(GamepadEvent.GAMEPAD_DISCONNECTED)) {
return ;
}

const gamepadEvent = new GamepadEvent(GamepadEvent.GAMEPAD_DISCONNECTED);
gamepadEvent.gamepadIndex = gamepad.index;
stage.dispatchEvent(gamepadEvent);
};
Loading