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
********************************************************************************************/
19
 
813 werner 20
#ifndef FOMESCRIPT_H
21
#define FOMESCRIPT_H
22
 
23
#include <QObject>
1065 werner 24
#include <QStringList>
813 werner 25
 
26
#include "fmstand.h"
27
#include "fmunit.h"
905 werner 28
namespace ABE {
813 werner 29
 
815 werner 30
class StandObj;
940 werner 31
class UnitObj;
815 werner 32
class SimulationObj;
958 werner 33
class SchedulerObj;
1061 werner 34
class STPObj;
884 werner 35
class FMTreeList; // forward
1061 werner 36
class FMSTP; // forward
963 werner 37
class ActivityObj;
815 werner 38
 
813 werner 39
/// FomeScript provides general helping functions for the Javascript world.
934 werner 40
/// the object is known as 'fmengine'.
813 werner 41
class FomeScript : public QObject
42
{
43
    Q_OBJECT
890 werner 44
    Q_PROPERTY(bool verbose READ verbose WRITE setVerbose)
897 werner 45
    Q_PROPERTY(int standId READ standId WRITE setStandId)
813 werner 46
public:
47
    explicit FomeScript(QObject *parent = 0);
884 werner 48
    ~FomeScript();
815 werner 49
    // prepare scripting features
50
    void setupScriptEnvironment();
51
    // functions
887 werner 52
    /// prepares the context for executing javascript functions
53
    /// by setting up all internal structures for the forest stand 'stand'.
938 werner 54
    static void setExecutionContext(FMStand *stand, bool add_agent=false);
887 werner 55
 
893 werner 56
    /// special function for setting context without a valid stand
57
    static void setActivity(Activity *act);
58
 
887 werner 59
    /// static accessor function for the responsible script bridge
886 werner 60
    static FomeScript *bridge();
887 werner 61
    /// returns a string for debug/trace messages
62
    const QString &context() const { return mStand?mStand->context():mInvalidContext; }
813 werner 63
 
1063 werner 64
    /// convert a javascript object to a string (for debug output)
65
    static QString JStoString(QJSValue value);
885 werner 66
 
1063 werner 67
 
885 werner 68
    StandObj *standObj() const { return mStandObj; }
940 werner 69
    UnitObj *siteObj() const { return mUnitObj; }
885 werner 70
    FMTreeList *treesObj() const { return mTrees; }
901 werner 71
    ActivityObj *activityObj() const { return mActivityObj; }
885 werner 72
 
890 werner 73
    // Properties
74
    /// verbose: when true, the logging intensity is increased significantly.
75
    bool verbose() const;
76
    void setVerbose(bool arg);
77
 
897 werner 78
    int standId() const;
79
    void setStandId(int new_stand_id);
80
 
813 werner 81
signals:
82
 
83
public slots:
887 werner 84
    /// logging function (which includes exeuction context)
85
    void log(QJSValue value);
901 werner 86
    /// abort execution
87
    void abort(QJSValue message);
870 werner 88
    /// adds a management program (STP) that is provided as the Javascript object 'program'. 'name' is used internally.
89
    bool addManagement(QJSValue program, QString name);
1207 werner 90
    /// set the STP with the name 'name' to the (new) 'program'. This reloads the STP definition (and all activities).
91
    /// if 'name' is not present, nothing happens.
92
    bool updateManagement(QJSValue program, QString name);
1208 werner 93
    /// add a certain stp (given by 'name') to the agent 'agentname'. Returns false if either stp or agent were not found.
94
    bool addManagementToAgentType(QString name, QString agentname);
884 werner 95
    /// add an agent definition (Javascript). 'name' is used internally. Returns true on success.
938 werner 96
    bool addAgentType(QJSValue program, QString name);
97
    /// create an agent of type 'agent_type' (the name of an agent type) and give the name 'agent_name'. 'agent_name' needs to be unique.
98
    QJSValue addAgent(QString agent_type, QString agent_name);
884 werner 99
    /// executes an activity for stand 'stand_id'. This bypasses the normal scheduling (useful for debugging/testing).
100
    /// returns false if activity could not be found for the stand.
101
    bool runActivity(int stand_id, QString activity);
1061 werner 102
    /// executes an the "evaluate" part of the activity for stand 'stand_id'. This bypasses the normal scheduling (useful for debugging/testing).
103
    /// returns false if activity could not be found for the stand.
104
    bool runActivityEvaluate(int stand_id, QString activity);
105
 
938 werner 106
    /// execute 'function' of the agent for the given stand; this is primarily aimed at testing/debugging.
107
    bool runAgent(int stand_id, QString function);
934 werner 108
    // special functions
951 werner 109
    bool isValidStand(int stand_id);
1059 werner 110
    QStringList standIds();
1089 werner 111
    QJSValue activity(QString stp_name, QString activity_name);
890 werner 112
 
934 werner 113
    void runPlanting(int stand_id, QJSValue planting_item);
940 werner 114
public:
115
    static int levelIndex(const QString &level_label);
116
    static const QString levelLabel(const int level_index);
890 werner 117
 
815 werner 118
private:
887 werner 119
    static QString mInvalidContext;
120
    const FMStand *mStand;
815 werner 121
    StandObj *mStandObj;
940 werner 122
    UnitObj *mUnitObj;
815 werner 123
    SimulationObj *mSimulationObj;
893 werner 124
    ActivityObj *mActivityObj;
884 werner 125
    FMTreeList *mTrees;
958 werner 126
    SchedulerObj *mSchedulerObj;
1061 werner 127
    STPObj *mSTPObj;
901 werner 128
    QString mLastErrorMessage;
893 werner 129
 
813 werner 130
};
131
 
132
/// StandObj is the bridge to stand variables from the Javascript world
133
class StandObj: public QObject
134
{
135
    Q_OBJECT
885 werner 136
    Q_PROPERTY (bool trace READ trace WRITE setTrace)
938 werner 137
    Q_PROPERTY (QJSValue agent READ agent)
813 werner 138
    Q_PROPERTY (double basalArea READ basalArea)
139
    Q_PROPERTY (double age READ age)
934 werner 140
    Q_PROPERTY (double absoluteAge READ absoluteAge WRITE setAbsoluteAge)
813 werner 141
    Q_PROPERTY (double volume READ volume)
1059 werner 142
    Q_PROPERTY (double height READ height)
143
    Q_PROPERTY (double topHeight READ topHeight)
869 werner 144
    Q_PROPERTY (int id READ id)
875 werner 145
    Q_PROPERTY (int nspecies READ nspecies)
1059 werner 146
    Q_PROPERTY (double area READ area)
934 werner 147
    Q_PROPERTY (int elapsed READ timeSinceLastExecution)
148
    Q_PROPERTY (QString lastActivity READ lastActivity)
940 werner 149
 
934 werner 150
    Q_PROPERTY (double U READ rotationLength)
940 werner 151
    Q_PROPERTY(QString speciesComposition READ speciesComposition )
152
    Q_PROPERTY(QString thinningIntensity READ thinningIntensity )
153
 
154
 
813 werner 155
/*    basalArea: 0, // total basal area/ha of the stand
156
    volume: 100, // total volume/ha of the stand
157
    speciesCount: 3, // number of species present in the stand with trees > 4m
158
    age: 100, // "age" of the stand (in relation to "U")
159
    flags: {}*/
160
public slots:
897 werner 161
    /// basal area of a given species (m2/ha) given by Id.
1101 werner 162
    double speciesBasalAreaOf(QString species_id) const {return mStand->basalArea(species_id); }
163
    double relSpeciesBasalAreaOf(QString species_id) const {return mStand->relBasalArea(species_id); }
164
    double speciesBasalArea(int index) const { if (index>=0 && index<nspecies()) return mStand->speciesData(index).basalArea; else return 0.; }
165
    double relSpeciesBasalArea(int index) const { if (index>=0 && index<nspecies()) return mStand->speciesData(index).relBasalArea; else return 0.; }
897 werner 166
    QString speciesId(int index) const;
813 werner 167
 
168
    // set and get standspecific data (persistent!)
815 werner 169
    void setFlag(const QString &name, QJSValue value){ const_cast<FMStand*>(mStand)->setProperty(name, value);}
170
    QJSValue flag(const QString &name) { return const_cast<FMStand*>(mStand)->property(name); }
888 werner 171
    QJSValue activity(QString name);
938 werner 172
    QJSValue agent();
888 werner 173
 
897 werner 174
    // actions
175
    /// force a reload of the stand data.
1063 werner 176
    void reload() { if (mStand) mStand->reload(true); }
177
    void sleep(int years) { if (mStand) mStand->sleep(years); }
897 werner 178
 
934 werner 179
    void setAbsoluteAge(double arg);
1208 werner 180
    /// start the management program again (initialize the stand)
181
    void reset();
934 werner 182
 
813 werner 183
public:
184
    explicit StandObj(QObject *parent = 0): QObject(parent), mStand(0) {}
885 werner 185
    // system stuff
887 werner 186
    void setStand(FMStand* stand) { mStand = stand; }
885 werner 187
    bool trace() const;
188
    void setTrace(bool do_trace);
189
 
190
    // properties of the forest
901 werner 191
    double basalArea() const { if (mStand)return mStand->basalArea(); throwError("basalArea"); return -1.;}
1059 werner 192
    double height() const { if (mStand)return mStand->height(); throwError("height"); return -1.;}
193
    double topHeight() const { if (mStand)return mStand->topHeight(); throwError("topHeight"); return -1.;}
901 werner 194
    double age() const {if (mStand)return mStand->age(); throwError("age"); return -1.;}
934 werner 195
    double absoluteAge() const {if (mStand)return mStand->absoluteAge(); throwError("absoluteAge"); return -1.;  }
901 werner 196
    double volume() const {if (mStand) return mStand->volume(); throwError("volume"); return -1.; }
197
    int id() const { if (mStand) return mStand->id(); throwError("id"); return -1; }
198
    int nspecies() const {if (mStand) return mStand->nspecies();  throwError("id"); return -1;}
1059 werner 199
    double area() const {if (mStand) return mStand->area();  throwError("area"); return -1;}
934 werner 200
    int timeSinceLastExecution() const;
201
    QString lastActivity() const;
202
    double rotationLength() const;
940 werner 203
    QString speciesComposition() const;
204
    QString thinningIntensity() const;
885 werner 205
 
206
 
934 werner 207
 
940 werner 208
 
813 werner 209
private:
901 werner 210
    void throwError(QString msg) const;
887 werner 211
    FMStand *mStand;
813 werner 212
};
213
 
1061 werner 214
/** @brief The UnitObj class is the Javascript object known as 'unit' in JS and represents
215
 * a management unit.
216
*/
940 werner 217
class UnitObj: public QObject
813 werner 218
{
219
    Q_OBJECT
220
    Q_PROPERTY (QString harvestMode READ harvestMode)
940 werner 221
    Q_PROPERTY(QString speciesComposition READ speciesComposition )
222
    Q_PROPERTY(double U READ U )
223
    Q_PROPERTY(QString thinningIntensity READ thinningIntensity )
224
    // performance indicators
225
    Q_PROPERTY(double MAIChange READ MAIChange )
226
    Q_PROPERTY(double MAILevel READ MAILevel )
977 werner 227
    Q_PROPERTY(double landscapeMAI READ landscapeMAI )
940 werner 228
    Q_PROPERTY(double mortalityChange READ mortalityChange )
229
    Q_PROPERTY(double mortalityLevel READ mortalityLevel )
230
    Q_PROPERTY(double regenerationChange READ regenerationChange )
231
    Q_PROPERTY(double regenerationLevel READ regenerationLevel )
232
 
233
public slots:
234
    /// main function to provide agent decisions to the engine
235
    bool agentUpdate(QString what, QString how, QString when);
813 werner 236
public:
940 werner 237
    explicit UnitObj(QObject *parent = 0): QObject(parent) {}
815 werner 238
    void setStand(const FMStand* stand) { mStand = stand; }
940 werner 239
    QString harvestMode() const;
240
    QString speciesComposition() const;
241
    double U() const;
242
    QString thinningIntensity() const;
243
 
244
    // performance indicators
245
    double MAIChange() const;
246
    double MAILevel() const;
977 werner 247
    double landscapeMAI() const;
940 werner 248
    double mortalityChange() const;
249
    double mortalityLevel() const;
250
    double regenerationChange() const;
251
    double regenerationLevel() const;
252
 
253
 
813 werner 254
private:
815 werner 255
    const FMStand *mStand;
813 werner 256
 
257
};
258
 
1061 werner 259
/** @brief The SimulationObj encapsulates the 'simulation' object in JS. The 'simulation' object
260
 * is used for global scenarios (e.g., changes in timber price).
261
*/
813 werner 262
class SimulationObj: public QObject
263
{
264
    Q_OBJECT
265
    Q_PROPERTY (double timberPriceIndex READ timberPriceIndex)
266
public:
267
    explicit SimulationObj(QObject *parent = 0): QObject(parent) {}
268
    double timberPriceIndex() const { return 1.010101; } // dummy
269
private:
270
 
271
};
870 werner 272
 
1061 werner 273
/** @brief The STPObj encapsulates the 'stp' object in JS. The 'stp' object
274
 * is provides a link to the currently active stand treatment programme.
275
*/
276
class STPObj: public QObject
277
{
278
    Q_OBJECT
279
    Q_PROPERTY (QString name READ name)
280
    Q_PROPERTY (QJSValue options READ options)
281
public:
282
    void setSTP(FMStand *stand);
283
    explicit STPObj(QObject *parent = 0): QObject(parent) { mSTP = 0;}
284
    QJSValue options() { return mOptions; }
285
    QString name();
286
private:
287
    FMSTP *mSTP;
288
    QJSValue mOptions; ///< options of the current STP
870 werner 289
 
1061 werner 290
 
291
};
292
/**
293
 * @brief The ActivityObj class encapsulates the 'activity' object in JS. The 'activity'
294
 * can be used to fine-tune the management activities (e.g., set the enable/disable flags).
295
 */
888 werner 296
class ActivityObj : public QObject
297
{
298
    Q_OBJECT
299
    Q_PROPERTY (bool enabled READ enabled WRITE setEnabled)
893 werner 300
    Q_PROPERTY(bool active READ active WRITE setActive)
301
    Q_PROPERTY(bool finalHarvest READ finalHarvest WRITE setFinalHarvest)
302
    Q_PROPERTY(bool scheduled READ scheduled WRITE setScheduled)
888 werner 303
    Q_PROPERTY(QString name READ name)
304
public:
893 werner 305
    explicit ActivityObj(QObject *parent = 0): QObject(parent) { mActivityIndex=-1; mStand=0; mActivity=0; }
306
    // used to construct a link to a given activty (with an index that could be not the currently active index!)
307
    ActivityObj(FMStand *stand, Activity *act, int index ): QObject(0) { mActivityIndex=index; mStand=stand; mActivity=act; }
901 werner 308
    /// default-case: set a forest stand as the context.
893 werner 309
    void setStand(FMStand *stand) { mStand = stand; mActivity=0; mActivityIndex=-1;}
901 werner 310
    /// set an activity context (without a stand) to access base properties of activities
893 werner 311
    void setActivity(Activity *act) { mStand = 0; mActivity=act; mActivityIndex=-1;}
901 werner 312
    /// set an activity that is not the current activity of the stand
313
    void setActivityIndex(const int index) { mActivityIndex = index; }
893 werner 314
 
315
    // properties
316
 
317
    QString name() const;
888 werner 318
    bool enabled() const;
319
    void setEnabled(bool do_enable);
893 werner 320
 
321
    bool active() const { return flags().active(); }
322
    void setActive(bool activate) { flags().setActive(activate);}
323
 
324
    bool finalHarvest() const { return flags().isFinalHarvest(); }
325
    void setFinalHarvest(bool isfinal) { flags().setFinalHarvest(isfinal);}
326
 
327
    bool scheduled() const { return flags().isScheduled(); }
328
    void setScheduled(bool issched) { flags().setIsScheduled(issched);}
888 werner 329
public slots:
330
private:
893 werner 331
    ActivityFlags &flags() const; // get (depending on the linked objects) the right flags
1063 werner 332
    static ActivityFlags mEmptyFlags;
888 werner 333
    int mActivityIndex; // link to base activity
334
    Activity *mActivity; // pointer
335
    FMStand *mStand; // and to the forest stand....
336
 
337
};
338
 
1061 werner 339
/**
340
 * @brief The SchedulerObj class is accessible via 'scheduler' in Javascript.
341
 */
958 werner 342
class SchedulerObj : public QObject
343
{
344
    Q_OBJECT
345
    Q_PROPERTY(bool enabled READ enabled WRITE setEnabled)
346
    Q_PROPERTY(double harvestIntensity READ harvestIntensity WRITE setHarvestIntensity)
347
    Q_PROPERTY(double useSustainableHarvest READ useSustainableHarvest WRITE setUseSustainableHarvest)
348
    Q_PROPERTY(double maxHarvestLevel READ maxHarvestLevel WRITE setMaxHarvestLevel)
1063 werner 349
public slots:
350
    void dump() const; ///< write log to console
958 werner 351
public:
352
    explicit SchedulerObj(QObject *parent = 0): QObject(parent) {mStand=0; }
353
    void setStand(FMStand *stand) { mStand = stand;}
354
 
355
    bool enabled();
356
    void setEnabled(bool is_enabled);
357
    double harvestIntensity();
358
    void setHarvestIntensity(double new_intensity);
359
    double useSustainableHarvest();
360
    void setUseSustainableHarvest(double new_level);
361
    double maxHarvestLevel();
362
    void setMaxHarvestLevel(double new_harvest_level);
363
 
364
private:
365
    FMStand *mStand; // link to the forest stand
366
};
367
 
368
 
870 werner 369
} // namespace
370
 
813 werner 371
#endif // FOMESCRIPT_H