Skip to content

Commit

Permalink
Added new class rudel-hook-state-machine to rudel-state-machine.el
Browse files Browse the repository at this point in the history
* rudel-state-machine.el (header): fixed keyword; added version 0.2 to
  history section
  (require rudel-util): new require; used by the hook state machine
  (rudel-state-machine::state): added writer method `rudel-set-state'
  (rudel-state-machine::initialize-instance): use `rudel-set-state'
  (rudel-state-machine::rudel-switch): use `rudel-set-state'
  (rudel-hook-state-machine): new class; a state machine that runs
  hooks when it accepts input or when it switches states
  • Loading branch information
scymtym committed Jun 13, 2010
1 parent bd83f62 commit c50f125
Showing 1 changed file with 55 additions and 3 deletions.
58 changes: 55 additions & 3 deletions rudel-state-machine.el
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
;; Copyright (C) 2009, 2010 Jan Moringen ;; Copyright (C) 2009, 2010 Jan Moringen
;; ;;
;; Author: Jan Moringen <scymtym@users.sourceforge.net> ;; Author: Jan Moringen <scymtym@users.sourceforge.net>
;; Keywords: Rudel, FSM ;; Keywords: rudel, fsm
;; X-RCS: $Id:$ ;; X-RCS: $Id:$
;; ;;
;; This file is part of Rudel. ;; This file is part of Rudel.
Expand Down Expand Up @@ -33,6 +33,8 @@


;;; History: ;;; History:
;; ;;
;; 0.2 - Hookable state machine
;;
;; 0.1 - Initial version ;; 0.1 - Initial version




Expand All @@ -45,6 +47,7 @@
(require 'eieio) (require 'eieio)


(require 'rudel-errors) (require 'rudel-errors)
(require 'rudel-util) ;; for `rudel-hook-object'




;;; Errors related to the state machine ;;; Errors related to the state machine
Expand Down Expand Up @@ -125,6 +128,7 @@
and STATE is an object of a class derived from rudel-state.") and STATE is an object of a class derived from rudel-state.")
(state :initarg :state (state :initarg :state
:type rudel-state-child :type rudel-state-child
:writer rudel-set-state
:documentation :documentation
"The current state of the machine.")) "The current state of the machine."))
"A finite state machine.") "A finite state machine.")
Expand Down Expand Up @@ -166,7 +170,7 @@ that fails as well, the first state in the state list is used."


;; Make start state the current state and call send an enter ;; Make start state the current state and call send an enter
;; message. ;; message.
(oset this :state start) (rudel-set-state this start)
(rudel--switch-to-return-value (rudel--switch-to-return-value
this start (apply #'rudel-enter start args)))) this start (apply #'rudel-enter start args))))
) )
Expand Down Expand Up @@ -255,10 +259,13 @@ state."
(null arguments)) (null arguments))
;; Return state ;; Return state
state state

;; Notify (old) current state. ;; Notify (old) current state.
(rudel-leave state) (rudel-leave state)

;; Update current state. ;; Update current state.
(setq state next) (rudel-set-state this next)

;; Notify (new) current state. Using the call's value as next ;; Notify (new) current state. Using the call's value as next
;; state is a bit dangerous since a long sequence of immediate ;; state is a bit dangerous since a long sequence of immediate
;; state switches could exhaust the stack. ;; state switches could exhaust the stack.
Expand Down Expand Up @@ -296,6 +303,51 @@ NEXT can nil, a list or a `rudel-state' object."
(call-next-method this " state: #start" strings)) (call-next-method this " state: #start" strings))
) )



;;; Class rudel-hook-state-machine
;;

(defclass rudel-hook-state-machine (rudel-hook-object
rudel-state-machine)
((last-args :initarg :last-args
:type list
:initform nil
:documentation
"In this slot `rudel-switch' stores the switch
arguments for processing in the `rudel-set-state' method.")
;; Hooks
(accept-hook :initarg :accept-hook
:type list
:initform nil
:documentation
"This hook is run when the state machine accepts
input.")
(switch-hook :initarg :switch-hook
:type list
:initform nil
:documentation
"This hook is run when the state machine switches
between states."))
"State machine objects of this class run hooks when they accept
arguments and when they switch states.")

(defmethod rudel-accept :before ((this rudel-hook-state-machine)
&rest arguments)
"This method runs 'accept-hook' before ARGUMENTS are processed."
(apply #'object-run-hook-with-args this 'accept-hook arguments))

(defmethod rudel-switch :before ((this rudel-hook-state-machine) next
&rest arguments)
"This method stores ARGUMENTS for later processing."
(oset this :last-args arguments))

(defmethod rudel-set-state :before ((this rudel-hook-state-machine) next
&rest arguments)
"This method runs 'switch-hook' when switching states."
(with-slots (last-args) this
(apply #'object-run-hook-with-args
this 'switch-hook next last-args)))



;;; Miscellaneous functions ;;; Miscellaneous functions
;; ;;
Expand Down

0 comments on commit c50f125

Please sign in to comment.