Skip to content

Commit

Permalink
监听物编变化
Browse files Browse the repository at this point in the history
  • Loading branch information
sumneko committed Jul 3, 2024
1 parent 34eca35 commit 2f1478b
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 32 deletions.
76 changes: 56 additions & 20 deletions src/editorTable/editorTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Table } from "../constants";
import { env } from "../env";
import * as vscode from "vscode";
import * as y3 from 'y3-helper';
import { throttle } from "../utility/decorators";

type ObjectShape = {
"name": string | number,
Expand Down Expand Up @@ -70,18 +71,26 @@ async function loadObject(tableName: Table.NameCN, key: number) {
}
}

function getFileID(uri: vscode.Uri): number|undefined {
if (!uri.path.toLowerCase().endsWith('.json')) {
function getFileID(fileName: string): number|undefined {
if (!fileName.toLowerCase().endsWith('.json')) {
return;
}
let id = parseInt(uri.path.slice(0, -5));
let idStr = fileName.slice(0, -5).split('/').pop();
if (!idStr) {
return;
}
// 确保只有数字
if (!/^\d+$/.test(idStr)) {
return;
}
let id = parseInt(idStr);
if (isNaN(id)) {
return;
}
return id;
}

class EditorTable<N extends Table.NameCN> extends vscode.Disposable {
export class EditorTable<N extends Table.NameCN> extends vscode.Disposable {
public uri;
public nameEN;
private _objectCache: { [key: number]: EditorObject | null | undefined } = {};
Expand Down Expand Up @@ -121,63 +130,90 @@ class EditorTable<N extends Table.NameCN> extends vscode.Disposable {
if (type !== vscode.FileType.File) {
continue;
}
if (!name.toLowerCase().endsWith('.json')) {
continue;
}
let id = parseInt(name.slice(0, -5));
if (isNaN(id)) {
let id = getFileID(name);
if (id === undefined) {
continue;
}
this._listCache.push(id);
}
this._listCache.sort();
}
this.resortList();
return this._listCache;
}

public fetchList() {
this.resortList();
return this._listCache;
}

private _listActions: ['create' | 'delete', number][] = [];
private resortList() {
if (this._listActions.length === 0) {
return;
}
let map: { [key: number]: boolean } = {};
let list: number[] = [];
for (const id of this._listCache!) {
map[id] = true;
}
for (const [action, id] of this._listActions) {
if (action === 'create') {
map[id] = true;
} else {
delete map[id];
}
}
this._listActions.length = 0;
for (const id in map) {
list.push(Number(id));
}
list.sort();
this._listCache = list;
}

@throttle(200)
private callOnDidChange() {
this._onDidChange.fire();
}

private _onDidChange: vscode.EventEmitter<void> = new vscode.EventEmitter();

private initWatcher() {
this.watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(this.uri, '*.json'));
this.watcher.onDidChange((fileUri) => {
let id = getFileID(fileUri);
let id = getFileID(fileUri.path);
if (id === undefined) {
return;
}
if (!this._objectCache[id]) {
return;
}
this._objectCache[id] = undefined;
this._onDidChange.fire();
this.callOnDidChange();
});
this.watcher.onDidCreate((fileUri) => {
let id = getFileID(fileUri);
let id = getFileID(fileUri.path);
if (id === undefined) {
return;
}
if (!this._listCache) {
return;
}
this._listCache.push(id);
this._onDidChange.fire();
this._listActions.push(['create', id]);
this.callOnDidChange();
});
this.watcher.onDidDelete((fileUri) => {
let id = getFileID(fileUri);
let id = getFileID(fileUri.path);
if (id === undefined) {
return;
}
if (!this._listCache) {
return;
}
let index = this._listCache.indexOf(id);
if (index !== -1) {
this._listCache.splice(index, 1);
}
this._objectCache[id] = undefined;
this._onDidChange.fire();
this._listActions.push(['delete', id]);
this.callOnDidChange();
});
}

Expand Down
44 changes: 32 additions & 12 deletions src/editorTable/treeView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class FileNode extends vscode.TreeItem {
public key: number,
) {
super(`加载中...(${key})`);

this.id = `${tableName}/${key}`;
}

public update(): void | Promise<void> {
Expand All @@ -39,24 +41,25 @@ class FileNode extends vscode.TreeItem {
class DirNode extends vscode.TreeItem {
readonly contextValue = 'directory';
readonly collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
readonly table: editorTable.EditorTable<any>;
constructor(
public tableName: Table.NameCN,
) {
super(`${tableName}(加载中...)`);

let table = editorTable.open(tableName);
this.resourceUri = table.uri;
this.table = editorTable.open(tableName);
this.resourceUri = this.table.uri;
this.id = tableName;
}

public update(): void | Promise<void> {
let table = editorTable.open(this.tableName);
let list = table.fetchList();
let list = this.table.fetchList();
if (list) {
this.label = `${this.tableName}(${list.length})`;
return;
} else {
return new Promise<void>(async resolve => {
await table.getList();
await this.table.getList();
resolve();
});
}
Expand All @@ -75,21 +78,38 @@ class DirNode extends vscode.TreeItem {

type TreeNode = FileNode | DirNode;

class TreeViewProvider implements vscode.TreeDataProvider<TreeNode> {
private async getRoot(): Promise<DirNode[]> {
let nodes: DirNode[] = [];
class TreeViewProvider extends vscode.Disposable implements vscode.TreeDataProvider<TreeNode> {
constructor() {
super(() => {
this.disposables.forEach(d => d.dispose());
});
}

private dirNodes?: DirNode[];
private disposables: vscode.Disposable[] = [];

private getRoot(): DirNode[] {
if (this.dirNodes) {
return this.dirNodes;
}
this.dirNodes = [];
for (const nameCN in Table.name.fromCN) {
nodes.push(new DirNode(nameCN as Table.NameCN));
let dirNode = new DirNode(nameCN as Table.NameCN);
this.dirNodes.push(dirNode);

this.disposables.push(dirNode.table.onDidChange(() => {
this.refresh(dirNode);
}));
}
return nodes;
return this.dirNodes;
}

public async getChildren(node?: TreeNode | undefined) {
if (!env.editorTableUri) {
return;
}
if (node === undefined) {
return await this.getRoot();
return this.getRoot();
} else if(node instanceof DirNode) {
return await node.getChildren();
} else {
Expand Down Expand Up @@ -122,7 +142,7 @@ class TreeView extends vscode.Disposable {
super(() => {
this.disposables.forEach(d => d.dispose());
});
this.provider = new TreeViewProvider();
this.disposables.push(this.provider = new TreeViewProvider());

this.disposables.push(this.treeView = vscode.window.createTreeView('y3-helper.editorTableView', {
treeDataProvider: this.provider,
Expand Down

0 comments on commit 2f1478b

Please sign in to comment.