123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- //#region ******************************** 类型声明 ********************************
- export type Callback<T = any> = (err: Error | null, data: T) => void;
- export type Constructor<T = unknown> = new (...args: any[]) => T;
- export type ObjectKeyAsValue<T> = { readonly [K in keyof T]: K; }
- export type KeyArrayAsValue<T extends string> = { readonly [V in T]: V; }
- //#endregion
- /**
- * 销毁接口
- */
- export interface IDispose {
- Dispose(): void;
- }
- /** 自动销毁附着对象 */
- export interface IDisposeAttachTarget {
- AutoDispose(toDispose: IDispose): void;
- }
- //#region ******************************** 辅助函数 ********************************
- export function CreateObjectKeyAsValueMap<T extends Object>(obj: T): ObjectKeyAsValue<T> {
- let keys = Object.keys(obj);
- let ret: ObjectKeyAsValue<T> = Object.create(null);
- keys.forEach(key => {
- ret[key] = key;
- })
- keys = undefined;
- return ret;
- }
- export function CreateIntEnum<T extends string>(states: Array<T>, stateVal: number = 1): { [V in T]: number } {
- let ret = Object.create(null);
- states.forEach(state => {
- ret[state] = stateVal;
- stateVal = stateVal + 1;
- })
- return ret;
- }
- export function MaxValueOf<T extends string>(intEnum: { [k: string]: number }) {
- let init = false;
- let maxVal = 0;
- for (let k in intEnum) {
- if (!init) {
- maxVal = intEnum[k];
- } else {
- maxVal = (intEnum[k] > maxVal) ? intEnum[k] : maxVal;
- }
- }
- return maxVal;
- }
- export function onceCall(cb: () => void, cnt: number = 1) {
- return () => {
- if (cnt <= 0) {
- return;
- };
- --cnt;
- if (cnt === 0) {
- cb()
- }
- };
- }
- export function onceArgCall<T>(cb: (p: T) => void, cnt: number) {
- return (p: T) => {
- if (cnt <= 0) {
- return;
- };
- --cnt;
- if (cnt === 0) {
- cb(p)
- }
- }
- }
- //#endregion
- /**
- * 尾插入排序(从小到大)
- * @param list
- * @param compare
- * @returns
- */
- export function insertionSort<T>(list: T[], compare: (a: T, b: T) => number) {
- for (let length = list.length, i = 1; i < length; i++) {
- let j, value: T = list[i]
- for (j = i - 1; j >= 0; j--) {
- if (compare(list[j], value) <= 0) break
- list[j + 1] = list[j]
- }
- list[j + 1] = value
- }
- return list
- }
- /**
- * 已排好序(从小到大)的数组,获得 value 应该排在哪个位置(有相同值的情况下,排最左边)
- * @param list
- * @param value
- * @param compare
- * @returns
- */
- export function sortedIndex<T, V>(list: T[], value: V, compare: (a: T, b: V) => number): number {
- let low = 0, high = list.length
- while (low < high) {
- let mid = (low + high) >>> 1
- if (compare(list[mid], value) < 0) low = mid + 1
- else high = mid
- }
- return low
- }
- /**
- * 已排好序(从小到大)的数组,获得 value 应该排在哪个位置(有相同值的情况下,排最右边)
- * @param list
- * @param value
- * @param compare
- * @returns
- */
- export function sortedLastIndex<T>(list: T[], value: T, compare: (a: T, b: T) => number): number {
- let low = 0, high = list.length
- while (low < high) {
- let mid = (low + high) >>> 1
- if (compare(list[mid], value) <= 0) low = mid + 1
- else high = mid
- }
- return high
- }
- /**
- * 快速删除数组元素(不保证删除后的顺序)
- * @param arr
- * @param idx
- */
- export function fastRemoveIndex(arr: any[], idx: number) {
- if (idx >= 0 && idx < arr.length) {
- arr[idx] = arr[arr.length - 1];
- arr.length--;
- }
- }
- /**
- * 拷贝内容到剪切板
- * @param copyStr 内容
- */
- export function copyToClipboardForWeb(copyStr: string, callback: (err?: Error) => void): void {
- const el = document.createElement('textarea');
- el.value = copyStr;
- // Prevent keyboard from showing on mobile
- el.setAttribute('readonly', '');
- //el.style.contain = 'strict';
- el.style.position = 'absolute';
- el.style.left = '-9999px';
- el.style.fontSize = '12pt'; // Prevent zooming on iOS
- const selection = getSelection()!;
- let originalRange;
- if (selection.rangeCount > 0) {
- originalRange = selection.getRangeAt(0);
- }
- document.body.appendChild(el);
- el.select();
- // Explicit selection workaround for iOS
- el.selectionStart = 0;
- el.selectionEnd = copyStr.length;
- let isSuccess = false;
- try {
- isSuccess = document.execCommand('copy');
- } catch (err) {
- isSuccess = false;
- } finally {
- document.body.removeChild(el);
- if (originalRange) {
- selection.removeAllRanges();
- selection.addRange(originalRange);
- }
- }
- /** 返回结果 */
- if (isSuccess) {
- callback();
- } else {
- callback(new Error("执行剪切板拷贝命令出错"))
- }
- }
|