Skip to content

Commit

Permalink
🦄 refactor: Optimize code readability
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangechen committed Apr 7, 2024
1 parent 666bbf2 commit cfb03f8
Show file tree
Hide file tree
Showing 76 changed files with 329 additions and 347 deletions.
32 changes: 18 additions & 14 deletions packages/chili-builder/src/appBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import { Application, CommandService, EditEventHandler, EditorService, HotkeyService } from "chili";
import { I18n, IDocument, INode, IService, IStorage, IWindow, Logger } from "chili-core";
import { IShapeFactory } from "chili-geo";
import { IVisualFactory } from "chili-vis";
import {
I18n,
IDocument,
INode,
IService,
IShapeFactory,
IStorage,
IVisualFactory,
IWindow,
Logger,
} from "chili-core";
import { IAdditionalModule } from "./additionalModule";

export class AppBuilder {
Expand Down Expand Up @@ -74,7 +82,7 @@ export class AppBuilder {
this._window,
);

this.loadAdditionalModule()
this.loadAdditionalModule();

Logger.info("Application build completed");
}
Expand All @@ -93,17 +101,13 @@ export class AppBuilder {

private loadAdditionalModule() {
for (const module of this._additionalModules) {
module.i18n().forEach(local => {
I18n.combineTranslation(local.code as any, local.translation)
})
module.i18n().forEach((local) => {
I18n.combineTranslation(local.code as any, local.translation);
});
if (this._window) {
module.commands().forEach(command => {
this._window!.registerRibbonCommand(
command.tabName,
command.groupName,
command.command
);
})
module.commands().forEach((command) => {
this._window!.registerRibbonCommand(command.tabName, command.groupName, command.command);
});
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions packages/chili-core/src/application.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import { IShapeFactory } from "chili-geo";
import { IVisualFactory } from "chili-vis";
import { ICommand } from "./command";
import { IDocument } from "./document";
import { IStorage, ObservableCollection } from "./foundation";
import { IShapeFactory } from "./geometry";
import { Serialized } from "./serialize";
import { IService } from "./service";
import { IWindow } from "./ui/window";
import { IView } from "./visual";
import { IView, IVisualFactory } from "./visual";

export interface IApplication {
readonly mainWindow?: IWindow;
Expand Down
10 changes: 5 additions & 5 deletions packages/chili-core/src/command/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ export namespace ICommand {
export abstract class CancelableCommand extends Observable implements ICanclableCommand {
private static readonly _propertiesCache: Map<string, any> = new Map(); // 所有命令共享

private _complete: boolean = false;
get complete() {
return this._complete;
private _isCompleted: boolean = false;
get isCompleted() {
return this._isCompleted;
}

private _application: IApplication | undefined;
Expand Down Expand Up @@ -53,7 +53,7 @@ export abstract class CancelableCommand extends Observable implements ICanclable
this.controller?.cancel();
await new Promise(async (resolve) => {
while (true) {
if (this._complete) {
if (this._isCompleted) {
break;
}
await new Promise((r) => setTimeout(r, 50));
Expand Down Expand Up @@ -87,7 +87,7 @@ export abstract class CancelableCommand extends Observable implements ICanclable
this.saveProperties();
PubSub.default.pub("closeCommandContext");
this.controller?.dispose();
this._complete = true;
this._isCompleted = true;
return Promise.resolve();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import { IConverter, IDisposable, IPropertyChanged } from "chili-core";
import { IConverter } from "./converter";
import { IPropertyChanged } from "./observer";

const registry = new FinalizationRegistry((binding: Binding) => {
binding.removeBinding();
});

export class Binding<T extends IPropertyChanged = any> implements IDisposable {
private _targets?: [element: WeakRef<object>, property: any];
export class Binding<T extends IPropertyChanged = any> {
private _target?: {
element: WeakRef<object>;
property: PropertyKey;
};

constructor(
readonly source: T,
Expand All @@ -16,25 +20,32 @@ export class Binding<T extends IPropertyChanged = any> implements IDisposable {
) {}

setBinding<U extends object>(element: U, property: keyof U) {
if (this._targets) {
if (this._target) {
throw new Error("Binding already set");
}
this._targets = [new WeakRef(element), property];
this._target = {
element: new WeakRef(element),
property,
};
this.setValue<U>(element, property);
this.source.onPropertyChanged(this._onPropertyChanged);
registry.register(element, this);
}

removeBinding() {
this._targets = undefined;
let element = this._target?.element.deref();
if (element) {
registry.unregister(element);
}
this._target = undefined;
this.source.removePropertyChanged(this._onPropertyChanged);
}

private _onPropertyChanged = (property: keyof T) => {
if (property === this.path && this._targets) {
let element = this._targets[0].deref();
if (property === this.path && this._target) {
let element = this._target.element.deref();
if (element) {
this.setValue(element, this._targets[1]);
this.setValue(element, this._target.property);
}
}
};
Expand All @@ -48,16 +59,11 @@ export class Binding<T extends IPropertyChanged = any> implements IDisposable {
let value: any = this.source[this.path];
if (this.converter) {
let result = this.converter.convert(value);
if (!result.success) {
if (!result.isOk) {
throw new Error(`Cannot convert value ${value}`);
}
value = result.getValue();
value = result.value;
}
return value;
}

dispose(): void {
this.source.removePropertyChanged(this._onPropertyChanged);
this._targets = undefined;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import { Result } from "../foundation";
import { Result } from "./result";

export interface IConverter<TFrom = any, TTo = string> {
convert(value: TFrom): Result<TTo>;
Expand Down
2 changes: 2 additions & 0 deletions packages/chili-core/src/foundation/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

export * from "./asyncController";
export * from "./binding";
export * from "./collection";
export * from "./converter";
export * from "./disposable";
export * from "./dto";
export * from "./equalityComparer";
Expand Down
1 change: 1 addition & 0 deletions packages/chili-core/src/foundation/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export abstract class HistoryObservable extends Observable {
onPropertyChanged?.(property, oldValue);
Transaction.add(
this.document,
this.document.history,
new PropertyHistoryRecord(this, property, oldValue, newValue),
);
},
Expand Down
23 changes: 9 additions & 14 deletions packages/chili-core/src/foundation/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,37 @@

export type Result<T, E = string> = {
unwrap(): T;
getValue(): T | undefined;
expect(msg: string): T;
} & (
| {
readonly success: true;
readonly status: "success";
readonly isOk: true;
readonly value: T;
}
| {
readonly success: false;
readonly status: "error";
readonly isOk: false;
readonly value: undefined;
readonly error: E;
}
);

export namespace Result {
export function success<T>(value: T): Result<T, never> {
export function ok<T>(value: T): Result<T, never> {
return {
status: "success",
value,
unwrap: () => value,
success: true,
getValue: () => value,
expect: (msg: string) => value,
isOk: true,
expect: (_msg: string) => value,
};
}

export function error<E>(error: E): Result<never, E> {
export function err<E>(error: E): Result<never, E> {
return {
status: "error",
error,
unwrap: () => {
throw error;
},
success: false,
getValue: () => undefined,
isOk: false,
value: undefined,
expect: (msg: string) => {
throw new Error(msg);
},
Expand Down
35 changes: 18 additions & 17 deletions packages/chili-core/src/foundation/transaction.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import { IDocument } from "../document";
import { ArrayRecord, IHistoryRecord } from "./history";
import { ArrayRecord, History, IHistoryRecord } from "./history";
import { Logger } from "./logger";

export class Transaction {
private static readonly _transactionMap: WeakMap<IDocument, ArrayRecord> = new WeakMap();
private static readonly _transactionMap: WeakMap<object | symbol, ArrayRecord> = new WeakMap();

constructor(
readonly document: IDocument,
readonly token: object | symbol,
readonly history: History,
readonly name: string,
) {}

static add(document: IDocument, record: IHistoryRecord) {
if (document.history.disabled) return;
let arrayRecord = Transaction._transactionMap.get(document);
static add(token: object | symbol, history: History, record: IHistoryRecord) {
if (history.disabled) return;
let arrayRecord = Transaction._transactionMap.get(token);
if (arrayRecord !== undefined) {
arrayRecord.records.push(record);
} else {
Transaction.addToHistory(document, record);
Transaction.addToHistory(history, record);
}
}

static addToHistory(document: IDocument, record: IHistoryRecord) {
document.history.add(record);
static addToHistory(history: History, record: IHistoryRecord) {
history.add(record);
Logger.info(`history added ${record.name}`);
}

static excute(document: IDocument, name: string, action: () => void) {
let trans = new Transaction(document, name);
let trans = new Transaction(document, document.history, name);
trans.start();
try {
action();
Expand All @@ -41,23 +42,23 @@ export class Transaction {

start(name?: string) {
let transactionName = name ?? this.name;
if (Transaction._transactionMap.get(this.document) !== undefined) {
if (Transaction._transactionMap.get(this.token) !== undefined) {
throw new Error(`The document has started a transaction ${this.name}`);
}
Transaction._transactionMap.set(this.document, new ArrayRecord(transactionName));
Transaction._transactionMap.set(this.token, new ArrayRecord(transactionName));
}

commit() {
let arrayRecord = Transaction._transactionMap.get(this.document);
let arrayRecord = Transaction._transactionMap.get(this.token);
if (arrayRecord === undefined) {
throw new Error("Transaction has not started");
}
if (arrayRecord.records.length > 0) Transaction.addToHistory(this.document, arrayRecord);
Transaction._transactionMap.delete(this.document);
if (arrayRecord.records.length > 0) Transaction.addToHistory(this.history, arrayRecord);
Transaction._transactionMap.delete(this.token);
}

rollback() {
Transaction._transactionMap.get(this.document)?.undo();
Transaction._transactionMap.delete(this.document);
Transaction._transactionMap.get(this.token)?.undo();
Transaction._transactionMap.delete(this.token);
}
}
14 changes: 7 additions & 7 deletions packages/chili-core/src/foundation/utils/readFileAsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export async function readFileAsync(
};
input.oncancel = () => {
document.body.removeChild(input);
resolve(Result.error(`cancel`));
resolve(Result.err(`cancel`));
};
document.body.appendChild(input);
input.click();
Expand All @@ -39,33 +39,33 @@ async function resolveFiles(
reader: "readAsText" | "readAsDataURL",
) {
if (!input.files) {
resolve(Result.error(`no files`));
resolve(Result.err(`no files`));
return;
}
for (let i = 0; i < input.files.length; i++) {
let file = input.files.item(i);
if (!file) continue;
let data = await asyncFileReader(file, reader);
if (data.success) {
if (data.isOk) {
result.push({
fileName: file.name,
data: data.value,
});
} else {
resolve(Result.error(data.error));
resolve(Result.err(data.error));
}
}
resolve(Result.success(result));
resolve(Result.ok(result));
}

function asyncFileReader(file: File, method: any): Promise<Result<string>> {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = (e) => {
resolve(Result.success(e.target!.result as string));
resolve(Result.ok(e.target!.result as string));
};
reader.onerror = (e) => {
resolve(Result.error(`Error occurred reading file: ${file.name}`));
resolve(Result.err(`Error occurred reading file: ${file.name}`));
};
(reader as any)[method](file);
});
Expand Down
1 change: 1 addition & 0 deletions packages/chili-core/src/geometry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export * from "./lineType";
export * from "./meshData";
export * from "./shape";
export * from "./shapeConverter";
export * from "./shapeFactory";
export * from "./shapeType";
Loading

0 comments on commit cfb03f8

Please sign in to comment.