# HG changeset patch # User gongo # Date 1198376293 -32400 # Node ID 5f83b978de82bba9c8231131fb5f7499ea016841 # Parent f07bc68d9750244a1c45c6a3868ac8bbb097abf0 add SessionInfo struct, Hash table, and those functions diff -r f07bc68d9750 -r 5f83b978de82 ChangeLog --- a/ChangeLog Sun Dec 23 10:20:20 2007 +0900 +++ b/ChangeLog Sun Dec 23 11:18:13 2007 +0900 @@ -1,5 +1,13 @@ 2007-12-23 Wataru MIYAGUNI + * redit-client-sm.el: Session Info struct, hash table + Session ID から取得できる Session Info 構造体を作成。 + これで Session 毎に情報を保持できると信じる。 + あとは、bufname => sid => session inf o を作る + hash table を2つ(以下のhashのキーについてぐらいを参照)。 + + こんどは実際に格納したり取り出したりのテストかな + * thinking: hash のキーについて 今まで、(buffer-name) をキーにしてコマンドリストをほげほげと 思ってたけど、受け取る command には Session ID があるので @@ -11,7 +19,7 @@ ================ put-ack, select-ack で Session ID, file name が来るので - + bufname-to-sid-table => key = bufname, value = sid; sid-to-session-table => key = sid, value = session; @@ -27,7 +35,6 @@ こんな二つの hash table を作る方がいいのかな。 bufname はグローバルだし、sid も確か ローカルなSession Managerでは一意に決まるはずだし。 - 送信受信(insert,delete,replace)の流れ的には - cmd 送信 diff -r f07bc68d9750 -r 5f83b978de82 redit-client-sm.el --- a/redit-client-sm.el Sun Dec 23 10:20:20 2007 +0900 +++ b/redit-client-sm.el Sun Dec 23 11:18:13 2007 +0900 @@ -1,11 +1,8 @@ ;; $Id$ -;; not use -;;(defcustom redit-client-program "/Users/gongo/src/cr/REP_project/emacs/redit_client.pl" -;; "The program to use as the remote-edit client." -;; :group 'redit -;; :type 'string) +(eval-when-compile (require 'cl)) +;; ;; REP Command ;; ;; 32 bits 32 32 32 32 32 textsiz @@ -23,8 +20,6 @@ ;; This size is variable length (textsiz). ;; -(eval-when-compile (require 'cl)) - (defvar redit-client-process nil "Remote-edit client process.") @@ -90,7 +85,7 @@ (defvar redit-put-command 45) (defvar redit-put-ack-command 46) (defvar redit-select-command 47) ;; obsolete -(defvar redit-select-ack-command 48) ;; obsolete +(defvar redit-select-ack-command 48) (defvar redit-register-command 49) ;; obsolete (defvar redit-register-ack-command 50) ;; obsolete (defvar redit-deregister-command 51) ;; obsolete @@ -98,17 +93,99 @@ (defvar redit-quit-command 53) (defvar redit-quit-ack-command 54) -;; Queue struct -;;(defstruct Queue (front nil) (rear nil)) -;;(setq redit-client-command-queue (make-Queue)) -;;(setq redit-client-receive-queue (make-Queue)) -;;(setq redit-client-send-queue (make-Queue)) +;;;;;;;;;;;;;;;;;; +;; Queue struct ;; +;;;;;;;;;;;;;;;;;; +(defstruct Queue (front nil) (rear nil)) + +;; memo +;; car: return first element of list +;; cdr: return elements list since the second of list +;; (ex.) +;; (car '(rose violet daisy buttercup)) => rose +;; (cdr '(rose violet daisy buttercup)) => (violet daisy buttercup) + +;; enqueue item in queue +(defun enqueue (queue item) + (let ((new-cell (list item))) + (if (Queue-front queue) + ;; update last cell + (setf (cdr (Queue-rear queue)) new-cell) + ;; if queue is empty + (setf (Queue-front queue) new-cell)) + (setf (Queue-rear queue) new-cell))) + +;; dequeue +(defun dequeue (queue) + (if (Queue-front queue) + (prog1 + (pop (Queue-front queue)) + (unless (Queue-front queue) + ;; if queue is empty + (setf (Queue-rear queue) nil))))) + +(defun dequeue-all (queue) + "clean queue" + (while (Queue-front queue) + (dequeue queue))) -;; line translated queue -;;(setq after-CQ (make-Queue)) -;;(setq after-RQ (make-Queue)) +(defun redit-get-command-from-queue (queue) + (nth 0 (Queue-front queue))) +(defun redit-get-line-from-queue (queue) + (nth 1 (Queue-front queue))) +(defun redit-get-uid-from-queue (queue) + (nth 2 (Queue-front queue))) +(defun redit-get-text-from-queue (queue) + (nth 3 (Queue-front queue))) + +;;(defvar redit-client-command-queue (make-Queue)) +;;(defvar redit-client-receive-queue (make-Queue)) +;;(defvar redit-client-send-queue (make-Queue)) + +;;;;;;;;;;;;;;;;;;;;;;;;; +;; Session Info struct ;; +;;;;;;;;;;;;;;;;;;;;;;;;; + +;; eid: Editor ID corresponding to Session ID +;; send_cmdlist: +;; rep_command list from user +;; recv_cmdlist: +;; rep_command list from Session Manager +(defstruct SessionInfo (eid nil) (send_cmdlist nil) (recv_cmdlist nil)) + +;; create and initialize +(defun redit-create-sessionInfo (eid send recv) + (make-SessionInfo :eid eid :send_cmdlist send :recv_cmdlist recv)) + +(defun redit-get-eid-from-sessionInfo (sinfo) + (SessionInfo-eid sinfo)) +(defun redit-get-sendqueue-from-sessionInfo (sinfo) + (SessionInfo-send_cmdlist sinfo)) +(defun redit-get-recvqueue-from-sessionInfo (sinfo) + (SessionInfo-recv_cmdlist sinfo)) + +;;;;;;;;;;;;;;;;; +;; hash table ;; +;;;;;;;;;;;;;;;;; + +(defvar bufname-to-sid-table (make-hash-table)) +(defvar sid-to-session-table (make-hash-table)) + +(defun redit-set-sid-to-bufname-table (bufname sid) + (setf (gethash bufname bufname-to-sid-table) sid)) +(defun redit-get-sid-from-bufname-table (bufname) + (gethash sid bufname-to-sid-table)) + +(defun redit-set-session-info-to-sid-table (sid sinfo) + (setf (gethash sid sid-to-session-table) sinfo)) +(defun redit-get-session-info-from-sid-table (sid) + (gethash sid sid-to-session-table)) + +;;;;;;;;;;;;;;;;;;; +;; pack / unpack ;; +;;;;;;;;;;;;;;;;;;; (defun redit-pack-int-loop (num count) (if (> count 0) (concat @@ -135,6 +212,9 @@ (redit-unpack-int-loop pkt (* pos 4) 4)) +;;;;;;;;;;;;;;;;;; +;; User Command ;; +;;;;;;;;;;;;;;;;;; (defun redit-join-command () "Allow this Emacs process to be a remote-edit session manager for client processes." @@ -143,10 +223,11 @@ (setq bufname (encode-coding-string (buffer-name) rep-string-encoding)) + (if redit-client-process (progn (set-process-sentinel redit-client-process nil) - (condition-case () ;; + (condition-case () ;; (delete-process redit-client-process) (error nil)))) (setq redit-client-process (open-network-stream @@ -225,47 +306,32 @@ (accept-process-output redit-client-process))))) (error "redit-client is not running."))) + ;; linenumで指定された行の編集をサーバへ送る ;; redit-client-process に insert コマンドと ;;バッファ番号、行番号、行の内容を送り、 Ack を受け取る (defun redit-client-insert-line (linenum isnewline) (if redit-client-process (save-excursion - (let ((beginp) (endp) (text) (length)) - ;; insert lines on server buffer + (let ((beginp) (endp) (text) (length) (packet)) (setq beginp (progn (goto-line linenum) (beginning-of-line) (point))) (setq endp (progn (goto-line linenum) (end-of-line) (point))) - ;; rep-string-encoding に変換してから長さを求める (setq text (encode-coding-string (buffer-substring beginp endp) rep-string-encoding)) (setq length (string-bytes text)) - - ;; トークンが回ってくるのを待つ場合は、 - ;; すぐに process-send-string せずに - ;; 編集情報を保存するだけにとどめる - ;;(enqueue - ;;redit-client-command-queue - ;;(concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-write-command) redit-client-session-id redit-client-editor-id (gen-seqno) linenum length) - ;;(buffer-substring beginp endp) - ;;(if (eq isnewline t) "\n") - ;;"\n")) - - ;; redit-client-process へ - ;; command_num + buffer_num + line_num + string - ;; の文字列を送る - - (process-send-string - redit-client-process - (concat (redit-pack redit-insert-command - redit-client-session-id - redit-client-editor-id - (gen-seqno) linenum length) - text - (if (eq isnewline t) "\n"))) - )) + + (setq packet (concat (redit-pack redit-insert-command + redit-client-session-id + redit-client-editor-id + (gen-seqno) linenum length) + text + (if (eq isnewline t) "\n"))) + + + (process-send-string redit-client-process packet))) (error "redit-client is not running."))) ;; linenum で指定した行の削除命令を redit-client-process に送信する @@ -326,6 +392,8 @@ 'redit-client-before-change-function t) (remove-hook 'after-change-functions 'redit-client-after-change-function t) + + (message "hoehohoe") (let ((command (rep-get-command-from-pkt string))) ;; command がどの命令かを判断し、対応した処理をする。case みたい @@ -580,6 +648,7 @@ (defun redit-client-exec-put (string) (setq redit-client-editor-id (rep-get-editor-id-from-pkt string)) (setq redit-client-session-id (rep-get-session-id-from-pkt string)) + (message (concat "Your Editor ID = " (number-to-string redit-client-editor-id) "\n")) (message (concat "Session ID = " (number-to-string redit-client-session-id) "\n"))) @@ -625,46 +694,13 @@ ;; 念のため、受け取った text-size と比較して ;; 同じならおk、だめならそのサイズ分だけ取る、って所か。 ;; 最初からサイズ分だけでいいんじゃね?と思ったりもするが。 +;; あと、現時点ではサイズが違う(失敗)時の処理いれてない。 (defun rep-get-text-from-pkt (pkt) (let ((size) (text)) (setq size (rep-get-text-size-from-pkt pkt)) (setq text (substring pkt 24)) (if (= size (string-bytes text)) text))) -;; enqueue item in queue -;; (defun enqueue (queue item) -;; (let ((new-cell (list item))) -;; (if (Queue-front queue) -;; ;; 最終セルを書き換える -;; (setf (cdr (Queue-rear queue)) new-cell) -;; ;; キューは空の状態 -;; (setf (Queue-front queue) new-cell)) -;; (setf (Queue-rear queue) new-cell))) - -;; deque last queue -;; (defun dequeue (queue) -;; (if (Queue-front queue) -;; (prog1 -;; (pop (Queue-front queue)) -;; (unless (Queue-front queue) -;; ;; キューは空になった -;; (setf (Queue-rear queue) nil))))) - -;; -;; USER -;; | i | r | d -;; ---|-------------------- -;; T i | 0\+1 | 0\+1 | 0\+1 -;; O ---|-------------------- -;; K r | +1\0 | 0\X | i\X -;; E ---|-------------------- -;; N d | +1\0 | X\i | X\X -;; -(defun dequeue-all (queue) - "clean queue" - (while (Queue-front queue) - (dequeue queue))) - (defun redit-line-translate-out (cque rque) "redit line translate for output" (let ((cc) (rc) (xcc) (xrc) (ccc) (crc) (cignore 0) (rignore 0)) @@ -794,12 +830,3 @@ "Print command queue." (interactive) (print redit-client-send-queue)) - -(defun redit-get-command-from-queue (queue) - (nth 0 (Queue-front queue))) -(defun redit-get-line-from-queue (queue) - (nth 1 (Queue-front queue))) -(defun redit-get-uid-from-queue (queue) - (nth 2 (Queue-front queue))) -(defun redit-get-text-from-queue (queue) - (nth 3 (Queue-front queue)))