capture
[rrq/gorite.git] / com / intendico / gorite / LoopGoal.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;
21
22 import com.intendico.data.Query;
23 import com.intendico.data.Ref;
24
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.Vector;
28
29 /**
30  * A LoopGoal is achieved by means of repeatedly achieving its sub
31  * goals in sequence, until eventually an embedded {@link EndGoal} is
32  * achieved. The usage pattern for this is as follows:
33  *
34  * <pre>
35  * new LoopGoal( "loop", new Goal [] {
36  *     .. // steps in the loop
37  *     .. new EndGoal( "break if", new Goal [] {
38  *            // optional sub goals for ending the loop if they succeed
39  *        } )
40  *     .. // more steps in the loop
41  * } )
42  * </pre>
43  *
44  * There may be any number of {@link EndGoal} to end the loop although
45  * of course only one will take effect. The {@link EndGoal} may be at
46  * any level within the LoopGoal goal hierarchy, except nested within
47  * another LoopGoal.
48  *
49  * @see EndGoal
50  * @see SequenceGoal
51  */
52 public class LoopGoal extends SequenceGoal {
53
54     /**
55      * Constructor.
56      */
57     public LoopGoal(String n,Goal [] sg) {
58         super( n, sg );
59     }
60
61     /**
62      * Convenience constructor without sub goals.
63      */
64     public LoopGoal(String n) {
65         this( n, null );
66     }
67
68     /**
69      * Creates and returns an instance object for achieving
70      * a LoopGoal.
71      */
72     public Instance instantiate(String head,Data d) {
73         return new LoopInstance( head );
74     }
75
76     /**
77      * Implements repeated, sequential exception.
78      */
79     public class LoopInstance extends SequenceInstance {
80
81         /**
82          * Constructor.
83          */
84         public LoopInstance(String h) {
85             super( h );
86         }
87
88         public int count = 0;
89
90         /**
91          * Repeatedly process all subgoals in sequence, until a
92          * thrown LoopEndException is caught.
93          */
94         public States action(String head,Data d)
95             throws LoopEndException, ParallelEndException {
96             for ( ;; count++ ) {
97                 States s;
98                 try {
99                     s = super.action( head + ":" + count, d );
100                 } catch (LoopEndException e) {
101                     // End this loop
102                     break;
103                 }
104                 if ( s != States.PASSED )
105                     return s;
106                 index = 0;
107             }
108             return States.PASSED;
109         }
110     }
111 }