initial commit

This commit is contained in:
Blue 2018-08-05 00:46:25 +03:00 committed by Юрий Губич
commit 4b60ece582
327 changed files with 28286 additions and 0 deletions

13
magnus/lib/CMakeLists.txt Normal file
View 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
View 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
View 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;

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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;

View file

@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 2.8.12)
configure_file(socket.js socket.js)
configure_file(server.js server.js)

View 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;

View 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;

View 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)

View 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)