Mercurial > hg > RemoteEditor > Eclipse
view src/pathfinder/mergetest/SessionManagerSimulatorWithMerger.java @ 154:6a3c982bd72a
*** empty log message ***
author | pin |
---|---|
date | Sun, 24 Aug 2008 13:43:50 +0900 |
parents | 6326e5ea4595 |
children | 0dfb6413a31e |
line wrap: on
line source
package pathfinder.mergetest; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import remoteeditor.command.REPCommand; import remoteeditor.network.REP; import sample.merge.TranslaterImp1; public class SessionManagerSimulatorWithMerger<P extends REPCommand> extends SeMaSimulator<P> { private List<TranslaterImp1> editorList; private SelectorSimulator<P> selector; private List<EditorObject<P>> editorList2; private int startQuit2; public SessionManagerSimulatorWithMerger(NetworkSimulator<P> _ns) { super(_ns); } public SessionManagerSimulatorWithMerger(NetworkSimulator<P> ns, int ne) { super(ns, ne); } public SessionManagerSimulatorWithMerger(NetworkSimulator<P> _ns, int max_client, int max_packet) { super(_ns, max_client, max_packet); editorList = new ArrayList<TranslaterImp1>(); selector = new SelectorSimulator<P>(_ns); editorList2 = new ArrayList<EditorObject<P>>(); } protected void checkAccept(){ ChannelSimulator<P> cs; while((cs=ns.accept())!=null){ csList.add(cs); editorList.add(new TranslaterImp1(editorList.size())); editorList2.add(new EditorObject<P>(editorList2.size(), cs, new TranslaterImp1(editorList2.size()))); registerChannel (selector, cs, SelectionKeySimulator.OP_READ); } } private void registerChannel(SelectorSimulator selector2, ChannelSimulator<P> cs, int key) { selector.register(cs); } public void run(){ ns.writeLog("SessionManager start.", 1); /* Main Loop */ //Selectorを用いた実装 //while(running && (MAX_PACKET==0 || count<MAX_PACKET)){ while(running){ // Main Loop selector.select(); for(SelectionKeySimulator<P> key : selector.selectedKeys()){ if(key.isAcceptable()){ ChannelSimulator<P> channel = key.channel(); channel = channel.accept(); selector.register(channel); }else if(key.isReadable()){ ChannelSimulator<P> channel = key.channel(); P packet = channel.read(); REPCommand command = unpack(packet); manage(channel, command); } } } ns.writeLog("SessionManager finish.", 1); } private void manage(ChannelSimulator<P> channel, REPCommand command) { // コマンドの処理 int eid = getEID(channel); int neid = getNextEID(eid); ns.writeLog("SessionManager received from " + ":" + eid + ": " + command, 3); EditorObject editor = getEditor(eid); EditorObject nextEditor = getEditor(neid); //editor.receive(command); switch(command.cmd){ case REP.SMCMD_QUIT_2: quit2(nextEditor, command, 0); break; case REP.SMCMD_QUIT: quit(nextEditor, command); break; default: translate(eid, neid, command); //REPCommand sendCommand = editor.receive(command); //nextEditor.send(command); } } private int getNextEID(int eid) { return (eid+1)%editorList2.size(); } private void quit(EditorObject nextEditor, REPCommand command) { nextEditor.send(command); if(command.eid == nextEditor.eid){ //quitコマンドが一周してきた if(editorList.get(nextEditor.eid).isEmpty()) { command.setCMD(REP.SMCMD_QUIT_2); } } } private void quit2(EditorObject nextEditor, REPCommand command, int fromPort) { if(command.eid == nextEditor.eid){ //quitコマンドが一周してきた command.setCMD(REP.SMCMD_QUIT_2); } nextEditor.send(command); if(startQuit2 == -1) startQuit2 = fromPort; else if(startQuit2 == nextEditor.eid) ;//finish(); } private void translate(int eid, int neid, REPCommand command) { ChannelSimulator<P> channel = getChannel(eid); ChannelSimulator<P> nextChannel = getChannel(neid); EditorObject editor = getEditor(eid); if(command.eid == eid){ if(checkOwnCommand(command)){ //エディタからの編集コマンドが戻ってきた場合、マージしてエディタへ反映 REPCommand[] cmds = editorList.get(eid).catchOwnCommand(command); for(REPCommand cmd : cmds){ REPCommand tmp2 = new REPCommand(cmd); tmp2.eid = REP.MERGE_EID; channel.write(pack(tmp2)); } }else{ //エディタからの新たな編集コマンド editorList.get(eid).transSendCmd(command); nextChannel.write(pack(command)); } }else if(command.eid == REP.MERGE_EID){ //マージのときにエディタからの割り込みがないか確認 if(editorList.get(eid).checkMergeConflict(command)){ LinkedList<REPCommand> againList = editorList.get(eid).getMergeAgain(); for(REPCommand againCommand : againList){ channel.write(pack(againCommand)); } } }else{ //他のエディタからのコマンドはマージャへ追加し次のエディタへ送信する REPCommand[] cmds = editorList.get(eid).transReceiveCmd(command); for(REPCommand cmd : cmds){ nextChannel.write(pack(cmd)); } } } private EditorObject getEditor(int eid) { for(EditorObject editor : editorList2){ if(editor.getEID() == eid) { return editor; } } return null; } private int getEID(ChannelSimulator<P> channel) { int eid = 0; for(EditorObject editor : editorList2){ if(editor.getChannel() == channel){ eid = editor.getEID(); } } return eid; } private ChannelSimulator<P> getChannel(int eid) { ChannelSimulator<P> channel = null; for(EditorObject<P> editor : editorList2){ if(editor.getEID() == eid){ channel = editor.getChannel(); } } return channel; } private boolean checkOwnCommand(REPCommand command) { boolean ownCommand = false; LinkedList<REPCommand> sentCommands = editorList.get(command.eid).getSentCmds(); if(sentCommands.size() > 0){ if(sentCommands.get(0).seq == command.seq){ ownCommand = true; } } return ownCommand; } private P pack(REPCommand command) { P cmd = (P) new REPCommand(command); return cmd; } private REPCommand unpack(P packet) { REPCommand cmd = null; if(packet instanceof REPCommand){ cmd = (REPCommand) packet; }else{ ns.writeLog("Error!! :Packet type is NOT REPCommand!", 1); } return new REPCommand(cmd); } }