Subversion Repositories public iLand

Rev

Rev 1221 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1033 werner 1
/********************************************************************************************
2
**    iLand - an individual based forest landscape and disturbance model
3
**    http://iland.boku.ac.at
4
**    Copyright (C) 2009-  Werner Rammer, Rupert Seidl
5
**
6
**    This program is free software: you can redistribute it and/or modify
7
**    it under the terms of the GNU General Public License as published by
8
**    the Free Software Foundation, either version 3 of the License, or
9
**    (at your option) any later version.
10
**
11
**    This program is distributed in the hope that it will be useful,
12
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
**    GNU General Public License for more details.
15
**
16
**    You should have received a copy of the GNU General Public License
17
**    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
********************************************************************************************/
807 werner 19
#ifndef ACTIVITY_H
20
#define ACTIVITY_H
808 werner 21
#include <QJSValue>
827 werner 22
#include <QVector>
924 werner 23
#include <QMap>
870 werner 24
 
808 werner 25
class Expression; // forward
870 werner 26
 
907 werner 27
namespace ABE {
870 werner 28
 
29
 
811 werner 30
class FMStand;
870 werner 31
class FMSTP;
807 werner 32
 
870 werner 33
 
34
class Schedule {
35
public:
36
    // setup and life cycle
37
    Schedule()  {}
38
    Schedule(QJSValue &js_value) { clear(); setup(js_value); }
872 werner 39
    void clear() { tmin=tmax=topt=-1; tminrel=tmaxrel=toptrel=-1.; force_execution=false; repeat_interval=-1; repeat=false; absolute=false; }
963 werner 40
    void setup(const QJSValue &js_value);
870 werner 41
    QString dump() const;
42
    // functions
897 werner 43
    /// value() evaluates the schedule for the given 'stand'.
44
    /// return 0..1 (0: no fit, 1: perfect time).
45
    /// Special value -1: expired (i.e. current time past the maximum schedule time).
955 werner 46
    double value(const FMStand *stand, const int specific_year=-1);
872 werner 47
    /// gives (fixed) earliest possible execution time
875 werner 48
    double minValue(const double U=100.) const;
49
    /// returns the latest possible execution time
50
    double maxValue(const double U=100.) const;
910 werner 51
    /// returns the "optimal" year, i.e. the first year when prob. to execute is highest.
52
    double optimalValue(const double U=100.) const;
870 werner 53
    // some stuffs
54
    int tmin; int tmax; int topt;
55
    double tminrel; double tmaxrel; double toptrel;
56
    bool force_execution;
871 werner 57
    // repeating
58
    int repeat_interval;
59
    bool repeat;
872 werner 60
    bool absolute;
870 werner 61
};
62
 
63
class Events {
64
public:
65
    Events() {}
66
    /// clear the list of events
67
    void clear();
68
    /// setup events from the javascript object
69
    void setup(QJSValue &js_value, QStringList event_names);
891 werner 70
    /// execute javascript event /if registered) in the context of the forest stand 'stand'.
1070 werner 71
    QJSValue run(const QString event, FMStand *stand, QJSValueList *params=0);
891 werner 72
    /// returns true, if the event 'event' is available.
73
    bool hasEvent(const QString &event) const;
870 werner 74
    QString dump(); ///< prints some debug info
75
private:
887 werner 76
    QJSValue mInstance; ///< object holding the events
77
    QMap<QString, QJSValue> mEvents; ///< list of event names and javascript functions
870 werner 78
};
79
 
944 werner 80
/** DynamicExpression encapsulates an "expression" that can be either a iLand expression, a constant or a javascript function.
81
*/
82
struct DynamicExpression {
83
    DynamicExpression(): filter_type(ftInvalid), expr(0) {}
84
    ~DynamicExpression();
963 werner 85
    void setup(const QJSValue &js_value);
944 werner 86
    bool evaluate(FMStand *stand) const;
87
    bool isValid() const { return filter_type!=ftInvalid;}
88
    QString dump() const;
89
private:
90
    enum { ftInvalid, ftExpression, ftJavascript} filter_type;
91
    Expression *expr;
92
    QJSValue func;
93
};
94
 
870 werner 95
class Constraints {
96
public:
97
    Constraints() {}
98
    void setup(QJSValue &js_value); ///< setup from javascript
889 werner 99
    double evaluate(FMStand *stand); ///< run the constraints
870 werner 100
    QStringList dump(); ///< prints some debug info
101
private:
944 werner 102
    QList<DynamicExpression> mConstraints;
870 werner 103
};
104
 
871 werner 105
class Activity; //forward
106
/** Activity meta data (enabled, active, ...) that need to be stored
107
    per stand. */
108
class ActivityFlags
109
{
110
public:
111
    ActivityFlags(): mActivity(0), mFlags(0) {}
112
    ActivityFlags(Activity *act): mActivity(act), mFlags(0) {}
891 werner 113
    Activity *activity() const {return mActivity; }
114
 
871 werner 115
    bool active() const {return flag(Active); }
116
    bool enabled() const {return flag(Enabled);}
117
    bool isRepeating() const {return flag(Repeater);}
875 werner 118
    bool isPending() const {return flag(Pending); }
119
    bool isForcedNext() const {return flag(ExecuteNext); }
889 werner 120
    bool isFinalHarvest() const {return flag(FinalHarvest); }
121
    bool isExecuteImmediate() const {return flag(ExecuteImmediate); }
891 werner 122
    bool isScheduled() const {return flag(IsScheduled);}
123
    bool isDoSimulate() const {return flag(DoSimulate);}
905 werner 124
    bool isSalvage() const {return flag(IsSalvage);}
891 werner 125
 
905 werner 126
 
871 werner 127
    void setActive(const bool active) { setFlag(Active, active); }
128
    void setEnabled(const bool enabled) { setFlag(Enabled, enabled); }
129
    void setIsRepeating(const bool repeat) { setFlag(Repeater, repeat); }
875 werner 130
    void setIsPending(const bool pending) { setFlag(Pending, pending); }
131
    void setForceNext(const bool isnext) { setFlag(ExecuteNext, isnext); }
889 werner 132
    void setFinalHarvest(const bool isfinal) { setFlag(FinalHarvest, isfinal); }
133
    void setExecuteImmediate(const bool doexec) { setFlag(ExecuteImmediate, doexec);}
891 werner 134
    void setIsScheduled(const bool doschedule) {setFlag(IsScheduled, doschedule); }
135
    void setDoSimulate(const bool dosimulate) {setFlag(DoSimulate, dosimulate); }
905 werner 136
    void setIsSalvage(const bool issalvage) {setFlag(IsSalvage, issalvage); }
875 werner 137
 
871 werner 138
private:
875 werner 139
    /// (binary coded)  flags
893 werner 140
    enum Flags { Active=1,  // if false, the activity has already been executed
875 werner 141
                 Enabled=2,  // if false, the activity can not be executed
142
                 Repeater=4, // if true, the activity is executed
143
                 ExecuteNext=8, // this activity should be executed next (kind of "goto"
889 werner 144
                 ExecuteImmediate=16, // should be executed immediately by the scheduler (e.g. required sanitary cuttings)
145
                 Pending=32,  // the activity is currently in the scheduling algorithm
891 werner 146
                 FinalHarvest=64,  // the management of the activity is a "endnutzung" (compared to "vornutzung")
147
                 IsScheduled=128, // the execution time of the activity is scheduled by the Scheduler component
905 werner 148
                 DoSimulate=256,  // the default operation mode of harvests (simulate or not)
149
                 IsSalvage=512   // the activity is triggered by tree mortality events
889 werner 150
                 };
871 werner 151
    bool flag(const ActivityFlags::Flags flag) const { return mFlags & flag; }
152
    void setFlag(const ActivityFlags::Flags flag, const bool value) { if (value) mFlags |= flag; else mFlags &= (flag ^ 0xffffff );}
153
    Activity *mActivity; ///< link to activity
154
    int mFlags;
155
};
870 werner 156
 
871 werner 157
 
963 werner 158
 
869 werner 159
/// Activity is the base class for management activities
807 werner 160
class Activity
161
{
162
public:
891 werner 163
    // life cycle
869 werner 164
    Activity(const FMSTP *parent);
1032 werner 165
    virtual ~Activity();
891 werner 166
    /// Activity factory - create activities for given 'type'
167
    static Activity *createActivity(const QString &type, FMSTP *stp);
168
 
169
    // properties
870 werner 170
    enum Phase { Invalid, Tending, Thinning, Regeneration, All };
869 werner 171
    const FMSTP *program() const { return mProgram; }
871 werner 172
    virtual QString type() const;
944 werner 173
    QString name() const {return mName; } ///< name of the activity as provided by JS
174
    int index() const { return mIndex; } ///< index of the activity within the STP
910 werner 175
    /// get earlist possible scheduled year (relative to rotation begin)
875 werner 176
    int earlistSchedule(const double U=100.) const {return mSchedule.minValue(U); }
910 werner 177
    /// get latest possible scheduled year (relative to rotation begin)
875 werner 178
    int latestSchedule(const double U=100.) const { return mSchedule.maxValue(U); }
910 werner 179
    /// get optimal scheduled year (relative to rotation begin)
180
    int optimalSchedule(const double U=100.) const { return mSchedule.optimalValue(U); }
901 werner 181
    bool isRepeatingActivity() const { return mSchedule.repeat; }
869 werner 182
    // main actions
870 werner 183
    /// setup of the activity (events, schedule, constraints). additional setup in derived classes.
869 werner 184
    virtual void setup(QJSValue value);
875 werner 185
    /// returns a value > 0 if the activity coult be scheduled now
955 werner 186
    virtual double scheduleProbability(FMStand *stand, const int specific_year=-1);
889 werner 187
    /// returns a probability for the activity to be executed (ie all constraints are fulfilled)
188
    /// return value is 0 if the activity can not be executed (maximum result is 1)
189
    virtual double execeuteProbability(FMStand *stand);
870 werner 190
    /// executes the action (usually defined in derived classes) using the context of 'stand'.
191
    virtual bool execute(FMStand *stand);
891 werner 192
    /// executes the evaluation of the forest stand.
193
    /// returns true, when the stand should enter the scheduler.
194
    virtual bool evaluate(FMStand *stand);
944 werner 195
    /// function that evaluates "bound" dynamic expressions
196
    virtual void evaluateDyanamicExpressions(FMStand *stand);
870 werner 197
    /// dumps some information for debugging
198
    virtual QStringList info();
869 werner 199
protected:
870 werner 200
    Schedule &schedule()  { return mSchedule; }
201
    Constraints &constraints()  { return mConstraints; }
202
    Events &events()  { return mEvents; }
911 werner 203
    ActivityFlags &standFlags(FMStand *stand=0);
891 werner 204
    ActivityFlags mBaseActivity; // base properties of the activity (that can be changed for each stand)
951 werner 205
    static QStringList mAllowedProperties; // list of properties (e.g. 'schedule') that are parsed by the base activity
869 werner 206
private:
871 werner 207
    void setIndex(const int index) { mIndex = index; } // used during setup
208
    void setName(const QString &name) { mName = name; }
944 werner 209
    int mIndex; ///< index of the activity within the STP
871 werner 210
    QString mName; ///< the name of the activity;
870 werner 211
    const FMSTP *mProgram; // link to the management programme the activity is part of
869 werner 212
    Schedule mSchedule; // timing of activity
213
    Constraints mConstraints; // constraining factors
214
    Events mEvents; // action handlers such as "onExecute"
944 werner 215
    DynamicExpression mEnabledIf; // enabledIf property (dynamically evaluated)
871 werner 216
    friend class FMSTP; // allow access of STP class to internals
888 werner 217
    friend class FMStand; // allow access of the activity class (e.g for events)
893 werner 218
    friend class ActivityObj; // allow access to scripting function
869 werner 219
};
220
 
870 werner 221
} // namespace
963 werner 222
 
223
Q_DECLARE_TYPEINFO(ABE::ActivityFlags, Q_PRIMITIVE_TYPE); // declare as POD structure to allow more efficient copying
224
 
807 werner 225
#endif // ACTIVITY_H