1 /** 2 * Copyright (C) 2012 KO GmbH <copyright@kogmbh.com> 3 * 4 * @licstart 5 * This file is part of WebODF. 6 * 7 * WebODF is free software: you can redistribute it and/or modify it 8 * under the terms of the GNU Affero General Public License (GNU AGPL) 9 * as published by the Free Software Foundation, either version 3 of 10 * the License, or (at your option) any later version. 11 * 12 * WebODF is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Affero General Public License for more details. 16 * 17 * You should have received a copy of the GNU Affero General Public License 18 * along with WebODF. If not, see <http://www.gnu.org/licenses/>. 19 * @licend 20 * 21 * @source: http://www.webodf.org/ 22 * @source: https://github.com/kogmbh/WebODF/ 23 */ 24 25 /*global ops, runtime, core*/ 26 27 /* 28 * route the operations. 29 * this implementation immediately passes them to the 30 * playback function. 31 * other implementations might want to send them to a 32 * server and wait for foreign ops. 33 */ 34 35 /** 36 * @constructor 37 * @implements ops.OperationRouter 38 */ 39 ops.TrivialOperationRouter = function TrivialOperationRouter() { 40 "use strict"; 41 42 var events = new core.EventNotifier([ 43 ops.OperationRouter.signalProcessingBatchStart, 44 ops.OperationRouter.signalProcessingBatchEnd 45 ]), 46 /**@type{!ops.OperationFactory}*/ 47 operationFactory, 48 playbackFunction, 49 /**@type{number}*/ 50 groupIdentifier = 0; 51 52 /** 53 * Sets the factory to use to create operation instances from operation specs. 54 * 55 * @param {!ops.OperationFactory} f 56 * @return {undefined} 57 */ 58 this.setOperationFactory = function (f) { 59 operationFactory = f; 60 }; 61 62 /** 63 * Sets the method which should be called to apply operations. 64 * 65 * @param {!function(!ops.Operation):boolean} playback_func 66 * @return {undefined} 67 */ 68 this.setPlaybackFunction = function (playback_func) { 69 playbackFunction = playback_func; 70 }; 71 72 /** 73 * Brings the locally created operations into the game. 74 * 75 * @param {!Array.<!ops.Operation>} operations 76 * @return {undefined} 77 */ 78 this.push = function (operations) { 79 // This is an extremely simplistic and VERY temporary implementation of operation grouping. 80 // In order to improve undo behaviour, the undo manager requires knowledge about what groups 81 // of operations were queued together, so these can be stored in a single undo state. 82 // The current implementation is only designed for a localeditor instance & the TrivialUndoManager. 83 // TODO redesign this concept to work with collaborative editing 84 groupIdentifier += 1; 85 events.emit(ops.OperationRouter.signalProcessingBatchStart, {}); 86 operations.forEach(function (op) { 87 var /**@type{?ops.Operation}*/ 88 timedOp, 89 opspec = op.spec(); 90 91 opspec.timestamp = Date.now(); 92 timedOp = operationFactory.create(opspec); 93 timedOp.group = "g" + groupIdentifier; 94 95 // TODO: handle return flag in error case 96 playbackFunction(timedOp); 97 }); 98 events.emit(ops.OperationRouter.signalProcessingBatchEnd, {}); 99 }; 100 101 /** 102 * @param {function()} cb 103 */ 104 this.close = function (cb) { 105 cb(); 106 }; 107 108 /** 109 * @param {!string} eventId 110 * @param {!Function} cb 111 * @return {undefined} 112 */ 113 this.subscribe = function (eventId, cb) { 114 events.subscribe(eventId, cb); 115 }; 116 117 /** 118 * @param {!string} eventId 119 * @param {!Function} cb 120 * @return {undefined} 121 */ 122 this.unsubscribe = function (eventId, cb) { 123 events.unsubscribe(eventId, cb); 124 }; 125 126 /** 127 * @return {!boolean} 128 */ 129 this.hasLocalUnsyncedOps = function () { 130 return false; 131 }; 132 133 /** 134 * @return {!boolean} 135 */ 136 this.hasSessionHostConnection = function () { 137 return true; 138 }; 139 }; 140