View communication

According to our specifications, each view must be able to tell the other two to highlight all occurrences of a given variable name. The scenario is completely symmetric: the stnode that encapsulates each view will be the same since each view should be able to emit and receive the highlight-variable signal. However, in Sophtalk, an stnode may not have an input and output port bearing the same name. To implement the kind of symmetry we require, we must introduce a neutral stnode that listens to a highlight request signal, then broadcasts a signal with a different name, received by the three view stnodes. The following stnode classes accomplish this:


(st-declare Exp-highlight-request-stnode (hi-var-request) (hi-variable))
(st-declare Exp-highlight-stnode (hi-variable) (hi-var-request))

An instance of the first class will encapsulate a neutral highlight request manager. An instance of the second class will encapsulate each of the views (source and environment). Each instance of the second class will encapsulate a Centaur variable structure so that a single callback function may be used for all source and environment views.


;;;;;;;;;;;;;;
;;Variable highlighting
;;;;;;;;;;;;;;
(setq #:sys-package:colon '#:Exp:interpreter)

(st-declare Exp-highlight-request-stnode (hi-var-request) (hi-variable))
(st-declare Exp-highlight-stnode (hi-variable) (hi-var-request))

;;;;;;;;;;;;;
;;In source.
;;;;;;;;;;;;;
(de :create (ctview)
    ... 
       ;;Add new stnodes for highlighting in the source view.
       (:create-tool-highlight-spy tool network)
       ...
       ))

;;;
;;;Define request manager structure.
;;;
(eval-when (load eval compile) 
     (defstruct :manager))

(de :create-tool-highlight-spy (tool network)
  (let ((req-stnode (st-create 'Exp-highlight-request-stnode))
        (hi-stnode  (st-create 'Exp-highlight-stnode))
        (manager (:manager:make))
        (ctedit (send 'source tool))
        (var ({ctedit}:subject ctedit))
        )
    ;;Encapsulate source variable to listen for highlight.
    (st-store-and-set-action hi-stnode var ':hi-callback)
    ;;Encapsulate manager to receive requests.
    (st-store-and-set-action req-stnode manager ':hi-manager-callback)
    ;;Include both stnodes in tool network.
    (st-include* network hi-stnode req-stnode)
    ))

Then we encapsulate the variable of each type of environment view:


;;;;;;;;;;;;;
;;In initial view.
;;;;;;;;;;;;;

(de :initial-env-callback:open-view (stnode port)
    (lets ((tool (st-object stnode))
           (tool-network (st-up stnode))
           (var (send 'initial-environment tool))
           (ctview (with ((current-manager 
                             #:gfxobj:look:ctview:plain-manager))
                      (map-ctview-var "Initial view" var
                                       () () () () () ())))
           (ctedit (send 'object ctview))
           (view-network ({ctedit}:network ctedit))
           (hi-stnode (st-create 'Exp-highlight-stnode))
           )
      ...
      ;;Since Exp environment not loaded for this view,
      ;;we must name the ctedit for mouse event resources.
      (#:properties:set-user-property ctedit 'Editor 'Exp)
      ;;Encapsulate initial view var to listen for highlight.
      (st-store-and-set-action hi-stnode var ':hi-callback) 
      (st-include (st-up stnode) hi-stnode)
      ;;Make hi-stnode dependent on view-network
      (st-dependent-stnode view-network hi-stnode)
      view-network
      ))

;;;;;;;;;;;;;
;;In result view.
;;;;;;;;;;;;;
(de :result-view-callback (port tool network name env-tree)
  (lets ((view (with 
                ((current-manager #:gfxobj:look:ctview:plain-manager))
                    (map-ctview "Result view" env-tree 
                                () () () () () ())))
         (ctedit (send 'object view))
         (var ({ctedit}:subject ctedit))
         (view-network ({ctedit}:network ctedit))
         (stnode (st-create 'Exp-result-spy))
         (hi-stnode (st-create 'Exp-highlight-stnode))
         )
       ...
       ;;Since Exp environment not loaded for this view,
       ;;we must name the ctedit for mouse event resources.
       (#:properties:set-user-property ctedit 'Editor 'Exp)
       ;;Encapsulate result view var to listen for highlight.
       (st-store-and-set-action hi-stnode var ':hi-callback)
       ;;Include in tool network.
       (st-include* network stnode hi-stnode)
       ;;Make stnodes dependent on view network
       (st-dependent-stnode view-network stnode)
       (st-dependent-stnode view-network hi-stnode)
       ;;Must return a network.
       view-network
       ))

Note that in addition to adding the highlight stnodes, we have specified the Editor property for each view ctedit. This was done in {Exp}:set-environment, but this function is not called for environment views. By naming these views Exp, we may share the same mouse event list as specified for ordinary source views.

Finally, we define the highlight callback functions:


;;;;;;;;;;;;;;;;;;;;;;;;;
;;Callbacks
;;;;;;;;;;;;;;;;;;;;;;;;;
;;The manager callback function
(de :hi-manager-callback:hi-var-request (stnode port variable-name)
    (st-emit stnode 'hi-variable variable-name))


;;The common highlight callback function. Supposes encapsulated
;;object is a variable.
(de :hi-callback:hi-variable (stnode port variable-name)
    (:select-variables (st-object stnode) variable-name))

Figure summarizes the different encapsulations made for highlighting. We define :select-variables below.


Tutorial