From b5d14b169c4873881f1e0088ec83e7a6a4c61701 Mon Sep 17 00:00:00 2001 From: Will Eastcott Date: Sat, 8 Jun 2024 13:25:31 +0100 Subject: [PATCH] Enable GitHub Actions (#108) * Enable GitHub Actions * Fix lint problems --- .eslintrc.json | 14 ++++++-- .github/workflows/ci.yml | 67 +++++++++++++++++++++++++++++++++++ src/asset-loader.ts | 2 +- src/controllers.ts | 2 +- src/edit-ops.ts | 7 ++-- src/editor.ts | 12 +++---- src/file-handler.ts | 4 +-- src/grid.ts | 1 - src/model.ts | 3 -- src/scene.ts | 2 +- src/shortcuts.ts | 6 ++-- src/splat-convert.ts | 8 ++--- src/splat-debug.ts | 4 +-- src/sw.ts | 4 +-- src/tools/picker-selection.ts | 2 +- src/tools/transform-tool.ts | 6 ++-- src/ui/editor.ts | 2 +- src/ui/tooltip.ts | 2 +- 18 files changed, 109 insertions(+), 39 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.eslintrc.json b/.eslintrc.json index 5039d7c..e9b96f5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -4,8 +4,16 @@ "extends": [ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:prettier/recommended" + "plugin:@typescript-eslint/recommended" ], - "plugins": ["@typescript-eslint", "prettier"] + "plugins": ["@typescript-eslint"], + "rules": { + "no-constant-condition": "off", + "no-empty": "off", + "no-prototype-builtins": "off", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-unused-vars": "off" + } } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..59461bc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,67 @@ +name: CI + +on: + workflow_dispatch: + push: + branches: [ main ] + paths-ignore: ['README.md', 'LICENSE'] + pull_request: + branches: [ main ] + paths-ignore: ['README.md', 'LICENSE'] + +concurrency: + group: ci-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build + runs-on: ubuntu-latest + + timeout-minutes: 10 + + strategy: + matrix: + node-version: [18.x] + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + + - name: Install + run: npm ci + + - name: Build + run: npm run build + + lint: + name: Lint + runs-on: ubuntu-latest + + timeout-minutes: 10 + + strategy: + matrix: + node-version: [18.x] + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + + - name: Install + run: npm ci + + - name: Lint + run: npm run lint diff --git a/src/asset-loader.ts b/src/asset-loader.ts index 8db5edf..82fbfaa 100644 --- a/src/asset-loader.ts +++ b/src/asset-loader.ts @@ -1,4 +1,4 @@ -import { Asset, AssetRegistry, StandardMaterial, TEXTURETYPE_RGBP } from 'playcanvas'; +import { Asset, AssetRegistry, TEXTURETYPE_RGBP } from 'playcanvas'; import { Model } from './model'; import { Splat } from './splat'; import { Env } from './env'; diff --git a/src/controllers.ts b/src/controllers.ts index 347b780..001abf1 100644 --- a/src/controllers.ts +++ b/src/controllers.ts @@ -67,7 +67,7 @@ class MouseController { }; let closestD = 0; - let closestP = new Vec3(); + const closestP = new Vec3(); let closestSplat = null; for (let i = 0; i < splats.length; ++i) { diff --git a/src/edit-ops.ts b/src/edit-ops.ts index 8097edf..2beb9e4 100644 --- a/src/edit-ops.ts +++ b/src/edit-ops.ts @@ -1,13 +1,12 @@ import { GSplatData, Quat, Vec3 } from 'playcanvas'; import { Scene } from './scene'; -import { Element } from './element'; import { Splat } from './splat'; enum State { selected = 1, hidden = 2, deleted = 4 -}; +} // build a splat index based on a boolean predicate const buildIndex = (splatData: GSplatData, pred: (i: number) => boolean) => { @@ -107,7 +106,7 @@ interface EntityTransform { position: Vec3; rotation: Quat; scale: Vec3; -}; +} interface EntityOp { splat: Splat; @@ -140,7 +139,7 @@ class EntityTransformOp { destroy() { this.entityOps = []; } -}; +} export { State, diff --git a/src/editor.ts b/src/editor.ts index 3c0343d..c4f467b 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -67,7 +67,7 @@ const registerEditorEvents = (events: Events, editHistory: EditHistory, scene: S const processSelection = (state: Uint8Array, op: string, pred: (i: number) => boolean) => { for (let i = 0; i < state.length; ++i) { - if (!!(state[i] & (State.deleted | State.hidden))) { + if (state[i] & (State.deleted | State.hidden)) { state[i] &= ~State.selected; } else { const result = pred(i); @@ -108,11 +108,11 @@ const registerEditorEvents = (events: Events, editHistory: EditHistory, scene: S lastExportCursor = editHistory.cursor; }); - events.on('camera.mode', (mode: string) => { + events.on('camera.mode', () => { scene.forceRender = true; }); - events.on('splatSize', (value: number) => { + events.on('splatSize', () => { scene.forceRender = true; }); @@ -164,7 +164,7 @@ const registerEditorEvents = (events: Events, editHistory: EditHistory, scene: S selectedSplats().forEach((splat) => { const splatData = splat.splatData; const state = splatData.getProp('state') as Uint8Array; - processSelection(state, 'set', (i) => true); + processSelection(state, 'set', () => true); splat.updateState(); }); }); @@ -173,7 +173,7 @@ const registerEditorEvents = (events: Events, editHistory: EditHistory, scene: S selectedSplats().forEach((splat) => { const splatData = splat.splatData; const state = splatData.getProp('state') as Uint8Array; - processSelection(state, 'set', (i) => false); + processSelection(state, 'set', () => false); splat.updateState(); }); }); @@ -200,7 +200,7 @@ const registerEditorEvents = (events: Events, editHistory: EditHistory, scene: S let scaleMin; let scaleMax; for (let i = 0; i < splatData.numSplats; ++i) { - if (!!(state[i] & State.deleted)) continue; + if (state[i] & State.deleted) continue; if (first) { first = false; scaleMin = Math.min(scale_0[i], scale_1[i], scale_2[i]); diff --git a/src/file-handler.ts b/src/file-handler.ts index 26e1ebb..e66696a 100644 --- a/src/file-handler.ts +++ b/src/file-handler.ts @@ -10,7 +10,7 @@ import { Splat } from './splat'; interface RemoteStorageDetails { method: string; url: string; -}; +} type ExportType = 'ply' | 'compressed-ply' | 'splat'; @@ -18,7 +18,7 @@ interface SceneWriteOptions { type: ExportType; filename?: string; stream?: FileSystemWritableFileStream; -}; +} const filePickerTypes = { 'ply': [{ diff --git a/src/grid.ts b/src/grid.ts index 6abd16b..db7908a 100644 --- a/src/grid.ts +++ b/src/grid.ts @@ -1,5 +1,4 @@ import { - BUFFER_STATIC, PRIMITIVE_LINES, SEMANTIC_COLOR, SEMANTIC_POSITION, diff --git a/src/model.ts b/src/model.ts index 0b47d5f..84c3511 100644 --- a/src/model.ts +++ b/src/model.ts @@ -2,7 +2,6 @@ import { Asset, BoundingBox, Entity, - Mat4, MeshInstance, RenderComponent, Vec3 @@ -11,8 +10,6 @@ import { Element, ElementType } from './element'; import { Serializer } from './serializer'; const vec = new Vec3(); -const mat = new Mat4(); -// const bound = new BoundingBox(); // calculate mesh sort distance by node origin (instead of the default bounding box origin) const calculateSortDistance = (drawCall: any, cameraPosition: Vec3, cameraForward: Vec3) => { diff --git a/src/scene.ts b/src/scene.ts index 1bb0b9a..61c0d82 100644 --- a/src/scene.ts +++ b/src/scene.ts @@ -195,7 +195,7 @@ class Scene { url: config.model.url, filename: config.model.filename })); - }; + } // load env if (config.env.url) { diff --git a/src/shortcuts.ts b/src/shortcuts.ts index 17bdd59..e17c8ed 100644 --- a/src/shortcuts.ts +++ b/src/shortcuts.ts @@ -5,7 +5,7 @@ interface ShortcutOptions { shift?: boolean; func?: () => void; event?: string; -}; +} class Shortcuts { shortcuts: { keys: string[], options: ShortcutOptions }[] = []; @@ -35,8 +35,8 @@ class Shortcuts { register(keys: string[], options: ShortcutOptions) { this.shortcuts.push({ keys, options }); - }; -}; + } +} export { Shortcuts diff --git a/src/splat-convert.ts b/src/splat-convert.ts index 0031d5d..3877df4 100644 --- a/src/splat-convert.ts +++ b/src/splat-convert.ts @@ -9,7 +9,7 @@ import { State } from './edit-ops'; interface ConvertEntry { splatData: GSplatData; modelMat: Mat4; -}; +} const countTotalSplats = (convertData: ConvertEntry[]) => { return convertData.reduce((total, entry) => { @@ -139,7 +139,7 @@ interface CompressedIndex { entryIndex: number; i: number; globalIndex: number; -}; +} class SingleSplat { x = 0; @@ -180,7 +180,7 @@ class SingleSplat { this.scale_1 = Math.log(Math.exp(this.scale_1) * scale.y); this.scale_2 = Math.log(Math.exp(this.scale_2) * scale.z); } -}; +} const compressedVal = (prop: string, index: CompressedIndex) => { return index.entry.splatData.getProp(prop)[index.i]; @@ -501,7 +501,7 @@ const convertPlyCompressed = (convertData: ConvertEntry[]) => { dataView.setFloat32(chunkOffset + i * 12 * 4 + 44, result.sz.max, true); // write splat data - let offset = vertexOffset + i * 256 * 4 * 4; + const offset = vertexOffset + i * 256 * 4 * 4; const chunkSplats = Math.min(numSplats, (i + 1) * 256) - i * 256; for (let j = 0; j < chunkSplats; ++j) { dataView.setUint32(offset + j * 4 * 4 + 0, chunk.position[j], true); diff --git a/src/splat-debug.ts b/src/splat-debug.ts index 998093d..cd34bfb 100644 --- a/src/splat-debug.ts +++ b/src/splat-debug.ts @@ -105,10 +105,10 @@ class SplatDebug { let count = 0; for (let i = 0; i < splatData.numSplats; ++i) { - if (!!(s[i] & State.deleted)) { + if (s[i] & State.deleted) { // deleted vertexData[i * 4 + 3] = -1; - } else if (!!(s[i] & State.hidden)) { + } else if (s[i] & State.hidden) { // hidden vertexData[i * 4 + 3] = -1; } else if (!(s[i] & State.selected)) { diff --git a/src/sw.ts b/src/sw.ts index 76c9a80..8111bc0 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -28,12 +28,12 @@ self.addEventListener('install', (event) => { ); }); -self.addEventListener('activate', (event) => { +self.addEventListener('activate', () => { console.log(`activating v${appVersion}`); // delete the old caches once this one is activated caches.keys().then((names) => { - for (let name of names) { + for (const name of names) { if (name !== cacheName) { caches.delete(name); } diff --git a/src/tools/picker-selection.ts b/src/tools/picker-selection.ts index 2cee15d..b35d660 100644 --- a/src/tools/picker-selection.ts +++ b/src/tools/picker-selection.ts @@ -35,7 +35,7 @@ class PickerSelection { deactivate() { this.root.style.display = 'none'; } -}; +} export { PickerSelection }; diff --git a/src/tools/transform-tool.ts b/src/tools/transform-tool.ts index 0a6859c..6f6a4cd 100644 --- a/src/tools/transform-tool.ts +++ b/src/tools/transform-tool.ts @@ -2,7 +2,7 @@ import { TransformGizmo } from 'playcanvas'; import { Scene } from '../scene'; import { Splat } from '../splat'; import { Events } from '../events'; -import { EditHistory, EditOp } from '../edit-history'; +import { EditHistory } from '../edit-history'; import { EntityOp, EntityTransformOp } from '../edit-ops'; // patch gizmo to be more opaque @@ -86,7 +86,7 @@ class TransformTool { } }); - events.on('scene.boundChanged', (editOp: EditOp) => { + events.on('scene.boundChanged', () => { if (this.splats) { this.gizmo.attach(this.splats.map((splat) => splat.entity)); } @@ -97,7 +97,7 @@ class TransformTool { scene.forceRender = true; }); - events.on('selection.changed', (selection: Splat) => { + events.on('selection.changed', () => { this.update(); }); } diff --git a/src/ui/editor.ts b/src/ui/editor.ts index 3fdbe3a..c27dc6d 100644 --- a/src/ui/editor.ts +++ b/src/ui/editor.ts @@ -1,4 +1,4 @@ -import { Container, InfoBox, Label } from 'pcui'; +import { Container, Label } from 'pcui'; import { ControlPanel } from './control-panel'; import { Toolbar } from './toolbar'; import { Events } from '../events'; diff --git a/src/ui/tooltip.ts b/src/ui/tooltip.ts index c8c9592..3fbd44b 100644 --- a/src/ui/tooltip.ts +++ b/src/ui/tooltip.ts @@ -46,6 +46,6 @@ class Tooltip extends Container { hide() { this.hidden = true; } -}; +} export { Tooltip };