UNPKG

mm_os

Version:

MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。

275 lines (249 loc) 6.73 kB
/** * 实体类 * 纯粹的实体标识符,不包含任何业务逻辑 * 只负责管理组件引用和实体生命周期 */ const { idGen } = require('../../ulits/id_gen.js'); class Entity { #is_dirty = false; /** * 构造函数 * @param {string} entity_id 实体ID * @param {string} player_id 玩家ID * @param {string} type 实体类型, 例如:玩家player、怪物monster、道具prop等 */ constructor(entity_id, player_id, type) { // 实体名称 this.name = ''; // 实体ID this.entity_id = entity_id || this.genId(); // 实体类型 this.type = type || ''; // 玩家ID - 如果是玩家就有此ID this.player_id = player_id || ''; // 是否活跃 this.is_active = true; // 实体组件 this._component = new Map(); // 创建属性代理 this._createProperty(); } /** * 检查实体是否脏数据 * @param {boolean} is_dirty 是否脏数据 * @returns {boolean} 是否脏数据 */ isDirty(is_dirty) { if (is_dirty !== undefined) { this.#is_dirty = is_dirty; } return this.#is_dirty; }; } /** * 创建属性代理 * 使组件属性可以通过点语法直接访问 * 例如:entity.attr.hp 可以访问 attr 组件中的 hp 属性 */ Entity.prototype._createProperty = function () { var self = this; // 为每个已存在的组件创建属性访问器 var keys = Array.from(self._component.keys()); for (var i = 0; i < keys.length; i++) { (function (name) { Object.defineProperty(self, name, { get: function () { return self._component.get(name); }, set: function (value) { if (typeof value === 'object' && value !== null) { self._component.set(name, value); // 标记为脏数据 self.isDirty(true); } }, enumerable: true, configurable: true }); })(keys[i]); } // 重写 addComponent 方法,使其在添加组件时自动创建属性访问器 let comp = self.addComponent; self.addComponent = function (name, component) { // 调用原始方法 comp.call(self, name, component); // 创建属性访问器 Object.defineProperty(self, name, { get: function () { return self._component.get(name); }, set: function (value) { if (typeof value === 'object' && value !== null) { self._component.set(name, value); // 标记为脏数据 self.isDirty(true); } }, enumerable: true, configurable: true }); }; }; /** * 获取实体ID * @returns {string} 实体ID */ Entity.prototype.getId = function () { return this.entity_id; }; /** * 检查实体是否活跃 * @returns {boolean} 是否活跃 */ Entity.prototype.isActive = function () { return this.is_active; }; /** * 激活实体 */ Entity.prototype.activate = function () { this.is_active = true; }; /** * 停用实体 */ Entity.prototype.deactivate = function () { this.is_active = false; }; /** * 添加组件 * @param {string} name 组件类型 * @param {object} component 组件数据 */ Entity.prototype.addComponent = function (name, component) { // 参数校验 if (typeof name !== 'string') { throw new TypeError('组件类型必须是字符串'); } if (typeof component !== 'object') { throw new TypeError('组件数据必须是对象'); } this._component.set(name, component); }; /** * 获取组件 * @param {string} name 组件类型 * @returns {object|null} 组件数据 */ Entity.prototype.getComponent = function (name) { // 参数校验 if (typeof name !== 'string') { throw new TypeError('组件类型必须是字符串'); } return this._component.get(name) || null; }; /** * 检查是否包含组件 * @param {string} name 组件类型 * @returns {boolean} 是否包含组件 */ Entity.prototype.hasComponent = function (name) { // 参数校验 if (typeof name !== 'string') { throw new TypeError('组件类型必须是字符串'); } return this._component.has(name); }; /** * 移除组件 * @param {string} name 组件类型 * @returns {boolean} 是否移除成功 */ Entity.prototype.delComponent = function (name) { // 参数校验 if (typeof name !== 'string') { throw new TypeError('组件类型必须是字符串'); } return this._component.delete(name); }; /** * 获取所有组件类型 * @returns {Array} 组件类型数组 */ Entity.prototype.getComponentTypes = function () { return Array.from(this._component.keys()); }; /** * 转换为JSON字符串 * @returns {string} JSON字符串 */ Entity.prototype.toJson = function () { let data = { entity_id: this.entity_id, player_id: this.player_id, is_active: this.is_active, name: this.name, type: this.type, components: Object.fromEntries(this._component) }; return JSON.stringify(data); }; /** * 从JSON字符串解析实体 * @param {string} json_str JSON字符串 * @returns {Entity} 实体对象 */ Entity.prototype.fromJson = function (json_str) { // 参数校验 if (typeof json_str !== 'string') { throw new TypeError('JSON字符串必须是字符串'); } let data = JSON.parse(json_str); if (!data.entity_id) { throw new Error('JSON字符串缺少实体ID'); } // 设置基本属性 this.entity_id = data.entity_id; this.player_id = data.player_id || ''; this.is_active = data.is_active !== undefined ? data.is_active : true; this.name = data.name || ''; this.type = data.type || ''; // 恢复组件 if (data.components && typeof data.components === 'object') { for (var k in data.components) { this.addComponent(k, data.components[k]); } // 创建属性访问器 this._createProperty(); } return this; }; /** * 生成唯一实体ID * @returns {string} 唯一实体ID */ Entity.prototype.genId = function () { return idGen.genId('entity'); }; /** * 设置实体模型 * @param {object} model 实体模型 */ Entity.prototype.setModel = function (model) { for (var k in model) { let value = model[k]; if (typeof value === 'object') { var component = this.getComponent(k); if (component) { $.push(component, value); this.addComponent(k, component); } } else if (this.hasOwnProperty(k)) { this[k] = value; } } }; module.exports = { Entity };