capture
[rrq/gorite.git] / com / intendico / gorite / addon / Handshake.java
1 /*********************************************************************
2 Copyright 2012, Ralph Ronnquist.
3
4 This file is part of GORITE.
5
6 GORITE is free software: you can redistribute it and/or modify it
7 under the terms of the Lesser GNU General Public License as published
8 by the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 GORITE is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14 License for more details.
15
16 You should have received a copy of the Lesser GNU General Public
17 License along with GORITE.  If not, see <http://www.gnu.org/licenses/>.
18 **********************************************************************/
19
20 package com.intendico.gorite.addon;
21
22 import com.intendico.gorite.Goal;
23 import com.intendico.gorite.Data;
24 import java.util.Observable;
25
26 /**
27  * Utility class to deal with request-response protocols between
28  * in-core performers with BellBoy capability.  The requester would
29  * include a {@link Handshake#create()} step in the requesting plan,
30  * with data elements "responder" and "request" set up, and the
31  * responder, who gets a Handshake object as BellBoy percept, uses the
32  * {@link Handshake#reply(Object)} method to issue their reply.
33  *
34  * <p> Note: a null response is not a response, but will make the
35  * requester keep waiting.
36  */
37 public class Handshake extends Observable {
38
39     /**
40      * The request message of this Handshake.
41      */
42     public Object message;
43
44     /**
45      * The response message of this Handshake.
46      */
47     public Object response;
48
49     /**
50      * Java method to set the reply and notify to the requester
51      * intention.
52      */
53     public void reply(Object r) {
54         response = r;
55         setChanged();
56         notifyObservers();
57     }
58
59     /**
60      * Returns a Goal object for performing a Handshake. It uses the
61      * data elements "responder" and "request" for input details, the
62      * data element "pending handshake" transiently, and the data
63      * element "response" for output, i.e. the reply object.
64      *
65      * Note that all incoming "pending handshake" values are
66      * forgotten, but not upon a completed handshake.
67      */
68     public static Goal create() {
69         return new Goal( "Perform handshake" ) {
70             /**
71              * Issue the request when the goal is instantiated.
72              */
73             public Instance instantiate(String head,Data data) {
74                 String who = (String) data.getValue( "responder" );
75                 Handshake h = new Handshake();
76                 h.message = data.getValue( "request" );
77                 data.forget( "pending handshake" );
78                 if ( BellBoy.send( who, h ) ) {
79                     data.setValue( "pending handshake", h );
80                 }
81                 return super.instantiate( head, data );
82             }
83
84             /**
85              * Keep blocking until there is a non-null reply
86              */
87             public States execute(Data data) {
88                 Handshake h = (Handshake) data.getValue( "pending handshake");
89                 if ( h == null ) {
90                     return States.FAILED;
91                 }
92                 if ( h.response == null ) {
93                     data.setTrigger( h );
94                     return States.BLOCKED;
95                 }
96                 data.setValue( "response", h.response );
97                 return States.PASSED;
98             }
99         };
100     }
101 }