#38 notify backend of lost connection, version bump to 0.3.1
[fanfix.git] / src / jexer / backend / MultiBackend.java
CommitLineData
88a99379
KL
1/*
2 * Jexer - Java Text User Interface
3 *
4 * The MIT License (MIT)
5 *
a69ed767 6 * Copyright (C) 2019 Kevin Lamonte
88a99379
KL
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29package jexer.backend;
30
31import java.util.LinkedList;
32import java.util.List;
33
34import jexer.event.TInputEvent;
35
36/**
37 * MultiBackend mirrors its I/O to several backends.
38 */
39public class MultiBackend implements Backend {
40
d36057df
KL
41 // ------------------------------------------------------------------------
42 // Variables --------------------------------------------------------------
43 // ------------------------------------------------------------------------
44
88a99379
KL
45 /**
46 * The screen to use.
47 */
48 private MultiScreen multiScreen;
49
50 /**
51 * The list of backends to use.
52 */
53 private List<Backend> backends = new LinkedList<Backend>();
54
d36057df
KL
55 // ------------------------------------------------------------------------
56 // Constructors -----------------------------------------------------------
57 // ------------------------------------------------------------------------
58
88a99379
KL
59 /**
60 * Public constructor requires one backend. Note that this backend's
61 * screen will be replaced with a MultiScreen.
62 *
63 * @param backend the backend to add
64 */
65 public MultiBackend(final Backend backend) {
66 backends.add(backend);
3e074355
KL
67 if (backend instanceof TWindowBackend) {
68 multiScreen = new MultiScreen(((TWindowBackend) backend).getOtherScreen());
69 } else {
70 multiScreen = new MultiScreen(backend.getScreen());
71 }
88a99379
KL
72 }
73
d36057df
KL
74 // ------------------------------------------------------------------------
75 // Backend ----------------------------------------------------------------
76 // ------------------------------------------------------------------------
88a99379
KL
77
78 /**
79 * Getter for sessionInfo.
80 *
81 * @return the SessionInfo
82 */
3e074355 83 public SessionInfo getSessionInfo() {
88a99379
KL
84 return backends.get(0).getSessionInfo();
85 }
86
87 /**
88 * Getter for screen.
89 *
90 * @return the Screen
91 */
3e074355 92 public Screen getScreen() {
88a99379
KL
93 return multiScreen;
94 }
95
96 /**
97 * Subclasses must provide an implementation that syncs the logical
98 * screen to the physical device.
99 */
100 public void flushScreen() {
101 for (Backend backend: backends) {
102 backend.flushScreen();
103 }
104 }
105
d36057df
KL
106 /**
107 * Check if there are events in the queue.
108 *
109 * @return if true, getEvents() has something to return to the application
110 */
111 public boolean hasEvents() {
112 for (Backend backend: backends) {
113 if (backend.hasEvents()) {
114 return true;
115 }
116 }
117 return false;
118 }
119
88a99379
KL
120 /**
121 * Subclasses must provide an implementation to get keyboard, mouse, and
122 * screen resize events.
123 *
124 * @param queue list to append new events to
125 */
126 public void getEvents(List<TInputEvent> queue) {
127 for (Backend backend: backends) {
128 backend.getEvents(queue);
129 }
130 }
131
132 /**
133 * Subclasses must provide an implementation that closes sockets,
134 * restores console, etc.
135 */
136 public void shutdown() {
137 for (Backend backend: backends) {
138 backend.shutdown();
139 }
140 }
141
142 /**
143 * Subclasses must provide an implementation that sets the window title.
144 *
145 * @param title the new title
146 */
147 public void setTitle(final String title) {
148 for (Backend backend: backends) {
149 backend.setTitle(title);
150 }
151 }
152
153 /**
154 * Set listener to a different Object.
155 *
156 * @param listener the new listening object that run() wakes up on new
157 * input
158 */
159 public void setListener(final Object listener) {
160 for (Backend backend: backends) {
161 backend.setListener(listener);
162 }
163 }
164
e23ea538
KL
165 /**
166 * Reload backend options from System properties.
167 */
168 public void reloadOptions() {
169 for (Backend backend: backends) {
170 backend.reloadOptions();
171 }
172 }
173
d36057df
KL
174 // ------------------------------------------------------------------------
175 // MultiBackend -----------------------------------------------------------
176 // ------------------------------------------------------------------------
177
178 /**
179 * Add a backend to the list.
180 *
181 * @param backend the backend to add
182 */
183 public void addBackend(final Backend backend) {
184 backends.add(backend);
185 if (backend instanceof TWindowBackend) {
186 multiScreen.addScreen(((TWindowBackend) backend).getOtherScreen());
187 } else {
188 multiScreen.addScreen(backend.getScreen());
189 }
190 }
191
192 /**
193 * Remove a backend from the list.
194 *
195 * @param backend the backend to remove
196 */
197 public void removeBackend(final Backend backend) {
198 if (backends.size() > 1) {
199 if (backend instanceof TWindowBackend) {
200 multiScreen.removeScreen(((TWindowBackend) backend).getOtherScreen());
201 } else {
202 multiScreen.removeScreen(backend.getScreen());
203 }
204 backends.remove(backend);
205 }
206 }
207
88a99379 208}