initial commit
This commit is contained in:
commit
4b60ece582
327 changed files with 28286 additions and 0 deletions
6
libjs/wModel/proxy/CMakeLists.txt
Normal file
6
libjs/wModel/proxy/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
configure_file(proxy.js proxy.js)
|
||||
configure_file(list.js list.js)
|
||||
configure_file(vocabulary.js vocabulary.js)
|
||||
configure_file(catalogue.js catalogue.js)
|
54
libjs/wModel/proxy/catalogue.js
Normal file
54
libjs/wModel/proxy/catalogue.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
"use strict";
|
||||
|
||||
var Proxy = require("./proxy");
|
||||
var Vocabulary = require("../../wType/vocabulary");
|
||||
var Vector = require("../../wType/vector");
|
||||
var Ctrl = require("../../wController/catalogue");
|
||||
|
||||
var Catalogue = Proxy.inherit({
|
||||
"className": "List", //no, it is not a typo, this is the way data structure here suppose to look like
|
||||
"constructor": function(address, ctrlAddr, ctrlOpts, socket) {
|
||||
var controller = new Ctrl(ctrlAddr, ctrlOpts);
|
||||
Proxy.fn.constructor.call(this, address, controller, socket);
|
||||
|
||||
this.controller.on("data", this._onRemoteData, this);
|
||||
this.controller.on("addElement", this._onRemoteAddElement, this);
|
||||
//this.controller.on("removeElement", this._onRemoteRemoveElement, this); //not supported yet
|
||||
},
|
||||
"_getAllData": function() {
|
||||
var vec = new Vector();
|
||||
|
||||
var itr = this.controller.data.begin();
|
||||
var end = this.controller.data.end();
|
||||
|
||||
for (; !itr["=="](end); itr["++"]()) {
|
||||
vec.push(itr["*"]().clone());
|
||||
}
|
||||
|
||||
return vec;
|
||||
},
|
||||
"_h_subscribe": function(ev) {
|
||||
Proxy.fn._h_subscribe.call(this, ev);
|
||||
|
||||
if (this.ready) {
|
||||
this._h_get(ev);
|
||||
}
|
||||
},
|
||||
"_onRemoteData": function() {
|
||||
this.setReady(true);
|
||||
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("data", this._getAllData());
|
||||
this.broadcast(vc, "get")
|
||||
},
|
||||
"_onRemoteAddElement": function(obj, before) {
|
||||
if (this.ready) { //only end appends are supported now
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("data", obj.clone());
|
||||
|
||||
this.broadcast(vc, "push");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Catalogue;
|
46
libjs/wModel/proxy/list.js
Normal file
46
libjs/wModel/proxy/list.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
"use strict";
|
||||
|
||||
var Proxy = require("./proxy");
|
||||
var Vocabulary = require("../../wType/vocabulary");
|
||||
var Ctrl = require("../../wController/list");
|
||||
|
||||
var List = Proxy.inherit({
|
||||
"className": "List",
|
||||
"constructor": function(address, controllerAddress, socket) {
|
||||
var controller = new Ctrl(controllerAddress);
|
||||
Proxy.fn.constructor.call(this, address, controller, socket);
|
||||
|
||||
this.controller.on("data", this._onRemoteData, this);
|
||||
this.controller.on("clear", this._onRemoteClear, this);
|
||||
this.controller.on("newElement", this._onRemoteNewElement, this);
|
||||
},
|
||||
"_h_subscribe": function(ev) {
|
||||
Proxy.fn._h_subscribe.call(this, ev);
|
||||
|
||||
if (this.ready) {
|
||||
this._h_get(ev);
|
||||
}
|
||||
},
|
||||
"_onRemoteClear": function() {
|
||||
if (this.ready) {
|
||||
this.broadcast(new Vocabulary(), "clear");
|
||||
}
|
||||
},
|
||||
"_onRemoteData": function() {
|
||||
this.setReady(true);
|
||||
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("data", this.controller.data.clone())
|
||||
this.broadcast(vc, "get")
|
||||
},
|
||||
"_onRemoteNewElement": function(obj) {
|
||||
if (this.ready) {
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("data", obj.clone());
|
||||
|
||||
this.broadcast(vc, "push");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = List;
|
180
libjs/wModel/proxy/proxy.js
Normal file
180
libjs/wModel/proxy/proxy.js
Normal file
|
@ -0,0 +1,180 @@
|
|||
"use strict";
|
||||
|
||||
var Model = require("../model");
|
||||
var Handler = require("../../wDispatcher/handler");
|
||||
var Vocabulary = require("../../wType/vocabulary");
|
||||
var Address = require("../../wType/address");
|
||||
|
||||
var config = require("../../../config/config.json");
|
||||
|
||||
var Proxy = Model.inherit({
|
||||
"className": "Proxy",
|
||||
"constructor": function(address, controller, socket) { //les't pretend - this class is abstract
|
||||
Model.fn.constructor.call(this, address);
|
||||
|
||||
this._socket = socket;
|
||||
this.ready = false;
|
||||
this.controller = controller;
|
||||
this.childrenPossible = false;
|
||||
this._destroyOnLastUnsubscription = false;
|
||||
this._destructionTimeout = undefined;
|
||||
this._childClass = undefined;
|
||||
this._waitingEvents = [];
|
||||
|
||||
this.addHandler("get");
|
||||
this.reporterHandler = new Handler(this._address["+"](new Address(["subscribeMember"])), this, this._h_subscribeMember);
|
||||
|
||||
this._uncyclic.push(function() {
|
||||
controller.destructor();
|
||||
});
|
||||
},
|
||||
"destructor": function() {
|
||||
if (this._destructionTimeout) {
|
||||
clearTimeout(this._destructionTimeout);
|
||||
}
|
||||
for (var i = 0; i < this._waitingEvents.length; ++i) {
|
||||
this._waitingEvents[i].destructor();
|
||||
}
|
||||
this.reporterHandler.destructor();
|
||||
Model.fn.destructor.call(this);
|
||||
},
|
||||
"checkSubscribersAndDestroy": function() {
|
||||
if (this._subscribersCount === 0 && this._destructionTimeout === undefined) {
|
||||
this.trigger("serviceMessage", this._address.toString() + " has no more subscribers, destroying model");
|
||||
this._destructionTimeout = setTimeout(this.trigger.bind(this, "destroyMe"), config.modelDestructionTimeout);
|
||||
}
|
||||
},
|
||||
"dispatchWaitingEvents": function() {
|
||||
for (var i = 0; i < this._waitingEvents.length; ++i) {
|
||||
var ev = this._waitingEvents[i];
|
||||
var cmd = "_h_" + ev.getDestination().back().toString();
|
||||
this[cmd](ev);
|
||||
ev.destructor();
|
||||
}
|
||||
this._waitingEvents = [];
|
||||
},
|
||||
"_getAllData": function() {
|
||||
return this.controller.data.clone();
|
||||
},
|
||||
"_h_get": function(ev) {
|
||||
if (this.ready) {
|
||||
var vc = new Vocabulary();
|
||||
|
||||
vc.insert("data", this._getAllData());
|
||||
this.response(vc, "get", ev);
|
||||
} else {
|
||||
this._waitingEvents.push(ev.clone());
|
||||
}
|
||||
},
|
||||
"_h_subscribe": function(ev) {
|
||||
Model.fn._h_subscribe.call(this, ev);
|
||||
|
||||
if (this._destructionTimeout) {
|
||||
clearTimeout(this._destructionTimeout);
|
||||
this._destructionTimeout = undefined;
|
||||
}
|
||||
},
|
||||
"_h_unsubscribe": function(ev) {
|
||||
Model.fn._h_unsubscribe.call(this, ev);
|
||||
|
||||
if (this._destroyOnLastUnsubscription) {
|
||||
this.checkSubscribersAndDestroy();
|
||||
}
|
||||
},
|
||||
"_h_subscribeMember": function(ev) {
|
||||
if (!this.childrenPossible) {
|
||||
return;
|
||||
}
|
||||
var dest = ev.getDestination();
|
||||
var lastHops = dest["<<"](this._address.length());
|
||||
|
||||
if (lastHops.length() === 2) {
|
||||
var command = lastHops.back().toString();
|
||||
var id = lastHops[">>"](1);
|
||||
if (command === "subscribe" || command === "get") {
|
||||
var child = new this._childClass(this._address["+"](id), this.controller._pairAddress["+"](id), this._socket);
|
||||
this.addModel(child);
|
||||
child._destroyOnLastUnsubscription = true;
|
||||
child["_h_" + command](ev);
|
||||
if (command === "get") {
|
||||
child.on("ready", child.checkSubscribersAndDestroy, child);
|
||||
}
|
||||
child.subscribe();
|
||||
child.on("destroyMe", this.destroyChild.bind(this, child)); //to remove model if it has no subscribers
|
||||
} else {
|
||||
this.trigger("serviceMessage", "Proxy model got a strange event: " + ev.toString(), 1);
|
||||
}
|
||||
} else {
|
||||
this.trigger("serviceMessage", "Proxy model got a strange event: " + ev.toString(), 1);
|
||||
}
|
||||
},
|
||||
"_onSocketDisconnected": function(ev, socket) {
|
||||
Model.fn._onSocketDisconnected.call(this, ev, socket);
|
||||
|
||||
if (this._destroyOnLastUnsubscription) {
|
||||
this.checkSubscribersAndDestroy();
|
||||
}
|
||||
},
|
||||
"register": function(dp, server) {
|
||||
Model.fn.register.call(this, dp, server);
|
||||
|
||||
this.controller.register(dp, this._socket);
|
||||
},
|
||||
"unregister": function() {
|
||||
Model.fn.unregister.call(this);
|
||||
|
||||
if (this.controller._subscribed) {
|
||||
this.controller.unsubscribe();
|
||||
}
|
||||
this.controller.unregister();
|
||||
},
|
||||
"setChildrenClass": function(Class) {
|
||||
if (this.childrenPossible) {
|
||||
this.trigger("serviceMessage", "An attempt to set another class for children in Proxy", 1);
|
||||
}
|
||||
if (!Class instanceof Proxy) {
|
||||
this.trigger("serviceMessage", "An attempt to set not inherited chidren class from Proxy to a Proxy", 2);
|
||||
}
|
||||
this.childrenPossible = true;
|
||||
this._childClass = Class;
|
||||
},
|
||||
"setReady": function(bool) {
|
||||
bool = !!bool;
|
||||
if (bool !== this.ready) {
|
||||
this.ready = bool;
|
||||
if (bool) {
|
||||
this.dispatchWaitingEvents();
|
||||
this.trigger("ready");
|
||||
} else {
|
||||
//todo do I realy need to trigger smth here?
|
||||
}
|
||||
}
|
||||
},
|
||||
"subscribe": function() {
|
||||
this.controller.subscribe();
|
||||
},
|
||||
"destroyChild": function(child) {
|
||||
this.removeModel(child);
|
||||
child.destructor();
|
||||
},
|
||||
"unsetChildrenClass": function() {
|
||||
if (!this.childrenPossible) {
|
||||
this.trigger("serviceMessage", "An attempt to unset children class in Proxy, which don't have it", 1);
|
||||
} else {
|
||||
delete this._childClass;
|
||||
this.childrenPossible = false;
|
||||
}
|
||||
},
|
||||
"unsubscribe": function() {
|
||||
this.controller.unsubscribe();
|
||||
this.setReady(false);
|
||||
}
|
||||
});
|
||||
|
||||
Proxy.onChildReady = function(ev) {
|
||||
this._h_get(ev);
|
||||
this.checkSubscribersAndDestroy();
|
||||
}
|
||||
|
||||
module.exports = Proxy;
|
||||
|
43
libjs/wModel/proxy/vocabulary.js
Normal file
43
libjs/wModel/proxy/vocabulary.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
|
||||
var Proxy = require("./proxy");
|
||||
var Vocabulary = require("../../wType/vocabulary");
|
||||
var Ctrl = require("../../wController/vocabulary");
|
||||
|
||||
var MVocabulary = Proxy.inherit({
|
||||
"className": "Vocabulary",
|
||||
"constructor": function(address, controllerAddress, socket) {
|
||||
var controller = new Ctrl(controllerAddress);
|
||||
Proxy.fn.constructor.call(this, address, controller, socket);
|
||||
|
||||
this.controller.on("data", this._onRemoteData, this);
|
||||
this.controller.on("clear", this._onRemoteClear, this);
|
||||
this.controller.on("change", this._onRemoteChange, this);
|
||||
},
|
||||
"_h_subscribe": function(ev) {
|
||||
Proxy.fn._h_subscribe.call(this, ev);
|
||||
|
||||
if (this.ready) {
|
||||
this._h_get(ev);
|
||||
}
|
||||
},
|
||||
"_onRemoteClear": function() {
|
||||
if (this.ready) {
|
||||
this.broadcast(new Vocabulary(), "clear");
|
||||
}
|
||||
},
|
||||
"_onRemoteData": function() {
|
||||
this.setReady(true);
|
||||
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("data", this._getAllData());
|
||||
this.broadcast(vc, "get")
|
||||
},
|
||||
"_onRemoteChange": function(data) {
|
||||
if (this.ready) {
|
||||
this.broadcast(data, "change");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = MVocabulary;
|
Loading…
Add table
Add a link
Reference in a new issue