initial commit
This commit is contained in:
commit
4b60ece582
327 changed files with 28286 additions and 0 deletions
5
magnus/core/CMakeLists.txt
Normal file
5
magnus/core/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
configure_file(magnus.js magnus.js)
|
||||
configure_file(commands.js commands.js)
|
||||
configure_file(connector.js connector.js)
|
85
magnus/core/commands.js
Normal file
85
magnus/core/commands.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
"use strict";
|
||||
|
||||
var ModelVocabulary = require("../lib/wModel/vocabulary");
|
||||
|
||||
var Vocabulary = require("../lib/wType/vocabulary");
|
||||
var String = require("../lib/wType/string");
|
||||
|
||||
var Commands = ModelVocabulary.inherit({
|
||||
"className": "Commands",
|
||||
"constructor": function(address) {
|
||||
ModelVocabulary.fn.constructor.call(this, address);
|
||||
|
||||
this._commands = global.Object.create(null);
|
||||
},
|
||||
"destructor": function() {
|
||||
for (var key in this._commands) {
|
||||
var cmd = this._commands[key];
|
||||
if (cmd.enabled) {
|
||||
this._removeHandler(cmd.handler);
|
||||
}
|
||||
cmd.name.destructor();
|
||||
cmd.handler.destructor();
|
||||
cmd.arguments.destructor();
|
||||
delete this._commands[key];
|
||||
}
|
||||
|
||||
ModelVocabulary.fn.destructor.call(this);
|
||||
},
|
||||
"addCommand": function(key, handler, args) {
|
||||
if (this._commands[key]) {
|
||||
throw new Error("Command with this key already exist");
|
||||
}
|
||||
this._commands[key] = {
|
||||
name: new String(key),
|
||||
handler: handler,
|
||||
arguments: args,
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
"_disableCommand": function(cmd) {
|
||||
this._removeHandler(cmd.handler);
|
||||
cmd.enabled = false;
|
||||
this.erase(cmd.name.toString());
|
||||
},
|
||||
"enableCommand": function(key, value) {
|
||||
var cmd = this._commands[key];
|
||||
|
||||
if (!cmd) {
|
||||
throw new Error("An attempt to access non existing command: " + key);
|
||||
}
|
||||
|
||||
if (cmd.enabled !== value) {
|
||||
if (value) {
|
||||
this._enableCommand(cmd);
|
||||
} else {
|
||||
this._disableCommand(cmd);
|
||||
}
|
||||
}
|
||||
},
|
||||
"_enableCommand": function(cmd) {
|
||||
this._addHandler(cmd.handler);
|
||||
cmd.enabled = true;
|
||||
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("address", cmd.handler.address.clone());
|
||||
vc.insert("arguments", cmd.arguments.clone());
|
||||
|
||||
this.insert(cmd.name.toString(), vc);
|
||||
},
|
||||
"removeCommand": function(name) {
|
||||
var cmd = this._commands[name];
|
||||
if (cmd === undefined) {
|
||||
throw new Error("An attempt to access non existing command: " + key);
|
||||
}
|
||||
if (cmd.enabled) {
|
||||
this._disableCommand(cmd);
|
||||
}
|
||||
cmd.name.destructor();
|
||||
cmd.handler.destructor();
|
||||
cmd.arguments.destructor();
|
||||
delete this._commands[name];
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Commands;
|
120
magnus/core/connector.js
Normal file
120
magnus/core/connector.js
Normal file
|
@ -0,0 +1,120 @@
|
|||
"use strict";
|
||||
|
||||
var Subscribable = require("../lib/utils/subscribable");
|
||||
var Handler = require("../lib/wDispatcher/handler");
|
||||
var String = require("../lib/wType/string");
|
||||
var Address = require("../lib/wType/address");
|
||||
var Uint64 = require("../lib/wType/uint64");
|
||||
var Object = require("../lib/wType/object");
|
||||
var Vocabulary = require("../lib/wType/vocabulary");
|
||||
var Socket = require("../lib/wSocket/socket");
|
||||
|
||||
var Connector = Subscribable.inherit({
|
||||
"className": "Connector",
|
||||
"constructor": function(dp, srv, cmds) {
|
||||
Subscribable.fn.constructor.call(this);
|
||||
|
||||
this._dispatcher = dp;
|
||||
this._server = srv;
|
||||
this._commands = cmds;
|
||||
this._nodes = global.Object.create(null);
|
||||
this._ignoredNodes = global.Object.create(null);
|
||||
|
||||
this._server.on("newConnection", this._onNewConnection, this);
|
||||
this._server.on("closedConnection", this._onClosedConnection, this);
|
||||
|
||||
var cn = new Address(["connect"]);
|
||||
var ch = new Handler(this._commands.getAddress()["+"](cn), this, this._h_connect);
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("address", new Uint64(Object.objectType.String));
|
||||
vc.insert("port", new Uint64(Object.objectType.Uint64));
|
||||
this._commands.addCommand("connect", ch, vc);
|
||||
this._commands.enableCommand("connect", true);
|
||||
cn.destructor();
|
||||
},
|
||||
"destructor": function() {
|
||||
this._server.off("newConnection", this._onNewConnection, this);
|
||||
this._server.off("closedConnection", this._onClosedConnection, this);
|
||||
|
||||
this._commands.removeCommand("connect");
|
||||
|
||||
for (var key in this._nodes) {
|
||||
this._commands.removeCommand("disconnect" + key);
|
||||
}
|
||||
|
||||
Subscribable.fn.destructor.call(this);
|
||||
},
|
||||
"addIgnoredNode": function(name) {
|
||||
this._ignoredNodes[name] = true;
|
||||
},
|
||||
"sendTo": function(key, event) {
|
||||
var id = this._nodes[key];
|
||||
if (!id) {
|
||||
throw new Error("An attempt to access non existing node in connector");
|
||||
}
|
||||
this._server.getConnection(id).send(event);
|
||||
},
|
||||
"_onNewConnection": function(socket) {
|
||||
var name = socket.getRemoteName().toString();
|
||||
|
||||
if (this._ignoredNodes[name] === undefined) {
|
||||
if (this._nodes[name] === undefined) {
|
||||
if (this._server.getName().toString() === name) {
|
||||
this.trigger("serviceMessage", "An attempt to connect node to itself, closing connection", 1);
|
||||
setTimeout(this._server.closeConnection.bind(this._server, socket.getId()));
|
||||
} else {
|
||||
var dc = "disconnect";
|
||||
var dn = dc + name;
|
||||
var dh = new Handler(this._commands.getAddress()["+"](new Address([dc, name])), this, this._h_disconnect);
|
||||
this._commands.addCommand(dn, dh, new Vocabulary());
|
||||
this._commands.enableCommand(dn, true);
|
||||
|
||||
this._nodes[name] = socket.getId();
|
||||
|
||||
this.trigger("serviceMessage", "New connection, id: " + socket.getId().toString(), 0);
|
||||
socket.on("message", this._dispatcher.pass, this._dispatcher);
|
||||
this.trigger("nodeConnected", name);
|
||||
}
|
||||
} else {
|
||||
this.trigger("serviceMessage", "Node " + name + " tried to connect, but connection with that node is already open, closing new connection", 1);
|
||||
setTimeout(this._server.closeConnection.bind(this._server, socket.getId()));
|
||||
}
|
||||
} else {
|
||||
this.trigger("serviceMessage", "New connection, id: " + socket.getId().toString(), 0);
|
||||
socket.on("message", this._dispatcher.pass, this._dispatcher);
|
||||
}
|
||||
},
|
||||
"_onClosedConnection": function(socket) {
|
||||
this.trigger("serviceMessage", "Connection closed, id: " + socket.getId().toString());
|
||||
|
||||
var name = socket.getRemoteName().toString();
|
||||
if (this._ignoredNodes[name] === undefined) {
|
||||
if (this._nodes[name]) {
|
||||
this._commands.removeCommand("disconnect" + name);
|
||||
delete this._nodes[name];
|
||||
this.trigger("nodeDisconnected", name);
|
||||
}
|
||||
}
|
||||
},
|
||||
"getNodeSocket": function(key) {
|
||||
var id = this._nodes[key];
|
||||
if (!id) {
|
||||
throw new Error("An attempt to access non existing node in connector");
|
||||
}
|
||||
return this._server.getConnection(id);
|
||||
},
|
||||
"_h_connect": function(ev) {
|
||||
var vc = ev.getData();
|
||||
this._server.openConnection(vc.at("address"), vc.at("port"));
|
||||
},
|
||||
"_h_disconnect": function(ev) {
|
||||
var addr = ev.getDestination();
|
||||
var id = this._nodes[addr.back().toString()];
|
||||
if (id) {
|
||||
this._server.closeConnection(id);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Connector;
|
153
magnus/core/magnus.js
Normal file
153
magnus/core/magnus.js
Normal file
|
@ -0,0 +1,153 @@
|
|||
"use strict";
|
||||
var Subscribable = require("../lib/utils/subscribable");
|
||||
var Socket = require("../lib/wSocket/socket");
|
||||
var Server = require("../lib/wSocket/server");
|
||||
var Address = require("../lib/wType/address");
|
||||
var String = require("../lib/wType/string");
|
||||
var Vocabulary = require("../lib/wType/vocabulary");
|
||||
var Dispatcher = require("../lib/wDispatcher/dispatcher");
|
||||
var ParentReporter = require("../lib/wDispatcher/parentreporter");
|
||||
var Logger = require("../lib/wDispatcher/logger");
|
||||
var log = require("../lib/log")(module);
|
||||
|
||||
var Commands = require("./commands");
|
||||
var Connector = require("./connector");
|
||||
|
||||
var GlobalControls = require("../lib/wModel/globalControls");
|
||||
var PageStorage = require("../lib/wModel/pageStorage");
|
||||
var ModelString = require("../lib/wModel/string");
|
||||
var Attributes = require("../lib/wModel/attributes");
|
||||
|
||||
var HomePage = require("../pages/home");
|
||||
var MusicPage = require("../pages/music");
|
||||
var TestPage = require("../pages/test");
|
||||
|
||||
var Magnus = Subscribable.inherit({
|
||||
"className": "Magnus",
|
||||
"constructor": function(config) {
|
||||
Subscribable.fn.constructor.call(this);
|
||||
|
||||
this._cfg = config;
|
||||
|
||||
this._initDispatcher();
|
||||
this._initServer();
|
||||
this._initModels();
|
||||
this._initConnector();
|
||||
this._initPages();
|
||||
|
||||
var port = this._cfg.get("webSocketServerPort");
|
||||
this.server.listen(port);
|
||||
|
||||
global.magnus = this;
|
||||
},
|
||||
"_initConnector": function() {
|
||||
this._connector = new Connector(this.dispatcher, this.server, this._commands);
|
||||
|
||||
this._connector.on("serviceMessage", this._onModelServiceMessage, this);
|
||||
this._connector.on("nodeConnected", this._onNodeConnected, this);
|
||||
this._connector.on("nodeDisconnected", this._onNodeDisconnected, this);
|
||||
|
||||
this._connector.addIgnoredNode("Lorgar");
|
||||
this._connector.addIgnoredNode("Roboute");
|
||||
},
|
||||
"_initDispatcher": function() {
|
||||
this.dispatcher = new Dispatcher();
|
||||
this._logger = new Logger();
|
||||
this._pr = new ParentReporter();
|
||||
this.dispatcher.registerDefaultHandler(this._pr);
|
||||
this.dispatcher.registerDefaultHandler(this._logger);
|
||||
},
|
||||
"_initModels": function() {
|
||||
this._commands = new Commands(new Address(["management"]));
|
||||
|
||||
var version = new ModelString(new Address(["version"]), this._cfg.get("version"));
|
||||
version.addProperty("backgroundColor","secondaryColor");
|
||||
version.addProperty("color", "secondaryFontColor");
|
||||
version.addProperty("fontFamily", "smallFont");
|
||||
version.addProperty("fontSize", "smallFontSize");
|
||||
|
||||
this._attributes = new Attributes(new Address(["attributes"]));
|
||||
this._gc = new GlobalControls(new Address(["magnus", "gc"]));
|
||||
var root = this._rootPage = new HomePage(new Address(["pages", "root"]), "root");
|
||||
this._ps = new PageStorage(new Address(["magnus", "ps"]), root, this._pr);
|
||||
|
||||
this._commands.on("serviceMessage", this._onModelServiceMessage, this);
|
||||
this._gc.on("serviceMessage", this._onModelServiceMessage, this);
|
||||
this._ps.on("serviceMessage", this._onModelServiceMessage, this);
|
||||
this._attributes.on("serviceMessage", this._onModelServiceMessage, this);
|
||||
|
||||
this._attributes.addAttribute("name", new ModelString(new Address(["attributes", "name"]), "Magnus"));
|
||||
this._attributes.addAttribute("connectionsAmount", new ModelString(new Address(["connectionsAmount"]), "0"));
|
||||
this._attributes.addAttribute("version", version);
|
||||
this._gc.addModelAsLink("version", version);
|
||||
|
||||
this._commands.register(this.dispatcher, this.server);
|
||||
this._gc.register(this.dispatcher, this.server);
|
||||
this._ps.register(this.dispatcher, this.server);
|
||||
this._attributes.register(this.dispatcher, this.server);
|
||||
},
|
||||
"_initPages": function() {
|
||||
this._gc.addNav("Home", this._rootPage.getAddress());
|
||||
|
||||
var music = this._musicPage = new MusicPage(new Address(["pages", "/music"]), "music");
|
||||
this._rootPage.addPage(music);
|
||||
this._gc.addNav("Music", music.getAddress());
|
||||
|
||||
var test = new TestPage(new Address(["pages", "/test"]), "test");
|
||||
this._rootPage.addPage(test);
|
||||
this._gc.addNav("Testing...", test.getAddress());
|
||||
},
|
||||
"_initServer": function() {
|
||||
this.server = new Server("Magnus");
|
||||
this.server.on("ready", this._onServerReady, this);
|
||||
this.server.on("connectionsCountChange", this._onConnectionsCountChange, this);
|
||||
},
|
||||
"hasPage": function(name) {
|
||||
return this._ps.hasPage(name);
|
||||
},
|
||||
"_onConnectionsCountChange": function(count) {
|
||||
this._attributes.setAttribute("connectionsAmount", count);
|
||||
},
|
||||
"_onModelServiceMessage": function(msg, severity) {
|
||||
var fn;
|
||||
|
||||
switch (severity) {
|
||||
case 2:
|
||||
fn = log.error;
|
||||
break;
|
||||
case 1:
|
||||
fn = log.warn;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
fn = log.info;
|
||||
break;
|
||||
}
|
||||
|
||||
fn(msg);
|
||||
},
|
||||
"_onNodeConnected": function(nodeName) {
|
||||
switch (nodeName) {
|
||||
case "Perturabo":
|
||||
this._musicPage.showBandList(this._connector.getNodeSocket(nodeName));
|
||||
break;
|
||||
case "Corax":
|
||||
break;
|
||||
}
|
||||
},
|
||||
"_onNodeDisconnected": function(nodeName) {
|
||||
switch (nodeName) {
|
||||
case "Perturabo":
|
||||
this._musicPage.showError();
|
||||
break;
|
||||
case "Corax":
|
||||
break;
|
||||
}
|
||||
},
|
||||
"_onServerReady": function() {
|
||||
log.info("Magnus is listening on port " + this._cfg.get("webSocketServerPort"));
|
||||
log.info("Magnus is ready");
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Magnus;
|
Loading…
Add table
Add a link
Reference in a new issue