initial commit
This commit is contained in:
commit
4b60ece582
327 changed files with 28286 additions and 0 deletions
15
magnus/CMakeLists.txt
Normal file
15
magnus/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
project(magnus)
|
||||
|
||||
add_subdirectory(config)
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(middleware)
|
||||
add_subdirectory(views)
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(pages)
|
||||
|
||||
configure_file(package.json package.json)
|
||||
configure_file(app.js app.js)
|
||||
|
||||
execute_process(COMMAND npm install WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
46
magnus/app.js
Normal file
46
magnus/app.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
var express = require("express");
|
||||
var morgan = require("morgan");
|
||||
var favicon = require("serve-favicon");
|
||||
var Magnus = require("./core/magnus");
|
||||
|
||||
require("./lib/utils/globalMethods");
|
||||
|
||||
var config = require("./config");
|
||||
var log = require("./lib/log")(module);
|
||||
|
||||
if (config.get("testing")) {
|
||||
var Test = require("./test/test");
|
||||
var test = new Test()
|
||||
test.run();
|
||||
test.destructor();
|
||||
}
|
||||
|
||||
var app = express();
|
||||
|
||||
app.set('view engine', 'jade');
|
||||
app.set('views', __dirname + '/views');
|
||||
|
||||
app.use(favicon(__dirname + "/public/favicon.ico"));
|
||||
|
||||
var httpLog = config.get("httpLog");
|
||||
if (httpLog) {
|
||||
app.use(morgan('dev'));
|
||||
}
|
||||
|
||||
app.use(require("./middleware/reply"));
|
||||
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
app.use(require("./middleware/pageInMagnus"));
|
||||
app.use(require("./middleware/notFound"));
|
||||
app.use(require("./middleware/errorHandler"));
|
||||
|
||||
var server = app.listen(config.get("webServerPort"), "127.0.0.1", function () {
|
||||
|
||||
var port = server.address().port;
|
||||
|
||||
log.info("Webserver is listening on port " + port);
|
||||
|
||||
});
|
||||
var magnus = global.magnus = new Magnus(config);
|
||||
|
4
magnus/config/CMakeLists.txt
Normal file
4
magnus/config/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
configure_file(index.js index.js)
|
||||
configure_file(config.json config.json)
|
9
magnus/config/config.json
Normal file
9
magnus/config/config.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"webServerPort": 3000,
|
||||
"webSocketServerPort": 8081,
|
||||
"version": "0.0.2",
|
||||
"build": "debug",
|
||||
"httpLog": false,
|
||||
"testing": true,
|
||||
"modelDestructionTimeout": 120000
|
||||
}
|
8
magnus/config/index.js
Normal file
8
magnus/config/index.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
var nconf = require("nconf");
|
||||
var path = require("path");
|
||||
|
||||
nconf.argv()
|
||||
.env()
|
||||
.file({file: path.join(__dirname, 'config.json')});
|
||||
|
||||
module.exports = nconf;
|
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;
|
13
magnus/lib/CMakeLists.txt
Normal file
13
magnus/lib/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
add_subdirectory(wSocket)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(wDispatcher)
|
||||
add_subdirectory(wType)
|
||||
add_subdirectory(wContainer)
|
||||
add_subdirectory(wController)
|
||||
add_subdirectory(wTest)
|
||||
add_subdirectory(wModel)
|
||||
|
||||
configure_file(log.js log.js)
|
||||
configure_file(httpError.js httpError.js)
|
15
magnus/lib/httpError.js
Normal file
15
magnus/lib/httpError.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
"use strict";
|
||||
var http = require("http");
|
||||
|
||||
class HttpError extends Error
|
||||
{
|
||||
constructor(status, message) {
|
||||
super(status, message);
|
||||
Error.captureStackTrace(this, HttpError);
|
||||
|
||||
this.status = status;
|
||||
this.message = message || http.STATUS_CODES[status] || "Error";
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HttpError;
|
18
magnus/lib/log.js
Normal file
18
magnus/lib/log.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
var Winston = require("winston");
|
||||
var config = require("../config");
|
||||
var ENV = config.get('build');
|
||||
|
||||
function getLogger(module) {
|
||||
var path = module.filename.split('/').slice(-2).join('/');
|
||||
|
||||
return new Winston.Logger({
|
||||
transports: [
|
||||
new Winston.transports.Console({
|
||||
colorize: true,
|
||||
level: ENV == 'debug' ? 'debug' : 'error'
|
||||
})
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = getLogger;
|
5
magnus/lib/utils/CMakeLists.txt
Normal file
5
magnus/lib/utils/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
add_jslib(utils/class.js lib/utils/class ${MAGNUS_DIR} node)
|
||||
add_jslib(utils/subscribable.js lib/utils/subscribable ${MAGNUS_DIR} node)
|
||||
add_jslib(utils/globalMethods.js lib/utils/globalMethods ${MAGNUS_DIR} node)
|
7
magnus/lib/wContainer/CMakeLists.txt
Normal file
7
magnus/lib/wContainer/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
add_jslib(wContainer/abstractmap.js lib/wContainer/abstractmap ${MAGNUS_DIR} node)
|
||||
add_jslib(wContainer/abstractlist.js lib/wContainer/abstractlist ${MAGNUS_DIR} node)
|
||||
add_jslib(wContainer/abstractorder.js lib/wContainer/abstractorder ${MAGNUS_DIR} node)
|
||||
add_jslib(wContainer/abstractpair.js lib/wContainer/abstractpair ${MAGNUS_DIR} node)
|
||||
add_jslib(wContainer/abstractset.js lib/wContainer/abstractset ${MAGNUS_DIR} node)
|
6
magnus/lib/wController/CMakeLists.txt
Normal file
6
magnus/lib/wController/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
add_jslib(wController/list.js lib/wController/list ${MAGNUS_DIR} node)
|
||||
add_jslib(wController/controller.js lib/wController/controller ${MAGNUS_DIR} node)
|
||||
add_jslib(wController/vocabulary.js lib/wController/vocabulary ${MAGNUS_DIR} node)
|
||||
add_jslib(wController/catalogue.js lib/wController/catalogue ${MAGNUS_DIR} node)
|
7
magnus/lib/wDispatcher/CMakeLists.txt
Normal file
7
magnus/lib/wDispatcher/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
add_jslib(wDispatcher/dispatcher.js lib/wDispatcher/dispatcher ${MAGNUS_DIR} node)
|
||||
add_jslib(wDispatcher/defaulthandler.js lib/wDispatcher/defaulthandler ${MAGNUS_DIR} node)
|
||||
add_jslib(wDispatcher/handler.js lib/wDispatcher/handler ${MAGNUS_DIR} node)
|
||||
add_jslib(wDispatcher/logger.js lib/wDispatcher/logger ${MAGNUS_DIR} node)
|
||||
add_jslib(wDispatcher/parentreporter.js lib/wDispatcher/parentreporter ${MAGNUS_DIR} node)
|
17
magnus/lib/wModel/CMakeLists.txt
Normal file
17
magnus/lib/wModel/CMakeLists.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
add_jslib(wModel/globalControls.js lib/wModel/globalControls ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/link.js lib/wModel/link ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/list.js lib/wModel/list ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/model.js lib/wModel/model ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/page.js lib/wModel/page ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/pageStorage.js lib/wModel/pageStorage ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/panesList.js lib/wModel/panesList ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/string.js lib/wModel/string ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/theme.js lib/wModel/theme ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/themeStorage.js lib/wModel/themeStorage ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/vocabulary.js lib/wModel/vocabulary ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/attributes.js lib/wModel/attributes ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/image.js lib/wModel/image ${MAGNUS_DIR} node)
|
||||
|
||||
add_subdirectory(proxy)
|
8
magnus/lib/wModel/proxy/CMakeLists.txt
Normal file
8
magnus/lib/wModel/proxy/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
add_jslib(wModel/proxy/proxy.js lib/wModel/proxy/proxy ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/proxy/list.js lib/wModel/proxy/list ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/proxy/vocabulary.js lib/wModel/proxy/vocabulary ${MAGNUS_DIR} node)
|
||||
add_jslib(wModel/proxy/catalogue.js lib/wModel/proxy/catalogue ${MAGNUS_DIR} node)
|
||||
|
||||
configure_file(pane.js pane.js)
|
32
magnus/lib/wModel/proxy/pane.js
Normal file
32
magnus/lib/wModel/proxy/pane.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
"use strict";
|
||||
|
||||
var MVocabulary = require("./vocabulary");
|
||||
|
||||
var Address = require("../../wType/address");
|
||||
var Boolean = require("../../wType/boolean");
|
||||
|
||||
var Pane = MVocabulary.inherit({
|
||||
"className": "Pane",
|
||||
"constructor": function(address, controllerAddress, socket) {
|
||||
MVocabulary.fn.constructor.call(this, address, controllerAddress, socket);
|
||||
|
||||
if (this.constructor.pageAddress) {
|
||||
this.hasPageLink = true;
|
||||
|
||||
var id = address.back();
|
||||
this._pageLink = this.constructor.pageAddress["+"](new Address([id.toString()]));
|
||||
}
|
||||
},
|
||||
"_getAllData": function() {
|
||||
var vc = this.controller.data.clone();
|
||||
|
||||
vc.insert("hasPageLink", new Boolean(this.hasPageLink));
|
||||
if (this.hasPageLink) {
|
||||
vc.insert("pageLink", this._pageLink.clone());
|
||||
}
|
||||
|
||||
return vc;
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Pane;
|
4
magnus/lib/wSocket/CMakeLists.txt
Normal file
4
magnus/lib/wSocket/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
configure_file(socket.js socket.js)
|
||||
configure_file(server.js server.js)
|
154
magnus/lib/wSocket/server.js
Normal file
154
magnus/lib/wSocket/server.js
Normal file
|
@ -0,0 +1,154 @@
|
|||
"use strict";
|
||||
|
||||
var WebSocketServer = require("ws").Server;
|
||||
var Socket = require("./socket");
|
||||
var Subscribable = require("../utils/subscribable");
|
||||
var AbstractMap = require("../wContainer/abstractmap");
|
||||
var AbstractSet = require("../wContainer/abstractset");
|
||||
var String = require("../wType/string");
|
||||
var Uint64 = require("../wType/uint64");
|
||||
|
||||
var Server = Subscribable.inherit({
|
||||
"className": "Server",
|
||||
"constructor": function(name) {
|
||||
if (!name) {
|
||||
throw new Error("Can't construct a socket without a name");
|
||||
}
|
||||
Subscribable.fn.constructor.call(this);
|
||||
|
||||
this._lastId = new Uint64(0);
|
||||
this._pool = new Server.Uint64Set(true);
|
||||
this._name = name instanceof String ? name : new String(name);
|
||||
this._server = undefined;
|
||||
this._connections = new Server.ConnectionsMap(true);
|
||||
this._listening = false;
|
||||
|
||||
this._initProxy();
|
||||
},
|
||||
"destructor": function() {
|
||||
if (this._listening) {
|
||||
this._server.stop();
|
||||
delete this._server;
|
||||
}
|
||||
this._lastId.destructor();
|
||||
this._pool.destructor();
|
||||
this._name.destructor();
|
||||
this._connections.destructor();
|
||||
|
||||
Subscribable.fn.destructor.call(this);
|
||||
},
|
||||
"getName": function() {
|
||||
return this._name;
|
||||
},
|
||||
"listen": function(port) {
|
||||
if (!this._listening) {
|
||||
this._listening = true;
|
||||
this._server = new WebSocketServer({port: port}, this._proxy.onReady);
|
||||
this._server.on("connection", this._proxy.onConnection);
|
||||
}
|
||||
},
|
||||
"stop": function() {
|
||||
if (this._listening) {
|
||||
this._listening = false;
|
||||
this._server.stop();
|
||||
this._lastId = new Uint64(0);
|
||||
this._connections.clear();
|
||||
this._pool.clear();
|
||||
delete this._server;
|
||||
}
|
||||
},
|
||||
"getConnection": function(id) {
|
||||
var itr = this._connections.find(id);
|
||||
if (itr["=="](this._connections.end())) {
|
||||
throw new Error("Connection not found");
|
||||
}
|
||||
return itr["*"]().second;
|
||||
},
|
||||
"getConnectionsCount": function() {
|
||||
return this._connections.size();
|
||||
},
|
||||
"openConnection": function(addr, port) {
|
||||
var webSocket = new Subscribable();
|
||||
var wSocket = this._createSocket(webSocket);
|
||||
wSocket._socket.destructor();
|
||||
wSocket.open(addr, port);
|
||||
},
|
||||
"closeConnection": function(id) {
|
||||
var itr = this._connections.find(id);
|
||||
if (itr["=="](this._connections.end())) {
|
||||
throw new Error("Connection not found");
|
||||
}
|
||||
itr["*"]().second.close();
|
||||
},
|
||||
"_createSocket": function(socket) {
|
||||
var connectionId;
|
||||
if (this._pool.size() === 0) {
|
||||
this._lastId["++"]()
|
||||
connectionId = this._lastId.clone();
|
||||
} else {
|
||||
var itr = this._pool.begin();
|
||||
connectionId = itr["*"]().clone();
|
||||
this._pool.erase(itr);
|
||||
}
|
||||
var wSocket = new Socket(this._name, socket, connectionId);
|
||||
this._connections.insert(connectionId, wSocket);
|
||||
|
||||
wSocket.on("connected", this._onSocketConnected.bind(this, wSocket));
|
||||
wSocket.on("disconnected", this._onSocketDisconnected.bind(this, wSocket));
|
||||
wSocket.on("negotiationId", this._onSocketNegotiationId.bind(this, wSocket));
|
||||
|
||||
return wSocket;
|
||||
},
|
||||
"_initProxy": function() {
|
||||
this._proxy = {
|
||||
onConnection: this._onConnection.bind(this),
|
||||
onReady: this._onReady.bind(this)
|
||||
};
|
||||
},
|
||||
"_onConnection": function(socket) {
|
||||
var wSocket = this._createSocket(socket);
|
||||
wSocket._setRemoteId();
|
||||
},
|
||||
"_onReady": function() {
|
||||
this.trigger("ready");
|
||||
},
|
||||
"_onSocketConnected": function(socket) {
|
||||
this.trigger("newConnection", socket);
|
||||
this.trigger("connectionCountChange", this._connections.size());
|
||||
},
|
||||
"_onSocketDisconnected": function(socket) {
|
||||
var cItr = this._connections.find(socket.getId());
|
||||
this._pool.insert(socket.getId().clone());
|
||||
this.trigger("closedConnection", socket);
|
||||
this.trigger("connectionCountChange", this._connections.size());
|
||||
setTimeout(this._connections.erase.bind(this._connections, cItr), 1);
|
||||
},
|
||||
"_onSocketNegotiationId": function(socket, id) {
|
||||
var oldId = socket.getId();
|
||||
if (id["=="](oldId)) {
|
||||
socket._setRemoteName();
|
||||
} else {
|
||||
var pItr = this._pool.lowerBound(id);
|
||||
var newId;
|
||||
if (pItr["=="](this._pool.end())) {
|
||||
this._lastId["++"]();
|
||||
newId = this._lastId.clone();
|
||||
} else {
|
||||
newId = pItr["*"]().clone();
|
||||
this._pool.erase(pItr);
|
||||
}
|
||||
var itr = this._connections.find(oldId);
|
||||
itr["*"]().second = undefined; //to prevent autodestruction of the socket;
|
||||
this._connections.erase(itr);
|
||||
this._pool.insert(oldId);
|
||||
socket._id = newId;
|
||||
this._connections.insert(newId.clone(), socket);
|
||||
socket._setRemoteId();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Server.ConnectionsMap = AbstractMap.template(Uint64, Socket);
|
||||
Server.Uint64Set = AbstractSet.template(Uint64);
|
||||
|
||||
module.exports = Server;
|
217
magnus/lib/wSocket/socket.js
Normal file
217
magnus/lib/wSocket/socket.js
Normal file
|
@ -0,0 +1,217 @@
|
|||
"use strict";
|
||||
|
||||
var WebSocket = require("ws");
|
||||
var Subscribable = require("../utils/subscribable");
|
||||
var Event = require("../wType/event");
|
||||
var ByteArray = require("../wType/bytearray");
|
||||
var String = require("../wType/string");
|
||||
var Vocabulary = require("../wType/vocabulary");
|
||||
var Uint64 = require("../wType/uint64");
|
||||
var Address = require("../wType/address");
|
||||
var factory = require("../wType/factory");
|
||||
|
||||
var Socket = Subscribable.inherit({
|
||||
"className": "Socket",
|
||||
"constructor": function(name, socket, id) {
|
||||
if (!name) {
|
||||
throw new Error("Can't construct a socket without a name");
|
||||
}
|
||||
Subscribable.fn.constructor.call(this);
|
||||
|
||||
this._state = DISCONNECTED;
|
||||
this._dState = SIZE;
|
||||
this._name = name instanceof String ? name : new String(name);
|
||||
this._remoteName = new String();
|
||||
this._id = new Uint64(0);
|
||||
this._serverCreated = false;
|
||||
this._helperBuffer = new ByteArray(4);
|
||||
|
||||
this._initProxy();
|
||||
if (socket) {
|
||||
this._serverCreated = true;
|
||||
this._socket = socket;
|
||||
this._id.destructor();
|
||||
this._id = id.clone();
|
||||
|
||||
this._socket.on("close", this._proxy.onClose);
|
||||
this._socket.on("error", this._proxy.onError);
|
||||
this._socket.on("message", this._proxy.onMessage);
|
||||
}
|
||||
},
|
||||
"destructor": function() {
|
||||
this.close();
|
||||
if (this._state === DISCONNECTING) {
|
||||
var onclose = function() {
|
||||
Subscribable.fn.destructor.call(this);
|
||||
}
|
||||
this.on("disconnected", onclose.bind(this));
|
||||
} else {
|
||||
Subscribable.fn.destructor.call(this);
|
||||
}
|
||||
},
|
||||
"close": function() {
|
||||
if ((this._state !== DISCONNECTED) && (this._state !== DISCONNECTING)) {
|
||||
this._state = DISCONNECTING;
|
||||
this._socket.close();
|
||||
}
|
||||
},
|
||||
"getId": function() {
|
||||
return this._id;
|
||||
},
|
||||
"getRemoteName": function() {
|
||||
return this._remoteName;
|
||||
},
|
||||
"_initProxy": function() {
|
||||
this._proxy = {
|
||||
onClose: this._onClose.bind(this),
|
||||
onError: this._onError.bind(this),
|
||||
onMessage: this._onMessage.bind(this)
|
||||
};
|
||||
},
|
||||
"isOpened": function() {
|
||||
return this._state !== undefined && this._state === CONNECTED;
|
||||
},
|
||||
"_onClose": function(ev) {
|
||||
this._state = DISCONNECTED;
|
||||
this.trigger("disconnected", ev, this);
|
||||
},
|
||||
"_onError": function(err) {
|
||||
this.trigger("error", err);
|
||||
},
|
||||
"_onEvent": function(ev) {
|
||||
if (ev.isSystem()) {
|
||||
var cmd = ev._data.at("command").toString();
|
||||
|
||||
switch(cmd) {
|
||||
case "setId":
|
||||
if (this._serverCreated) {
|
||||
if (this._state === CONNECTING) {
|
||||
this.trigger("negotiationId", ev._data.at("id"));
|
||||
} else {
|
||||
throw new Error("An attempt to set id in unexpected time");
|
||||
}
|
||||
} else {
|
||||
this._setId(ev._data.at("id"));
|
||||
this._setRemoteName();
|
||||
}
|
||||
break;
|
||||
case "setName":
|
||||
this._setName(ev._data.at("name"));
|
||||
if (!ev._data.at("yourName")["=="](this._name)) {
|
||||
this._setRemoteName();
|
||||
}
|
||||
this._state = CONNECTED;
|
||||
this.trigger("connected");
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unknown system command: " + cmd);
|
||||
}
|
||||
} else {
|
||||
this.trigger("message", ev);
|
||||
}
|
||||
ev.destructor();
|
||||
},
|
||||
"_onMessage": function(msg) {
|
||||
var raw = new Uint8Array(msg);
|
||||
var i = 0;
|
||||
|
||||
while (i < raw.length) {
|
||||
switch (this._dState) {
|
||||
case SIZE:
|
||||
i = this._helperBuffer.fill(raw, raw.length, i);
|
||||
|
||||
if (this._helperBuffer.filled()) {
|
||||
var size = this._helperBuffer.pop32();
|
||||
this._helperBuffer.destructor();
|
||||
this._helperBuffer = new ByteArray(size + 1);
|
||||
this._dState = BODY;
|
||||
}
|
||||
break;
|
||||
case BODY:
|
||||
i = this._helperBuffer.fill(raw, raw.length, i);
|
||||
|
||||
if (this._helperBuffer.filled()) {
|
||||
var ev = factory(this._helperBuffer);
|
||||
this._onEvent(ev);
|
||||
this._helperBuffer.destructor();
|
||||
this._helperBuffer = new ByteArray(4);
|
||||
this._dState = SIZE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
"open": function(addr, port) {
|
||||
if (this._state === DISCONNECTED) {
|
||||
this._state = CONNECTING;
|
||||
this._remoteName.destructor();
|
||||
this._remoteName = new String();
|
||||
this._socket = new WebSocket("ws://"+ addr + ":" + port);
|
||||
|
||||
this._socket.on("close", this._proxy.onClose);
|
||||
this._socket.on("error", this._proxy.onError);
|
||||
this._socket.on("message", this._proxy.onMessage);
|
||||
}
|
||||
},
|
||||
"send": function(ev) {
|
||||
var size = ev.size();
|
||||
var ba = new ByteArray(size + 5);
|
||||
ba.push32(size);
|
||||
ba.push8(ev.getType());
|
||||
ev.serialize(ba);
|
||||
|
||||
this._socket.send(ba.data().buffer);
|
||||
},
|
||||
"_setId": function(id) {
|
||||
if (this._state === CONNECTING) {
|
||||
this._id.destructor();
|
||||
this._id = id.clone();
|
||||
} else {
|
||||
throw new Error("An attempt to set id in unexpected time");
|
||||
}
|
||||
},
|
||||
"_setName": function(name) {
|
||||
if ((this._state === CONNECTING) && (this._id.valueOf() !== 0)) {
|
||||
this._remoteName.destructor();
|
||||
this._remoteName = name.clone();
|
||||
} else {
|
||||
throw new Error("An attempt to set name in unexpected time");
|
||||
}
|
||||
},
|
||||
"_setRemoteName": function() {
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("command", new String("setName"));
|
||||
vc.insert("name", this._name.clone());
|
||||
vc.insert("yourName", this._remoteName.clone());
|
||||
|
||||
var ev = new Event(new Address(), vc, true);
|
||||
ev.setSenderId(this._id.clone());
|
||||
this.send(ev);
|
||||
|
||||
ev.destructor();
|
||||
},
|
||||
"_setRemoteId": function() {
|
||||
if (this._state === DISCONNECTED) {
|
||||
this._state = CONNECTING;
|
||||
}
|
||||
var vc = new Vocabulary();
|
||||
vc.insert("command", new String("setId"));
|
||||
vc.insert("id", this._id.clone());
|
||||
|
||||
var ev = new Event(new Address(), vc, true);
|
||||
ev.setSenderId(this._id.clone());
|
||||
this.send(ev);
|
||||
|
||||
ev.destructor();
|
||||
}
|
||||
});
|
||||
|
||||
var DISCONNECTED = 111;
|
||||
var DISCONNECTING = 110;
|
||||
var CONNECTING = 101;
|
||||
var CONNECTED = 100;
|
||||
|
||||
var SIZE = 1
|
||||
var BODY = 10;
|
||||
|
||||
module.exports = Socket;
|
7
magnus/lib/wTest/CMakeLists.txt
Normal file
7
magnus/lib/wTest/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
add_jslib(wTest/test.js lib/wTest/test ${MAGNUS_DIR} node)
|
||||
add_jslib(wTest/abstractmap.js lib/wTest/abstractmap ${MAGNUS_DIR} node)
|
||||
add_jslib(wTest/abstractlist.js lib/wTest/abstractlist ${MAGNUS_DIR} node)
|
||||
add_jslib(wTest/abstractorder.js lib/wTest/abstractorder ${MAGNUS_DIR} node)
|
||||
add_jslib(wTest/uint64.js lib/wTest/uint64 ${MAGNUS_DIR} node)
|
13
magnus/lib/wType/CMakeLists.txt
Normal file
13
magnus/lib/wType/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
add_jslib(wType/address.js lib/wType/address ${MAGNUS_DIR} node)
|
||||
add_jslib(wType/boolean.js lib/wType/boolean ${MAGNUS_DIR} node)
|
||||
add_jslib(wType/bytearray.js lib/wType/bytearray ${MAGNUS_DIR} node)
|
||||
add_jslib(wType/event.js lib/wType/event ${MAGNUS_DIR} node)
|
||||
add_jslib(wType/object.js lib/wType/object ${MAGNUS_DIR} node)
|
||||
add_jslib(wType/string.js lib/wType/string ${MAGNUS_DIR} node)
|
||||
add_jslib(wType/uint64.js lib/wType/uint64 ${MAGNUS_DIR} node)
|
||||
add_jslib(wType/vector.js lib/wType/vector ${MAGNUS_DIR} node)
|
||||
add_jslib(wType/vocabulary.js lib/wType/vocabulary ${MAGNUS_DIR} node)
|
||||
add_jslib(wType/blob.js lib/wType/blob ${MAGNUS_DIR} node)
|
||||
add_jslib(wType/factory.js lib/wType/factory ${MAGNUS_DIR} node)
|
6
magnus/middleware/CMakeLists.txt
Normal file
6
magnus/middleware/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
configure_file(errorHandler.js errorHandler.js)
|
||||
configure_file(reply.js reply.js)
|
||||
configure_file(notFound.js notFound.js)
|
||||
configure_file(pageInMagnus.js pageInMagnus.js)
|
36
magnus/middleware/errorHandler.js
Normal file
36
magnus/middleware/errorHandler.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
var defaultHandler = require("errorhandler");
|
||||
|
||||
var config = require("../config");
|
||||
var log = require("../lib/log");
|
||||
var HttpError = require("../lib/httpError");
|
||||
|
||||
function errorHandler(err, req, res, next) {
|
||||
if (typeof err == "number") {
|
||||
err = new HttpError(err);
|
||||
}
|
||||
|
||||
if (err instanceof HttpError) {
|
||||
sendHttpError(err, res, req);
|
||||
} else {
|
||||
if (config.get("build") === "debug") {
|
||||
var handler = defaultHandler();
|
||||
handler(err, req, res, next);
|
||||
} else {
|
||||
log.error(err);
|
||||
err = new HttpError(500);
|
||||
sendHttpError(err, res, req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sendHttpError(error, res, req) {
|
||||
res.status(error.status);
|
||||
//if (req.headers['x-requested-with'] == 'XMLHttpRequest') {
|
||||
// res.json(error);
|
||||
//} else {
|
||||
// res.reply(error);
|
||||
//}
|
||||
res.reply(error);
|
||||
}
|
||||
|
||||
module.exports = errorHandler;
|
6
magnus/middleware/notFound.js
Normal file
6
magnus/middleware/notFound.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
"use strict";
|
||||
var HttpError = require("../lib/httpError");
|
||||
|
||||
module.exports = function(req, res, next) {
|
||||
return next(new HttpError(404, 'Page not found!'));
|
||||
};
|
9
magnus/middleware/pageInMagnus.js
Normal file
9
magnus/middleware/pageInMagnus.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
"use strict";
|
||||
module.exports = function(req, res, next) {
|
||||
if (global.magnus.hasPage(req.path)) {
|
||||
res.reply("Building " + req.path + "...");
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
};
|
||||
|
8
magnus/middleware/reply.js
Normal file
8
magnus/middleware/reply.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
"use strict";
|
||||
var path = require("path");
|
||||
module.exports = function(req, res, next) {
|
||||
res.reply = function(info) {
|
||||
this.render("index", {info: info});
|
||||
};
|
||||
next();
|
||||
};
|
20
magnus/package.json
Normal file
20
magnus/package.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "magnus",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node app.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "*",
|
||||
"async": "*",
|
||||
"winston": "*",
|
||||
"morgan": "*",
|
||||
"nconf": "*",
|
||||
"errorhandler": "*",
|
||||
"serve-favicon": "*",
|
||||
"jade": "*",
|
||||
"ws": "*",
|
||||
"bintrees": "*"
|
||||
}
|
||||
}
|
10
magnus/pages/CMakeLists.txt
Normal file
10
magnus/pages/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
configure_file(music.js music.js)
|
||||
configure_file(home.js home.js)
|
||||
configure_file(test.js test.js)
|
||||
configure_file(list.js list.js)
|
||||
configure_file(tempPage.js tempPage.js)
|
||||
configure_file(artist.js artist.js)
|
||||
configure_file(album.js album.js)
|
||||
configure_file(song.js song.js)
|
144
magnus/pages/album.js
Normal file
144
magnus/pages/album.js
Normal file
|
@ -0,0 +1,144 @@
|
|||
"use strict";
|
||||
|
||||
var TempPage = require("./tempPage");
|
||||
var String = require("../lib/wModel/string");
|
||||
var ProxyCatModel = require("../lib/wModel/proxy/catalogue");
|
||||
var PaneModel = require("../lib/wModel/proxy/pane");
|
||||
var Image = require("../lib/wModel/image");
|
||||
var Model = require("../lib/wModel/model");
|
||||
|
||||
var VCController = require("../lib/wController/vocabulary");
|
||||
|
||||
var Address = require("../lib/wType/address");
|
||||
var Uint64 = require("../lib/wType/uint64");
|
||||
var Vocabulary = require("../lib/wType/vocabulary");
|
||||
|
||||
var AlbumPage = TempPage.inherit({
|
||||
"className": "AlbumPage",
|
||||
"constructor": function(address, name, id, proxySocket) {
|
||||
TempPage.fn.constructor.call(this, address, name);
|
||||
|
||||
this._remoteId = id;
|
||||
this._proxySocket = proxySocket;
|
||||
this._ctrls = Object.create(null);
|
||||
|
||||
this._image = new Image(this._address["+"](new Address(["image"])), new Uint64(0));
|
||||
var imageOptions = new Vocabulary();
|
||||
imageOptions.insert("minWidth", new Uint64(200));
|
||||
imageOptions.insert("maxWidth", new Uint64(200));
|
||||
imageOptions.insert("minHeight", new Uint64(200));
|
||||
imageOptions.insert("maxHeight", new Uint64(200));
|
||||
this.addItem(this._image, 0, 0, 2, 1, TempPage.Aligment.CenterCenter, new Uint64(TempPage.getModelTypeId(this._image)), imageOptions);
|
||||
|
||||
var header = this._header = new String(this._address["+"](new Address(["header"])), "");
|
||||
header.addProperty("fontFamily", "casualFont");
|
||||
this.addItem(header, 0, 1, 1, 1, TempPage.Aligment.LeftTop);
|
||||
|
||||
var artist = this._artist = new String(this._address["+"](new Address(["artist"])), "Artist name");
|
||||
artist.addProperty("fontFamily", "casualFont");
|
||||
this.addItem(artist, 1, 1, 1, 1, TempPage.Aligment.LeftTop);
|
||||
|
||||
var spacer = new Model(this._address["+"](new Address(["spacer"])));
|
||||
this.addItem(spacer, 0, 2, 2, 1);
|
||||
|
||||
this._songs = new ProxyCatModel(
|
||||
this._address["+"](new Address(["songs"])),
|
||||
new Address(["songs"]),
|
||||
{
|
||||
sorting: {ascending: true, field: "name"},
|
||||
filter: {album: id.clone()}
|
||||
},
|
||||
proxySocket
|
||||
);
|
||||
this._songs.className = "PanesList";
|
||||
var PaneClass = PaneModel.Songs;
|
||||
this._songs.setChildrenClass(PaneClass);
|
||||
this.addItem(this._songs, 2, 0, 1, 3, TempPage.Aligment.CenterTop);
|
||||
},
|
||||
"destructor": function() {
|
||||
this._clearCtrls();
|
||||
|
||||
TempPage.fn.destructor.call(this);
|
||||
},
|
||||
"_clearCtrls": function() {
|
||||
for (var key in this._ctrls) {
|
||||
this._ctrls[key].destructor();
|
||||
}
|
||||
|
||||
this._ctrls = Object.create(null);
|
||||
},
|
||||
"_onAlbumNewElement": function(key, el) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._header.set(el);
|
||||
break;
|
||||
case "image":
|
||||
this._image.set(el.clone());
|
||||
break;
|
||||
case "artist":
|
||||
var arVC = new VCController(new Address(["artists", el.toString()]));
|
||||
arVC.on("newElement", this._onArtistNewElement, this);
|
||||
arVC.on("removeElement", this._onArtistRemoveElement, this);
|
||||
this._ctrls.artist = arVC;
|
||||
arVC.register(this._dp, this._proxySocket);
|
||||
arVC.subscribe();
|
||||
break;
|
||||
}
|
||||
},
|
||||
"_onAlbumRemoveElement": function(key) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._header.set("");
|
||||
break;
|
||||
case "image":
|
||||
this._image.set(new Uint64(0));
|
||||
break;
|
||||
case "artist":
|
||||
this._artist.set("");
|
||||
this._ctrls.artist.destructor();
|
||||
delete this._ctrls.artist;
|
||||
}
|
||||
},
|
||||
"_onArtistNewElement": function(key, el) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._artist.set(el);
|
||||
break;
|
||||
}
|
||||
},
|
||||
"_onArtistRemoveElement": function(key) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._artist.set("unknown");
|
||||
}
|
||||
},
|
||||
"register": function(dp, server) {
|
||||
TempPage.fn.register.call(this, dp, server);
|
||||
|
||||
for (var key in this._ctrls) {
|
||||
this._ctrls[key].register(dp, this._proxySocket);
|
||||
}
|
||||
},
|
||||
"setParentReporter": function(pr) {
|
||||
TempPage.fn.setParentReporter.call(this, pr);
|
||||
|
||||
this._pr.registerParent(this._songs.getAddress(), this._songs.reporterHandler);
|
||||
this._songs.subscribe();
|
||||
|
||||
var albumVC = new VCController(new Address(["albums", this._remoteId.toString()]));
|
||||
albumVC.on("newElement", this._onAlbumNewElement, this);
|
||||
albumVC.on("removeElement", this._onAlbumRemoveElement, this);
|
||||
this._ctrls.album = albumVC;
|
||||
albumVC.register(this._dp, this._proxySocket);
|
||||
albumVC.subscribe();
|
||||
},
|
||||
"unsetParentReporter": function() {
|
||||
this._pr.unregisterParent(this._songs.getAddress());
|
||||
|
||||
this._clearCtrls();
|
||||
|
||||
TempPage.fn.unsetParentReporter.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = AlbumPage;
|
112
magnus/pages/artist.js
Normal file
112
magnus/pages/artist.js
Normal file
|
@ -0,0 +1,112 @@
|
|||
"use strict";
|
||||
|
||||
var TempPage = require("./tempPage");
|
||||
var String = require("../lib/wModel/string");
|
||||
var ProxyCatModel = require("../lib/wModel/proxy/catalogue");
|
||||
var PaneModel = require("../lib/wModel/proxy/pane");
|
||||
|
||||
var VCController = require("../lib/wController/vocabulary");
|
||||
|
||||
var Address = require("../lib/wType/address");
|
||||
|
||||
var ArtistPage = TempPage.inherit({
|
||||
"className": "ArtistPage",
|
||||
"constructor": function(address, name, id, proxySocket) {
|
||||
TempPage.fn.constructor.call(this, address, name);
|
||||
|
||||
this._remoteId = id;
|
||||
this._proxySocket = proxySocket;
|
||||
this._ctrls = Object.create(null);
|
||||
|
||||
var header = this._header = new String(this._address["+"](new Address(["header"])), "");
|
||||
header.addProperty("fontFamily", "casualFont");
|
||||
this.addItem(header, 0, 0, 1, 1, TempPage.Aligment.CenterTop);
|
||||
|
||||
this._albums = new ProxyCatModel(
|
||||
this._address["+"](new Address(["albums"])),
|
||||
new Address(["albums"]),
|
||||
{
|
||||
sorting: {ascending: true, field: "name"},
|
||||
filter: {artist: id.clone()}
|
||||
},
|
||||
proxySocket
|
||||
);
|
||||
this._albums.className = "PanesList";
|
||||
var PaneClass = PaneModel.Albums;
|
||||
this._albums.setChildrenClass(PaneClass);
|
||||
this.addItem(this._albums, 1, 0, 1, 1, TempPage.Aligment.CenterTop);
|
||||
|
||||
this._songs = new ProxyCatModel(
|
||||
this._address["+"](new Address(["songs"])),
|
||||
new Address(["songs"]),
|
||||
{
|
||||
sorting: {ascending: true, field: "name"},
|
||||
filter: {artist: id.clone()}
|
||||
},
|
||||
proxySocket
|
||||
);
|
||||
this._songs.className = "PanesList";
|
||||
var PaneClass = PaneModel.Songs;
|
||||
this._songs.setChildrenClass(PaneClass);
|
||||
this.addItem(this._songs, 2, 0, 1, 1, TempPage.Aligment.CenterTop);
|
||||
},
|
||||
"destructor": function() {
|
||||
this._clearCtrls();
|
||||
|
||||
TempPage.fn.destructor.call(this);
|
||||
},
|
||||
"_clearCtrls": function() {
|
||||
for (var key in this._ctrls) {
|
||||
this._ctrls[key].destructor();
|
||||
}
|
||||
|
||||
this._ctrls = Object.create(null);
|
||||
},
|
||||
"_onArtistNewElement": function(key, el) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._header.set(el);
|
||||
break;
|
||||
}
|
||||
},
|
||||
"_onArtistRemoveElement": function(key) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._header.set("");
|
||||
break;
|
||||
}
|
||||
},
|
||||
"register": function(dp, server) {
|
||||
TempPage.fn.register.call(this, dp, server);
|
||||
|
||||
for (var key in this._ctrls) {
|
||||
this._ctrls[key].register(dp, this._proxySocket);
|
||||
}
|
||||
},
|
||||
"setParentReporter": function(pr) {
|
||||
TempPage.fn.setParentReporter.call(this, pr);
|
||||
|
||||
this._pr.registerParent(this._albums.getAddress(), this._albums.reporterHandler);
|
||||
this._pr.registerParent(this._songs.getAddress(), this._songs.reporterHandler);
|
||||
|
||||
this._albums.subscribe()
|
||||
this._songs.subscribe();
|
||||
|
||||
var artistVC = new VCController(new Address(["artists", this._remoteId.toString()]));
|
||||
artistVC.on("newElement", this._onArtistNewElement, this);
|
||||
artistVC.on("removeElement", this._onArtistRemoveElement, this);
|
||||
this._ctrls.artist = artistVC;
|
||||
artistVC.register(this._dp, this._proxySocket);
|
||||
artistVC.subscribe();
|
||||
},
|
||||
"unsetParentReporter": function() {
|
||||
this._pr.unregisterParent(this._albums.getAddress());
|
||||
this._pr.unregisterParent(this._songs.getAddress());
|
||||
|
||||
this._clearCtrls();
|
||||
|
||||
TempPage.fn.unsetParentReporter.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = ArtistPage;
|
19
magnus/pages/home.js
Normal file
19
magnus/pages/home.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
"use strict";
|
||||
|
||||
var Page = require("../lib/wModel/page");
|
||||
var String = require("../lib/wModel/string");
|
||||
|
||||
var Address = require("../lib/wType/address");
|
||||
|
||||
var HomePage = Page.inherit({
|
||||
"className": "HomePage",
|
||||
"constructor": function(address, name) {
|
||||
Page.fn.constructor.call(this, address, name);
|
||||
|
||||
var header = new String(this._address["+"](new Address(["message"])), "This is the root page");
|
||||
header.addProperty("fontFamily", "casualFont");
|
||||
this.addItem(header, 0, 0, 1, 1, Page.Aligment.CenterTop);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = HomePage;
|
115
magnus/pages/list.js
Normal file
115
magnus/pages/list.js
Normal file
|
@ -0,0 +1,115 @@
|
|||
"use strict";
|
||||
|
||||
var Page = require("../lib/wModel/page");
|
||||
var String = require("../lib/wModel/string");
|
||||
var ProxyCatModel = require("../lib/wModel/proxy/catalogue");
|
||||
var PaneModel = require("../lib/wModel/proxy/pane");
|
||||
|
||||
var Address = require("../lib/wType/address");
|
||||
var Uint64 = require("../lib/wType/uint64");
|
||||
|
||||
var Handler = require("../lib/wDispatcher/handler");
|
||||
|
||||
var List = Page.inherit({
|
||||
"className": "ListPage",
|
||||
"constructor": function(address, name, remoteAddress, socket, ChildClass) {
|
||||
Page.fn.constructor.call(this, address, name);
|
||||
|
||||
this._proxySocket = socket;
|
||||
this._ChildClass = ChildClass;
|
||||
|
||||
var header = new String(this._address["+"](new Address(["header"])), name);
|
||||
header.addProperty("fontFamily", "casualFont");
|
||||
this.addItem(header, 0, 0, 1, 1, Page.Aligment.CenterTop);
|
||||
|
||||
this._list = new ProxyCatModel(
|
||||
this._address["+"](new Address(["list"])),
|
||||
remoteAddress,
|
||||
{
|
||||
sorting: {ascending: true, field: "name"}
|
||||
},
|
||||
socket
|
||||
);
|
||||
this._list.className = "PanesList";
|
||||
var PaneClass = PaneModel[name];
|
||||
if (!PaneClass) {
|
||||
PaneClass = PaneModel.inherit({});
|
||||
PaneClass.pageAddress = address;
|
||||
}
|
||||
this._list.setChildrenClass(PaneClass);
|
||||
this.addItem(this._list, 1, 0, 1, 1, Page.Aligment.CenterTop);
|
||||
|
||||
this._reporterHandler = new Handler(this._address["+"](new Address(["subscribeMember"])), this, this._h_subscribeMember);
|
||||
},
|
||||
"destructor": function() {
|
||||
this._reporterHandler.destructor();
|
||||
this.removeItem(this._list);
|
||||
this._list.destructor();
|
||||
|
||||
Page.fn.destructor.call(this);
|
||||
},
|
||||
"_createChildPage": function(id) {
|
||||
var childName = id.toString();
|
||||
var postfix = new Address([childName]);
|
||||
var childAddr = this._address["+"](postfix);
|
||||
|
||||
var child = new this._ChildClass(childAddr, childName, id.clone(), this._proxySocket);
|
||||
this.addPage(child);
|
||||
child.on("destroyMe", this._destroyChild.bind(this, child)); //to remove model if it has no subscribers
|
||||
child.checkSubscribersAndDestroy();
|
||||
|
||||
return child;
|
||||
},
|
||||
"_destroyChild": function(child) {
|
||||
this.removePage(child);
|
||||
child.destructor();
|
||||
},
|
||||
"getChildPage": function(name) {
|
||||
var child = this._childPages[name];
|
||||
if (child === undefined) {
|
||||
var int = parseInt(name);
|
||||
if (int == name) {
|
||||
var id = new Uint64(int);
|
||||
var itr = this._list.controller.data.find(id);
|
||||
if (!itr["=="](this._list.controller.data.end())) {
|
||||
child = this._createChildPage(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return child;
|
||||
},
|
||||
"_h_subscribeMember": function(ev) {
|
||||
var dest = ev.getDestination();
|
||||
var lastHops = dest["<<"](this._address.length());
|
||||
|
||||
if (lastHops.length() === 2) {
|
||||
var command = lastHops.back().toString();
|
||||
var numId = parseInt(lastHops.front().toString());
|
||||
if ((command === "subscribe" || command === "get" || command === "ping") && numId === numId) {
|
||||
var id = new Uint64(numId);
|
||||
var child = this._createChildPage(id);
|
||||
child["_h_" + command](ev);
|
||||
} else {
|
||||
this.trigger("serviceMessage", "ListPage model got a strange event: " + ev.toString(), 1);
|
||||
}
|
||||
} else {
|
||||
this.trigger("serviceMessage", "ListPage model got a strange event: " + ev.toString(), 1);
|
||||
}
|
||||
},
|
||||
"setParentReporter": function(pr) {
|
||||
Page.fn.setParentReporter.call(this, pr);
|
||||
|
||||
this._pr.registerParent(this._list.getAddress(), this._list.reporterHandler);
|
||||
this._pr.registerParent(this.getAddress(), this._reporterHandler);
|
||||
this._list.subscribe();
|
||||
},
|
||||
"unsetParentReporter": function() {
|
||||
this._pr.unregisterParent(this.getAddress());
|
||||
this._pr.unregisterParent(this._list.getAddress());
|
||||
|
||||
Page.fn.unsetParentReporter.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = List;
|
198
magnus/pages/music.js
Normal file
198
magnus/pages/music.js
Normal file
|
@ -0,0 +1,198 @@
|
|||
"use strict";
|
||||
|
||||
var Page = require("../lib/wModel/page");
|
||||
var String = require("../lib/wModel/string");
|
||||
var PanesList = require("../lib/wModel/panesList");
|
||||
|
||||
var Address = require("../lib/wType/address");
|
||||
var Vocabulary = require("../lib/wType/vocabulary");
|
||||
var Boolean = require("../lib/wType/boolean");
|
||||
|
||||
var Link = require("../lib/wModel/link");
|
||||
|
||||
var List = require("./list");
|
||||
var Artist = require("./artist");
|
||||
var Album = require("./album");
|
||||
var Song = require("./song");
|
||||
|
||||
var PaneModel = require("../lib/wModel/proxy/pane");
|
||||
|
||||
var MusicPage = Page.inherit({
|
||||
"className": "MusicPage",
|
||||
"constructor": function(address, name) {
|
||||
Page.fn.constructor.call(this, address, name);
|
||||
|
||||
this._dbConnected = false;
|
||||
this._addresses = Object.create(null);
|
||||
|
||||
this._createAddresses();
|
||||
|
||||
var header = new String(this._address["+"](new Address(["header"])), "Music");
|
||||
header.addProperty("fontFamily", "casualFont");
|
||||
//var hvo = new Vocabulary();
|
||||
this.addItem(header, 0, 0, 1, 1, Page.Aligment.CenterTop);
|
||||
|
||||
this._errMessage = new String(this._address["+"](new Address(["message"])), "Database is not connected");
|
||||
this._errMessage.addProperty("fontFamily", "largeFont");
|
||||
this._errMessage.addProperty("fontSize", "largeFontSize");
|
||||
|
||||
this.addItem(this._errMessage, 1, 0, 1, 1, Page.Aligment.CenterTop);
|
||||
},
|
||||
"destructor": function() {
|
||||
if (this._dbConnected && this._hasParentReporter) {
|
||||
this._destroyLists();
|
||||
} else {
|
||||
this.removeItem(this._errMessage);
|
||||
}
|
||||
this._errMessage.destructor();
|
||||
|
||||
for (var tag in this._addresses) {
|
||||
var group = this._addresses[tag];
|
||||
for (var name in group) {
|
||||
group[name].destructor();
|
||||
}
|
||||
}
|
||||
|
||||
Page.fn.destructor.call(this);
|
||||
},
|
||||
"_createAddresses": function() {
|
||||
var ra = new Address(["artists"]);
|
||||
var ral = new Address(["albums"]);
|
||||
var rs = new Address(["songs"]);
|
||||
|
||||
var artists = Object.create(null);
|
||||
var albums = Object.create(null);
|
||||
var songs = Object.create(null);
|
||||
|
||||
artists.remote = ra.clone();
|
||||
artists.local = this._address["+"](ra);
|
||||
|
||||
albums.remote = ral.clone();
|
||||
albums.local = this._address["+"](ral);
|
||||
|
||||
songs.remote = rs.clone();
|
||||
songs.local = this._address["+"](rs);
|
||||
|
||||
this._addresses.artists = artists;
|
||||
this._addresses.albums = albums;
|
||||
this._addresses.songs = songs;
|
||||
|
||||
var PaneArtist = PaneModel.Artists;
|
||||
if (!PaneArtist) {
|
||||
PaneArtist = PaneModel.inherit({});
|
||||
PaneModel.Artists = PaneArtist;
|
||||
} else {
|
||||
PaneArtist.pageAddress.destructor()
|
||||
}
|
||||
PaneArtist.pageAddress = artists.local.clone();
|
||||
|
||||
var PaneAlbum = PaneModel.Albums;
|
||||
if (!PaneAlbum) {
|
||||
PaneAlbum = PaneModel.inherit({});
|
||||
PaneModel.Albums = PaneAlbum;
|
||||
} else {
|
||||
PaneAlbum.pageAddress.destructor()
|
||||
}
|
||||
PaneAlbum.pageAddress = albums.local.clone();
|
||||
|
||||
var PaneSongs = PaneModel.Songs;
|
||||
if (!PaneSongs) {
|
||||
PaneSongs = PaneModel.inherit({});
|
||||
PaneModel.Songs = PaneSongs;
|
||||
} else {
|
||||
PaneSongs.pageAddress.destructor()
|
||||
}
|
||||
PaneSongs.pageAddress = songs.local.clone();
|
||||
|
||||
ra.destructor();
|
||||
ral.destructor();
|
||||
rs.destructor();
|
||||
},
|
||||
"_createLists": function(socket) {
|
||||
this._artists = new List(
|
||||
this._addresses.artists.local.clone(),
|
||||
"Artists",
|
||||
this._addresses.artists.remote.clone(),
|
||||
socket,
|
||||
Artist
|
||||
);
|
||||
this._artistsLink = new Link(this._address["+"](new Address(["artistsLink"])), "Artists", this._addresses.artists.local.clone());
|
||||
this._artistsLink.label.addProperty("fontSize", "largeFontSize");
|
||||
this._artistsLink.label.addProperty("fontFamily", "largeFont");
|
||||
this._artistsLink.label.addProperty("color", "primaryFontColor");
|
||||
this._artistsLink.addProperty("backgroundColor", "primaryColor");
|
||||
|
||||
this._albums = new List(
|
||||
this._addresses.albums.local.clone(),
|
||||
"Albums",
|
||||
this._addresses.albums.remote.clone(),
|
||||
socket,
|
||||
Album
|
||||
);
|
||||
this._albumsLink = new Link(this._address["+"](new Address(["albumsLink"])), "Albums", this._addresses.albums.local.clone());
|
||||
this._albumsLink.label.addProperty("fontSize", "largeFontSize");
|
||||
this._albumsLink.label.addProperty("fontFamily", "largeFont");
|
||||
this._albumsLink.label.addProperty("color", "primaryFontColor");
|
||||
this._albumsLink.addProperty("backgroundColor", "primaryColor");
|
||||
|
||||
this._songs = new List(
|
||||
this._addresses.songs.local.clone(),
|
||||
"Songs",
|
||||
this._addresses.songs.remote.clone(),
|
||||
socket,
|
||||
Song
|
||||
);
|
||||
this._songsLink = new Link(this._address["+"](new Address(["songsLink"])), "Songs", this._addresses.songs.local.clone());
|
||||
this._songsLink.label.addProperty("fontSize", "largeFontSize");
|
||||
this._songsLink.label.addProperty("fontFamily", "largeFont");
|
||||
this._songsLink.label.addProperty("color", "primaryFontColor");
|
||||
this._songsLink.addProperty("backgroundColor", "primaryColor");
|
||||
|
||||
this.addItem(this._artistsLink, 1, 0, 1, 1);
|
||||
this.addItem(this._albumsLink, 2, 0, 1, 1);
|
||||
this.addItem(this._songsLink, 3, 0, 1, 1);
|
||||
|
||||
this.addPage(this._artists);
|
||||
this.addPage(this._albums);
|
||||
this.addPage(this._songs);
|
||||
},
|
||||
"_destroyLists": function() {
|
||||
this.removePage(this._artists);
|
||||
this.removePage(this._albums);
|
||||
this.removePage(this._songs);
|
||||
|
||||
this.removeItem(this._artistsLink);
|
||||
this.removeItem(this._albumsLink);
|
||||
this.removeItem(this._songsLink);
|
||||
|
||||
this._artists.destructor();
|
||||
this._albums.destructor();
|
||||
this._songs.destructor();
|
||||
|
||||
this._artistsLink.destructor();
|
||||
this._albumsLink.destructor();
|
||||
this._songsLink.destructor();
|
||||
},
|
||||
"showError": function() {
|
||||
if (this._dbConnected) {
|
||||
if (!this._hasParentReporter) {
|
||||
throw new Error("Parent reporter is required in music page");
|
||||
}
|
||||
this._destroyLists()
|
||||
this.addItem(this._errMessage, 1, 0, 1, 1, Page.Aligment.CenterTop);
|
||||
this._dbConnected = false;
|
||||
}
|
||||
},
|
||||
"showBandList": function(perturaboSocket) {
|
||||
if (!this._hasParentReporter) {
|
||||
throw new Error("Parent reporter is required in music page");
|
||||
}
|
||||
if (!this._dbConnected) {
|
||||
this.removeItem(this._errMessage);
|
||||
this._createLists(perturaboSocket);
|
||||
this._dbConnected = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = MusicPage;
|
151
magnus/pages/song.js
Normal file
151
magnus/pages/song.js
Normal file
|
@ -0,0 +1,151 @@
|
|||
"use strict";
|
||||
|
||||
var TempPage = require("./tempPage");
|
||||
var String = require("../lib/wModel/string");
|
||||
var Image = require("../lib/wModel/image");
|
||||
|
||||
var VCController = require("../lib/wController/vocabulary");
|
||||
|
||||
var Address = require("../lib/wType/address");
|
||||
var Uint64 = require("../lib/wType/uint64");
|
||||
|
||||
var SongPage = TempPage.inherit({
|
||||
"className": "SongPage",
|
||||
"constructor": function(address, name, id, proxySocket) {
|
||||
TempPage.fn.constructor.call(this, address, name);
|
||||
|
||||
this._remoteId = id;
|
||||
this._proxySocket = proxySocket;
|
||||
this._ctrls = Object.create(null);
|
||||
|
||||
var header = this._header = new String(this._address["+"](new Address(["header"])), "");
|
||||
header.addProperty("fontFamily", "casualFont");
|
||||
this.addItem(header, 0, 1, 1, 1, TempPage.Aligment.CenterTop);
|
||||
|
||||
var album = this._album = new String(this._address["+"](new Address(["album"])), "Album name");
|
||||
album.addProperty("fontFamily", "casualFont");
|
||||
this.addItem(album, 1, 1, 1, 1, TempPage.Aligment.CenterTop);
|
||||
|
||||
var artist = this._artist = new String(this._address["+"](new Address(["artist"])), "Artist name");
|
||||
artist.addProperty("fontFamily", "casualFont");
|
||||
this.addItem(artist, 2, 1, 1, 1, TempPage.Aligment.CenterTop);
|
||||
|
||||
var image = this._image = new Image(this._address["+"](new Address(["image"])), new Uint64(0));
|
||||
this.addItem(image, 0, 0, 3, 1, TempPage.Aligment.CenterCenter);
|
||||
},
|
||||
"destructor": function() {
|
||||
this._clearCtrls();
|
||||
|
||||
TempPage.fn.destructor.call(this);
|
||||
},
|
||||
"_clearCtrls": function() {
|
||||
for (var key in this._ctrls) {
|
||||
this._ctrls[key].destructor();
|
||||
}
|
||||
|
||||
this._ctrls = Object.create(null);
|
||||
},
|
||||
"_onAlbumNewElement": function(key, el) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._album.set(el);
|
||||
break;
|
||||
case "image":
|
||||
this._image.set(el.clone());
|
||||
break;
|
||||
|
||||
}
|
||||
},
|
||||
"_onAlbumRemoveElement": function(key) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._album.set("unknown");
|
||||
case "image":
|
||||
this._image.set(new Uint64(0));
|
||||
break;
|
||||
}
|
||||
},
|
||||
"_onArtistNewElement": function(key, el) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._artist.set(el);
|
||||
break;
|
||||
}
|
||||
},
|
||||
"_onArtistRemoveElement": function(key) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._artist.set("unknown");
|
||||
}
|
||||
},
|
||||
"_onSongNewElement": function(key, el) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._header.set(el);
|
||||
break;
|
||||
case "album":
|
||||
if (this._ctrls.album) {
|
||||
this.trigger("serviceMessage", "an album controller reinitializes in song page, not suppose to happen!", 1);
|
||||
this._ctrls.album.destructor();
|
||||
}
|
||||
var aVC = new VCController(new Address(["albums", el.toString()]));
|
||||
aVC.on("newElement", this._onAlbumNewElement, this);
|
||||
aVC.on("removeElement", this._onAlbumRemoveElement, this);
|
||||
this._ctrls.album = aVC;
|
||||
aVC.register(this._dp, this._proxySocket);
|
||||
aVC.subscribe();
|
||||
break;
|
||||
case "artist":
|
||||
if (this._ctrls.artist) {
|
||||
this.trigger("serviceMessage", "an artist controller reinitializes in song page, not suppose to happen!", 1);
|
||||
this._ctrls.artist.destructor();
|
||||
}
|
||||
var arVC = new VCController(new Address(["artists", el.toString()]));
|
||||
arVC.on("newElement", this._onArtistNewElement, this);
|
||||
arVC.on("removeElement", this._onArtistRemoveElement, this);
|
||||
this._ctrls.artist = arVC;
|
||||
arVC.register(this._dp, this._proxySocket);
|
||||
arVC.subscribe();
|
||||
break;
|
||||
}
|
||||
},
|
||||
"_onSongRemoveElement": function(key) {
|
||||
switch(key) {
|
||||
case "name":
|
||||
this._header.set("");
|
||||
break;
|
||||
case "album":
|
||||
this._album.set("");
|
||||
this._ctrls.album.destructor();
|
||||
delete this._ctrls.album;
|
||||
case "artist":
|
||||
this._artist.set("");
|
||||
this._ctrls.artist.destructor();
|
||||
delete this._ctrls.artist;
|
||||
}
|
||||
},
|
||||
"register": function(dp, server) {
|
||||
TempPage.fn.register.call(this, dp, server);
|
||||
|
||||
for (var key in this._ctrls) {
|
||||
this._ctrls[key].register(dp, this._proxySocket);
|
||||
}
|
||||
},
|
||||
"setParentReporter": function(pr) {
|
||||
TempPage.fn.setParentReporter.call(this, pr);
|
||||
|
||||
var songVC = new VCController(new Address(["songs", this._remoteId.toString()]));
|
||||
songVC.on("newElement", this._onSongNewElement, this);
|
||||
songVC.on("removeElement", this._onSongRemoveElement, this);
|
||||
this._ctrls.song = songVC;
|
||||
songVC.register(this._dp, this._proxySocket);
|
||||
songVC.subscribe();
|
||||
},
|
||||
"unsetParentReporter": function() {
|
||||
this._clearCtrls();
|
||||
|
||||
TempPage.fn.unsetParentReporter.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = SongPage;
|
46
magnus/pages/tempPage.js
Normal file
46
magnus/pages/tempPage.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
"use strict";
|
||||
|
||||
var Page = require("../lib/wModel/page");
|
||||
|
||||
var config = require("../config/config.json");
|
||||
|
||||
var TempPage = Page.inherit({
|
||||
"className": "TempPage",
|
||||
"constructor": function(address, name) {
|
||||
Page.fn.constructor.call(this, address, name);
|
||||
|
||||
this._destructionTimeout = undefined;
|
||||
},
|
||||
"destructor": function() {
|
||||
if (this._destructionTimeout) {
|
||||
clearTimeout(this._destructionTimeout);
|
||||
}
|
||||
Page.fn.destructor.call(this);
|
||||
},
|
||||
"checkSubscribersAndDestroy": function() {
|
||||
if (this._subscribersCount === 0 && this._destructionTimeout === undefined) {
|
||||
this.trigger("serviceMessage", this._address.toString() + " has no more subscribers, destroying page");
|
||||
this._destructionTimeout = setTimeout(this.trigger.bind(this, "destroyMe"), config.modelDestructionTimeout);
|
||||
}
|
||||
},
|
||||
"_h_subscribe": function(ev) {
|
||||
Page.fn._h_subscribe.call(this, ev);
|
||||
|
||||
if (this._destructionTimeout !== undefined) {
|
||||
clearTimeout(this._destructionTimeout);
|
||||
this._destructionTimeout = undefined;
|
||||
}
|
||||
},
|
||||
"_h_unsubscribe": function(ev) {
|
||||
Page.fn._h_unsubscribe.call(this, ev);
|
||||
|
||||
this.checkSubscribersAndDestroy();
|
||||
},
|
||||
"_onSocketDisconnected": function(ev, socket) {
|
||||
Page.fn._onSocketDisconnected.call(this, ev, socket);
|
||||
|
||||
this.checkSubscribersAndDestroy();
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = TempPage;
|
19
magnus/pages/test.js
Normal file
19
magnus/pages/test.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
"use strict";
|
||||
|
||||
var Page = require("../lib/wModel/page");
|
||||
var String = require("../lib/wModel/string");
|
||||
|
||||
var Address = require("../lib/wType/address");
|
||||
|
||||
var TestPage = Page.inherit({
|
||||
"className": "TestPage",
|
||||
"constructor": function(address, name) {
|
||||
Page.fn.constructor.call(this, address, name);
|
||||
|
||||
var header = new String(this._address["+"](new Address(["message"])), "This is a test page");
|
||||
header.addProperty("fontFamily", "casualFont");
|
||||
this.addItem(header, 0, 0, 1, 1, Page.Aligment.CenterTop);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = TestPage;
|
3
magnus/test/CMakeLists.txt
Normal file
3
magnus/test/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
configure_file(test.js test.js)
|
64
magnus/test/test.js
Normal file
64
magnus/test/test.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
"use strict";
|
||||
var Class = require("../lib/utils/class");
|
||||
var TUint64 = require("../lib/wTest/uint64");
|
||||
var TAbstractMap = require("../lib/wTest/abstractmap");
|
||||
var TAbstractList = require("../lib/wTest/abstractlist");
|
||||
var TAbstractOrder = require("../lib/wTest/abstractorder");
|
||||
var log = require("../lib/log")(module);
|
||||
|
||||
var Test = Class.inherit({
|
||||
"className": "Test",
|
||||
"constructor": function() {
|
||||
Class.fn.constructor.call(this);
|
||||
|
||||
this._s = 0;
|
||||
this._t = 0;
|
||||
this._tests = [];
|
||||
|
||||
this.addTest(new TUint64());
|
||||
this.addTest(new TAbstractList());
|
||||
this.addTest(new TAbstractMap());
|
||||
this.addTest(new TAbstractOrder());
|
||||
},
|
||||
"destructor": function() {
|
||||
for (var i = 0; i < this._tests.length; ++i) {
|
||||
this._tests[i].destructor();
|
||||
}
|
||||
|
||||
Class.fn.destructor.call(this);
|
||||
},
|
||||
"addTest": function(test) {
|
||||
test.on("start", this._onStart, this);
|
||||
test.on("end", this._onEnd, this);
|
||||
test.on("progress", this._onProgress, this);
|
||||
test.on("fail", this._onFail, this);
|
||||
|
||||
this._tests.push(test);
|
||||
},
|
||||
"run": function() {
|
||||
log.info("Starting tests");
|
||||
for (var i = 0; i < this._tests.length; ++i) {
|
||||
this._tests[i].run();
|
||||
}
|
||||
log.info("Testing complete. " + this._s + "/" + this._t);
|
||||
},
|
||||
"_onStart": function(name) {
|
||||
log.info("Testing " + name);
|
||||
},
|
||||
"_onEnd": function(name, s, t) {
|
||||
log.info("Finished " + name + ". " + s + "/" + t);
|
||||
|
||||
this._s += s;
|
||||
this._t += t;
|
||||
},
|
||||
"_onProgress": function(name, current, total) {
|
||||
|
||||
},
|
||||
"_onFail": function(name, current, error) {
|
||||
log.warn("Test failed! Action " + current + ".");
|
||||
log.warn("Error message:" + error.message);
|
||||
log.warn("Error stack: \n" + error.stack);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Test;
|
3
magnus/views/CMakeLists.txt
Normal file
3
magnus/views/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
configure_file(index.jade index.jade)
|
15
magnus/views/index.jade
Normal file
15
magnus/views/index.jade
Normal file
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
Created by betrayer on 27.11.15.
|
||||
|
||||
doctype html
|
||||
html(lang='en')
|
||||
head
|
||||
meta(charset='utf-8')
|
||||
title RadioW
|
||||
link(href='/css/main.css', rel='stylesheet')
|
||||
script(data-main='/main' src='/lib/requirejs/require.js')
|
||||
|
||||
body
|
||||
#serverMessage
|
||||
= info
|
||||
p I am
|
Loading…
Add table
Add a link
Reference in a new issue