Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
pearone committed Feb 27, 2024
1 parent 5a9fc93 commit aeb5608
Show file tree
Hide file tree
Showing 14 changed files with 476 additions and 135 deletions.
3 changes: 3 additions & 0 deletions packages/event/indexedDB.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/**
* 一个indexdb的增删改查
*/
2 changes: 1 addition & 1 deletion packages/event/src/color/computed.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { formatFloatNumber } from '../utils';
import { formatFloatNumber } from '../event';
import { clamp, sortColors } from './base';
import { toHsl } from './tohsl';
import { RGBFormatType, RGB, toRgb, toRgbaByCanvas } from './torgba';
Expand Down
2 changes: 1 addition & 1 deletion packages/event/src/color/tohsl.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { formatFloatNumber } from '../utils';
import { formatFloatNumber } from '../event';
import { RGBA, RGBFormatType, toRgba } from './torgba';

export interface HSLA {
Expand Down
2 changes: 1 addition & 1 deletion packages/event/src/color/torgba.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { formatFloatNumber } from '../utils';
import { formatFloatNumber } from '../event';
import { isRgb } from './base';
import { toHex } from './tohex';

Expand Down
3 changes: 0 additions & 3 deletions packages/event/src/community/message.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Task, MessageQueue } from './priority_queue';
/**
* 单向通信
* 有接收方和发送方的概念
Expand Down Expand Up @@ -62,5 +61,3 @@ export class ChannelFormatterMessage {
this.data = data;
}
}

export { Task, MessageQueue };
175 changes: 121 additions & 54 deletions packages/event/src/community/priority_queue.ts
Original file line number Diff line number Diff line change
@@ -1,71 +1,138 @@
/**
* 一个队列执行器:
* 任务可以支持有优先级的任务,
* 批量执行,清空任务列表
* 生产者、消费者、优先级队列
* 生产者生产到优先级任务,任务指定消费者消费
*/
import { genAutoIdString } from '..';
type Task = {
id: number;
priority: number;
consumerId: number;
};

/** 任务信息 */
export class Task<T> {
message: T;
class ProducerManager {
private producers: Map<number, Producer>;

constructor(message: T) {
this.message = message;
constructor() {
this.producers = new Map();
}

registerProducer(producerId: number) {
const producer = new Producer(producerId);
this.producers.set(producerId, producer);
return producer;
}

getProducer(producerId: number) {
return this.producers.get(producerId) || null;
}
}

/** 任务优先级队列 */
export class MessageQueue<T> {
/** 任务队列 */
queue: Map<string, Task<T>> = new Map();
/** 执行器 */
executor: (token: string, task: Task<T>) => void;
/** 是否是优先级队列 */
is_priority_queue: boolean = false;

constructor({
executor,
is_priority_queue
}: {
executor: (task: Task<T>) => void;
is_priority_queue?: boolean;
}) {
this.is_priority_queue = is_priority_queue ?? false;
this.queue = new Map();
this.executor = (token: string, task: Task<T>) => {
executor(task);
this.delete(token);
};
class ConsumerManager {
private consumers: Map<number, Consumer>;

constructor() {
this.consumers = new Map();
}

registerConsumer(consumerId: number) {
const consumer = new Consumer(consumerId);
this.consumers.set(consumerId, consumer);
return consumer;
}

getConsumer(consumerId: number) {
return this.consumers.get(consumerId) || null;
}
}

class PriorityQueue {
private tasks: Task[];

constructor() {
this.tasks = [];
}

enqueue(task: Task) {
this.tasks.push(task);
this.tasks.sort((a, b) => b.priority - a.priority);
}

dequeue() {
return this.tasks.shift() || null;
}

/** 添加任务 */
add(task: Task<T>) {
const token = genAutoIdString();
this.queue.set(token, task);
return token;
isEmpty() {
return this.tasks.length === 0;
}
}

class Producer {
private producerId: number;
private queue: PriorityQueue;

/** 删除任务 */
delete(token: string) {
this.queue.delete(token);
constructor(producerId: number) {
this.producerId = producerId;
this.queue = new PriorityQueue();
}

/** 运行任务 */
run() {
let sort_queue = this.is_priority_queue
? Array.from(this.queue.keys()).sort((a_token, b_token) => {
const a = this.queue.get(a_token)!;
const b = this.queue.get(b_token)!;
const a_priority = (a.message as any)?.priority ?? 0;
const b_priority = (b.message as any)?.priority ?? 0;
return a_priority > b_priority ? -1 : 1;
})
: Array.from(this.queue.keys());
produceTask(priority: number, consumerId: number) {
const task: Task = {
id: Date.now(),
priority,
consumerId
};

this.queue.enqueue(task);
}

let token = sort_queue.shift();
while (token) {
this.executor(token, this.queue.get(token)!);
token = sort_queue.shift();
consumeTask() {
if (!this.queue.isEmpty()) {
return this.queue.dequeue();
}

return null;
}
}

class Consumer {
private consumerId: number;

constructor(consumerId: number) {
this.consumerId = consumerId;
}

consumeTask(task: Task) {
console.log(`Consumer ${this.consumerId} is consuming task:`, task);
// 执行任务的消费逻辑
}
}

// 示例用法
const producerManager = new ProducerManager();
const consumerManager = new ConsumerManager();

const producer1 = producerManager.registerProducer(1);
const producer2 = producerManager.registerProducer(2);

const consumer1 = consumerManager.registerConsumer(1);
const consumer2 = consumerManager.registerConsumer(2);

producer1.produceTask(2, consumer1.consumerId);
producer2.produceTask(1, consumer2.consumerId);
producer1.produceTask(3, consumer2.consumerId);
producer2.produceTask(1, consumer1.consumerId);

let task = producer1.consumeTask();
if (task) {
const consumer = consumerManager.getConsumer(task.consumerId);
if (consumer) {
consumer.consumeTask(task);
}
}

task = producer2.consumeTask();
if (task) {
const consumer = consumerManager.getConsumer(task.consumerId);
if (consumer) {
consumer.consumeTask(task);
}
}
146 changes: 146 additions & 0 deletions packages/event/src/data/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/** 数值类型 */
export function isNumber(num: any) {
return !isNaN(Number(num));
}

/** 格式化十进制四舍五入保留小数位 */
export function formatFloatNumber(num: number, precision: number) {
return Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision);
}

/* 格式化数值为固定小数位数
>>> toFixedNumber(0.4517, 1)
0.5
*/
export function toFixedNumber(num: number, fraction: number): number {
return Number(Number(num).toFixed(fraction));
}

/* 格式化数值为百分比,支持设定小数位数
>>> formatNumberToPercent(0.4517, 1)
45.2%
*/
export function formatNumberToPercentString(
data: number | '' | '0' | 'null' | '-' | '(NULL)',
fraction?: number
): string {
if (!isNumber(data) || data === '') {
return data as string;
}
data = (data as number) * 100;

// 小数位数
if (fraction != null) {
data = data = toFixedNumber(data, fraction!);
}

return data + '%';
}

/**
* 千分位
* @param num 数值
* @returns
*/
export function getThousandthSeparatedNumber(num: any) {
if (!isNumber(num)) {
return num;
}
const sep = function (str: string) {
return (str + '').replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,');
};
num = num + '';
num = num.split('.');
const num_0 = sep(num[0]);
if (num.length === 1) {
return num_0;
}
return num_0 + '.' + num[1];
}

/** 单位 */
export enum Unit {
'无' = '无',
'K' = 'K',
'千' = '千',
'万' = '万',
'亿' = '亿',
'兆' = '兆',
'M' = 'M',
'百万' = '百万',
'B' = 'B'
}
/**
* 格式化单位
* @param num 数值
* @param unit_value 单位
* @param fraction 小数位数
* @returns
*/
export function formatNumberUnit(
num: number,
unit_value: Unit,
fraction?: number
) {
switch (unit_value) {
case '无':
break;

case 'K':
case '千':
num = num / 1000;
break;

case '万':
num = num / 10000;
break;

case 'M':
case '百万':
num = num / 100_0000;
break;

case '亿':
num = num / 1_0000_0000;
break;

case 'B':
num = num / 10_0000_0000;
break;
}

if (fraction != null) {
num = toFixedNumber(num, fraction!);
}

return num;
}

// 将数字转的为人眼好识别的文字
export function readableNumbers(num: number, base = 1000): string {
if (isNaN(num * 1)) {
return num.toString();
}

const neg = num < 0;
const units = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];

if (neg) {
num = -num;
}

if (num < 1) {
return (neg ? '-' : '') + num;
}

const exponent = Math.min(
Math.floor(Math.log(num) / Math.log(base)),
units.length - 1
);

num = Number((num / Math.pow(base, exponent)).toFixed(2));

const unit = units[exponent];

return (neg ? '-' : '') + num + unit;
}
Loading

0 comments on commit aeb5608

Please sign in to comment.