180 lines
5.0 KiB
JavaScript
180 lines
5.0 KiB
JavaScript
/*
|
||
|
||
定义当对象从文件生成时的基类,
|
||
当文件内部调用this.inherit(父类名)后,将真正继承父类的原型和实例属性。
|
||
但是文件内部不能修改this.prototype,修改将会作用到父类上面。
|
||
可以用this.XXX扩展属性和方法
|
||
*/
|
||
|
||
BASE = function () {
|
||
|
||
}
|
||
|
||
BASE.prototype.set = function (pars) {
|
||
if (!pars) return;
|
||
for (var item in pars) {
|
||
this[item] = pars[item];
|
||
}
|
||
}
|
||
/*
|
||
该方法使用直接赋值方式继承父对象的所有原型方法,
|
||
如果子对象对原型修改,将会改变父对象的原型。
|
||
所以该方法只能获取父对象的原型不能修改它,
|
||
|
||
实际上是作为new的另外一种方式,通过apply获取实例属性,通过__proto__获取父类原型
|
||
|
||
*/
|
||
BASE.prototype.inherits = function (ctor) {
|
||
this.__proto__ = ctor.prototype;
|
||
ctor.apply(this);
|
||
}
|
||
/*
|
||
create方法由继承自base类的类自己实现,当对象被从文件创建时候调用
|
||
参数fname=该对象的文件的相对路径,ctor=构造方法
|
||
*/
|
||
BASE.prototype.create = function (fname, ctor) {
|
||
}
|
||
BASE.prototype.add_event = function (fname, func, time) {
|
||
///在time秒内用新的func替换旧的fname方法
|
||
if (!this[fname])
|
||
this[fname] = this.fire_event.bind(this, fname);
|
||
if (!this._events) this._events = {};
|
||
if (!this._events[fname]) this._events[fname] = [];
|
||
this._events[fname].push({
|
||
func: func,
|
||
time: time ? (Date.now() + time) : Number.MAX_SAFE_INTEGER
|
||
});
|
||
//var old_func = this[fname];
|
||
//this[fname] = func;
|
||
//if (time) this.call_out(() => this[fname] = old_func, time);
|
||
//return old_func;
|
||
}
|
||
BASE.prototype.remove_event = function (name, func) {
|
||
if (!this._events) return;
|
||
var evts = this._events[name];
|
||
if (!evts) return;
|
||
for (var i = 0; i < evts.length; i++) {
|
||
if (evts[i].func === func) {
|
||
evts.splice(i, 1);
|
||
i--;
|
||
}
|
||
}
|
||
|
||
if (!evts.length) {
|
||
this._events[name] = null;
|
||
this[name] = null;
|
||
}
|
||
}
|
||
BASE.prototype.fire_event = function (name) {
|
||
if (!this._events) return;
|
||
var evts = this._events[name];
|
||
if (!evts) return;
|
||
var dt = Date.now();
|
||
for (var i = 0; i < evts.length; i++) {
|
||
if (evts[i].time > dt) {
|
||
if (evts[i].func.call(this) == false) return false;
|
||
} else {
|
||
evts.splice(i, 1);
|
||
i--;
|
||
}
|
||
}
|
||
if (!evts.length) {
|
||
this._events[name] = null;
|
||
this[name] = null;
|
||
}
|
||
}
|
||
/*
|
||
生成对象标识,前8位是毫秒级时间戳的36进制形式,后4位随机码,
|
||
最起码保证每毫秒生成的标识不会重复
|
||
*/
|
||
var key = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||
BASE.prototype.create_uid = function () {
|
||
var str = [];
|
||
str.push(Date.now().toString(36));
|
||
var length = key.length;
|
||
for (var i = 0; i < 4; i++) {
|
||
str.push(key[Math.floor(Math.random() * length)]);
|
||
}
|
||
return str.join("");
|
||
}
|
||
BASE.prototype.random = function (num) {
|
||
return Math.floor(Math.random() * num);
|
||
}
|
||
BASE.prototype.call_out = function (func, time, arg1, arg2) {
|
||
return setTimeout(func.bind(this, arg1, arg2), time);
|
||
}
|
||
BASE.prototype.call_interval = function (func, time, count, end_func) {
|
||
count--;
|
||
var index = 0;
|
||
if (func(index++) === false || count === 0) {
|
||
return end_func && end_func();
|
||
}
|
||
var handler = 0;
|
||
handler = setInterval(function () {
|
||
|
||
count--;
|
||
if (func(index++) === false || count === 0) {
|
||
clearInterval(handler);
|
||
end_func && end_func();
|
||
}
|
||
}, time);
|
||
return handler;
|
||
}
|
||
|
||
|
||
const vm = require('vm');
|
||
const fs = require("fs");
|
||
//根据文件路径new一个对象
|
||
BASE.ITEMS = {};
|
||
BASE.CREATE = function (path, fname) {
|
||
|
||
var ary = BASE.PATH_REG.exec(fname);
|
||
if (!ary) {
|
||
return console.error("path %s is incorrect:", path + fname);
|
||
}
|
||
fname = ary[1];
|
||
var paras = ary[2];
|
||
var fkey = path + fname;
|
||
var func = BASE.ITEMS[fkey];
|
||
if (func) {
|
||
return BASE.NEW(fname, func, paras);
|
||
}
|
||
const filepath = fkey + ".js";
|
||
try {
|
||
const script = fs.readFileSync(filepath);
|
||
func = vm.compileFunction(script.toString(), [],
|
||
{ filename: filepath });
|
||
|
||
BASE.ITEMS[fkey] = func;
|
||
return BASE.NEW(fname, func, paras);
|
||
} catch (e) {
|
||
console.error("create %s%s error:", filepath, e, e.stack);
|
||
}
|
||
}
|
||
BASE.CLONE = function (fname) {
|
||
}
|
||
BASE.PATH_REG = /^(\w+(?:\/\w+)*)(#\w+)?$/;
|
||
BASE.NEW = function (fname, func, par) {
|
||
var obj = new BASE();
|
||
func.apply(obj);
|
||
obj.path = fname;
|
||
obj.create(fname, par);
|
||
return obj;
|
||
}
|
||
|
||
BASE.UPDATE = function (path, fname) {
|
||
var ary = BASE.PATH_REG.exec(fname);
|
||
if (!ary) {
|
||
throw "path " + fname + " is incorrect:";
|
||
}
|
||
fname = ary[1];
|
||
var fkey = path + fname;
|
||
var data = fs.readFileSync(fkey + ".js");
|
||
var func = new Function(data);
|
||
BASE.ITEMS[fkey] = func;
|
||
var obj = new BASE();
|
||
func.apply(obj);
|
||
obj.path = fname;
|
||
obj.update && obj.update(fname, ary[2]);
|
||
}
|