From ca67a8e8bc21794ed0964b8893e64a7be080de48 Mon Sep 17 00:00:00 2001 From: blue Date: Wed, 29 Aug 2018 22:54:18 +0300 Subject: [PATCH] a new oblect utils - enum, enum view, refactoring of mainLayout, debugging, states for sockets --- corax/corax.cpp | 6 ++- lib/wModel/button.cpp | 34 +++++++----- lib/wSsh/CMakeLists.txt | 2 +- libjs/utils/CMakeLists.txt | 3 +- libjs/utils/enum.js | 69 ++++++++++++++++++++++++ libjs/wController/localModel.js | 1 + lorgar/core/lorgar.js | 95 ++++++++++++++++++++++----------- lorgar/lib/utils/CMakeLists.txt | 3 +- lorgar/main.js | 2 +- lorgar/views/CMakeLists.txt | 1 + lorgar/views/enumeration.js | 53 ++++++++++++++++++ lorgar/views/mainLayout.js | 41 +++++++++++--- lorgar/views/view.js | 5 +- magnus/lib/log.js | 2 +- 14 files changed, 260 insertions(+), 57 deletions(-) create mode 100644 libjs/utils/enum.js create mode 100644 lorgar/views/enumeration.js diff --git a/corax/corax.cpp b/corax/corax.cpp index 3bcc4df..2183914 100644 --- a/corax/corax.cpp +++ b/corax/corax.cpp @@ -9,7 +9,7 @@ Corax* Corax::corax = 0; Corax::Corax(QObject *parent): QObject(parent), - started(false) + started(false), server(new W::Server(W::String(u"Corax"), this)), logger(new W::Logger()), parentReporter(new W::ParentReporter()), @@ -262,6 +262,7 @@ void Corax::onNodeConnected(const W::String& name) cout << "connected node " << name.toString() << endl; if (name == u"Perturabo") { commands->enableCommand(W::String(u"parseDirectory"), true); + commands->enableCommand(W::String(u"givePlayer"), true); } } @@ -270,6 +271,7 @@ void Corax::onNodeDisconnected(const W::String& name) cout << "disconnected node " << name.toString() << endl; if (name == u"Perturabo") { commands->enableCommand(W::String(u"parseDirectory"), false); + commands->enableCommand(W::String(u"givePlayer"), false); } } @@ -294,6 +296,6 @@ void Corax::h_givePlayer(const W::Event& ev) W::Event res(source + W::Address{u"getPlayer"}, vc); res.setSenderId(id); - connector->getConnection(id)->send(ev); + connector->getConnection(id)->send(res); } diff --git a/lib/wModel/button.cpp b/lib/wModel/button.cpp index 16d103e..649f999 100644 --- a/lib/wModel/button.cpp +++ b/lib/wModel/button.cpp @@ -28,16 +28,20 @@ void M::Button::setImage(const W::String& p_image) if (hasImage) { if (*imageName != p_image) { imageName = static_cast(p_image.copy()); - W::Vocabulary* vc = new W::Vocabulary(); - vc->insert(u"image", p_image); - broadcast(vc, W::Address{u"changeImage"}); + if (registered) { + W::Vocabulary* vc = new W::Vocabulary(); + vc->insert(u"image", p_image); + broadcast(vc, W::Address{u"changeImage"}); + } } } else { imageName = static_cast(p_image.copy()); hasImage = true; - W::Vocabulary* vc = new W::Vocabulary(); - vc->insert(u"image", p_image); - broadcast(vc, W::Address{u"setImage"}); + if (registered) { + W::Vocabulary* vc = new W::Vocabulary(); + vc->insert(u"image", p_image); + broadcast(vc, W::Address{u"setImage"}); + } } hasImage = true; } @@ -46,9 +50,11 @@ void M::Button::setEnabled(bool p_enabled) { if (enabled != p_enabled) { enabled = p_enabled; - W::Vocabulary* vc = new W::Vocabulary(); - vc->insert(u"enable", new W::Boolean(enabled)); - broadcast(vc, W::Address{u"setEnabled"}); + if (registered) { + W::Vocabulary* vc = new W::Vocabulary(); + vc->insert(u"enable", new W::Boolean(enabled)); + broadcast(vc, W::Address{u"setEnabled"}); + } } } @@ -59,10 +65,12 @@ void M::Button::setLabel(const W::String& p_label) } else { label = new M::String(p_label, address + W::Address{u"label"}); addModel(label); - W::Vocabulary* vc = new W::Vocabulary(); - vc->insert(u"hasLabel", new W::Boolean(true)); - vc->insert(u"label", label->getAddress()); - broadcast(vc, W::Address{u"setLabel"}); + if (registered) { + W::Vocabulary* vc = new W::Vocabulary(); + vc->insert(u"hasLabel", new W::Boolean(true)); + vc->insert(u"label", label->getAddress()); + broadcast(vc, W::Address{u"setLabel"}); + } hasLabel = true; } } diff --git a/lib/wSsh/CMakeLists.txt b/lib/wSsh/CMakeLists.txt index 167eb7d..fa56fa8 100644 --- a/lib/wSsh/CMakeLists.txt +++ b/lib/wSsh/CMakeLists.txt @@ -20,4 +20,4 @@ add_library(wSsh ${HEADERS} ${SOURCES}) target_link_libraries(wSsh Qt5::Core) target_link_libraries(wSsh ssh) -target_link_libraries(wSsh ssh_threads) +#target_link_libraries(wSsh ssh_threads) diff --git a/libjs/utils/CMakeLists.txt b/libjs/utils/CMakeLists.txt index 2d5d83b..a0018e8 100644 --- a/libjs/utils/CMakeLists.txt +++ b/libjs/utils/CMakeLists.txt @@ -2,4 +2,5 @@ cmake_minimum_required(VERSION 2.8.12) configure_file(class.js class.js) configure_file(subscribable.js subscribable.js) -configure_file(globalMethods.js globalMethods.js) \ No newline at end of file +configure_file(globalMethods.js globalMethods.js) +configure_file(enum.js enum.js) diff --git a/libjs/utils/enum.js b/libjs/utils/enum.js new file mode 100644 index 0000000..9f1215c --- /dev/null +++ b/libjs/utils/enum.js @@ -0,0 +1,69 @@ +"use strict"; + +var Class = require("./class"); + +var Enum = Class.inherit({ + className: "Enum", + constructor: function(name, additional) { + if (typeof name !== "string" || name.length === 0) { + throw new Error("An attempt to register enum with wrong or empty name"); + } + + if (storage[name]) { + throw new Error("An attempt to register enum " + name + " for the second time"); + } + + Class.fn.constructor.call(this); + + this.name = name; + + this.straight = Object.create(null); + this.reversed = Object.create(null); + + this.additional = Object.create(null); + this._additionals = additional || []; + + this._lastId = 0; + + storage[name] = this; + }, + add: function(name, additional, id) { + if (typeof name !== "string" || name.length === 0) { + throw new Error("An attempt to add an entry with invalid name to enum " + name); + } + + if (!id) { + id = this._lastId + 1; + } + if (this.straight[id] !== undefined) { + throw new Error("Id duplication in enum " + this.name + " during an attempt to add entry " + name); + } + + if (this.reversed[name] !== undefined) { + throw new Error("Name duplication in enum " + this.name + " during an attempt to add entry " + name); + } + + this.straight[name] = id; + this.reversed[id] = name; + this.additional[id] = Object.create(null); + + for (var i = 0; i < this._additionals.length; ++i) { + var key = this._additionals[i]; + var aVal = additional[key]; + if (aVal === undefined) { + throw new Error("An attempt to add an entry " + name + " into enum " + this.name + " without providing additional value " + key); + } + this.additional[id][key] = aVal; + } + + this._lastId = id; + }, + hasAdditional: function(name) { + return this._additionals.indexOf(name) !== -1; + } +}); + +var storage = Object.create(null); +Enum.storage = storage; + +module.exports = Enum; diff --git a/libjs/wController/localModel.js b/libjs/wController/localModel.js index 8b1b786..f556396 100644 --- a/libjs/wController/localModel.js +++ b/libjs/wController/localModel.js @@ -21,6 +21,7 @@ var LocalModel = Subscribable.inherit({ }, "setData": function(data) { this.data = data; + this.initialized = true; this.trigger("data"); } }); diff --git a/lorgar/core/lorgar.js b/lorgar/core/lorgar.js index bc19b87..ea02cb0 100644 --- a/lorgar/core/lorgar.js +++ b/lorgar/core/lorgar.js @@ -4,6 +4,7 @@ var defineArray = []; defineArray.push("lib/utils/class"); + defineArray.push("lib/utils/enum"); defineArray.push("lib/wSocket/socket"); defineArray.push("lib/wDispatcher/dispatcher"); defineArray.push("lib/wDispatcher/handler"); @@ -27,6 +28,7 @@ define(moduleName, defineArray, function lorgar_module() { var Class = require("lib/utils/class"); + var Enum = require("lib/utils/enum"); var Socket = require("lib/wSocket/socket"); var Dispatcher = require("lib/wDispatcher/dispatcher"); var Handler = require("lib/wDispatcher/handler"); @@ -53,16 +55,18 @@ "constructor": function() { Class.fn.constructor.call(this); + this._playerCtl = undefined; this._currentPageCtl = undefined; this._nodes = Object.create(null); this._initDispatcher(); + this._initModels(); + this._initViews(); this._prepareNode("Magnus", "localhost", 8081); this._prepareNode("Corax", "localhost", 8080); - this._initModels(); - this._initViews(); + this._registerModels(); this.connectNode("Magnus"); this.connectNode("Corax"); @@ -70,6 +74,8 @@ }, "destructor": function() { window.onpopstate = undefined; + this._unregisterModels(); + if (this._currentPageCtl) { this._currentPage.destructor(); this._currentPageCtl.destructor(); @@ -77,16 +83,17 @@ this._gc.destructor(); this._ps.destructor(); - this._mainColorHelper.destructor(); this._emptyHelper.destructor(); this._body.destructor(); this.coraxSocket.close(); + this.dispatcher.unregisterHandler(this._playerResponseHandler); this.dispatcher.unregisterDefaultHandler(this._logger); this._logger.destructor(); this.dispatcher.destructor(); + this._playerResponseHandler.destructor(); //this.magnusSocket.destructor(); //this.coraxSocket.destructor(); @@ -106,31 +113,34 @@ } node.socket.open(node.address, node.port); + node.state.setData(SocketState.straight.connecting); }, - "_initCoraxSocket": function() { - this.coraxSocket = new Socket("Lorgar"); - this.coraxSocket.on("connected", this._coraxSocketConnected, this); - this.coraxSocket.on("disconnected", this._coraxSocketDisconnected, this); - this.coraxSocket.on("error", this._coraxSocketError, this); - this.coraxSocket.on("message", this.dispatcher.pass, this.dispatcher); + _registerModels: function () { + this._gc.register(this.dispatcher, this._nodes.Magnus.socket); + this._ps.register(this.dispatcher, this._nodes.Magnus.socket); + }, + _unregisterModels: function() { + if (this._currentPageCtl) { + this._currentPageCtl.unregister(); + } + + this._gc.unregister(); + this._ps.unregister(); }, "_initDispatcher": function() { this.dispatcher = new Dispatcher(); this._logger = new Logger(); + this._playerResponseHandler = new Handler(new Address(["getPlayer"]), this, this._responsePlayer); this.dispatcher.registerDefaultHandler(this._logger); + this.dispatcher.registerHandler(this._playerResponseHandler); }, "_initModels": function() { this._gc = new GlobalControls(new Address(["magnus", "gc"])); this._ps = new PageStorage(new Address(["magnus", "ps"])); - this._mainColorHelper = new LocalModel({backgroundColor: "mainColor"}); this._emptyHelper = new LocalModel(); this._gc.on("themeSelected", this.setTheme, this); - - this._gc.register(this.dispatcher, this._nodes.Magnus.socket); - this._ps.register(this.dispatcher, this._nodes.Magnus.socket); - this._ps.on("pageName", this._onPageName, this); }, "_initPageController": function(addr) { @@ -150,18 +160,10 @@ document.body.innerHTML = ""; document.body.appendChild(this._body._e); - window.addEventListener("resize",this._onWindowResize.bind(this) ,false); + window.addEventListener("resize", this._onWindowResize.bind(this), false); this._body.setSize(document.body.offsetWidth, document.body.offsetHeight); this._body.append(this._mainLayout); - var spacerL = new View(this._mainColorHelper, { - maxWidth: 50 - }); - var spacerR = new View(this._mainColorHelper, { - maxWidth: 50 - }); - this._mainLayout.append(spacerL, 1, 0, 1, 1); - this._mainLayout.append(spacerR, 1, 2, 1, 1); }, "_onHistoryPopState": function(e) { this._initPageController(new Address(e.state.address)); @@ -175,6 +177,7 @@ console.log(name + " socket connected"); var node = this._nodes[name]; node.connected = true; + node.state.setData(SocketState.straight.connected); for (var id in node.foreigns) { if (node.foreigns[id].subscribed) { @@ -182,13 +185,18 @@ } } - if (name === "Magnus") { - this._gc.subscribe(); + switch (name) { + case "Magnus": + this._gc.subscribe(); - if (!this._currentPageCtl) { - this._ps.getPageAddress(location.pathname); - this._ps.one("pageAddress", this._initPageController, this); - } + if (!this._currentPageCtl) { + this._ps.getPageAddress(location.pathname); + this._ps.one("pageAddress", this._initPageController, this); + } + break; + case "Corax": + this._requestPlayer(); + break; } }, "_onSocketDisconnected": function(name) { @@ -201,8 +209,9 @@ node.foreigns[id].controller._onSocketDisconnected; } } + node.state.setData(SocketState.straight.disconnected); }, - "_onSocketError": function(name) { + "_onSocketError": function(name, e) { console.log(name + " socket error: "); console.log(e); }, @@ -220,12 +229,17 @@ obj.socket = new Socket("Lorgar"); obj.connected = false; obj.foreigns = Object.create(null); + obj.state = new LocalModel({fontFamily: "casualFont"}); + obj.state.enum = SocketState; + obj.state.setData(SocketState.straight.disconnected); obj.socket.on("connected", this._onSocketConnected.bind(this, name)); obj.socket.on("disconnected", this._onSocketDisconnected.bind(this, name)); obj.socket.on("error", this._onSocketError.bind(this, name)); obj.socket.on("message", this.dispatcher.pass, this.dispatcher); + this._mainLayout.addState(name, obj.state); + this._nodes[name] = obj; }, "registerForeignController": function(node, controller) { @@ -243,6 +257,22 @@ node.foreigns[controller.id] = obj; controller.register(this.dispatcher, node.socket); }, + "_requestPlayer": function() { + var vc = new Vocabulary(); + vc.insert("source", new Address([])); + + var ev = new Event(new Address(["management", "givePlayer"]), vc); + + var socket = this._nodes.Corax.socket; + ev.setSenderId(socket.getId().clone()); + socket.send(ev); + ev.destructor(); + }, + "_responsePlayer": function(ev) { + var data = ev.getData(); + + console.log('Received player address: ' + data.at("address").toString()); + }, "setTheme": function(theme) { View.setTheme(theme); }, @@ -284,6 +314,11 @@ } }); + var SocketState = new Enum("SocketState", ["description"]); + SocketState.add("disconnected", {description: "Socket is disconnected"}); + SocketState.add("connecting", {description: "Socket is connecting to remote host"}); + SocketState.add("connected", {description: "Socket is connected"}); + return Lorgar; }); })(); diff --git a/lorgar/lib/utils/CMakeLists.txt b/lorgar/lib/utils/CMakeLists.txt index b06c48f..fc6a3f2 100644 --- a/lorgar/lib/utils/CMakeLists.txt +++ b/lorgar/lib/utils/CMakeLists.txt @@ -2,4 +2,5 @@ cmake_minimum_required(VERSION 2.8.12) add_jslib(utils/class.js lib/utils/class ${LORGAR_DIR} browser) add_jslib(utils/subscribable.js lib/utils/subscribable ${LORGAR_DIR} browser) -add_jslib(utils/globalMethods.js lib/utils/globalMethods ${LORGAR_DIR} browser) \ No newline at end of file +add_jslib(utils/globalMethods.js lib/utils/globalMethods ${LORGAR_DIR} browser) +add_jslib(utils/enum.js lib/utils/enum ${LORGAR_DIR} browser) diff --git a/lorgar/main.js b/lorgar/main.js index e5aa4fc..a328497 100644 --- a/lorgar/main.js +++ b/lorgar/main.js @@ -37,7 +37,7 @@ } Controller.initialize(["String", "List", "Vocabulary", "Page", "PanesList", "Link", "Image", "Button"], waiter.check.bind(waiter, "controllers")); - View.initialize(["Label", "Page", "PanesList", "Nav", "Image", "Button"], waiter.check.bind(waiter, "views")); + View.initialize(["Label", "Page", "PanesList", "Nav", "Image", "Button", "Enumeration"], waiter.check.bind(waiter, "views")); var test = new Test(); test.run(); diff --git a/lorgar/views/CMakeLists.txt b/lorgar/views/CMakeLists.txt index 2a4393b..840b699 100644 --- a/lorgar/views/CMakeLists.txt +++ b/lorgar/views/CMakeLists.txt @@ -12,5 +12,6 @@ configure_file(page.js page.js) configure_file(pane.js pane.js) configure_file(image.js image.js) configure_file(button.js button.js) +configure_file(enumeration.js enumeration.js) add_subdirectory(helpers) diff --git a/lorgar/views/enumeration.js b/lorgar/views/enumeration.js new file mode 100644 index 0000000..3400372 --- /dev/null +++ b/lorgar/views/enumeration.js @@ -0,0 +1,53 @@ +"use strict"; +(function view_enumeration_js() { + var moduleName = "views/enumeration"; + + var deps = []; + deps.push("views/gridLayout"); + deps.push("views/label"); + deps.push("lib/wController/localModel"); + + define(moduleName, deps, function view_enumeration_module() { + var GridLayout = require("views/gridLayout"); + var Label = require("views/label"); + var LocalModel = require("lib/wController/localModel"); + + var Enumeration = GridLayout.inherit({ + className: "Enumeration", + constructor: function(controller, options) { + var base = {}; + W.extend(base, options) + + this._lm = new LocalModel(); + GridLayout.fn.constructor.call(this, controller, base); + + this._lv = new Label(this._lm); + this.append(this._lv, 0, 0, 1, 1, GridLayout.Aligment.CenterCenter); + + this._uncyclic.push(this._lm.destructor.bind(this._lm)); + }, + _onData: function() { + if (this._f.initialized) { + var e = this._f.enum; + var value = this._f.data; + var title; + if (e.hasAdditional("title")) { + title = e.additional[value].title; + } else { + title = e.reversed[value]; + } + + var desc = ""; + if (e.hasAdditional("description")) { + desc = e.additional[value].description; + } + + this._lm.setData(title); + this._e.setAttribute("title", desc); + } + } + }); + + return Enumeration; + }) +})(); diff --git a/lorgar/views/mainLayout.js b/lorgar/views/mainLayout.js index 8571ea9..b7876b0 100644 --- a/lorgar/views/mainLayout.js +++ b/lorgar/views/mainLayout.js @@ -5,19 +5,43 @@ var defineArray = []; defineArray.push("views/gridLayout"); defineArray.push("views/label"); + defineArray.push("views/view"); defineArray.push("views/navigationPanel"); defineArray.push("views/layout"); + defineArray.push("views/enumeration"); defineArray.push("lib/wController/localModel"); define(moduleName, defineArray, function mainLayout_module() { var GridLayout = require("views/gridLayout"); var ViewLabel = require("views/label"); + var View = require("views/view"); var ViewNavigationPanel = require("views/navigationPanel"); var Layout = require("views/layout"); + var Enumeration = require("views/enumeration"); var LocalModel = require("lib/wController/localModel"); var MainLayout = GridLayout.inherit({ "className": "MainLayout", + "constructor": function(controller, options) { + GridLayout.fn.constructor.call(this, controller, options); + + this._statusBarPosition = 2; + + this._mainColorHelper = new LocalModel({backgroundColor: "mainColor"}); + this._statusBarModel = new LocalModel({backgroundColor: "secondaryColor"}); + + this._uncyclic.push(this._statusBarModel.destructor.bind(this._statusBarModel)); + this._uncyclic.push(this._mainColorHelper.destructor.bind(this._mainColorHelper)); + + var spacerL = new View(this._mainColorHelper, {maxWidth: 50}); + var spacerR = new View(this._mainColorHelper, {maxWidth: 50}); + this.append(spacerL, 1, 0, 1, 1); + this.append(spacerR, 1, 2, 1, 1); + + this._statusBar = new GridLayout(this._statusBarModel); + this._statusBar.append(new View(this._statusBarModel), 0, 1, 1, 1); + this.append(this._statusBar, 3, 0, 1, 3); + }, "_onNewController": function(controller) { GridLayout.fn._onNewController.call(this, controller); @@ -25,13 +49,8 @@ switch (controller.name) { case "version": - var lm = new LocalModel({ - backgroundColor: "secondaryColor" - }); - var lay = new Layout(lm, {maxHeight: 15}) view = new ViewLabel(controller); - lay.append(view, Layout.Aligment.RightCenter); - this.append(lay, 2, 0, 1, 3); + this._statusBar.append(view, 0, 0, 1, 1, Layout.Aligment.LeftCenter); break; case "navigationPanel": view = new ViewNavigationPanel(controller); @@ -43,6 +62,16 @@ //this.trigger("serviceMessage", "Unsupported view: " + name + " (" + type + ")", 1); break; } + }, + addState: function(name, state) { + var lm = new LocalModel({fontFamily: "casualFont"}); + lm.setData(name + ": "); + var lv = new ViewLabel(lm); + var e = new Enumeration(state); + this._statusBar.append(lv, 0, this._statusBarPosition++, 1, 1, Layout.Aligment.LeftCenter); + this._statusBar.append(e, 0, this._statusBarPosition++, 1, 1, Layout.Aligment.LeftCenter); + + this._uncyclic.push(lm.destructor.bind(lm)); } }); diff --git a/lorgar/views/view.js b/lorgar/views/view.js index ba4231f..6a9222b 100644 --- a/lorgar/views/view.js +++ b/lorgar/views/view.js @@ -290,6 +290,7 @@ Image: 4, Button: 5, View: 6, + Enumeration: 7, Page: 102, PanesList: 104, @@ -302,6 +303,7 @@ "4": "Image", "5": "Button", "6": "View", + "7": "Enumeration", "101": "Nav", "102": "Page", @@ -317,7 +319,8 @@ PanesList: "views/panesList", Image: "views/image", Button: "views/button", - Player: "views/player" + Player: "views/player", + Enumeration: "views/enumeration" }; View.constructors = { diff --git a/magnus/lib/log.js b/magnus/lib/log.js index 51778e4..f983ea7 100644 --- a/magnus/lib/log.js +++ b/magnus/lib/log.js @@ -5,7 +5,7 @@ var ENV = config.get('build'); function getLogger(module) { var path = module.filename.split('/').slice(-2).join('/'); - return new Winston.Logger({ + return Winston.createLogger({ transports: [ new Winston.transports.Console({ colorize: true,