代码拉取完成,页面将自动刷新
/**
* Created by HAM on 16-07-02.
*/
/////////////////////////////////////////////////////////begin//////////////////////////////////////////////////////////
if (undefined === global.__MyActor_actor_id) {
global.__MyActor_actor_id = 0;
}
if (undefined === global.__MyActor_trace_error_stack) {
global.__MyActor_trace_error_stack = false;
}
if (undefined === global.__MyActor_delta_stamp) {
let tmp = setTimeout(()=>{}, 0);
if (undefined != tmp._idleStart) {
global.__MyActor_delta_stamp = (new Date()).valueOf() - tmp._idleStart;
} else {
global.__MyActor_delta_stamp = (new Date()).valueOf();
}
clearTimeout(tmp);
}
if (undefined === global.__MyActor_trace_buff) {
global.__MyActor_trace_buff = "";
}
if (undefined === global.__MyActor_hold_count) {
global.__MyActor_hold_count = 0;
global.__MyActor_hold_id = undefined;
}
if (undefined === global.__MyActor_exception_handler) {
global.__MyActor_exception_handler = function (msg, err) {
console.log(msg, err);
if (global.__MyActor_trace_error_stack && err.stack) {
console.log(err.stack);
}
};
}
function MsgQueue() {
let self = this;
self.__head = self.__tail = null;
self.__size = 0;
}
MsgQueue.prototype.push_back = function (msg) {
let self = this;
let newNode = [msg, null];
if (!self.__head) {
self.__head = newNode;
} else {
self.__tail[1] = newNode;
}
self.__tail = newNode;
self.__size++;
};
MsgQueue.prototype.push_front = function (msg) {
let self = this;
let newNode = [msg, self.__head];
self.__head = newNode;
if (!self.__tail) {
self.__tail = newNode;
}
self.__size++;
};
MsgQueue.prototype.transfer_back = function (other) {
let self = this;
if (!other.empty()) {
if (!self.__head) {
self.__head = other.__head;
} else {
self.__tail[1] = other.__head;
}
self.__tail = other.__tail;
self.__size += other.__size;
other.__size = 0;
other.__head = other.__tail = null;
}
};
MsgQueue.prototype.transfer_front = function (other) {
let self = this;
if (!other.empty()) {
if (!self.__head) {
self.__head = other.__head;
self.__tail = other.__tail;
} else {
other.__tail[1] = self.__head;
self.__head = other.__head;
}
self.__size += other.__size;
other.__size = 0;
other.__head = other.__tail = null;
}
};
MsgQueue.prototype.pop_front = function () {
let self = this;
if (0 == self.__size)
throw new Error("msg queue is empty");
let front = self.__head[0];
self.__head = self.__head[1];
self.__size--;
if (0 == self.__size) {
self.__tail = null;
}
return front;
};
MsgQueue.prototype.front = function () {
let self = this;
if (0 == self.__size)
throw new Error("msg queue is empty");
return self.__head[0];
};
MsgQueue.prototype.back = function () {
let self = this;
if (0 == self.__size)
throw new Error("msg queue is empty");
return self.__tail[0];
};
MsgQueue.prototype.length = function () {
let self = this;
return self.__size;
};
MsgQueue.prototype.empty = function () {
let self = this;
return 0 == self.__size;
};
MsgQueue.prototype.clear = function () {
let self = this;
let it = self.__head;
while (it) {
self.__size--;
let t = it;
it = it[1];
t[1] = null;
}
self.__head = self.__tail = null;
};
MsgQueue.prototype.swap = function (other) {
let self = this;
if (other != self) {
let t = self.__head;
self.__head = other.__head;
other.__head = t;
t = self.__tail;
self.__tail = other.__tail;
other.__tail = t;
t = self.__size;
self.__size = other.__size;
other.__size = t;
}
};
//----------------------------------------------------------------------------------------------------------------------
function Stack() {
let self = this;
self.__stack = new MsgQueue();
}
Stack.prototype.push = function (msg) {
let self = this;
self.__stack.push_front(msg);
};
Stack.prototype.pop = function () {
let self = this;
return self.__stack.pop_front();
};
Stack.prototype.transfer = function (other) {
let self = this;
self.__stack.transfer_back(other);
};
Stack.prototype.front = function () {
let self = this;
return self.__stack.front();
};
Stack.prototype.length = function () {
let self = this;
return self.__stack.length();
};
Stack.prototype.empty = function () {
let self = this;
return self.__stack.empty();
};
Stack.prototype.clear = function () {
let self = this;
self.__stack.clear();
};
//----------------------------------------------------------------------------------------------------------------------
function List() {
let self = this;
self.__guard = [null, null, null];
self.__guard[1] = self.__guard[2] = self.__guard;
self.__size = 0;
}
List.prototype.push_back = function (msg) {
let self = this;
self.__size++;
return self.__guard[2] = self.__guard[2][1] = [msg, self.__guard, self.__guard[2]];
};
List.prototype.push_front = function (msg) {
let self = this;
self.__size++;
return self.__guard[1] = self.__guard[1][2] = [msg, self.__guard[1], self.__guard];
};
List.prototype.transfer_back = function (other) {
let self = this;
if (!other.empty()) {
self.__guard[2][1] = other.__guard[1];
other.__guard[1][2] = self.__guard[2];
self.__guard[2] = other.__guard[2];
self.__guard[2][1] = self.__guard;
self.__size += other.__size;
other.__size = 0;
other.__guard[1] = other.__guard[2] = other.__guard;
}
};
List.prototype.transfer_front = function (other) {
let self = this;
if (!other.empty()) {
self.__guard[1][2] = other.__guard[2];
other.__guard[2][1] = self.__guard[1];
self.__guard[1] = other.__guard[1];
self.__guard[1][2] = self.__guard;
self.__size += other.__size;
other.__size = 0;
other.__guard[1] = other.__guard[2] = other.__guard;
}
};
List.prototype.pop_back = function () {
let self = this;
if (0 == self.__size)
throw new Error("list is empty");
return self.erase(self.__guard[2]);
};
List.prototype.pop_front = function () {
let self = this;
if (0 == self.__size)
throw new Error("list is empty");
return self.erase(self.__guard[1]);
};
List.prototype.unshift = function (msg) {
let self = this;
return self.push_front(msg);
};
List.prototype.shift = function () {
let self = this;
return self.pop_front();
};
List.prototype.push = function (msg) {
let self = this;
return self.push_back(msg);
};
List.prototype.pop = function () {
let self = this;
return self.pop_back();
};
List.prototype.front = function () {
let self = this;
if (0 == self.__size)
throw new Error("list is empty");
return self.__guard[1][0];
};
List.prototype.back = function () {
let self = this;
if (0 == self.__size)
throw new Error("list is empty");
return self.__guard[2][0];
};
List.prototype.begin = function () {
let self = this;
return self.__guard[1];
};
List.prototype.end = function () {
let self = this;
return self.__guard;
};
List.prototype.next = function (node) {
let self = this;
if (node == self.__guard)
throw new Error("list iterator.next overstep");
return node[2];
};
List.prototype.next_erase = function(node) {
let self = this;
if (node == self.__guard)
throw new Error("list iterator.next overstep");
let nt = node[2];
self.erase(node);
return nt;
};
List.prototype.previous = function (node) {
let self = this;
if (node[1] == self.__guard)
throw new Error("list iterator.previous overstep");
return node[1];
};
List.prototype.is_end = function (node) {
let self = this;
return node == self.__guard;
};
List.prototype.is_invalid = function (node) {
return !node || !node[1] || !node[2];
};
List.prototype.element = function (node) {
if (!node[1] || !node[2])
throw new Error("list node is error");
return node[0];
};
List.prototype.length = function () {
let self = this;
return self.__size;
};
List.prototype.empty = function () {
let self = this;
return 0 == self.__size;
};
List.prototype.erase = function (node) {
let self = this;
if (0 == self.__size)
throw new Error("list is empty");
if (!node[1] || !node[2])
throw new Error("list node is error");
self.__size--;
node[1][2] = node[2];
node[2][1] = node[1];
let ele = node[0];
node[0] = node[1] = node[2] = null;
return ele;
};
List.prototype.clear = function () {
let self = this;
let it = self.__guard[2];
while (self.__size) {
self.__size--;
let t = it;
it = it[2];
t[0] = t[1] = t[2] = null;
}
self.__guard[1] = self.__guard[2] = self.__guard;
};
List.prototype.swap = function (other) {
let self = this;
if (other != self) {
let t = self.__guard;
self.__guard = other.__guard;
other.__guard = t;
t = self.__size;
self.__size = other.__size;
other.__size = t;
}
};
//----------------------------------------------------------------------------------------------------------------------
function Channel(maxLength = 0) {
if (maxLength >= 1) {
let self = this;
self.__type = MyActor.__msg_type_channel_handle;
self.__closed = false;
self.__queue = new MsgQueue();
self.__push_wait_queue = new List();
self.__pop_wait_queue = new List();
self.__max_length = Math.floor(maxLength);
} else {
NilChannel.call(this);
this.__proto__ = NilChannel.prototype;
}
}
Channel.state_undefined = -1;
Channel.state_ok = 0;
Channel.state_fail = 1;
Channel.state_closed = 2;
Channel.state_cancel = 3;
Channel.state_overtime = 4;
Channel.prototype.push = function (msg, callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("Channel push callback error", ()=> callback(Channel.state_closed));
return;
}
if (self.__queue.length() == self.__max_length) {
self.__push_wait_queue.push_back(function (state) {
if (state == Channel.state_ok) {
self.push(msg, callback);
} else {
MyActor.check_exception_callback("Channel push callback error", ()=> callback(state));
}
});
} else {
self.__queue.push_back(msg);
if (!self.__pop_wait_queue.empty()) {
self.__pop_wait_queue.pop_front()(Channel.state_ok);
}
MyActor.check_exception_callback("Channel push callback error", ()=> callback(Channel.state_ok));
}
};
Channel.prototype.try_push = function (msg, callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("Channel try_push callback error", ()=> callback(Channel.state_closed));
return;
}
if (self.__queue.length() == self.__max_length) {
MyActor.check_exception_callback("Channel try_push callback error", ()=> callback(Channel.state_fail));
} else {
self.__queue.push_back(msg);
if (!self.__pop_wait_queue.empty()) {
self.__pop_wait_queue.pop_front()(Channel.state_ok);
}
MyActor.check_exception_callback("Channel try_push callback error", ()=> callback(Channel.state_ok));
}
};
Channel.prototype.timed_push = function (ms, msg, callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("Channel timed_push callback error", ()=> callback(Channel.state_closed));
return;
}
if (self.__queue.length() == self.__max_length) {
if (ms > 0) {
let tmid;
let node = self.__push_wait_queue.push_back(function (state) {
if (tmid) {
clearTimeout(tmid);
}
if (state == Channel.state_ok) {
self.push(msg, callback);
} else {
MyActor.check_exception_callback("Channel timed_push callback error", ()=> callback(state));
}
});
tmid = setTimeout(function () {
tmid = null;
let pushWait = self.__push_wait_queue.erase(node);
pushWait(Channel.state_overtime);
}, ms);
} else {
MyActor.check_exception_callback("Channel timed_push callback error", ()=> callback(Channel.state_overtime));
}
} else {
self.__queue.push_back(msg);
if (!self.__pop_wait_queue.empty()) {
self.__pop_wait_queue.pop_front()(Channel.state_ok);
}
MyActor.check_exception_callback("Channel timed_push callback error", ()=> callback(Channel.state_ok));
}
};
Channel.prototype.pop = function (callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("Channel pop callback error", ()=> callback(Channel.state_closed));
return;
}
if (!self.__queue.empty()) {
let msg = self.__queue.pop_front();
if (!self.__push_wait_queue.empty()) {
self.__push_wait_queue.pop_front()(Channel.state_ok);
}
MyActor.check_exception_callback("Channel pop callback error", ()=> callback(Channel.state_ok, msg));
} else {
self.__pop_wait_queue.push_back(function (state) {
if (state == Channel.state_ok) {
self.pop(callback);
} else {
MyActor.check_exception_callback("Channel pop callback error", ()=> callback(state));
}
});
}
};
Channel.prototype.try_pop = function (callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("Channel try_pop callback error", ()=> callback(Channel.state_closed));
return;
}
if (!self.__queue.empty()) {
let msg = self.__queue.pop_front();
if (!self.__push_wait_queue.empty()) {
self.__push_wait_queue.pop_front()(Channel.state_ok);
}
MyActor.check_exception_callback("Channel try_pop callback error", ()=> callback(Channel.state_ok, msg));
} else {
MyActor.check_exception_callback("Channel try_pop callback error", ()=> callback(Channel.state_fail));
}
};
Channel.prototype.timed_pop = function (ms, callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("Channel timed_pop callback error", ()=> callback(Channel.state_closed));
return;
}
if (!self.__queue.empty()) {
let msg = self.__queue.pop_front();
if (!self.__push_wait_queue.empty()) {
self.__push_wait_queue.pop_front()(Channel.state_ok);
}
MyActor.check_exception_callback("Channel timed_pop callback error", ()=> callback(Channel.state_ok, msg));
} else if (ms > 0) {
let tmid;
let node = self.__pop_wait_queue.push_back(function (state) {
if (tmid) {
clearTimeout(tmid);
}
if (state == Channel.state_ok) {
self.pop(callback);
} else {
MyActor.check_exception_callback("Channel timed_pop callback error", ()=> callback(state));
}
});
tmid = setTimeout(function () {
tmid = null;
let popWait = self.__pop_wait_queue.erase(node);
popWait(Channel.state_overtime);
}, ms);
} else {
MyActor.check_exception_callback("Channel timed_pop callback error", ()=> callback(Channel.state_fail));
}
};
Channel.prototype.yield_push = function* (msg) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("Channel yield_push not in actor");
let inside = true;
let result = null;
self.push(msg, function (state) {
if (!inside) {
host.__pull_yield(state);
} else {
inside = false;
result = state;
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
Channel.prototype.yield_try_push = function* (msg) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("Channel yield_try_push not in actor");
let inside = true;
let result = null;
self.try_push(msg, function (state) {
if (!inside) {
host.__pull_yield(state);
} else {
inside = false;
result = state;
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
Channel.prototype.yield_timed_push = function* (ms, msg) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("Channel yield_timed_push not in actor");
let inside = true;
let result = null;
self.timed_push(ms, msg, function (state) {
if (!inside) {
host.__pull_yield(state);
} else {
inside = false;
result = state;
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
Channel.prototype.yield_pop = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("Channel yield_pop not in actor");
let inside = true;
let result = null;
self.pop(function (state, msg) {
if (!inside) {
host.__pull_yield([state, msg]);
} else {
inside = false;
result = [state, msg];
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
Channel.prototype.yield_try_pop = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("Channel yield_try_pop not in actor");
let inside = true;
let result = null;
self.try_pop(function (state, msg) {
if (!inside) {
host.__pull_yield([state, msg]);
} else {
inside = false;
result = [state, msg];
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
Channel.prototype.yield_timed_pop = function* (ms) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("Channel yield_timed_pop not in actor");
let inside = true;
let result = null;
self.timed_pop(ms, function (state, msg) {
if (!inside) {
host.__pull_yield([state, msg]);
} else {
inside = false;
result = [state, msg];
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
Channel.prototype.append_pop_notify = function (callback, ntfSign) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("Channel append_pop_notify callback error", ()=> callback(Channel.state_closed));
return;
}
if (!self.__queue.empty()) {
ntfSign.__ntf_sign = true;
ntfSign.__effect = false;
MyActor.check_exception_callback("Channel append_pop_notify callback error", ()=> callback(Channel.state_ok));
} else {
ntfSign.__ntf_sign = false;
ntfSign.__effect = true;
ntfSign.__ntf_node = self.__pop_wait_queue.push_back(function (state) {
ntfSign.__ntf_sign = true;
MyActor.check_exception_callback("Channel append_pop_notify callback error", ()=> callback(state));
});
}
};
Channel.prototype.remove_pop_notify = function (ntfSign) {
let self = this;
if (self.__closed) {
return Channel.state_closed;
}
let effect = ntfSign.__effect;
ntfSign.__effect = false;
if (!ntfSign.__ntf_sign) {
ntfSign.__ntf_sign = true;
self.__pop_wait_queue.erase(ntfSign.__ntf_node);
return Channel.state_ok;
} else {
if (effect && !self.__queue.empty() && !self.__pop_wait_queue.empty()) {
self.__pop_wait_queue.pop_front()(Channel.state_ok);
}
return Channel.state_fail;
}
};
Channel.prototype.__has_msg = function () {
let self = this;
return !self.__queue.empty();
};
Channel.prototype.close = function () {
let self = this;
self.__closed = true;
self.__queue.clear();
let tempQueue1 = new List();
let tempQueue2 = new List();
self.__push_wait_queue.swap(tempQueue1);
self.__pop_wait_queue.swap(tempQueue2);
while (!tempQueue1.empty()) {
tempQueue1.pop_front()(Channel.state_closed);
}
while (!tempQueue2.empty()) {
tempQueue2.pop_front()(Channel.state_closed);
}
};
Channel.prototype.reset = function () {
let self = this;
self.__closed = false;
};
Channel.prototype.cancel = function () {
let self = this;
let tempQueue1 = new List();
let tempQueue2 = new List();
self.__push_wait_queue.swap(tempQueue1);
self.__pop_wait_queue.swap(tempQueue2);
while (!tempQueue1.empty()) {
tempQueue1.pop_front()(Channel.state_cancel);
}
while (!tempQueue2.empty()) {
tempQueue2.pop_front()(Channel.state_cancel);
}
};
Channel.prototype.cancel_push = function () {
let self = this;
let tempQueue = new List();
self.__push_wait_queue.swap(tempQueue);
while (!tempQueue.empty()) {
tempQueue.pop_front()(Channel.state_cancel);
}
};
Channel.prototype.cancel_pop = function () {
let self = this;
let tempQueue = new List();
self.__pop_wait_queue.swap(tempQueue);
while (!tempQueue.empty()) {
tempQueue.pop_front()(Channel.state_cancel);
}
};
//----------------------------------------------------------------------------------------------------------------------
function NilChannel () {
let self = this;
self.__type = MyActor.__msg_type_channel_handle;
self.__has = false;
self.__msg = undefined;
self.__closed = false;
self.__push_wait_queue = new List();
self.__pop_wait_queue = new List();
}
NilChannel.prototype.push = function (msg, callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("NilChannel push callback error", ()=> callback(Channel.state_closed));
return;
}
if (self.__has) {
self.__push_wait_queue.push_back(function (state) {
if (state == Channel.state_ok) {
self.push(msg, callback);
} else {
MyActor.check_exception_callback("NilChannel push callback error", ()=> callback(state));
}
});
} else {
self.__has = true;
self.__msg = msg;
self.__push_wait_queue.push_back(function (state) {
if (state == Channel.state_ok && !self.__push_wait_queue.empty()) {
self.__push_wait_queue.pop_front()(Channel.state_ok);
}
MyActor.check_exception_callback("NilChannel push callback error", ()=> callback(state));
});
if (!self.__pop_wait_queue.empty()) {
self.__pop_wait_queue.pop_front()(Channel.state_ok);
}
}
};
NilChannel.prototype.try_push = function (msg, callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("NilChannel try_push callback error", ()=> callback(Channel.state_closed));
return;
}
if (self.__has) {
MyActor.check_exception_callback("NilChannel try_push callback error", ()=> callback(Channel.state_fail));
} else {
self.__has = true;
self.__msg = msg;
self.__push_wait_queue.push_back(function (state) {
if (state == Channel.state_ok && !self.__push_wait_queue.empty()) {
self.__push_wait_queue.pop_front()(Channel.state_ok);
}
MyActor.check_exception_callback("NilChannel try_push callback error", ()=> callback(state));
});
if (!self.__pop_wait_queue.empty()) {
self.__pop_wait_queue.pop_front()(Channel.state_ok);
}
}
};
NilChannel.prototype.timed_push = function (ms, msg, callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("NilChannel timed_push callback error", ()=> callback(Channel.state_closed));
return;
}
if (self.__has) {
if (msg > 0) {
let tmid;
let node = self.__push_wait_queue.push_back(function (state) {
if (tmid) {
clearTimeout(tmid);
}
if (state == Channel.state_ok) {
self.push(msg, callback);
} else {
MyActor.check_exception_callback("NilChannel timed_push callback error", ()=> callback(state));
}
});
tmid = setTimeout(function () {
tmid = null;
let pushWait = self.__push_wait_queue.erase(node);
pushWait(Channel.state_overtime);
}, ms);
} else {
MyActor.check_exception_callback("NilChannel timed_push callback error", ()=> callback(Channel.state_overtime));
}
} else {
self.__has = true;
self.__msg = msg;
self.__push_wait_queue.push_back(function (state) {
if (state == Channel.state_ok && !self.__push_wait_queue.empty()) {
self.__push_wait_queue.pop_front()(Channel.state_ok);
}
MyActor.check_exception_callback("NilChannel timed_push callback error", ()=> callback(state));
});
if (!self.__pop_wait_queue.empty()) {
self.__pop_wait_queue.pop_front()(Channel.state_ok);
}
}
};
NilChannel.prototype.pop = function (callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("NilChannel pop callback error", ()=> callback(Channel.state_closed));
return;
}
if (self.__has) {
self.__has = false;
let msg = self.__msg;
self.__msg = undefined;
self.__push_wait_queue.pop_front()(Channel.state_ok);
MyActor.check_exception_callback("NilChannel pop callback error", ()=> callback(Channel.state_ok, msg));
} else {
self.__pop_wait_queue.push_back(function (state) {
if (state == Channel.state_ok) {
self.pop(callback);
} else {
MyActor.check_exception_callback("NilChannel pop callback error", ()=> callback(state));
}
});
}
};
NilChannel.prototype.try_pop = function (callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("NilChannel try_pop callback error", ()=> callback(Channel.state_closed));
return;
}
if (self.__has) {
self.__has = false;
let msg = self.__msg;
self.__msg = undefined;
self.__push_wait_queue.pop_front()(Channel.state_ok);
MyActor.check_exception_callback("NilChannel try_pop callback error", ()=> callback(Channel.state_ok, msg));
} else {
MyActor.check_exception_callback("NilChannel try_pop callback error", ()=> callback(Channel.state_fail));
}
};
NilChannel.prototype.timed_pop = function (ms, callback) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("NilChannel timed_pop callback error", ()=> callback(Channel.state_closed));
return;
}
if (self.__has) {
self.__has = false;
let msg = self.__msg;
self.__msg = undefined;
self.__push_wait_queue.pop_front()(Channel.state_ok);
MyActor.check_exception_callback("NilChannel timed_pop callback error", ()=> callback(Channel.state_ok, msg));
} else if (ms > 0) {
let tmid;
let node = self.__pop_wait_queue.push_back(function (state) {
if (tmid) {
clearTimeout(tmid);
}
if (state == Channel.state_ok) {
self.pop(callback);
} else {
MyActor.check_exception_callback("NilChannel timed_pop callback error", ()=> callback(state));
}
});
tmid = setTimeout(function () {
tmid = null;
let popWait = self.__pop_wait_queue.erase(node);
popWait(Channel.state_overtime);
}, ms);
} else {
MyActor.check_exception_callback("NilChannel timed_pop callback error", ()=> callback(Channel.state_overtime));
}
};
NilChannel.prototype.yield_push = function* (msg) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("NilChannel yield_push not in actor");
let inside = true;
let result = null;
self.push(msg, function (state) {
if (!inside) {
host.__pull_yield(state);
} else {
inside = false;
result = state;
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
NilChannel.prototype.yield_try_push = function* (msg) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("NilChannel yield_try_push not in actor");
let inside = true;
let result = null;
self.try_push(msg, function (state) {
if (!inside) {
host.__pull_yield(state);
} else {
inside = false;
result = state;
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
NilChannel.prototype.yield_timed_push = function* (ms, msg) {
let self = this;
let host = MyActor.self_actor();
if (host || !host.__in_actor)
throw new Error("NilChannel yield_timed_push not in actor");
let inside = true;
let result = null;
self.timed_push(ms, msg, function (state) {
if (!inside) {
host.__pull_yield(state);
} else {
inside = false;
result = state;
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
NilChannel.prototype.yield_pop = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("NilChannel yield_pop not in actor");
let inside = true;
let result = null;
self.pop(function (state, msg) {
if (!inside) {
host.__pull_yield([state, msg]);
} else {
inside = false;
result = [state, msg];
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
NilChannel.prototype.yield_try_pop = function* () {
let self = this;
let host = MyActor.self_actor();
if (host || !host.__in_actor)
throw new Error("NilChannel yield_try_pop not in actor");
let inside = true;
let result = null;
self.try_pop(function (state, msg) {
if (!inside) {
host.__pull_yield([state, msg]);
} else {
inside = false;
result = [state, msg];
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
NilChannel.prototype.yield_timed_pop = function* (ms) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("NilChannel yield_timed_pop not in actor");
let inside = true;
let result = null;
self.timed_pop(ms, function (state, msg) {
if (!inside) {
host.__pull_yield([state, msg]);
} else {
inside = false;
result = [state, msg];
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
NilChannel.prototype.append_pop_notify = function (callback, ntfSign) {
let self = this;
if (self.__closed) {
MyActor.check_exception_callback("NilChannel append_pop_notify callback error", ()=> callback(Channel.state_closed));
return;
}
if (self.__has) {
ntfSign.__ntf_sign = true;
ntfSign.__effect = false;
MyActor.check_exception_callback("NilChannel append_pop_notify callback error", ()=> callback(Channel.state_ok));
} else {
ntfSign.__ntf_sign = false;
ntfSign.__effect = true;
ntfSign.__ntf_node = self.__pop_wait_queue.push_back(function (state) {
ntfSign.__ntf_sign = true;
MyActor.check_exception_callback("NilChannel append_pop_notify callback error", ()=> callback(state));
});
}
};
NilChannel.prototype.remove_pop_notify = function (ntfSign) {
let self = this;
if (self.__closed) {
return Channel.state_closed;
}
let effect = ntfSign.__effect;
ntfSign.__effect = false;
if (!ntfSign.__ntf_sign) {
ntfSign.__ntf_sign = true;
self.__pop_wait_queue.erase(ntfSign.__ntf_node);
return Channel.state_ok;
} else {
if (effect && self.__has && !self.__pop_wait_queue.empty()) {
self.__pop_wait_queue.pop_front()(Channel.state_ok);
}
return Channel.state_fail;
}
};
NilChannel.prototype.__has_msg = function () {
let self = this;
return self.__has;
};
NilChannel.prototype.close = function () {
let self = this;
self.__closed = true;
self.__has = false;
self.__msg = undefined;
let tempQueue1 = new List();
let tempQueue2 = new List();
self.__push_wait_queue.swap(tempQueue1);
self.__pop_wait_queue.swap(tempQueue2);
while (!tempQueue1.empty()) {
tempQueue1.pop_front()(Channel.state_closed);
}
while (!tempQueue2.empty()) {
tempQueue2.pop_front()(Channel.state_closed);
}
};
NilChannel.prototype.reset = function () {
let self = this;
self.__closed = false;
};
NilChannel.prototype.cancel = function () {
let self = this;
let tempQueue1 = new List();
let tempQueue2 = new List();
self.__push_wait_queue.swap(tempQueue1);
self.__pop_wait_queue.swap(tempQueue2);
while (!tempQueue1.empty()) {
tempQueue1.pop_front()(Channel.state_cancel);
}
while (!tempQueue2.empty()) {
tempQueue2.pop_front()(Channel.state_cancel);
}
};
NilChannel.prototype.cancel_push = function () {
let self = this;
let tempQueue = new List();
self.__push_wait_queue.swap(tempQueue);
while (!tempQueue.empty()) {
tempQueue.pop_front()(Channel.state_cancel);
}
};
NilChannel.prototype.cancel_pop = function () {
let self = this;
let tempQueue = new List();
self.__pop_wait_queue.swap(tempQueue);
while (!tempQueue.empty()) {
tempQueue.pop_front()(Channel.state_cancel);
}
};
//----------------------------------------------------------------------------------------------------------------------
function Csp () {
let self = this;
self.__type = MyActor.__msg_type_csp_handle;
self.__sender_queue = new List();
self.__receiver_queue= new List();
}
Csp.prototype.yield_invoke = function* (...args) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("csp yield_invoke not in actor");
let result = null;
if (!self.__receiver_queue.empty()) {
let inside = true;
let dst = self.__receiver_queue.pop_front();
dst.__pull_yield([function (res) {
result = res;
if (!inside) {
host.__pull_yield();
} else {
inside = false;
}
}, args]);
if (inside) {
inside = false;
yield null;
}
} else {
self.__sender_queue.push_back([host, function (res) {
result = res;
host.__pull_yield();
}, args]);
yield null;
}
return result;
};
Csp.prototype.yield_timed_invoke = function* (ms,...args) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("csp yield_timed_invoke not in actor");
let result = null;
if (!self.__receiver_queue.empty()) {
let inside = true;
let dst = self.__receiver_queue.pop_front();
dst.__pull_yield([function (res) {
result = {ok: true, value: res};
if (!inside) {
host.__pull_yield();
} else {
inside = false;
}
}, args]);
if (inside) {
inside = false;
yield null;
}
} else {
let node = self.__sender_queue.push_back([host, function (res) {
result = {ok: true, value: res};
host.__pull_yield();
}, args]);
host.__timer_out(function () {
self.__sender_queue.erase(node);
result = {ok: false};
host.__pull_yield();
}, ms);
yield null;
}
return result;
};
Csp.prototype.yield_try_invoke = function* (...args) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("csp yield_try_invoke not in actor");
let result = null;
if (!self.__receiver_queue.empty()) {
let inside = true;
let dst = self.__receiver_queue.pop_front();
dst.__pull_yield([function (res) {
result = {ok: true, value: res};
if (!inside) {
host.__pull_yield();
} else {
inside = false;
}
}, args]);
if (inside) {
inside = false;
yield null;
}
} else {
result = {ok: false};
}
return result;
};
Csp.prototype.yield_wait = function* (handler) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("csp yield_wait not in actor");
if (!self.__sender_queue.empty()) {
let msg = self.__sender_queue.pop_front();
msg[0].__cancel_timer();
msg[1](yield* handler.apply(null, msg[2]));
} else {
let [reply, args] = yield self.__receiver_queue.push_back(host);
reply(yield* handler.apply(null, args));
}
};
Csp.prototype.yield_timed_wait = function* (ms, handler) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("csp yield_timed_wait not in actor");
if (!self.__sender_queue.empty()) {
let msg = self.__sender_queue.pop_front();
msg[0].__cancel_timer();
msg[1](yield* handler.apply(null, msg[2]));
return false;
} else {
let node = self.__receiver_queue.push_back(host);
let [reply, args] = yield host.__timer_out(function () {
self.__receiver_queue.erase(node);
host.__pull_yield();
}, ms);
host.__cancel_timer();
if (reply) {
reply(yield* handler.apply(null, args));
return false;
} else {
return true;
}
}
};
Csp.prototype.yield_try_wait = function* (handler) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("csp yield_try_wait not in actor");
if (!self.__sender_queue.empty()) {
let msg = self.__sender_queue.pop_front();
msg[0].__cancel_timer();
msg[1](yield* handler.apply(null, msg[2]));
return true;
} else {
return false;
}
};
//----------------------------------------------------------------------------------------------------------------------
function Mutex() {
let self = this;
self.__wait_queue = new List();
self.__inside_id = 0;
self.__inside_count = 0
}
Mutex.prototype.yield_lock = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("Mutex yield_lock not in actor");
if (0 == self.__inside_id) {
self.__inside_id = host.__actor_id;
self.__inside_count = 1;
} else if (self.__inside_id == host.__actor_id) {
self.__inside_count++;
} else {
self.__wait_queue.push_back(host);
yield null;
}
};
Mutex.prototype.try_lock = function () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("Mutex yield_try_lock not in actor");
if (0 == self.__inside_id) {
self.__inside_id = host.__actor_id;
self.__inside_count = 1;
} else if (self.__inside_id == host.__actor_id) {
self.__inside_count++;
} else {
return false;
}
return true;
};
Mutex.prototype.yield_timed_lock = function* (ms) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("Mutex yield_timed_lock not in actor");
if (0 == self.__inside_id) {
self.__inside_id = host.__actor_id;
self.__inside_count = 1;
} else if (self.__inside_id == host.__actor_id) {
self.__inside_count++;
} else {
let node = self.__wait_queue.push_back(host);
host.__timer_out(function() {
self.__wait_queue.erase(node);
host.__pull_yield(false);
}, ms);
return yield null;
}
return false;
};
Mutex.prototype.unlock = function () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("Mutex yield_timed_lock not in actor");
if (self.__inside_id != host.__actor_id || self.__inside_count <= 0) {
throw new Error("unlock error");
}
self.__inside_count--;
if (0 == self.__inside_count) {
if (!self.__wait_queue.empty()) {
let ele = self.__wait_queue.pop_front();
self.__inside_id = ele.__actor_id;
self.__inside_count = 1;
if (ele.__timer_completed) {
ele.__pull_yield();
} else {
ele.__cancel_timer();
ele.__pull_yield(true);
}
} else {
self.__inside_id = 0;
}
}
};
//----------------------------------------------------------------------------------------------------------------------
function SharedMutex() {
let self = this;
self.__upgrade_mutex = new Mutex();
self.__wait_queue = new List();
self.__shared_map = new Map();
}
SharedMutex.prototype.yield_lock = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex yield_lock not in actor");
if (0 == self.__shared_map.size && (!self.__upgrade_mutex.__inside_id || host.__actor_id == self.__upgrade_mutex.__inside_id)) {
self.__upgrade_mutex.__inside_id = host.__actor_id;
self.__upgrade_mutex.__inside_count++;
} else {
self.__wait_queue.push_back({wait: host, state: 1});
yield null;
}
};
SharedMutex.prototype.try_lock = function () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex try_lock not in actor");
if (self.__inside_id != host.__actor_id || self.__inside_count <= 0) {
throw new Error("try_lock error");
}
if (0 == self.__shared_map.size && (!self.__upgrade_mutex.__inside_id || host.__actor_id == self.__upgrade_mutex.__inside_id)) {
self.__upgrade_mutex.__inside_id = host.__actor_id;
self.__upgrade_mutex.__inside_count++;
return true;
}
return false;
};
SharedMutex.prototype.yield_timed_lock = function* (ms) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex yield_timed_lock not in actor");
if (0 == self.__shared_map.size && (!self.__upgrade_mutex.__inside_id || host.__actor_id == self.__upgrade_mutex.__inside_id)) {
self.__upgrade_mutex.__inside_id = host.__actor_id;
self.__upgrade_mutex.__inside_count++;
return true;
} else {
let node = self.__wait_queue.push_back({wait: host, state: 1});
host.__timer_out(function () {
self.__wait_queue.erase(node);
host.__pull_yield(false);
}, ms);
return yield null;
}
};
SharedMutex.prototype.yield_lock_shared = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex yield_lock_shared not in actor");
if (0 != self.__shared_map.size || !self.__upgrade_mutex.__inside_id) {
if (self.__shared_map.has(host.__actor_id)) {
self.__shared_map.set(host.__actor_id, self.__shared_map.get(host.__actor_id)+1);
} else {
self.__shared_map.set(host.__actor_id, 1);
}
} else {
self.__wait_queue.push_back({wait: host, state: 0});
yield null;
}
};
SharedMutex.prototype.try_lock_shared = function () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex try_lock_shared not in actor");
if (0 != self.__shared_map.size || !self.__upgrade_mutex.__inside_id) {
if (self.__shared_map.has(host.__actor_id)) {
self.__shared_map.set(host.__actor_id, self.__shared_map.get(host.__actor_id)+1);
} else {
self.__shared_map.set(host.__actor_id, 1);
}
return true;
}
return false;
};
SharedMutex.prototype.yield_timed_lock_shared = function* (ms) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex yield_timed_lock_shared not in actor");
if (0 != self.__shared_map.size || !self.__upgrade_mutex.__inside_id) {
if (self.__shared_map.has(host.__actor_id)) {
self.__shared_map.set(host.__actor_id, self.__shared_map.get(host.__actor_id)+1);
} else {
self.__shared_map.set(host.__actor_id, 1);
}
} else {
let node = self.__wait_queue.push_back({wait: host, state: 0});
host.__timer_out(function () {
self.__wait_queue.erase(node);
host.__pull_yield(false);
}, ms);
return yield null;
}
return true;
};
SharedMutex.prototype.yield_lock_pess_shared = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex yield_lock_pess_shared not in actor");
if (self.__wait_queue.empty() && (0 != self.__shared_map.size || !self.__upgrade_mutex.__inside_id)) {
if (self.__shared_map.has(host.__actor_id)) {
self.__shared_map.set(host.__actor_id, self.__shared_map.get(host.__actor_id)+1);
} else {
self.__shared_map.set(host.__actor_id, 1);
}
} else {
self.__wait_queue.push_back({wait: host, state: 0});
yield null;
}
};
SharedMutex.prototype.yield_lock_upgrade = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex yield_lock_upgrade not in actor");
yield* self.__upgrade_mutex.yield_lock();
};
SharedMutex.prototype.try_lock_upgrade = function () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex try_lock_upgrade not in actor");
return self.__upgrade_mutex.try_lock();
};
SharedMutex.prototype.unlock = function () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex unlock not in actor");
self.__upgrade_mutex.__inside_count--;
if (0 == self.__upgrade_mutex.__inside_count && !self.__wait_queue.empty()) {
let waitQueue = new MsgQueue();
let ele = self.__wait_queue.front();
self.__wait_queue.pop_front();
waitQueue.push_back(ele.wait);
if (0 == ele.state) {
self.__upgrade_mutex.__inside_id = 0;
self.__shared_map.set(ele.wait.__actor_id, 1);
for (let it = self.__wait_queue.begin(); !self.__wait_queue.is_end(it);) {
let ele = self.__wait_queue.element(it);
if (0 == ele.state) {
self.__shared_map.set(ele.wait.__actor_id, 1);
waitQueue.push_back(ele.wait);
it = self.__wait_queue.next_erase(it);
} else {
it = self.__wait_queue.next(it);
}
}
} else {
self.__upgrade_mutex.__inside_id = ele.wait.__actor_id;
self.__upgrade_mutex.__inside_count++;
}
while (!waitQueue.empty()) {
let wait = waitQueue.pop_front();
if (wait.__timer_completed) {
wait.__pull_yield();
} else {
wait.__cancel_timer();
wait.__pull_yield(true);
}
}
}
};
SharedMutex.prototype.unlock_upgrade = function () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex unlock_upgrade not in actor");
self.__upgrade_mutex.unlock();
};
SharedMutex.prototype.unlock_shared = function () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex unlock_shared not in actor");
let sc = self.__shared_map.get(host.__actor_id)-1;
if (0 == sc) {
self.__shared_map.delete(host.__actor_id);
if (0 == self.__shared_map.size && !self.__wait_queue.empty()) {
let waitQueue = new MsgQueue();
let ele = self.__wait_queue.front();
self.__wait_queue.pop_front();
waitQueue.push_back(ele.wait);
if (0 == ele.state) {
self.__upgrade_mutex.__inside_id = 0;
self.__shared_map.set(ele.wait.__actor_id, 1);
for (let it = self.__wait_queue.begin(); !self.__wait_queue.is_end(it);) {
let ele = self.__wait_queue.element(it);
if (0 == ele.state) {
self.__shared_map.set(ele.wait.__actor_id, 1);
waitQueue.push_back(ele.wait);
it = self.__wait_queue.next_erase(it);
} else {
it = self.__wait_queue.next(it);
}
}
} else {
self.__upgrade_mutex.__inside_id = ele.wait.__actor_id;
self.__upgrade_mutex.__inside_count++;
}
while (!waitQueue.empty()) {
let wait = waitQueue.pop_front();
if (wait.__timer_completed) {
wait.__pull_yield();
} else {
wait.__cancel_timer();
wait.__pull_yield(true);
}
}
}
} else {
self.__shared_map.set(host.__actor_id, sc);
}
};
SharedMutex.prototype.yield_unlock_and_lock_shared = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex yield_unlock_and_lock_shared not in actor");
self.unlock();
yield* self.yield_lock_shared();
};
SharedMutex.prototype.yield_unlock_and_lock_upgrade = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex yield_unlock_and_lock_upgrade not in actor");
self.unlock();
yield* self.yield_lock_shared();
yield* self.yield_lock_upgrade();
};
SharedMutex.prototype.yield_unlock_upgrade_and_lock = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex yield_unlock_upgrade_and_lock not in actor");
self.unlock_upgrade();
self.unlock_shared();
yield* self.yield_lock();
};
SharedMutex.prototype.yield_unlock_shared_and_lock = function* () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("SharedMutex yield_unlock_shared_and_lock not in actor");
self.unlock_shared();
yield* self.yield_lock();
};
//----------------------------------------------------------------------------------------------------------------------
function ConditionVariable() {
let self = this;
self.__wait_queue = new List();
}
ConditionVariable.prototype.yield_wait = function* (mtx) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("ConditionVariable yield_wait not in actor");
let inside = true;
self.__wait_queue.push_back(function () {
if (!inside) {
host.__pull_yield();
} else {
inside = false;
}
});
mtx.unlock();
if (inside) {
inside = false;
yield null;
}
yield* mtx.yield_lock();
};
ConditionVariable.prototype.yield_timed_wait = function* (mtx, ms) {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("ConditionVariable yield_timed_wait not in actor");
let inside = true;
let overtime = false;
let node = self.__wait_queue.push_back(function () {
host.__cancel_timer();
if (!inside) {
host.__pull_yield();
} else {
inside = false;
}
});
host.__timer_out(function () {
overtime = true;
self.__wait_queue.erase(node);
if (!inside) {
host.__pull_yield();
} else {
inside = false;
}
}, ms);
mtx.unlock();
if (inside) {
inside = false;
yield null;
}
yield* mtx.yield_lock();
return !overtime;
};
ConditionVariable.prototype.notify_one = function () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("ConditionVariable notify_one not in actor");
if (!self.__wait_queue.empty()) {
self.__wait_queue.pop_front()();
}
};
ConditionVariable.prototype.notify_all = function () {
let self = this;
let host = MyActor.self_actor();
if (!host || !host.__in_actor)
throw new Error("ConditionVariable notify_all not in actor");
let tempQueue = new List();
self.__wait_queue.swap(tempQueue);
while (!tempQueue.empty()) {
tempQueue.pop_front()();
}
};
//----------------------------------------------------------------------------------------------------------------------
function MyActor(handler, quited_callback) {
let self = this;
self.__actor_id = ++global.__MyActor_actor_id;
self.__is_run = false;
self.__is_exited = false;
self.__is_quited = false;
self.__is_suspend = false;
self.__is_force = false;
self.__is_error = false;
self.__in_actor = false;
self.__context_count = 0;
self.__parent_actor_id = -1;
self.__timer_id = null;
self.__timer_completed = true;
self.__timer_start = 0;
self.__timer_timeout = 0;
self.__timer_end = 0;
self.__timer_suspended = false;
self.__timer_handler = null;
self.__lock_quit = 0;
self.__lock_suspend = 0;
self.__hold_pull = false;
self.__hold_quited = false;
self.__hold_suspended = false;
self.__wait_quit_msg = false;
self.__quited_exec = [];
self.__quited_notify = new MsgQueue();
self.__suspend_queue = new MsgQueue();
self.__error_notify = new MsgQueue();
self.__msg_table = {};
self.__child_map = new Map;
self.__result = undefined;
self.__temp_result = undefined;
self.__top_handler = handler(self);
self.__quited_callback = quited_callback;
self.__handler_stack = new Stack();
}
MyActor.__msg_type_notify_handle = 0;
MyActor.__msg_type_trig_handle = 1;
MyActor.__msg_type_msg_handle = 2;
MyActor.__msg_type_csp_handle = 3;
MyActor.__msg_type_channel_handle = 4;
MyActor.__msg_type_quit_handle = 5;
MyActor.create = function (handler, quited_callback) {
return new MyActor(handler, quited_callback);
};
MyActor.bind = function (handler, ...args) {
return function (self) {
return handler(self, ...args);
};
};
MyActor.sleep = function (ms) {
let self = global.__MyActor_self_actor;
if (!self || !self.__in_actor)
throw new Error("sleep not in actor");
if (isNaN(ms))
throw new Error("sleep number error");
setTimeout(function () {
self.__pull_yield();
}, ms);
};
MyActor.tick = function () {
return (new Date()).valueOf() - global.__MyActor_delta_stamp;
};
MyActor.time_string = function () {
let fmt = (i)=>i>=10?i:"0"+i;
let dt = new Date();
return ""+dt.getFullYear()+"-"+fmt(1+dt.getMonth())+"-"+fmt(dt.getDate())+" "+fmt(dt.getHours())+":"+fmt(dt.getMinutes())+":"+fmt(dt.getSeconds());
};
MyActor.tick_string = function () {
let fmt = (i)=>i>=10?i:"0"+i;
let dt = new Date();
let ms = dt.getMilliseconds();
return ""+dt.getFullYear()+"-"+fmt(1+dt.getMonth())+"-"+fmt(dt.getDate())+" "+fmt(dt.getHours())+":"+fmt(dt.getMinutes())+":"+fmt(dt.getSeconds())+"."+(ms>=100?ms:(ms>=10?"0"+ms:"00"+ms));
};
MyActor.self_actor = function () {
return global.__MyActor_self_actor;
};
MyActor.create_queue = function () {
return new MsgQueue();
};
MyActor.create_stack = function () {
return new Stack();
};
MyActor.create_list = function () {
return new List();
};
MyActor.register_exception_handler = function (handler) {
global.__MyActor_exception_handler = function (msg, err) {
try {
handler(msg, err);
} catch (e) {
console.log("register_exception_handler error");
}
}
};
MyActor.make_mutex = function () {
return new Mutex();
};
MyActor.make_shared_mutex = function () {
return new SharedMutex();
};
MyActor.make_condition_variable = function () {
return new ConditionVariable();
};
MyActor.trace = function (...args) {
for (let ele of args) {
global.__MyActor_trace_buff += JSON.stringify(ele);
}
};
MyActor.trace_flush = function (){
console.log(global.__MyActor_trace_buff);
global.__MyActor_trace_buff = "";
};
MyActor.trace_space = function (...args) {
let msg = "";
for (let i in args) {
if (i < args.length-1) {
msg += JSON.stringify(args[i]) + " ";
} else {
msg += JSON.stringify(args[i]);
}
}
console.log(msg);
};
MyActor.trace_comma = function (...args) {
let msg = "";
for (let i in args) {
if (i < args.length-1) {
msg += JSON.stringify(args[i]) + ", ";
} else {
msg += JSON.stringify(args[i]);
}
}
console.log(msg);
};
MyActor.wrap_tick = function (handler) {
return function (...args) {
process.nextTick(function () {
handler(...args);
});
}
};
MyActor.wrap_tick_target = function (handler) {
return function (...args) {
let self = this;
process.nextTick(function () {
handler.call(self,...args);
});
}
};
MyActor.wrap_post = function (handler) {
return function (...args) {
setImmediate(function () {
handler(...args);
});
}
};
MyActor.wrap_post_target = function (handler) {
return function (...args) {
let self = this;
setImmediate(function () {
handler.call(self,...args);
});
}
};
MyActor.wrap_hold_work = function (handler, cb) {
MyActor.hold_work();
let isInvoked = false;
return function (...args) {
if (isInvoked) {
throw new Error("wrap_hold_work error");
}
isInvoked = true;
let result = handler(...args);
MyActor.release_work(cb);
return result;
}
};
MyActor.hold_work = function (holdNum) {
if (undefined === holdNum) {
holdNum = 1;
} else if (holdNum <= 0) {
throw new Error("hold_work error");
}
if (0 == global.__MyActor_hold_count) {
global.__MyActor_hold_id = setInterval(()=>{}, 0x7FFFFFFF);
}
global.__MyActor_hold_count += holdNum;
};
MyActor.release_work = function (cb) {
if (global.__MyActor_hold_count <= 0) {
throw new Error("release_work error");
}
global.__MyActor_hold_count--;
if (0 == global.__MyActor_hold_count) {
clearInterval(global.__MyActor_hold_id);
global.__MyActor_hold_id = undefined;
if (cb) {
MyActor.check_exception_callback("release_work callback error", cb);
}
}
};
MyActor.force_trace_error_stack = function () {
global.__MyActor_trace_error_stack = true;
};
MyActor.enable_source_map_trace = function () {
try {
require("source-map-support").install();
} catch (err) {
global.__MyActor_exception_handler("enable_source_map_trace error", err);
}
};
MyActor.check_exception_callback = function (msg, handler) {
try {
handler();
} catch (err) {
MyActor.__MyActor_exception_handler(msg, err);
}
};
MyActor.prototype.make_mutex = MyActor.make_mutex;
MyActor.prototype.make_shared_mutex = MyActor.make_shared_mutex;
MyActor.prototype.make_condition_variable = MyActor.make_condition_variable;
MyActor.prototype.self_id = function () {
let self = this;
return self.__actor_id;
};
MyActor.prototype.result = function () {
let self = this;
if (!self.__is_exited)
throw new Error("get result error");
return self.__result;
};
MyActor.prototype.create_child = function (handler, cb) {
let self = this;
if (!self.__in_actor)
throw new Error("create_child not in actor");
let child = new MyActor(handler, function (result) {
if (cb) {
MyActor.check_exception_callback("create_child callback error", ()=> cb(result));
}
self.__child_quited_handler(child);
});
child.__parent_actor_id = self.__actor_id;
self.__child_map.set(child.__actor_id, child);
return child;
};
MyActor.prototype.run = function () {
let self = this;
if (!self.__is_quited && !self.__is_run) {
self.__is_run = true;
self.__pull_yield();
}
return self;
};
MyActor.prototype.force_quit = function (cb) {
let self = this;
setImmediate(function () {
if (!self.__is_quited) {
if (cb) {
self.__quited_notify.push_back(cb);
}
if (!self.__lock_quit) {
self.__is_force = true;
self.__is_quited = true;
self.__is_suspend = false;
self.__lock_suspend = 0;
self.__hold_pull = false;
self.__hold_suspended = false;
self.__cancel_timer();
if (self.__child_map.size) {
self.__child_map.forEach((child, id)=> child.force_quit());
} else {
self.__quited_to_do();
}
} else {
self.__hold_quited = true;
if (self.__wait_quit_msg) {
self.__wait_quit_msg = false;
self.__pull_yield();
}
}
} else if (cb) {
if (self.__is_exited) {
MyActor.check_exception_callback("force_quit callback error", cb);
} else {
self.__quited_notify.push_back(cb);
}
}
});
};
MyActor.prototype.children_force_quit = function () {
let self = this;
if (!self.__in_actor)
throw new Error("children_force_quit not in actor");
self.__child_map.forEach((child, id)=> child.force_quit());
};
MyActor.prototype.is_start = function () {
let self = this;
return self.__is_run;
};
MyActor.prototype.is_exited = function () {
let self = this;
return self.__is_exited;
};
MyActor.prototype.is_force = function () {
let self = this;
if (!self.__is_exited)
throw new Error("is_force error");
return self.__is_force;
};
MyActor.prototype.is_error = function () {
let self = this;
if (!self.__is_exited)
throw new Error("is_error error");
return self.__is_error;
};
MyActor.prototype.has_quit_msg = function () {
let self = this;
if (!self.__in_actor)
throw new Error("has_quit_msg not in actor");
return self.__hold_quited;
};
MyActor.prototype.yield_suspend = function* (...otherActors) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_suspend not in actor");
let count = otherActors.length;
if (count) {
let inside = true;
for (let ele of otherActors) {
ele.__notify_suspend(function () {
count--;
if (0 == count) {
if (!inside) {
self.__pull_yield();
} else {
inside = false;
}
}
});
}
if (inside) {
inside = false;
yield null;
}
}
};
MyActor.prototype.yield_resume = function* (...otherActors) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_resume not in actor");
let count = otherActors.length;
if (count) {
let inside = true;
for (let ele of otherActors) {
ele.__notify_resume(function () {
count--;
if (0 == count) {
if (!inside) {
self.__pull_yield();
} else {
inside = false;
}
}
});
}
if (inside) {
inside = false;
yield null;
}
}
};
MyActor.prototype.suspend = function (cb) {
let self = this;
setImmediate(function () {
self.__notify_suspend(function () {
if (cb) {
MyActor.check_exception_callback("suspend callback error", cb);
}
});
});
};
MyActor.prototype.resume = function (cb) {
let self = this;
setImmediate(function () {
self.__notify_resume(function () {
if (cb) {
MyActor.check_exception_callback("resume callback error", cb);
}
});
});
};
MyActor.prototype.yield_children_suspend = function* () {
let self = this;
if (!self.__in_actor)
throw new Error("yield_children_suspend not in actor");
let count = self.__child_map.size;
if (count) {
let inside = true;
self.__child_map.forEach(function(child, id) {
child.__notify_suspend(function () {
count--;
if (0 == count) {
if (!inside) {
self.__pull_yield();
} else {
inside = false;
}
}
})
});
if (inside) {
inside = false;
yield null;
}
}
};
MyActor.prototype.yield_children_resume = function* () {
let self = this;
if (!self.__in_actor)
throw new Error("yield_children_resume not in actor");
let count = self.__child_map.size;
if (count) {
let inside = true;
self.__child_map.forEach((child, id)=> child.__notify_resume(function () {
count--;
if (0 == count) {
if (!inside) {
self.__pull_yield();
} else {
inside = false;
}
}
}));
if (inside) {
inside = false;
yield null;
}
}
};
MyActor.prototype.yield_safe_suspend = function* (...otherActors) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_safe_suspend not in actor");
self.lock_quit();
yield* self.yield_suspend(...otherActors);
yield* self.yield_unlock_quit();
};
MyActor.prototype.yield_safe_resume = function* (...otherActors) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_safe_resume not in actor");
self.lock_quit();
yield* self.yield_resume(...otherActors);
yield* self.yield_unlock_quit();
};
MyActor.prototype.yield_safe_children_suspend = function* () {
let self = this;
if (!self.__in_actor)
throw new Error("yield_safe_children_suspend not in actor");
self.lock_quit();
yield* self.yield_children_suspend();
yield* self.yield_unlock_quit();
};
MyActor.prototype.yield_safe_children_resume = function* () {
let self = this;
if (!self.__in_actor)
throw new Error("yield_safe_children_resume not in actor");
self.lock_quit();
yield* self.yield_children_resume();
yield* self.yield_unlock_quit();
};
MyActor.prototype.lock_suspend = function () {
let self = this;
if (!self.__in_actor)
throw new Error("lock_suspend not in actor");
self.__lock_suspend++;
};
MyActor.prototype.yield_unlock_suspend = function* () {
let self = this;
if (!self.__in_actor)
throw new Error("yield_unlock_suspend not in actor");
if (0 == self.__lock_suspend)
throw new Error("yield_unlock_suspend error");
self.__lock_suspend--;
if (!self.__lock_suspend && self.__hold_suspended) {
self.__hold_suspended = false;
if (self.__suspend_queue.front().is_suspend) {
self.__suspend();
} else {
self.__resume();
}
self.__post_pull();
yield null;
}
};
MyActor.prototype.yield_force_quit = function* (...otherActors) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_force_quit not in actor");
let count = otherActors.length;
if (count) {
for (let ele of otherActors) {
ele.force_quit(function () {
count--;
if (0 == count) {
self.__pull_yield();
}
});
}
yield null;
}
};
MyActor.prototype.yield_children_force_quit = function* () {
let self = this;
if (!self.__in_actor)
throw new Error("yield_children_force_quit not in actor");
let count = self.__child_map.size;
if (count) {
self.__child_map.forEach((child, id)=> child.force_quit(function () {
count--;
if (0 == count) {
self.__pull_yield();
}
}));
yield null;
}
};
MyActor.prototype.yield_safe_force_quit = function* (...otherActors) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_safe_force_quit not in actor");
self.lock_quit();
yield* self.yield_force_quit(...otherActors);
yield* self.yield_unlock_quit();
};
MyActor.prototype.yield_safe_children_force_quit = function* () {
let self = this;
if (!self.__in_actor)
throw new Error("yield_safe_children_force_quit not in actor");
self.lock_quit();
yield* self.yield_children_force_quit();
yield* self.yield_unlock_quit();
};
MyActor.prototype.lock_quit = function () {
let self = this;
if (!self.__in_actor)
throw new Error("lock_quit not in actor");
self.__lock_quit++;
};
MyActor.prototype.yield_unlock_quit = function* () {
let self = this;
if (!self.__in_actor)
throw new Error("yield_unlock_quit not in actor");
if (!self.__lock_quit)
throw new Error("yield_unlock_quit error");
self.__lock_quit--;
if (0 == self.__lock_quit && self.__hold_quited) {
self.force_quit();
yield null;
}
};
MyActor.prototype.append_quited_notify = function (cb) {
let self = this;
if (self.__is_exited) {
MyActor.check_exception_callback("append_quited_notify callback error", cb);
} else {
self.__quited_notify.push_back(cb);
}
};
MyActor.prototype.append_quited_exec = function (handler) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_unlock_quit not in actor");
self.__quited_exec.push(handler);
};
MyActor.prototype.append_error_notify = function (cb) {
let self = this;
if (self.__is_exited) {
if (self.__is_error) {
MyActor.check_exception_callback("append_error_notify callback error", cb);
}
} else {
self.__error_notify.push_back(cb);
}
};
MyActor.prototype.yield_wait_quit = function* (...otherActors) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_wait_quit not in actor");
let count = otherActors.length;
if (count) {
let inside = true;
for (let ele of otherActors) {
ele.append_quited_notify(function () {
count--;
if (0 == count) {
if (!inside) {
self.__pull_yield();
} else {
inside = false;
}
}
});
}
if (inside) {
inside = false;
yield null;
}
}
};
MyActor.prototype.yield_wait_once_quit = function* (... otherActors) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_wait_once_quit not in actor");
if (otherActors.length) {
let inside = true;
let returned = false;
let result = null;
for (let ele of otherActors) {
ele.append_quited_notify(function () {
if (!returned) {
returned = true;
if (!inside) {
self.__pull_yield(ele);
} else {
inside = false;
result = ele;
}
}
});
}
if (inside) {
inside = false;
return yield null;
}
return result;
}
};
MyActor.prototype.yield_timed_wait_quit = function* (ms, ...otherActors) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_timed_wait_quit not in actor");
let count = otherActors.length;
if (count) {
let inside = true;
let timeout = false;
let result = null;
for (let ele of otherActors) {
ele.append_quited_notify(function () {
count--;
if (0 == count && !timeout) {
if (!inside) {
self.__pull_yield(true);
} else {
inside = false;
result = true;
}
}
});
}
if (inside) {
inside = false;
self.__timer_out(function () {
timeout = true;
self.__pull_yield(false);
}, ms);
return yield null;
}
return result;
}
return true;
};
MyActor.prototype.yield_timed_wait_once_quit = function* (ms, ...otherActors) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_timed_wait_once_quit not in actor");
if (otherActors.length) {
let inside = true;
let returned = false;
let result = null;
for (let ele of otherActors) {
ele.append_quited_notify(function () {
if (!returned) {
returned = true;
if (!inside) {
self.__pull_yield({ok: true, value: ele});
} else {
inside = false;
result = {ok: true, value: ele};
}
}
});
}
if (inside) {
inside = false;
self.__timer_out(function () {
returned = true;
self.__pull_yield({ok: false});
}, ms);
return yield null;
}
return result;
}
return {ok: true};
};
MyActor.prototype.yield_children_wait_quit = function* () {
let self = this;
if (!self.__in_actor)
throw new Error("yield_children_wait_quit not in actor");
let count = self.__child_map.size;
if (count) {
let inside = true;
self.__child_map.forEach((child, id)=> child.append_quited_notify(function () {
count--;
if (0 == count) {
if (!inside) {
self.__pull_yield();
} else {
inside = false;
}
}
}));
if (inside) {
inside = false;
yield null;
}
}
};
MyActor.prototype.yield_children_wait_once_quit = function* () {
let self = this;
if (!self.__in_actor)
throw new Error("yield_children_wait_once_quit not in actor");
if (self.__child_map.size) {
let inside = true;
let returned = false;
self.__child_map.forEach((child, id)=> child.append_quited_notify(function () {
if (!returned) {
returned = true;
if (!inside) {
self.__pull_yield();
} else {
inside = false;
}
}
}));
if (inside) {
inside = false;
yield null;
}
}
};
MyActor.prototype.yield_children_timed_wait_quit = function* (ms) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_children_timed_wait_quit not in actor");
let count = self.__child_map.size;
if (count) {
let inside = true;
let timeout = false;
let result = null;
self.__child_map.forEach((child, id)=> child.append_quited_notify(function () {
count--;
if (0 == count && !timeout) {
if (!inside) {
self.__pull_yield(true);
} else {
inside = false;
result = true;
}
}
}));
if (inside) {
inside = false;
self.__timer_out(function () {
timeout = true;
self.__pull_yield(false);
}, ms);
return yield null;
}
return result;
}
return true;
};
MyActor.prototype.yield_children_timed_wait_once_quit = function* (ms) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_children_timed_wait_once_quit not in actor");
if (self.__child_map.size) {
let inside = true;
let returned = false;
let result = null;
self.__child_map.forEach((child, id)=> child.append_quited_notify(function () {
if (!returned) {
returned = true;
if (!inside) {
self.__pull_yield({ok: true, value: child});
} else {
inside = false;
result = {ok: true, value: child};
}
}
}));
if (inside) {
inside = false;
self.__timer_out(function () {
returned = true;
self.__pull_yield({ok: false});
}, ms);
return yield null;
}
return result;
}
return {ok: true};
};
MyActor.prototype.yield_wait_quit_result = function* (otherActor) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_wait_quit_result not in actor");
yield* self.yield_wait_quit(otherActor);
if (otherActor.is_error()) {
throw otherActor.result();
}
return otherActor.result();
};
MyActor.prototype.yield_sleep = function (ms) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_sleep not in actor");
self.__timer_out(function () {
self.__pull_yield();
}, ms);
};
MyActor.prototype.yield_tick = function () {
let self = this;
if (!self.__in_actor)
throw new Error("yield_tick not in actor");
self.__post_pull();
};
MyActor.prototype.make_notify_handle = function () {
let self = this;
let handle = {
__type: MyActor.__msg_type_notify_handle,
__msg_queue: new MsgQueue(),
__is_wait: false,
__closed: false,
__actor_id: self.__actor_id,
__warning_length: 0x7FFFFFFF,
__warning_handler: undefined
};
self.__quited_exec.push(function () {
handle.__closed = true;
handle.__warning_handler = undefined;
while (!handle.__msg_queue.empty()) {
let msg = handle.__msg_queue.pop_front();
if (msg.reply) {
MyActor.check_exception_callback("notify reply error", ()=> msg.reply(undefined, {err: "not processed"}));
}
}
});
return handle;
};
MyActor.prototype.make_multi_notify_handle = function (num) {
let self = this;
if (isNaN(num) || num > 10) {
throw new Error("make_multi_notify_handle error");
}
let result = [];
for (let i = 0; i < num; i++) {
result[i] = self.make_notify_handle();
}
return result;
};
MyActor.prototype.notify_msg_number = function (handle) {
let self = this;
if (!self.__in_actor)
throw new Error("notify_msg_number not in actor");
return handle.__msg_queue.length();
};
MyActor.prototype.notify_msg_warning = function (handle, num, handler) {
let self = this;
if (!self.__in_actor)
throw new Error("notify_msg_warning not in actor");
handle.__warning_length = num;
if (handler) {
handle.__warning_handler = handler;
} else {
handle.__warning_handler = function () {
throw new Error("notify msg is too much");
};
}
};
MyActor.prototype.make_notify = function (handle) {
let self = this;
return self.make_notify_translate(handle);
};
MyActor.prototype.make_notify_translate = function (handle, translator) {
let self = this;
return function (...args) {
if (translator) {
args = translator(...args);
}
let [msg, reply] = args;
if (!handle.__is_quited) {
if (!handle.__closed) {
if (handle.__is_wait) {
handle.__is_wait = false;
if (self.__timer_completed) {
self.__pull_yield({value: msg, reply: reply});
} else {
self.__cancel_timer();
self.__pull_yield({ok: true, value: msg, reply: reply});
}
} else {
handle.__msg_queue.push_back({value: msg, reply: reply});
if (handle.__msg_queue.length() > handle.__warning_length) {
MyActor.check_exception_callback("notify warning error", ()=> handle.__warning_handler());
}
}
} else if (reply) {
MyActor.check_exception_callback("notify reply error", ()=> reply(undefined, {err: "not receive"}));
}
} else {
if (!handle.__is_exited) {
handle.__msg_queue.push_back({value: msg, reply: reply});
} else if (reply) {
MyActor.check_exception_callback("notify reply error", ()=> reply(undefined, {err: "not receive"}));
}
}
}
};
MyActor.prototype.yield_wait_notify = function* (handle) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_wait_notify not in actor");
if (handle.__actor_id != self.__actor_id)
throw new Error("yield_wait_notify is not current actor");
if (handle.__msg_queue.empty()) {
handle.__is_wait = true;
return yield null;
}
return handle.__msg_queue.pop_front();
};
MyActor.prototype.yield_wait_many_notify = function* (handle, num) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_wait_many_notify not in actor");
if (handle.__actor_id != self.__actor_id)
throw new Error("yield_wait_many_notify is not current actor");
let result = [];
while (num-- > 0) {
if (handle.__msg_queue.empty()) {
handle.__is_wait = true;
result.push(yield null);
} else {
result.push(handle.__msg_queue.pop_front());
}
}
return result;
};
MyActor.prototype.yield_timed_wait_notify = function* (ms, handle) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_timed_wait_notify not in actor");
if (handle.__actor_id != self.__actor_id)
throw new Error("yield_timed_wait_notify is not current actor");
if (handle.__msg_queue.empty()) {
handle.__is_wait = true;
self.__timer_out(function () {
handle.__is_wait = false;
self.__pull_yield({ok: false});
}, ms);
return yield null;
}
let msg = handle.__msg_queue.pop_front();
return {ok: true, value: msg.value, reply: msg.reply};
};
MyActor.prototype.close_notify_handle = function (...handles) {
let self = this;
if (!self.__in_actor)
throw new Error("close_notify_handle not in actor");
for (let handle of handles) {
if (handle.__actor_id != self.__actor_id)
throw new Error("close_notify_handle is not current actor");
handle.__closed = true;
handle.__warning_handler = undefined;
while (!handle.__msg_queue.empty()) {
let msg = handle.__msg_queue.pop_front();
if (msg.reply) {
MyActor.check_exception_callback("notify reply error", ()=> msg.reply(undefined, {err: "not processed"}));
}
}
}
};
MyActor.prototype.close_trig_handle = function (...handles) {
let self = this;
if (!self.__in_actor)
throw new Error("close_trig_handle not in actor");
for (let handle of handles) {
if (handle.__actor_id != self.__actor_id)
throw new Error("close_trig_handle is not current actor");
handle.__closed = true;
if (handle.__has_msg) {
handle.__has_msg = false;
if (handle.__msg.reply) {
MyActor.check_exception_callback("trig reply error", ()=> handle.__msg.reply(undefined, {err: "not processed"}));
handle.__msg = undefined;
}
}
}
};
MyActor.prototype.is_handle_closed = function (handle) {
return handle.__closed;
};
MyActor.prototype.make_trig_handle = function () {
let self = this;
let handle = {
__type: MyActor.__msg_type_trig_handle,
__msg: undefined,
__is_triged: false,
__is_wait: false,
__closed: false,
__has_msg: false,
__actor_id: self.__actor_id
};
self.__quited_exec.push(function () {
handle.__closed = true;
if (handle.__has_msg) {
handle.__has_msg = false;
if (handle.__msg.reply) {
MyActor.check_exception_callback("trig reply error", ()=> handle.__msg.reply(undefined, {err: "not processed"}));
handle.__msg = undefined;
}
}
});
return handle;
};
MyActor.prototype.make_multi_trig_handle = function (num) {
let self = this;
if (isNaN(num) || num > 10) {
throw new Error("make_multi_trig_handle error");
}
let result = [];
for (let i = 0; i < num; i++) {
result[i] = self.make_trig_handle();
}
return result;
};
MyActor.prototype.make_trig = function (handle) {
let self = this;
return self.make_trig_translate(handle);
};
MyActor.prototype.make_trig_translate = function (handle, translator) {
let self = this;
return function (...args) {
if (translator) {
args = translator(...args);
}
let [msg, reply] = args;
if (!self.__is_quited) {
if (!handle.__is_triged && !handle.__closed) {
handle.__is_triged = true;
if (handle.__is_wait) {
handle.__is_wait = false;
if (self.__timer_completed) {
self.__pull_yield({value: msg, reply: reply});
} else {
self.__cancel_timer();
self.__pull_yield({ok: true, value: msg, reply: reply});
}
} else {
handle.__has_msg = true;
handle.__msg = {value: msg, reply: reply};
}
} else if (reply) {
MyActor.check_exception_callback("trig reply error", ()=> reply(undefined, {err: "not receive"}));
}
} else {
if (!self.__is_exited && !handle.__is_triged) {
handle.__has_msg = true;
handle.__msg = {value: msg, reply: reply};
} else if (reply) {
MyActor.check_exception_callback("trig reply error", ()=> reply(undefined, {err: "not receive"}));
}
}
}
};
MyActor.prototype.yield_wait_trig = function* (handle) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_wait_trig not in actor");
if (handle.__actor_id != self.__actor_id)
throw new Error("yield_wait_trig is not current actor");
if (!handle.__has_msg) {
handle.__is_wait = true;
return yield null;
}
handle.__has_msg = false;
let msg = handle.__msg;
handle.__msg = undefined;
return msg;
};
MyActor.prototype.yield_timed_wait_trig = function* (ms, handle) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_timed_wait_trig not in actor");
if (handle.__actor_id != self.__actor_id)
throw new Error("yield_timed_wait_trig is not current actor");
if (!handle.__has_msg) {
handle.__is_wait = true;
self.__timer_out(function () {
handle.__is_wait = false;
self.__pull_yield({ok: false});
}, ms);
return yield null;
}
handle.__has_msg = false;
return {ok: true, value: handle.__msg.value, reply: handle.__msg.reply};
};
MyActor.prototype.get_msg_handle = function (id) {
let self = this;
return self.__msg_handle(id);
};
MyActor.prototype.get_quit_handle = function () {
return {__type: MyActor.__msg_type_quit_handle, __optioned: false};
};
MyActor.prototype.msg_number = function (id) {
let self = this;
if (!self.__in_actor)
throw new Error("msg_number not in actor");
return self.__msg_handle(id).__msg_state.__msg_queue.length();
};
MyActor.prototype.post_msg = function (id, msg, reply) {
let self = this;
self.make_msg_notify(id)(msg, reply);
};
MyActor.prototype.yield_send_msg = function* (otherActor, id, msg) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_send_msg not in actor");
let inside = true;
let result = null;
otherActor.post_msg(id, msg, function (...args) {
if (!inside) {
self.__pull_yield(args);
} else {
inside = false;
result = args;
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
MyActor.prototype.make_channel_handle = function (maxLength = 0) {
return new Channel(maxLength);
};
MyActor.prototype.yield_channel_push = function (handle, msg) {
return handle.yield_push(msg);
};
MyActor.prototype.yield_channel_try_push = function (handle, msg) {
return handle.yield_try_push(msg);
};
MyActor.prototype.yield_channel_timed_push = function (handle, ms, msg) {
return handle.yield_timed_push(ms, msg);
};
MyActor.prototype.yield_channel_pop = function (handle) {
return handle.yield_pop();
};
MyActor.prototype.yield_channel_try_pop = function (handle) {
return handle.yield_try_pop();
};
MyActor.prototype.yield_channel_timed_pop = function (handle, ms) {
return handle.yield_timed_pop(ms);
};
MyActor.prototype.make_csp_handle = function() {
return new Csp();
};
MyActor.prototype.yield_csp_invoke = function (handle, ...args) {
return handle.yield_invoke(...args);
};
MyActor.prototype.yield_timed_csp_invoke = function (ms, handle, ...args) {
return handle.yield_timed_invoke(ms, ...args);
};
MyActor.prototype.yield_try_csp_invoke = function (handle, ...args) {
return handle.yield_try_invoke(...args);
};
MyActor.prototype.yield_wait_csp = function (handle, handler) {
return handle.yield_wait(handler);
};
MyActor.prototype.yield_timed_wait_csp = function (ms, handle, handler) {
return handle.yield_timed_wait(ms, handler);
};
MyActor.prototype.yield_try_wait_csp = function (handle, handler) {
return handle.yield_try_wait(handler);
};
MyActor.prototype.make_msg_notify = function (id) {
let self = this;
let msg_handle = self.__msg_handle(id);
return function (msg, reply) {
let ele = msg_handle;
if (!self.__is_quited) {
if (!ele.__msg_state.__is_wait) {
ele.__msg_state.__msg_queue.push_back({value: msg, reply: reply});
} else {
ele.__msg_state.__is_wait = false;
let processActor;
do {
processActor = ele.__ext_actor;
ele = ele.__agent_handle;
} while (ele);
if (processActor) {
if (processActor.__timer_completed) {
processActor.__pull_yield({value: msg, reply: reply});
} else {
processActor.__cancel_timer();
processActor.__pull_yield({ok: true, value: msg, reply: reply})
}
}
}
} else {
if (self.__is_exited) {
if (ele.__root_id != self.__root_id) {
ele.__msg_state.__msg_queue.push_back({value: msg, reply: reply});
} else if (reply) {
MyActor.check_exception_callback("msg reply error", ()=> reply(undefined, {err: "not receive"}));
}
} else {
ele.__msg_state.__msg_queue.push_back({value: msg, reply: reply});
}
}
}
};
MyActor.prototype.make_msg_sender = function (id) {
let self = this;
let notify = self.make_msg_notify(id);
return function* (msg) {
let host = MyActor.self_actor();
if (!host.__in_actor)
throw new Error("msg_sender not in actor");
let inside = true;
let result = null;
notify(msg, function (...reply) {
if (!inside) {
host.__pull_yield(reply);
} else {
inside = false;
result = reply;
}
});
if (inside) {
inside = false;
return yield null;
}
return result;
};
};
MyActor.prototype.msg_agent_to = function (id, childActor) {
let self = this;
if (!self.__in_actor)
throw new Error("msg_agent_to not in actor");
if (childActor.__parent_actor_id != self.__actor_id)
throw new Error("msg_agent_to error");
if (childActor.__is_quited)
return false;
let ele = self.__msg_handle(id);
if (ele.__agent_handle && ele.__agent_handle.__ext_actor && ele.__agent_handle.__ext_actor.__actor_id == childActor.__actor_id)
return false;
if (ele.__agent_handle)
self.cancel_msg_agent(id);
let eleit = childActor.__msg_handle(id);
let eleStateBak = eleit.__msg_state;
do {
eleit.__msg_state = ele.__msg_state;
eleit.__root_id = ele.__root_id;
ele.__agent_handle = eleit;
ele = eleit;
eleit = eleit.__agent_handle;
} while (eleit);
if (eleStateBak.__is_wait) {
eleStateBak.__is_wait = false;
if (!ele.__is_quited) {
if (ele.__msg_state.__msg_queue.empty()) {
ele.__msg_state.__is_wait = true;
} else {
if (ele.__ext_actor.__timer_completed) {
ele.__ext_actor.__pull_yield(ele.__msg_state.__msg_queue.pop_front());
} else {
ele.__ext_actor.__cancel_timer();
let msg = ele.__msg_state.__msg_queue.pop_front();
ele.__ext_actor.__pull_yield({ok: true, value: msg.value, reply: msg.reply});
}
}
}
}
return true;
};
MyActor.prototype.cancel_msg_agent = function (id) {
let self = this;
if (!self.__in_actor)
throw new Error("cancel_msg_agent not in actor");
let ele = self.__msg_handle(id);
let eleit = ele.__agent_handle;
ele.__agent_handle = null;
if (eleit && eleit.__ext_actor) {
let rootId = eleit.__ext_actor.__actor_id;
let newState = {
__msg_queue: new MsgQueue(),
__is_wait: ele.__msg_state.__is_wait
};
do {
eleit.__msg_state.__is_wait = false;
eleit.__msg_state = newState;
eleit.__root_id = rootId;
eleit = eleit.__agent_handle;
} while (eleit);
}
};
MyActor.prototype.yield_wait_msg = function* (id) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_wait_msg not in actor");
let ele = self.__msg_handle(id);
if (ele.__agent_handle)
self.cancel_msg_agent(id);
if (ele.__msg_state.__msg_queue.empty()) {
ele.__msg_state.__is_wait = true;
return yield null;
}
return ele.__msg_state.__msg_queue.pop_front();
};
MyActor.prototype.yield_wait_many_msg = function* (id, num) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_wait_many_msg not in actor");
let ele = self.__msg_handle(id);
if (ele.__agent_handle)
self.cancel_msg_agent(id);
let result = [];
while (num-- > 0) {
if (ele.__msg_state.__msg_queue.empty()) {
ele.__msg_state.__is_wait = true;
result.push(yield null);
} else {
result.push(ele.__msg_state.__msg_queue.pop_front());
}
}
return result;
};
MyActor.prototype.yield_timed_wait_msg = function* (ms, id) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_timed_wait_msg not in actor");
let ele = self.__msg_handle(id);
if (ele.__agent_handle)
self.cancel_msg_agent(id);
if (ele.__msg_state.__msg_queue.empty()) {
ele.__msg_state.__is_wait = true;
self.__timer_out(function () {
ele.__msg_state.__is_wait = false;
self.__pull_yield({ok: false});
}, ms);
return yield null;
}
let msg = ele.__msg_state.__msg_queue.pop_front();
return {ok: true, value: msg.value, reply: msg.reply};
};
MyActor.prototype.yield_select_msg = function* (...args) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_select_msg not in actor");
for (let i = 0; i < args.length; i+=2) {
if (undefined === args[i].__type) {
throw new Error("yield_select_msg param is error");
}
if (args[i].__type == MyActor.__msg_type_channel_handle) {
args[i] = {__type: MyActor.__msg_type_channel_handle, channel: args[i], ntfSign: {__ntf_sign: true, __effect: false}};
}
}
let cspNode;
let setHandleWait = function (handle, is_wait) {
switch (handle.__type) {
case MyActor.__msg_type_notify_handle: handle.__is_wait = is_wait; break;
case MyActor.__msg_type_trig_handle: handle.__is_wait = is_wait; break;
case MyActor.__msg_type_msg_handle: handle.__msg_state.__is_wait = is_wait; break;
case MyActor.__msg_type_csp_handle:
if (is_wait) {
cspNode = handle.__receiver_queue.push_back(self);
} else if (!handle.__receiver_queue.is_invalid(cspNode)) {
handle.__receiver_queue.erase(cspNode);
}
break;
case MyActor.__msg_type_channel_handle:
if (is_wait) {
handle.channel.append_pop_notify(function (state) {
handle.channel.try_pop((state, msg)=> self.__pull_yield([state, msg]));
}, handle.ntfSign);
} else {
handle.channel.remove_pop_notify(handle.ntfSign);
}
break;
case MyActor.__msg_type_quit_handle: self.__wait_quit_msg = handle.__optioned ? false : is_wait; break;
}
};
let getHandleIsWait = function (handle) {
switch (handle.__type) {
case MyActor.__msg_type_notify_handle: return handle.__is_wait;
case MyActor.__msg_type_trig_handle: return handle.__is_wait;
case MyActor.__msg_type_msg_handle: return handle.__msg_state.__is_wait;
case MyActor.__msg_type_csp_handle: return !handle.__receiver_queue.is_invalid(cspNode);
case MyActor.__msg_type_channel_handle: return !handle.ntfSign.__ntf_sign;
case MyActor.__msg_type_quit_handle:
let res = handle.__optioned ? true : self.__wait_quit_msg;
if (!res) {
handle.__optioned = true;
}
return res;
}
};
let handleInvoke = function(handle, handler, msg) {
switch (handle.__type) {
case MyActor.__msg_type_notify_handle: return handler(msg);
case MyActor.__msg_type_trig_handle: return handler(msg);
case MyActor.__msg_type_msg_handle: return handler(msg);
case MyActor.__msg_type_csp_handle: return handler(msg[0], msg[1]);
case MyActor.__msg_type_channel_handle: return handler(msg[0], msg[1]);
case MyActor.__msg_type_quit_handle: return handler();
}
};
let stop = false;
do {
let runOnce = false;
for (let i = 0; i < args.length && !runOnce && !stop; i+=2) {
let handle = args[i];
try {
switch (handle.__type) {
case MyActor.__msg_type_notify_handle:
if (!handle.__msg_queue.empty()) {
runOnce = true;
stop = yield* handleInvoke(handle, args[i + 1], handle.__msg_queue.pop_front());
}
break;
case MyActor.__msg_type_trig_handle:
if (handle.__has_msg) {
runOnce = true;
handle.__has_msg = false;
handle.__is_triged = true;
let msg = handle.__msg;
handle.__msg = undefined;
stop = yield* handleInvoke(handle, args[i + 1], msg);
}
break;
case MyActor.__msg_type_msg_handle:
if (!handle.__msg_state.__msg_queue.empty()) {
runOnce = true;
stop = yield* handleInvoke(handle, args[i + 1], handle.__msg_state.__msg_queue.pop_front());
}
break;
case MyActor.__msg_type_csp_handle:
if (!handle.__sender_queue.empty()) {
runOnce = true;
let [src, reply, msg] = handle.__sender_queue.pop_front();
src.__cancel_timer();
stop = yield* handleInvoke(handle, args[i + 1], [reply, msg]);
}
break;
case MyActor.__msg_type_channel_handle:
if (handle.channel.__has_msg()) {
runOnce = true;
let result = null;
handle.channel.try_pop((state, msg)=> result = [state, msg]);
stop = yield* handleInvoke(handle, args[i + 1], result);
}
break;
case MyActor.__msg_type_quit_handle:
if (self.__hold_quited && !handle.__optioned) {
handle.__optioned = true;
stop = yield* handleInvoke(handle, args[i + 1]);
}
break;
}
} catch (err) {
global.__MyActor_exception_handler("select msg handler exception", err);
}
}
if (!runOnce) {
for (let i = 0; i < args.length; i+=2) {
setHandleWait(args[i], true);
}
let msg = yield null;
for (let i = 0; i < args.length; i+=2) {
if (!getHandleIsWait(args[i])) {
let ti = i;
for (i+=2; i < args.length; i+=2) {
setHandleWait(args[i], false);
}
try {
stop = yield* handleInvoke(args[ti], args[ti + 1], msg);
} catch(err) {
global.__MyActor_exception_handler("select msg handler exception", err);
}
break;
} else {
setHandleWait(args[i], false);
}
}
}
} while (!stop);
};
MyActor.prototype.delay_trig = function (ms, handler) {
let self = this;
if (!self.__in_actor)
throw new Error("delay_trig not in actor");
self.__timer_out(handler, ms);
};
MyActor.prototype.cancel_delay_trig = function () {
let self = this;
if (!self.__in_actor)
throw new Error("cancel_delay_trig not in actor");
self.__cancel_timer();
};
MyActor.prototype.make_context = function () {
let self = this;
if (!self.__in_actor)
throw new Error("make_context not in actor");
let contextId = self.__context_count;
return function (arg) {
if (contextId == self.__context_count) {
self.__context_count++;
self.__post_pull(arg);
} else {
throw new Error("make_context repeat callback");
}
};
};
MyActor.prototype.make_asio_context = function () {
let self = this;
if (!self.__in_actor)
throw new Error("make_asio_context not in actor");
let contextId = self.__context_count;
return function (arg) {
if (contextId == self.__context_count) {
self.__context_count++;
self.__pull_yield(arg);
} else {
throw new Error("make_asio_context repeat callback");
}
};
};
MyActor.prototype.make_multi_context = function () {
let self = this;
if (!self.__in_actor)
throw new Error("make_multi_context not in actor");
let contextId = self.__context_count;
return function (...args) {
if (contextId == self.__context_count) {
self.__context_count++;
self.__post_pull(args);
} else {
throw new Error("make_multi_context repeat callback");
}
};
};
MyActor.prototype.make_asio_multi_context = function () {
let self = this;
if (!self.__in_actor)
throw new Error("make_asio_multi_context not in actor");
let contextId = self.__context_count;
return function (...args) {
if (contextId == self.__context_count) {
self.__context_count++;
self.__pull_yield(args);
} else {
throw new Error("make_asio_multi_context repeat callback");
}
};
};
MyActor.prototype.make_timed_context = function (ms, overtimeHandler) {
let self = this;
if (!self.__in_actor)
throw new Error("make_timed_context not in actor");
let overtime = false;
let contextId = self.__context_count;
self.__timer_out(function () {
overtime = true;
if (overtimeHandler) {
MyActor.check_exception_callback("make_timed_context callback error", overtimeHandler);
}
self.__pull_yield({ok: false});
}, ms);
return function (arg) {
setImmediate(function () {
if (contextId == self.__context_count) {
self.__context_count++;
if (!overtime) {
self.__cancel_timer();
self.__pull_yield({ok: true, value: arg});
}
} else {
throw new Error("make_timed_context repeat callback");
}
});
};
};
MyActor.prototype.make_timed_multi_context = function (ms, overtimeHandler) {
let self = this;
if (!self.__in_actor)
throw new Error("make_timed_multi_context not in actor");
let overtime = false;
let contextId = self.__context_count;
self.__timer_out(function () {
overtime = true;
if (overtimeHandler) {
MyActor.check_exception_callback("make_timed_multi_context callback error", overtimeHandler);
}
self.__pull_yield({ok: false});
}, ms);
return function (...args) {
setImmediate(function () {
if (contextId == self.__context_count) {
self.__context_count++;
if (!overtime) {
self.__cancel_timer();
self.__pull_yield({ok: true, value: args});
}
} else {
throw new Error("make_timed_multi_context repeat callback");
}
});
};
};
MyActor.prototype.make_timed_asio_context = function (ms, overtimeHandler) {
let self = this;
if (!self.__in_actor)
throw new Error("make_timed_asio_context not in actor");
let overtime = false;
let contextId = self.__context_count;
self.__timer_out(function () {
overtime = true;
if (overtimeHandler) {
MyActor.check_exception_callback("make_timed_asio_context callback error", overtimeHandler);
}
self.__pull_yield({ok: false});
}, ms);
return function (arg) {
if (contextId == self.__context_count) {
self.__context_count++;
if (!overtime) {
self.__cancel_timer();
self.__pull_yield({ok: true, value: arg});
}
} else {
throw new Error("make_timed_asio_context repeat callback");
}
};
};
MyActor.prototype.make_timed_asio_multi_context = function (ms, overtimeHandler) {
let self = this;
if (!self.__in_actor)
throw new Error("make_timed_asio_multi_context not in actor");
let overtime = false;
let contextId = self.__context_count;
self.__timer_out(function () {
overtime = true;
if (overtimeHandler) {
MyActor.check_exception_callback("make_timed_asio_multi_context callback error", overtimeHandler);
}
self.__pull_yield({ok: false});
}, ms);
return function (...args) {
if (contextId == self.__context_count) {
self.__context_count++;
if (!overtime) {
self.__cancel_timer();
self.__pull_yield({ok: true, value: args});
}
} else {
throw new Error("make_timed_asio_multi_context repeat callback");
}
};
};
MyActor.prototype.yield_quit_guard = function* (handler) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_quit_guard not in actor");
self.lock_quit();
yield* handler();
yield* self.yield_unlock_quit();
};
MyActor.prototype.yield_suspend_guard = function* (handler) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_suspend_guard not in actor");
self.lock_suspend();
yield* handler();
yield* self.yield_unlock_suspend();
};
MyActor.prototype.yield_lock_guard = function* (handle, handler) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_lock_guard not in actor");
yield* handle.yield_lock();
yield* handler();
handle.unlock();
};
MyActor.prototype.yield_shared_guard = function* (handle, handler) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_shared_guard not in actor");
yield* handle.yield_lock_shared();
yield* handler();
handle.unlock_shared();
};
MyActor.prototype.yield_pess_shared_guard = function* (handle, handler) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_pess_shared_guard not in actor");
yield* handle.yield_lock_pess_shared();
yield* handler();
handle.unlock_shared();
};
MyActor.prototype.yield_upgrade_guard = function* (handle, handler) {
let self = this;
if (!self.__in_actor)
throw new Error("yield_upgrade_guard not in actor");
yield* handle.yield_lock_upgrade();
yield* handler();
handle.unlock_upgrade();
};
MyActor.prototype.__make_msg_handle = function () {
let self = this;
return {
__type: 2,
__agent_handle: null,
__ext_actor: self,
__root_id: self.__actor_id,
__msg_state: {
__msg_queue: new MsgQueue(),
__is_wait: false
}
};
};
MyActor.prototype.__msg_handle = function (id) {
let self = this;
let handle = self.__msg_table[id];
if (!handle) {
handle = self.__make_msg_handle();
self.__msg_table[id] = handle;
}
return handle;
};
MyActor.prototype.__timer_out = function (handler, ms) {
let self = this;
if (!self.__timer_completed)
throw new Error("timer error");
if (isNaN(ms))
throw new Error("timer number error");
self.__timer_completed = false;
self.__timer_timeout = ms;
self.__timer_handler = handler;
self.__timer_id = setTimeout(function () {
self.__timer_id = null;
self.__timer_completed = true;
self.__timer_handler();
if (self.__timer_completed)
self.__timer_handler = null;
}, ms);
self.__timer_start = self.__timer_id._idleStart;
if (undefined == self.__timer_start) {
self.__timer_stamp();
}
};
MyActor.prototype.__cancel_timer = function () {
let self = this;
if (!self.__timer_completed)
{
self.__timer_completed = true;
self.__timer_handler = null;
if (self.__timer_id) {
clearTimeout(self.__timer_id);
self.__timer_id = null
}
}
};
MyActor.prototype.__suspend_timer = function () {
let self = this;
if (!self.__timer_suspended) {
self.__timer_suspended = true;
if (!self.__timer_completed) {
clearTimeout(self.__timer_id);
self.__timer_id = null;
self.__timer_end = self.__timer_stamp();
if (self.__timer_end > self.__timer_start + self.__timer_timeout) {
self.__timer_end = self.__timer_start + self.__timer_timeout;
}
}
}
};
MyActor.prototype.__resume_timer = function () {
let self = this;
if (self.__timer_suspended) {
self.__timer_suspended = false;
if (!self.__timer_completed) {
self.__timer_timeout -= self.__timer_end - self.__timer_start;
self.__timer_id = setTimeout(function () {
self.__timer_id = null;
self.__timer_completed = true;
self.__timer_handler();
if (self.__timer_completed)
self.__timer_handler = null;
}, self.__timer_timeout);
}
}
};
MyActor.prototype.__timer_stamp = function () {
return (new Date()).valueOf() - global.__MyActor_delta_stamp;
};
MyActor.prototype.__get_tick = function () {
return (new Date()).valueOf();
};
MyActor.prototype.__pull_yield = function (arg) {
let self = this;
self.__cancel_timer();
if (!self.__is_quited) {
if (self.__is_suspend) {
self.__hold_pull = true;
self.__temp_result = arg;
return;
}
let old = global.__MyActor_self_actor;
global.__MyActor_self_actor = self;
self.__in_actor = true;
let result;
try {
result = self.__top_handler.next(arg);
} catch (err) {
global.__MyActor_exception_handler("an uncaught actor exception:", err);
self.__handler_stack.clear();
self.__is_error = true;
result = {done: true, value: err};
self.__child_map.forEach((child, id)=> child.force_quit());
}
self.__in_actor = false;
global.__MyActor_self_actor = old;
if (result.done) {
if (self.__handler_stack.empty()) {
self.__is_quited = true;
self.__result = result.value;
if (0 == self.__child_map.size) {
self.__quited_to_do();
}
} else {
self.__top_handler = self.__handler_stack.pop();
self.__pull_yield(result.value);
}
} else if (result.value) {
if (result.value.constructor === self.__top_handler.constructor) {
self.__handler_stack.push(self.__top_handler);
self.__top_handler = result.value;
self.__pull_yield();
}
}
}
};
MyActor.prototype.__tick_pull = function (arg) {
let self = this;
process.nextTick(function () {
self.__pull_yield(arg);
});
};
MyActor.prototype.__post_pull = function (arg) {
let self = this;
setImmediate(function () {
self.__pull_yield(arg);
})
};
MyActor.prototype.__notify_suspend = function (cb) {
let self = this;
if (!self.__is_exited) {
self.__suspend_queue.push_back({is_suspend: true, cb: cb});
if (!self.__lock_suspend) {
if (1 == self.__suspend_queue.length()) {
self.__suspend();
}
} else {
self.__hold_suspended = true;
}
} else {
cb();
}
};
MyActor.prototype.__suspend = function () {
let self = this;
self.__suspend_timer();
self.__is_suspend = true;
if (self.__child_map.size) {
let count = self.__child_map.size;
self.__child_map.forEach((child, id)=> child.__notify_suspend(function () {
count--;
if (0 == count) {
child_suspend_then();
}
}));
} else {
child_suspend_then();
}
function child_suspend_then() {
self.__suspend_queue.pop_front().cb();
if (!self.__suspend_queue.empty()) {
if (self.__suspend_queue.front().is_suspend) {
self.__suspend();
} else {
self.__resume();
}
}
}
};
MyActor.prototype.__notify_resume = function (cb) {
let self = this;
if (!self.__is_exited) {
self.__suspend_queue.push_back({is_suspend: false, cb: cb});
if (!self.__lock_suspend) {
if (1 == self.__suspend_queue.length()) {
self.__resume();
}
} else {
self.__hold_suspended = true;
}
} else {
cb();
}
};
MyActor.prototype.__resume = function () {
let self = this;
if (self.__child_map.size) {
let count = self.__child_map.size;
self.__child_map.forEach((child, id)=> child.__notify_resume(function () {
count--;
if (0 == count) {
child_resume_then();
}
}));
} else {
child_resume_then();
}
function child_resume_then() {
self.__suspend_queue.pop_front().cb();
if (!self.__suspend_queue.empty()) {
if (self.__suspend_queue.front().is_suspend) {
self.__suspend();
} else {
self.__resume();
}
} else {
self.__resume_timer();
self.__is_suspend = false;
if (self.__hold_pull) {
self.__hold_pull = false;
let p = self.__temp_result;
self.__temp_result = undefined;
self.__pull_yield(p);
}
}
}
};
MyActor.prototype.__quited_to_do = function () {
let self = this;
self.__is_exited = true;
for (let i in self.__msg_table) {
let ele = self.__msg_table[i];
ele.__ext_actor = null;
ele.__agent_handle = null;
if (ele.__root_id == self.__actor_id) {
ele.__msg_state.__is_wait = false;
while (!ele.__msg_state.__msg_queue.empty()) {
let eleMsg = ele.__msg_state.__msg_queue.pop_front();
if (eleMsg.reply) {
MyActor.check_exception_callback("msg reply error", ()=> eleMsg.reply(undefined, {err: "not processed"}));
}
}
}
}
while (!self.__suspend_queue.empty()) {
MyActor.check_exception_callback("suspend_queue callback error", self.__suspend_queue.pop_front().cb);
}
while (self.__quited_exec.length) {
MyActor.check_exception_callback("quited_exec callback error", self.__quited_exec.pop());
}
while (!self.__quited_notify.empty()) {
MyActor.check_exception_callback("quited_notify error", self.__quited_notify.pop_front());
}
if (self.__quited_callback) {
MyActor.check_exception_callback("quited_callback error",
()=> !self.__is_error ? self.__quited_callback(self.__result) : self.__quited_callback(undefined, self.__result));
self.__quited_callback = null;
}
if (self.__is_error) {
while (!self.__error_notify.empty()) {
MyActor.check_exception_callback("error_callback error", self.__error_notify.pop_front());
}
} else {
self.__error_notify.clear();
}
self.__temp_result = undefined;
self.__suspend_queue = null;
self.__top_handler = null;
self.__handler_stack = null;
self.__quited_notify = null;
self.__error_notify = null;
self.__child_map = null;
};
MyActor.prototype.__child_quited_handler = function (child) {
let self = this;
self.__child_map.delete(child.__actor_id);
if (0 == self.__child_map.size) {
if (self.__is_quited) {
self.__quited_to_do();
}
}
};
/////////////////////////////////////////////////////////end///////////////////////////////////////////////////////////
exports.MsgQueue = MsgQueue;
exports.Stack = Stack;
exports.List = List;
exports.Channel = Channel;
exports.Csp = Csp;
exports.Mutex = Mutex;
exports.SharedMutex = SharedMutex;
exports.MyActor = MyActor;
exports.create = MyActor.create;
exports.bind = MyActor.bind;
exports.sleep = MyActor.sleep;
exports.tick = MyActor.tick;
exports.time_string = MyActor.time_string;
exports.tick_string = MyActor.tick_string;
exports.self_actor = MyActor.self_actor;
exports.create_queue = MyActor.create_queue;
exports.create_stack = MyActor.create_stack;
exports.create_list = MyActor.create_list;
exports.create_async_queue = MyActor.create_async_queue;
exports.register_exception_handler = MyActor.register_exception_handler;
exports.wrap_hold_work = MyActor.wrap_hold_work;
exports.hold_work = MyActor.hold_work;
exports.release_work = MyActor.release_work;
exports.force_trace_error_stack = MyActor.force_trace_error_stack;
exports.enable_source_map_trace = MyActor.enable_source_map_trace;
exports.check_exception_callback = MyActor.check_exception_callback;
exports.make_mutex = MyActor.make_mutex;
exports.make_shared_mutex = MyActor.make_shared_mutex;
exports.make_condition_variable = MyActor.make_condition_variable;
exports.trace = MyActor.trace;
exports.trace_flush = MyActor.trace_flush;
exports.trace_space = MyActor.trace_space;
exports.trace_comma = MyActor.trace_comma;
exports.wrap_post = MyActor.wrap_post;
exports.wrap_post_target = MyActor.wrap_post_target;
exports.wrap_tick = MyActor.wrap_tick;
exports.wrap_tick_target = MyActor.wrap_tick_target;
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。