Subversion Repositories public iLand

Rev

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