1 Star 0 Fork 0

cuijinquan/nodejs actor framework

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
.babelrc
main.js
my_actor.js
readme.txt
to_web.js
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
my_actor.js 126.49 KB
一键复制 编辑 原始数据 按行查看 历史
hamasm 提交于 9年前 . no message
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018
/**
* 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;
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
NodeJS
1
https://gitee.com/cuijinquan/nodejs-actor-framework.git
git@gitee.com:cuijinquan/nodejs-actor-framework.git
cuijinquan
nodejs-actor-framework
nodejs actor framework
master

搜索帮助