Subversion Repositories public iLand

Rev

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