This commit is contained in:
YipLee
2021-01-19 22:30:12 +08:00
commit c4f716c8e9
165 changed files with 61216 additions and 0 deletions

View File

@@ -0,0 +1,242 @@
/**
* 事件名
*/
export enum EventName {
/** 调节节点大小 */
RESIZE,
/** 删除参数 */
PARAM_DELETE,
/** 参数名更改 */
PARAM_NAME_CHANGED,
/** 选中ParamItem */
PARAM_SELECT,
/** 设置状态机视图的显示 */
SET_CUR_STATE_MACHINE,
/** 状态名更改 */
STATE_NAME_CHANGED,
/** AnyState改变坐标 */
ANY_STATE_MOVE,
/** 状态机名更改 */
STATE_MACHINE_NAME_CHANGED,
/** 父状态机节点改变坐标 */
UP_STATE_MACHINE_MOVE,
/** 选择连线连向子状态机内部的状态 */
LINE_TO_MACHINE_STATE,
/** 删除line */
LINE_DELETE,
/** 新增transition */
TRANSITION_ADD,
/** 删除transition */
TRANSITION_DELETE,
/** 点击按钮选中TransitionItem */
TRANSITION_SELECT,
/** 点击按钮选中ConditionItem */
CONDITION_SELECT,
/** 选中multiplier参数 */
MULTIPLIER_SELECT,
/** 隐藏inspector显示的内容 */
INSPECTOR_HIDE,
/** 显示unit信息 */
INSPECTOR_SHOW_UNIT,
/** 显示line信息 */
INSPECTOR_SHOW_LINE,
/** 关闭菜单层 */
CLOSE_MENU,
/** 显示状态机界面右键菜单 */
SHOW_RIGHT_MENU,
/** 显示连线目标状态机内部所有状态选择界面 */
SHOW_LINE_TO_List,
/** 显示添加参数时选择界面 */
SHOW_PARAM_ADD,
/** 显示condition的参数选择界面 */
SHOW_PARAM_SELECT,
/** 显示condition的logic选项 */
SHOW_LOGIC,
/** 显示multiplier选择界面 */
SHOW_MULTIPLIER,
};
/**
* 非静态成员函数装饰器用于预先载入待注册的事件配合targetOn使用
* @param event 事件名
*/
export function preloadEvent(event: EventName) {
return function (target: any, funcName: string, desc: PropertyDescriptor) {
let arr = Events.classMap.get(target.constructor);
if (arr === undefined) {
arr = [];
Events.classMap.set(target.constructor, arr);
} else {
let find = arr.find((e) => {
return e.event === event && e.funcName === funcName;
});
if (find) {
cc.error(`event: ${EventName[event]} 重复载入`);
return;
}
}
arr.push({
event: event,
funcName: funcName
});
};
}
/**
* 监听函数类型
*/
type Listener = (arg: any) => void;
/**
* 事件收发管理类
*/
export default class Events {
/**
* 存储监听事件、监听函数与监听对象
*/
private static _eventsMap: Map<EventName, Map<Object, Listener[]>> = new Map();
/**
* 存储构造函数、监听事件、监听函数名,用于实例化时注册事件
*/
public static classMap: Map<Function, Array<{ event: EventName, funcName: string }>> = new Map();
/**
* 注册与target构造函数预先绑定的所有事件
* @param target 注册目标
* @param onSuper 是否注册父类成员函数上绑定的事件
*/
public static targetOn(target: Object, onSuper: boolean = true) {
if (onSuper) {
this.classMap.forEach((value: Array<{ event: EventName, funcName: string }>, key: Function) => {
if (target instanceof key) {
value.forEach((e) => {
this.on(e.event, target[e.funcName], target);
});
}
});
} else {
let arr = this.classMap.get(target.constructor);
if (arr) {
arr.forEach((e) => {
this.on(e.event, target[e.funcName], target);
});
}
}
}
/**
* 注册事件
* @param event 事件名
* @param listener 处理事件的监听函数
* @param target 注册目标
*/
public static on(event: EventName, listener: Listener, target: Object) {
if (!listener || !target) {
cc.error(`event: ${EventName[event]} listener或target不能为空`);
return;
}
let map: Map<Object, Listener[]> = this._eventsMap.get(event);
let list: Listener[] = [];
if (map === undefined) {
map = new Map();
map.set(target, list);
this._eventsMap.set(event, map);
} else {
list = map.get(target);
if (list === undefined) {
list = [];
map.set(target, list);
} else {
let result = list.find((e) => { return e === listener });
if (result) {
cc.error(`event: ${EventName[event]} 重复注册`);
return;
}
}
}
list.push(listener);
}
/**
* 移除事件
* @param event 事件名
* @param listener 处理事件的监听函数
* @param target 注册目标
*/
public static off(event: EventName, listener: Listener, target: Object) {
if (!listener || !target) {
cc.error(`event: ${EventName[event]} listener或target不能为空`);
return;
}
let map: Map<Object, Listener[]> = this._eventsMap.get(event);
if (map === undefined) {
cc.error(`event: ${EventName[event]} 未注册该事件`);
return;
}
let list: Listener[] = map.get(target);
if (list === undefined) {
cc.error(`event: ${EventName[event]} target上未注册该事件`);
return;
}
let index = list.findIndex((e) => { return e === listener; });
if (index < 0) {
cc.error(`event: ${EventName[event]} target上未以该listener注册该事件`);
return;
}
list.splice(index, 1);
if (list.length <= 0) {
map.delete(target);
map.size <= 0 && this._eventsMap.delete(event);
}
}
/**
* 移除target上注册的所有事件
* @param target 注册目标
*/
public static targetOff(target: Object) {
if (!target) {
cc.error(`event: ${target} target不能为空`);
return;
}
this._eventsMap.forEach((map, event) => {
map.delete(target);
map.size <= 0 && this._eventsMap.delete(event);
});
}
/**
* 派发事件
* @param event 事件名
* @param args 事件参数
*/
public static emit(event: EventName, ...args: any[]) {
let map: Map<Object, Listener[]> = this._eventsMap.get(event);
if (map === undefined) {
cc.warn(`event: ${EventName[event]} 未注册该事件`);
return;
}
map.forEach((list, target) => {
list.forEach((listener) => {
listener.call(target, ...args);
});
});
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "1.0.5",
"uuid": "438a264f-5181-4f14-8330-5b700ab8eac7",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,110 @@
/**
* 用于使用节点池的节点所绑定脚本组件实现
*/
export interface RecycleNode {
/**
* 回收前调用
*/
unuse(): void;
/**
* 取出前调用
*/
reuse(): void;
}
/**
* 节点池
*/
export default class RecyclePool {
private static _poolMap: Map<{ prototype: cc.Component }, cc.Node[]> = new Map();
/**
* 根据类型判断节点池中节点数量
*/
public static size(type: { prototype: cc.Component }): number {
let list = this._poolMap.get(type);
if (list === undefined) {
return 0;
}
return list.length;
}
/**
* 根据类型清空节点
*/
public static clear(type: { prototype: cc.Component }) {
let list = this._poolMap.get(type);
if (list === undefined) {
return;
}
let count = list.length;
for (let i = 0; i < count; ++i) {
list[i].destroy();
}
list.length = 0;
this._poolMap.delete(type);
}
/**
* 清空全部节点
*/
public static clearAll() {
this._poolMap.forEach((list: cc.Node[]) => {
list.forEach((node: cc.Node) => {
node.destroy();
});
});
this._poolMap.clear();
}
/**
* 根据类型从节点池取出节点
*/
public static get(type: { prototype: cc.Component }): cc.Node {
let list = this._poolMap.get(type);
if (list === undefined || list.length <= 0) {
return null;
}
let last = list.length - 1;
let node = list[last];
list.length = last;
// Invoke pool handler
let handler: any = node.getComponent(type);
if (handler && handler.reuse) {
handler.reuse();
}
return node;
}
/**
* 根据类型将节点放入节点池
*/
public static put(type: { prototype: cc.Component }, node: cc.Node) {
if (!node) {
cc.error(`[RecyclePool.put] error: 传入节点为空`);
return;
}
let list = this._poolMap.get(type);
if (list === undefined) {
list = [];
this._poolMap.set(type, list);
} else if (list.indexOf(node) !== -1) {
cc.error(`[RecyclePool.put] error: 不可将节点重复放入节点池中`);
return;
}
node.removeFromParent(false);
// Invoke pool handler
let handler: any = node.getComponent(type);
if (handler && handler.unuse) {
handler.unuse();
}
list.push(node);
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "1.0.5",
"uuid": "2650e9f4-6f08-4845-bf8b-31afece7a66b",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,68 @@
/**
* 资源管理类
*/
export default class Res {
/**
* 资源缓存
*/
private static _cacheMap: Map<string, cc.Asset> = new Map();
/**
* 获取已经预加载的资源。!!!调用前需确保资源已预加载
* @param url 资源路径
*/
public static getLoaded(url: string): any {
let asset = this._cacheMap.get(url);
if (asset === undefined) {
cc.error(`[Res.getLoaded] error: 资源未加载`);
return null;
}
return asset;
}
/**
* 加载resources文件夹下单个资源
* @param url 资源路径
* @param type 资源类型
*/
public static async load(url: string, type: typeof cc.Asset): Promise<any> {
let asset = this._cacheMap.get(url);
if (asset) {
return asset;
}
return await new Promise((resolve, reject) => {
cc.loader.loadRes(url, type, (error: Error, resource: cc.Asset) => {
if (error) {
cc.error(`[Res.load] error: ${error}`);
resolve(null);
} else {
this._cacheMap.set(url, resource);
resolve(resource);
}
});
});
}
/**
* 加载resources文件夹下某个文件夹内全部资源
* @param url 资源路径
* @param type 资源类型
*/
public static async loadDir(url: string, type: typeof cc.Asset): Promise<any[]> {
return await new Promise((resolve, reject) => {
cc.loader.loadResDir(url, type, (error: Error, resource: any[], urls: string[]) => {
if (error) {
cc.error(`[Res.loadDir] error: ${error}`);
resolve([]);
} else {
urls.forEach((v: string, i: number) => {
this._cacheMap.set(v, resource[i]);
});
resolve(resource);
}
});
});
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "1.0.5",
"uuid": "1d8423c7-71dd-417b-8df3-8b9c83e1496b",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,108 @@
/**
* 工具类
*/
export default class Tool {
/**
* 随机返回数组中的某个元素
* @param arr
*/
public static randArray<T>(arr: Array<T>): T {
if (arr.length <= 0) {
return null;
}
return arr[this.randInt(0, arr.length - 1)];
}
/**
* 获取 [min, max] 区间的随机整数
* @param min
* @param max
*/
public static randInt(min: number, max: number) {
min = Math.ceil(min);
max = Math.floor(max);
if (min >= max) {
return max;
}
return Math.floor(Math.random() * (max - min + 1)) + min;
}
/**
* 获取 [min, max) 区间的随机浮点数
* @param min
* @param max
*/
public static randFloat(min: number, max: number) {
if (min >= max) {
return max;
}
return Math.random() * (max - min) + min;
}
/**
* 返回value是否在 [min, max] 区间内
* @param min
* @param max
* @param value
* @param includeEdge 是否包含边界值min和max默认包含
*/
public static inRange(min: number, max: number, value: number, includeEdge: boolean = true) {
return includeEdge ? value >= min && value <= max : value > min && value < max;
}
/**
* 判断数组中是否有某个元素
*/
public static arrayHas<T>(arr: T[], ele: T): boolean {
let idx = arr.findIndex((e) => { return e === ele; });
return idx >= 0;
}
/**
* 根据下标交换数组两个元素位置
*/
public static arraySwap<T>(arr: T[], idx1: number, idx2: number) {
if (idx1 === idx2 || !this.inRange(0, arr.length - 1, idx1) || !this.inRange(0, arr.length - 1, idx2)) {
return;
}
[arr[idx1], arr[idx2]] = [arr[idx2], arr[idx1]];
}
/**
* 将元素从fromIdx位置移到toIdx位置其余元素相对位置不变
*/
public static arrayMove<T>(arr: T[], fromIdx: number, toIdx: number) {
if (fromIdx === toIdx || !this.inRange(0, arr.length - 1, fromIdx) || !this.inRange(0, arr.length - 1, toIdx)) {
return;
}
let from: T[] = arr.splice(fromIdx, 1);
arr.splice(toIdx, 0, from[0]);
}
/**
* 添加元素
* @param canRepeat 是否可重复添加相同元素 默认false
* @returns 是否确实执行了添加操作
*/
public static arrayAdd<T>(arr: T[], ele: T, canRepeat: boolean = false): boolean {
if (!canRepeat && this.arrayHas(arr, ele)) {
return false;
}
arr.push(ele);
return true;
}
/**
* 删除元素
* @returns 是否确实执行了删除操作
*/
public static arrayDelete<T>(arr: T[], ele: T): boolean {
let idx = arr.findIndex((e) => { return e === ele; });
if (idx === -1) {
return false;
}
arr.splice(idx, 1);
return true
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "1.0.5",
"uuid": "8a83b733-dd4e-4b3d-aa1e-121f58ba4f88",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}