"use strict"; (function lorgar_js() { var moduleName = "core/lorgar"; 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"); defineArray.push("lib/wDispatcher/logger"); defineArray.push("lib/wType/event"); defineArray.push("lib/wType/address"); defineArray.push("lib/wType/vocabulary"); defineArray.push("lib/wType/string"); defineArray.push("lib/wController/globalControls"); defineArray.push("lib/wController/pageStorage"); defineArray.push("lib/wController/page"); defineArray.push("lib/wController/localModel"); defineArray.push("lib/wController/player"); defineArray.push("views/view"); defineArray.push("views/layout"); defineArray.push("views/gridLayout"); defineArray.push("views/page"); defineArray.push("views/mainLayout"); 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"); var Logger = require("lib/wDispatcher/logger"); var Event = require("lib/wType/event"); var Address = require("lib/wType/address"); var Vocabulary = require("lib/wType/vocabulary"); var String = require("lib/wType/string"); var GlobalControls = require("lib/wController/globalControls"); var PageStorage = require("lib/wController/pageStorage"); var PageController = require("lib/wController/page"); var LocalModel = require("lib/wController/localModel"); var PlayerModel = require("lib/wController/player"); var View = require("views/view"); var Layout = require("views/layout"); var GridLayout = require("views/gridLayout"); var Page = require("views/page"); var MainLayout = require("views/mainLayout"); var Lorgar = Class.inherit({ "className": "Lorgar", "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._registerModels(); this.connectNode("Magnus"); this.connectNode("Corax"); window.onpopstate = this._onHistoryPopState.bind(this) }, "destructor": function() { window.onpopstate = undefined; this._unregisterModels(); if (this._currentPageCtl) { this._currentPage.destructor(); this._currentPageCtl.destructor(); } this._gc.destructor(); this._ps.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(); Class.fn.destructor.call(this); }, "changePage": function(addr) { if (this._currentPageCtl && this._currentPageCtl.getPairAddress()["=="](addr)) { return; } this._ps.getPageName(addr); this._initPageController(addr.clone()); }, "connectNode": function(name) { var node = this._nodes[name]; if (node === undefined) { throw new Error("An attempt to connect not prepared node " + name); } node.socket.open(node.address, node.port); node.state.setData(SocketState.straight.connecting); }, _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._emptyHelper = new LocalModel(); this._gc.on("serviceMessage", this._onServiceMessage, this); this._ps.on("serviceMessage", this._onServiceMessage, this); this._gc.on("themeSelected", this.setTheme, this); this._ps.on("pageName", this._onPageName, this); }, "_initPageController": function(addr) { if (this._currentPageCtl) { this._currentPage.destructor(); this._currentPageCtl.destructor(); } this._currentPageCtl = new PageController(addr); this._currentPageCtl.register(this.dispatcher, this._nodes.Magnus.socket); this._currentPage = new Page(this._currentPageCtl); this._currentPageCtl.subscribe(); this._mainLayout.append(this._currentPage, 1, 1, 1, 1); }, "_initViews": function() { this._body = new Layout(this._emptyHelper); this._mainLayout = new MainLayout(this._gc); document.body.innerHTML = ""; document.body.appendChild(this._body._e); window.addEventListener("resize", this._onWindowResize.bind(this), false); this._body.setSize(document.body.offsetWidth, document.body.offsetHeight); this._body.append(this._mainLayout); }, "_onHistoryPopState": function(e) { this._initPageController(new Address(e.state.address)); }, "_onPageName": function(name) { window.history.pushState({ address: this._currentPageCtl.getPairAddress().toArray() }, "", name); }, "_onServiceMessage": function(text, severity) { var fn; switch (severity) { case 2: fn = console.error; break; case 1: fn = console.warn; break; case 0: default: fn = console.info; break; } fn(text); }, "_onSocketConnected": function(name) { 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) { node.foreigns[id].controller.subscribe(); } } switch (name) { case "Magnus": this._gc.subscribe(); if (!this._currentPageCtl) { this._ps.getPageAddress(location.pathname); this._ps.one("pageAddress", this._initPageController, this); } break; case "Corax": this._requestPlayer(); break; } }, "_onSocketDisconnected": function(name) { console.log(name + " socket disconnected"); var node = this._nodes[name]; node.connected = false; switch (name) { case "Corax": if (this._playerCtl) { this._mainLayout.removePlayer(); this._playerCtl._onSocketDisconnected(); this._playerCtl.unregister(); this._playerCtl.destructor(); this._playerCtl = undefined; } } for (var id in node.foreigns) { if (node.foreigns[id].subscribed) { node.foreigns[id].controller._onSocketDisconnected(); } } node.state.setData(SocketState.straight.disconnected); }, "_onSocketError": function(name, e) { console.log(name + " socket error: "); console.log(e); }, "_onWindowResize": function() { this._body.setSize(document.body.offsetWidth, document.body.offsetHeight); }, "play": function(id) { if (this._nodes.Corax && this._nodes.Corax.connected) { var vc = new Vocabulary(); vc.insert("id", id.clone()); var ev = new Event(this._playerCtl.getPairAddress()["+="](play), vc); var socket = this._nodes.Corax.socket; ev.setSenderId(socket.getId().clone()); socket.send(ev); ev.destructor(); } }, "_prepareNode": function(name, address, port) { if (this._nodes[name]) { throw new Error("An attempt to prepeare node " + name + " for the second time"); } var obj = Object.create(null); obj.name = name; obj.address = address; obj.port = port; 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(nodeName, controller) { var node = this._nodes[nodeName]; if (node === undefined) { throw new Error("An attempt to register controller to an unknown node " + nodeName); } if (node.foreigns[controller.id] !== undefined) { throw new Error("An attempt to register a controller under node " + nodeName + " for a second time"); } var obj = Object.create(null); obj.controller = controller; obj.subscribed = false; 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(); this._playerCtl = new PlayerModel(data.at("address").clone()); this._playerCtl.register(this.dispatcher, this._nodes["Corax"].socket); this._playerCtl.subscribe(); this._mainLayout.appendPlayer(this._playerCtl); this._playerCtl.on("serviceMessage", this._onServiceMessage, this); }, "scheduleToPlay": function(id) { if (this._nodes.Corax && this._nodes.Corax.connected) { var vc = new Vocabulary(); vc.insert("id", id.clone()); var ev = new Event(this._playerCtl.getPairAddress()["+="](queue), vc); var socket = this._nodes.Corax.socket; ev.setSenderId(socket.getId().clone()); socket.send(ev); ev.destructor(); } }, "setTheme": function(theme) { View.setTheme(theme); }, "subscribeForeignController": function(nodeName, controller) { var node = this._nodes[nodeName]; if (node === undefined) { throw new Error("An attempt to subscribe a controller to an unknown node " + nodeName); } if (node.foreigns[controller.id] === undefined) { throw new Error("An attempt to subscribe not registered controller to node " + nodeName); } node.foreigns[controller.id].subscribed = true; controller.subscribe(); }, "unregisterForeignController": function(nodeName, controller) { var node = this._nodes[nodeName]; if (node === undefined) { throw new Error("An attempt to unregister a controller from an unknown node " + nodeName); } if (node.foreigns[controller.id] === undefined) { throw new Error("An attempt to unregister not registered controller from node " + nodeName); } delete node.foreigns[controller.id]; controller.unregister(); }, "unsubscribeForeignController": function(nodeName, controller) { var node = this._nodes[nodeName]; if (node === undefined) { throw new Error("An attempt to unsubscribe a controller from an unknown node " + nodeName); } if (node.foreigns[controller.id] === undefined) { throw new Error("An attempt to unsubscribe not registered controller from node " + nodeName); } node.foreigns[controller.id].subscribed = false; controller.unsubscribe(); } }); 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"}); var queue = new Address(["queue"]); var play = new Address(["play"]); return Lorgar; }); })();