Skip to content

Commit

Permalink
实现物编管理器
Browse files Browse the repository at this point in the history
  • Loading branch information
sumneko committed Jul 2, 2024
1 parent d7466c2 commit dc05ad7
Showing 1 changed file with 132 additions and 13 deletions.
145 changes: 132 additions & 13 deletions src/editorTable/editorTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,43 @@ type MapShape = {
};

class EditorObject {
public raw: ObjectShape;
public name: string;
constructor(public key: number, public uri: vscode.Uri, json: string) {
this.raw = JSON.parse(json);
let name = this.raw['name'];
this.name = y3.language.get(name) ?? '<未知>';
private _raw?: ObjectShape;
private _name?: string;
constructor(public key: number, public uri: vscode.Uri, private json: string) {
}

public get raw(): ObjectShape {
if (!this._raw) {
this._raw = JSON.parse(this.json);
}
return this._raw!;
}

public get name(): string {
if (!this._name) {
let name = this.json.match(/"name"\s*:\s*\(-?\d*)/);
if (name && name[1]) {
let id = parseInt(name[1]);
if (!isNaN(id)) {
this._name = y3.language.get(id);
}
} else {
let name = this.raw.name;
if (typeof name === 'string') {
this._name = name;
} else if (typeof name === 'number') {
this._name = y3.language.get(name);
}
}
}
if (!this._name) {
this._name = '<未知名称>';
}
return this._name;
}
}

async function openObject(tableName: Table.NameCN, key: number) {
async function loadObject(tableName: Table.NameCN, key: number) {
let uri = vscode.Uri.joinPath(env.editorTableUri!, Table.path.fromCN[tableName], `${key}.json`);
let file = await y3.fs.readFile(uri);
if (!file) {
Expand All @@ -43,11 +70,26 @@ async function openObject(tableName: Table.NameCN, key: number) {
}
}

class EditorTable<N extends Table.NameCN> {
function getFileID(uri: vscode.Uri): number|undefined {
if (!uri.path.endsWith('.json')) {
return;
}
let id = parseInt(uri.path.slice(0, -5));
if (isNaN(id)) {
return;
}
return id;
}

class EditorTable<N extends Table.NameCN> extends vscode.Disposable {
public tableUri;
public nameEN;
private _objectCache: { [key: number]: EditorObject | null } = {};
private _objectCache: { [key: number]: EditorObject | null | undefined } = {};
private watcher?: vscode.FileSystemWatcher;
constructor(public nameCN: N) {
super(() => {
this.watcher?.dispose();
});
if (!env.editorTableUri) {
throw new Error('未选择地图路径');
}
Expand All @@ -57,12 +99,89 @@ class EditorTable<N extends Table.NameCN> {

public async get(id: number): Promise<EditorObject | null> {
if (this._objectCache[id] === undefined) {
this._objectCache[id] = await openObject(this.nameCN, id);
this._objectCache[id] = await loadObject(this.nameCN, id);
}
return this._objectCache[id];
return this._objectCache[id]!;
}

private _listCache?: number[];
public async list() {
if (!this._listCache) {
this._listCache = [];
let files = await y3.fs.dir(this.tableUri);
this.initWatcher();
if (!files) {
return this._listCache;
}
for (const [name, type] of files) {
if (type !== vscode.FileType.File) {
continue;
}
if (!name.endsWith('.json')) {
continue;
}
let id = parseInt(name.slice(0, -5));
if (isNaN(id)) {
continue;
}
this._listCache.push(id);
}
}
return this._listCache;
}

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

private initWatcher() {
this.watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(this.tableUri, '*.json'));
this.watcher.onDidChange((fileUri) => {
let id = getFileID(fileUri);
if (id === undefined) {
return;
}
if (!this._objectCache[id]) {
return;
}
this._objectCache[id] = undefined;
this._onDidChange.fire();
});
this.watcher.onDidCreate((fileUri) => {
let id = getFileID(fileUri);
if (id === undefined) {
return;
}
if (!this._listCache) {
return;
}
this._listCache.push(id);
this._onDidChange.fire();
});
this.watcher.onDidDelete((fileUri) => {
let id = getFileID(fileUri);
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();
});
}

public onDidChange(callback: () => void) {
return this._onDidChange.event(callback);
}
}

export function open<N extends Table.NameCN>(tableName: N) {
return new EditorTable<N>(tableName);
let editorTables: { [key: string]: any } = {};

export function open<N extends Table.NameCN>(tableName: N): EditorTable<N> {
let table = editorTables[tableName]
?? (editorTables[tableName] = new EditorTable(tableName));
return table;
}

0 comments on commit dc05ad7

Please sign in to comment.