Mercurial > hg > RemoteEditor > REPSessionManager
view rep/translater/TranslaterImp1.java @ 323:1e605880d49e
*** empty log message ***
author | kono |
---|---|
date | Fri, 10 Oct 2008 18:04:09 +0900 |
parents | c83a3faec487 |
children |
line wrap: on
line source
package rep.translater; import java.util.Collection; import java.util.Comparator; import java.util.LinkedList; import java.util.Stack; import java.util.TreeSet; import rep.Editor; import rep.Forwarder; import rep.REPCommand; import rep.REP; public class TranslaterImp1 implements Translater{ public int eid; /* * queue が5つもいるって、あまりに馬鹿げてる。 */ private LinkedList<REPCommand> sentCmds; private Stack<REPCommand> unMergedCmds; private LinkedList<REPCommand> undoReplaceList; private LinkedList<REPCommand> sentMergedList; private LinkedList<REPCommand> mergeAgainList; public TranslaterImp1(int _eid){ eid = _eid; sentCmds = new LinkedList<REPCommand>(); unMergedCmds = new Stack<REPCommand>(); undoReplaceList = new LinkedList<REPCommand>(); mergeAgainList = new LinkedList<REPCommand>(); sentMergedList = new LinkedList<REPCommand>(); } /** * New command from an editor * The command is sent to the next editor * @param cmd * @return translated command. */ public REPCommand transSendCmd(REPCommand cmd){ sentCmds.add(cmd); unMergedCmds.push(cmd); //マージ中にユーザから割り込みがあった場合 if(isMerging()){ mergeAgainList.add(cmd); } return cmd; } /** * My command is returned from the session ring. At this * stage writeQueue is empty, our editor is waiting for me. * Start merge process. * @param cmd */ public boolean catchOwnCommand(Editor editor){ LinkedList<REPCommand> output = new LinkedList<REPCommand>(); LinkedList<REPCommand> cmds = new LinkedList<REPCommand>(); //スタック上にあるコマンドを全部undoコマンドにする while ( !unMergedCmds.isEmpty() ){ REPCommand cmd0 = unMergedCmds.pop(); output.add( createUndo(cmd0) ); cmds.add(cmd0); } /* 必要な分だけソートして返却用のリストに追加 */ output.addAll( sortCmds(cmds) ); /* 残ったコマンドも再び実行させるが、まだマージされてないのでunMergedにも入れる */ output.addAll(cmds); for(REPCommand c: cmds) { output.add(c); unMergedCmds.push(c); } return editor.optimizedSend(output); } public REPCommand prev() { return sentCmds.poll(); } private REPCommand createUndo(REPCommand cmd){ REPCommand retCmd = new REPCommand(cmd); if (cmd.cmd==REP.REPCMD_INSERT) retCmd.cmd=REP.REPCMD_DELETE; else if (cmd.cmd==REP.REPCMD_DELETE) retCmd.cmd=REP.REPCMD_INSERT; return retCmd; } class REPCommandComparator implements Comparator<REPCommand>{ public int compare(REPCommand o1, REPCommand o2) { if ( o2.lineno > o1.lineno ) return 1; else if ( o2.lineno < o1.lineno || o2.eid > o1.eid ) return -1; return 1; } } private Collection<REPCommand> sortCmds(LinkedList<REPCommand> cmds) { TreeSet<REPCommand> sortedCmds1 = new TreeSet<REPCommand>(new REPCommandComparator()); int top; int prevEid=-1; while ( -1 != (top=getPrecedence(cmds, prevEid+1)) ){ REPCommand tmp = cmds.remove(top); sortedCmds1.add(tmp); prevEid = tmp.eid; } return sortedCmds1; } /* search cmd. ordering by min EID that is lower lowEid and min SEQ. */ private int getPrecedence(LinkedList<REPCommand> cmds, int lowEid) { int cEid, cSeq; cEid=cSeq=Integer.MAX_VALUE; int ret=-1; for (int i=0; i<cmds.size(); i++){ REPCommand c = cmds.get(i); if ( c.eid<lowEid ) continue; else if ( c.eid>cEid ) continue; else if ( c.eid==cEid ) { if ( c.seq>cSeq ) continue; cSeq=c.seq; ret = i; } else { /* tmp.eid<cEid */ cEid = c.eid; cSeq = c.seq; ret = i; } } return ret; } /** * Translate Command cmd that was received from SeMa. * @param cmd the command to be translated. * @return translated commannd. */ public void transReceiveCmd(Forwarder nextEditor,REPCommand cmd){ assert (cmd.eid != eid); // nop command の挿入は Editor 側で行って、こちら側ではやらない unMergedCmds.push(cmd); nextEditor.send(cmd); } public void setEid(int _eid){ eid = _eid; } public Stack<REPCommand> getList() { // TODO Auto-generated method stub return unMergedCmds; } public LinkedList<REPCommand> getSentCmds() { // TODO Auto-generated method stub return sentCmds; } public void setUndoCommand(REPCommand command) { // TODO Auto-generated method stub undoReplaceList.add(command); } public boolean checkMergeConflict(REPCommand command) { // sentMergedList.remove(); if(mergeAgainList.size() > 0){ mergeAgainList.add(command); if(sentMergedList.size() == 0){ return true; } } return false; } public LinkedList<REPCommand> getMergeAgain() { LinkedList<REPCommand> returnCommand = new LinkedList<REPCommand>(); for(int i = 0; i < mergeAgainList.size(); i++){ //eid = REP.MEGE_EID returnCommand.add(createUndo(mergeAgainList.get(mergeAgainList.size() - i -1))); } for(REPCommand command : mergeAgainList){ if(command.eid == REP.MERGE_EID.id){ returnCommand.add(command); } } for(REPCommand command : mergeAgainList){ if(command.eid == eid){ command.eid = REP.MERGE_EID.id; returnCommand.add(command); } } mergeAgainList.clear(); sentMergedList = returnCommand; return returnCommand; } public boolean isFinished() { if(unMergedCmds.size() > 0) return false; if(sentMergedList.size() > 0) return false; if(sentCmds.size() > 0) return false; return true; } public boolean isMerging() { if(sentMergedList.size() > 0) return true; return false; } public void startMerge(REPCommand cmd) { sentMergedList.add(cmd); } public void mergeAck() { sentMergedList.remove(); } }