/*=============================================================================#
# Copyright (c) 2008-2016 Stephan Wahlbrink (WalWare.de) and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of either (per the licensee's choosing)
# - the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html, or
# - the GNU Lesser General Public License v2.1 or newer
# which accompanies this distribution, and is available at
# http://www.gnu.org/licenses/lgpl.html
#
# Contributors:
# Stephan Wahlbrink - initial API and implementation
#=============================================================================*/
package de.walware.rj.server;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import de.walware.rj.data.RJIO;
/**
* Server-to-Client list with {@link MainCmdItem}s.
*/
public final class MainCmdS2CList implements RjsComObject, Externalizable {
static final AutoIdMap<ComHandler> gComHandlers = new AutoIdMap<>();
private int id;
private boolean isBusy;
private MainCmdItem first;
public MainCmdS2CList(final MainCmdItem first, final boolean isBusy) {
this.isBusy = isBusy;
this.first = first;
}
/**
* Constructor for automatic deserialization
*/
public MainCmdS2CList() {
this.isBusy = false;
this.first = null;
}
@Override
public void writeExternal(final ObjectOutput out) throws IOException {
out.writeShort(this.id);
out.writeBoolean(this.isBusy);
final RJIO io = RJIO.get(out);
final int check = io.writeCheck1();
MainCmdItem item = this.first;
if (item != null) {
do {
out.writeByte(item.getCmdType());
item.writeExternal(io);
} while ((item = item.next) != null);
}
out.writeByte(MainCmdItem.T_NONE);
io.writeCheck2(check);
io.disconnect(out);
}
@Override
public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
this.id = in.readUnsignedShort();
if (this.id != 0) {
gComHandlers.get(this.id).processMainCmd(in);
return;
}
this.isBusy = in.readBoolean();
final RJIO io = RJIO.get(in);
final int check = io.readCheck1();
{ // first
final byte type = in.readByte();
switch (type) {
case MainCmdItem.T_NONE:
this.first = null;
io.readCheck2(check);
io.disconnect(in);
return;
case MainCmdItem.T_CONSOLE_READ_ITEM:
this.first = new ConsoleReadCmdItem(io);
break;
case MainCmdItem.T_CONSOLE_WRITE_ITEM:
this.first = new ConsoleWriteCmdItem(io);
break;
case MainCmdItem.T_MESSAGE_ITEM:
this.first = new ConsoleMessageCmdItem(io);
break;
case MainCmdItem.T_EXTENDEDUI_ITEM:
this.first = new ExtUICmdItem(io);
break;
case MainCmdItem.T_MAIN_CTRL_ITEM:
this.first= new MainCtrlCmdItem(io);
break;
case MainCmdItem.T_DATA_ITEM:
this.first = new DataCmdItem(io);
break;
case MainCmdItem.T_GRAPHICS_OP_ITEM:
this.first = new GraOpCmdItem(io);
break;
case MainCmdItem.T_DBG_ITEM:
this.first = new DbgCmdItem(io);
break;
default:
throw new ClassNotFoundException("Unknown cmdtype id: "+type);
}
}
MainCmdItem item = this.first;
while (true) {
final byte type = in.readByte();
switch (type) {
case MainCmdItem.T_NONE:
io.readCheck2(check);
io.disconnect(in);
return;
case MainCmdItem.T_CONSOLE_READ_ITEM:
item = item.next = new ConsoleReadCmdItem(io);
continue;
case MainCmdItem.T_CONSOLE_WRITE_ITEM:
item = item.next = new ConsoleWriteCmdItem(io);
continue;
case MainCmdItem.T_MESSAGE_ITEM:
item = item.next = new ConsoleMessageCmdItem(io);
continue;
case MainCmdItem.T_EXTENDEDUI_ITEM:
item = item.next = new ExtUICmdItem(io);
continue;
case MainCmdItem.T_MAIN_CTRL_ITEM:
this.first= new MainCtrlCmdItem(io);
break;
case MainCmdItem.T_DATA_ITEM:
item = item.next = new DataCmdItem(io);
continue;
case MainCmdItem.T_GRAPHICS_OP_ITEM:
item = item.next = new GraOpCmdItem(io);
continue;
case MainCmdItem.T_DBG_ITEM:
item = item.next = new DbgCmdItem(io);
continue;
default:
io.disconnect(in);
throw new ClassNotFoundException("Unknown cmdtype id: "+type);
}
}
}
public void clear() {
MainCmdItem item = this.first;
while (item != null) {
final MainCmdItem tmp = item;
item = item.next;
tmp.next = null;
}
this.first = null;
}
public boolean isEmpty() {
return (this.first == null);
}
public void setId(final int id) {
this.id = (short) id;
}
public void setBusy(final boolean isBusy) {
this.isBusy = isBusy;
}
public void setObjects(final MainCmdItem first) {
this.first = first;
}
@Override
public int getComType() {
return RjsComObject.T_MAIN_LIST;
}
public MainCmdItem getItems() {
return this.first;
}
public boolean isBusy() {
return this.isBusy;
}
public boolean testEquals(final MainCmdS2CList other) {
if (this.isBusy != other.isBusy()) {
return false;
}
MainCmdItem thisItem = this.first;
MainCmdItem otherItem = other.first;
while (thisItem != null && otherItem != null) {
if (!thisItem.equals(otherItem)) {
return false;
}
thisItem = thisItem.next;
otherItem = otherItem.next;
}
if (thisItem != null || otherItem != null) {
return false;
}
return true;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder(128);
sb.append("MainCmdS2CList (isBusy=");
sb.append(this.isBusy);
sb.append(')');
if (this.first != null) {
sb.append(':');
}
MainCmdItem item = this.first;
int i = 0;
while (item != null) {
sb.append("\n<ITEM i=\"");
sb.append(i);
sb.append("\">\n");
sb.append(item.toString());
sb.append("\n</ITEM>");
item = item.next;
i++;
}
return sb.toString();
}
}