Subversion Repositories public iLand

Rev

Rev 217 | Rev 245 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1
 
185 werner 2
#include "global.h"
3
#include "management.h"
4
#include "helper.h"
186 werner 5
#include "model.h"
189 iland 6
#include "resourceunit.h"
186 werner 7
#include "tree.h"
216 werner 8
#include "expressionwrapper.h"
186 werner 9
 
242 werner 10
#include "climateconverter.h"
186 werner 11
 
185 werner 12
#include <QtScript>
216 werner 13
#include <QTextEdit>
14
QObject *Management::scriptOutput = 0;
185 werner 15
 
216 werner 16
QScriptValue script_debug(QScriptContext *ctx, QScriptEngine *eng)
17
 {
18
     QString value = ctx->argument(0).toString();
19
     if (Management::scriptOutput) {
20
         QTextEdit *e = qobject_cast<QTextEdit*>(Management::scriptOutput);
21
         if (e)
22
             e->append(value);
23
     } else {
24
         qDebug() << "Script:" << value;
25
     }
26
     return QScriptValue();
27
     //return ctx->thisObject().property(name);
28
 }
186 werner 29
 
216 werner 30
// global output function
31
QString Management::executeScript(QString cmd)
32
{
33
    DebugTimer t("execute javascript");
34
    if (mEngine)
35
        mEngine->evaluate(cmd);
36
    if (mEngine->hasUncaughtException())
37
        return QString( "Script Error occured: %1").arg( mEngine->uncaughtException().toString());
38
    else
39
        return QString();
40
}
41
 
185 werner 42
Management::Management()
43
{
44
    // setup the engine
45
    mEngine = new QScriptEngine();
46
    QScriptValue objectValue = mEngine->newQObject(this);
216 werner 47
    QScriptValue dbgprint = mEngine->newFunction(script_debug);
185 werner 48
    mEngine->globalObject().setProperty("management", objectValue);
216 werner 49
    mEngine->globalObject().setProperty("print",dbgprint);
242 werner 50
    // other object types
51
    ClimateConverter::addToScriptEngine(*mEngine);
216 werner 52
 
185 werner 53
}
54
 
55
Management::~Management()
56
{
57
    delete mEngine;
58
}
59
 
60
void Management::loadScript(const QString &fileName)
61
{
216 werner 62
    mScriptFile = fileName;
185 werner 63
    QString program = Helper::loadTextFile(fileName);
64
    if (program.isEmpty())
65
        return;
66
 
67
    mEngine->evaluate(program);
68
    qDebug() << "management script loaded";
69
    if (mEngine->hasUncaughtException())
70
        qDebug() << "Script Error occured: " << mEngine->uncaughtExceptionBacktrace();
71
 
72
}
73
 
74
void Management::remain(int number)
75
{
76
    qDebug() << "remain called (number): " << number;
186 werner 77
    Model *m = GlobalSettings::instance()->model();
78
    AllTreeIterator at(m);
79
    QList<Tree*> trees;
80
    while (Tree *t=at.next())
81
        trees.push_back(t);
82
    int to_kill = trees.count() - number;
83
    qDebug() << trees.count() << " standing, targetsize" << number << ", hence " << to_kill << "trees to remove";
84
    for (int i=0;i<to_kill;i++) {
187 iland 85
        int index = irandom(0, trees.count());
186 werner 86
        trees[index]->die();
87
        trees.removeAt(index);
88
    }
89
    mRemoved += to_kill;
185 werner 90
}
91
 
92
 
216 werner 93
// from the range percentile range pctfrom to pctto (each 1..100)
94
int Management::kill(int pctfrom, int pctto, int number)
95
{
96
    if (mTrees.isEmpty())
97
        return 0;
98
    int index_from = limit(int(pctfrom/100. * mTrees.count()), 0, mTrees.count());
99
    int index_to = limit(int(pctto/100. * mTrees.count()), 0, mTrees.count());
100
    if (index_from>=index_to)
101
        return 0;
217 werner 102
    qDebug() << "attempting to remove" << number << "trees between indices" << index_from << "and" << index_to;
216 werner 103
    int i;
104
    int count = number;
217 werner 105
    if (index_to-index_from <= number)  {
216 werner 106
        // kill all
107
        for (i=index_from; i<index_to; i++)
108
            mTrees.at(i).first->die();
109
        count = index_to - index_from;
110
    } else {
111
        // kill randomly the provided number
112
        int cancel = 1000;
113
        while(number>=0) {
114
            int rnd_index = irandom(index_from, index_to);
115
            if (mTrees[rnd_index].first->isDead()) {
116
                if (--cancel<0) {
117
                    qDebug() << "Management::kill: canceling search." << number << "trees left.";
217 werner 118
                    count-=number; // not all trees were killed
216 werner 119
                    break;
120
                }
121
                continue;
122
            }
123
            cancel = 1000;
124
            number--;
125
            mTrees[rnd_index].first->die();
126
        }
127
    }
217 werner 128
    qDebug() << count << "removed.";
216 werner 129
    return count; // killed
130
}
131
 
185 werner 132
void Management::run()
133
{
216 werner 134
    mTrees.clear();
186 werner 135
    mRemoved=0;
185 werner 136
    qDebug() << "Management::run() called";
137
    QScriptValue mgmt = mEngine->globalObject().property("manage");
138
    int year = GlobalSettings::instance()->currentYear();
139
    mgmt.call(QScriptValue(), QScriptValueList()<<year);
140
    if (mEngine->hasUncaughtException())
141
        qDebug() << "Script Error occured: " << mEngine->uncaughtExceptionBacktrace();
142
 
186 werner 143
    if (mRemoved>0) {
187 iland 144
        foreach(ResourceUnit *ru, GlobalSettings::instance()->model()->ruList())
186 werner 145
           ru->cleanTreeList();
146
   }
185 werner 147
}
216 werner 148
 
149
 
150
int Management::load(QString filter)
151
{
152
    TreeWrapper tw;
153
    Model *m = GlobalSettings::instance()->model();
154
    mTrees.clear();
155
    AllTreeIterator at(m);
156
    if (filter.isEmpty()) {
157
        while (Tree *t=at.next())
158
            if (!t->isDead())
159
                mTrees.push_back(QPair<Tree*, double>(t, 0.));
160
    } else {
161
        Expression expr(filter,&tw);
162
        qDebug() << "filtering with" << filter;
163
        while (Tree *t=at.next()) {
164
            tw.setTree(t);
165
            if (!t->isDead() && expr.execute())
166
                mTrees.push_back(QPair<Tree*, double>(t, 0.));
167
        }
168
    }
169
    return mTrees.count();
170
}
171
 
172
bool treePairValue(const QPair<Tree*, double> &p1, const QPair<Tree*, double> &p2)
173
{
174
    return p1.second < p2.second;
175
}
176
 
177
void Management::sort(QString statement)
178
{
179
    TreeWrapper tw;
180
    Expression sorter(statement, &tw);
181
    // fill the "value" part of the tree storage with a value for each tree
182
    for (int i=0;i<mTrees.count(); ++i) {
183
        tw.setTree(mTrees.at(i).first);
184
        mTrees[i].second = sorter.execute();
185
   }
186
   // now sort the list....
187
   qSort(mTrees.begin(), mTrees.end(), treePairValue);
188
}
189
 
190
double Management::percentile(int pct)
191
{
192
    if (mTrees.count()==0)
193
        return -1.;
194
    int idx = int( (pct/100.) * mTrees.count());
195
    if (idx>=0 && idx<mTrees.count())
196
        return mTrees.at(idx).second;
197
    else
198
        return -1;
199
}