Subversion Repositories public iLand

Rev

Rev 1087 | Rev 1157 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1087 Rev 1104
1
Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/ilandc/consoleshell.cpp':
1
Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/ilandc/consoleshell.cpp':
2
/********************************************************************************************
2
/********************************************************************************************
3
**    iLand - an individual based forest landscape and disturbance model
3
**    iLand - an individual based forest landscape and disturbance model
4
**    http://iland.boku.ac.at
4
**    http://iland.boku.ac.at
5
**    Copyright (C) 2009-  Werner Rammer, Rupert Seidl
5
**    Copyright (C) 2009-  Werner Rammer, Rupert Seidl
6
**
6
**
7
**    This program is free software: you can redistribute it and/or modify
7
**    This program is free software: you can redistribute it and/or modify
8
**    it under the terms of the GNU General Public License as published by
8
**    it under the terms of the GNU General Public License as published by
9
**    the Free Software Foundation, either version 3 of the License, or
9
**    the Free Software Foundation, either version 3 of the License, or
10
**    (at your option) any later version.
10
**    (at your option) any later version.
11
**
11
**
12
**    This program is distributed in the hope that it will be useful,
12
**    This program is distributed in the hope that it will be useful,
13
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
**    GNU General Public License for more details.
15
**    GNU General Public License for more details.
16
**
16
**
17
**    You should have received a copy of the GNU General Public License
17
**    You should have received a copy of the GNU General Public License
18
**    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
**    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
********************************************************************************************/
19
********************************************************************************************/
20
20
21
#include "consoleshell.h"
21
#include "consoleshell.h"
22
22
23
#include <QtCore>
23
#include <QtCore>
24
//#include <QKeyEvent>
24
//#include <QKeyEvent>
25
25
26
#include "global.h"
26
#include "global.h"
27
#include "model.h"
27
#include "model.h"
28
#include "modelcontroller.h"
28
#include "modelcontroller.h"
29
#include "../iland/version.h"
29
#include "../iland/version.h"
30
30
31
QTextStream *ConsoleShell::mLogStream = 0;
31
QTextStream *ConsoleShell::mLogStream = 0;
32
bool ConsoleShell::mFlushLog = false;
32
bool ConsoleShell::mFlushLog = false;
33
33
34
// a try to really get keyboard strokes in console mode...
34
// a try to really get keyboard strokes in console mode...
35
// did not work.
35
// did not work.
36
class KeyboardTaker : public QThread
36
class KeyboardTaker : public QThread
37
 {
37
 {
38
 public:
38
 public:
39
     void run();
39
     void run();
40
     bool stop;
40
     bool stop;
41
 };
41
 };
42
42
43
 void KeyboardTaker::run()
43
 void KeyboardTaker::run()
44
 {
44
 {
45
     stop = false;
45
     stop = false;
46
     QTextStream qin(stdin, QFile::ReadOnly);
46
     QTextStream qin(stdin, QFile::ReadOnly);
47
     while (!stop) {
47
     while (!stop) {
48
         QString input = qin.read(1);
48
         QString input = qin.read(1);
49
         if (!input.isNull()) {
49
         if (!input.isNull()) {
50
             // .. process input
50
             // .. process input
51
             qWarning() << "input:" << input;
51
             qWarning() << "input:" << input;
52
         }
52
         }
53
     }
53
     }
54
 }
54
 }
55
55
56
ConsoleShell::ConsoleShell()
56
ConsoleShell::ConsoleShell()
57
{
57
{
58
}
58
}
59
59
60
/*
60
/*
61
*/
61
*/
62
62
63
void ConsoleShell::run()
63
void ConsoleShell::run()
64
{
64
{
65
65
66
    QString xml_name = QCoreApplication::arguments().at(1);
66
    QString xml_name = QCoreApplication::arguments().at(1);
67
    // get the number of years to run...
67
    // get the number of years to run...
68
    bool ok;
68
    bool ok;
69
    int years = QCoreApplication::arguments().at(2).toInt(&ok);
69
    int years = QCoreApplication::arguments().at(2).toInt(&ok);
70
    if (years<0 || !ok) {
70
    if (years<0 || !ok) {
71
        qDebug() << QCoreApplication::arguments().at(2) << "is an invalid number of years to run!";
71
        qDebug() << QCoreApplication::arguments().at(2) << "is an invalid number of years to run!";
72
        QCoreApplication::quit();
72
        QCoreApplication::quit();
73
        return;
73
        return;
74
    }
74
    }
75
75
76
    if (!QFile::exists(xml_name)) {
76
    if (!QFile::exists(xml_name)) {
77
        qDebug() << "invalid XML project file: " << xml_name;
77
        qDebug() << "invalid XML project file: " << xml_name;
78
        QCoreApplication::quit();
78
        QCoreApplication::quit();
79
        return;
79
        return;
80
    }
80
    }
81
    try {
81
    try {
82
82
83
        ModelController iland_model;
83
        ModelController iland_model;
84
        GlobalSettings::instance()->setModelController( &iland_model );
84
        GlobalSettings::instance()->setModelController( &iland_model );
85
        QObject::connect(&iland_model, SIGNAL(year(int)),SLOT(runYear(int)));
85
        QObject::connect(&iland_model, SIGNAL(year(int)),SLOT(runYear(int)));
86
        iland_model.setFileName(xml_name);
86
        iland_model.setFileName(xml_name);
87
        if (iland_model.hasError()) {
87
        if (iland_model.hasError()) {
88
            qWarning() << "!!!! ERROR !!!!";
88
            qWarning() << "!!!! ERROR !!!!";
89
            qWarning() << iland_model.lastError();
89
            qWarning() << iland_model.lastError();
90
            qWarning() << "!!!! ERROR !!!!";
90
            qWarning() << "!!!! ERROR !!!!";
91
            QCoreApplication::quit();
91
            QCoreApplication::quit();
92
            return;
92
            return;
93
        }
93
        }
94
94
95
        mParams.clear();
95
        mParams.clear();
96
        if (QCoreApplication::arguments().count()>3) {
96
        if (QCoreApplication::arguments().count()>3) {
97
            qWarning() << "set command line values:";
97
            qWarning() << "set command line values:";
98
            for (int i=3;i<QCoreApplication::arguments().count();++i) {
98
            for (int i=3;i<QCoreApplication::arguments().count();++i) {
99
                QString line = QCoreApplication::arguments().at(i);
99
                QString line = QCoreApplication::arguments().at(i);
100
                mParams.append(line);
100
                mParams.append(line);
101
                QString key = line.left(line.indexOf('='));
101
                QString key = line.left(line.indexOf('='));
102
                QString value = line.mid(line.indexOf('=')+1);
102
                QString value = line.mid(line.indexOf('=')+1);
103
                const_cast<XmlHelper&>(GlobalSettings::instance()->settings()).setNodeValue(key, value);
103
                const_cast<XmlHelper&>(GlobalSettings::instance()->settings()).setNodeValue(key, value);
104
                qWarning() << "set" << key << "to value:" << value << "(set:" << GlobalSettings::instance()->settings().value(key) << ").";
104
                qWarning() << "set" << key << "to value:" << value << "(set:" << GlobalSettings::instance()->settings().value(key) << ").";
105
            }
105
            }
106
        }
106
        }
107
        setupLogging();
107
        setupLogging();
108
108
109
        qDebug() << "**************************************************";
109
        qDebug() << "**************************************************";
110
        qDebug() << "***********     iLand console session     ********";
110
        qDebug() << "***********     iLand console session     ********";
111
        qDebug() << "**************************************************";
111
        qDebug() << "**************************************************";
112
        qDebug() << "started at: " << QDateTime::currentDateTime().toString(Qt::ISODate);
112
        qDebug() << "started at: " << QDateTime::currentDateTime().toString(Qt::ISODate);
113
        qDebug() << "iLand " << currentVersion() << " (" << svnRevision() << ")";
113
        qDebug() << "iLand " << currentVersion() << " (" << svnRevision() << ")";
114
        qDebug() << "**************************************************";
114
        qDebug() << "**************************************************";
115
115
116
        qWarning() << "*** creating model...";
116
        qWarning() << "*** creating model...";
117
        qWarning() << "**************************************************";
117
        qWarning() << "**************************************************";
118
118
119
        iland_model.create();
119
        iland_model.create();
120
        if (iland_model.hasError()) {
120
        if (iland_model.hasError()) {
121
            qWarning() << "!!!! ERROR !!!!";
121
            qWarning() << "!!!! ERROR !!!!";
122
            qWarning() << iland_model.lastError();
122
            qWarning() << iland_model.lastError();
123
            qWarning() << "!!!! ERROR !!!!";
123
            qWarning() << "!!!! ERROR !!!!";
124
            QCoreApplication::quit();
124
            QCoreApplication::quit();
125
            return;
125
            return;
126
        }
126
        }
127
        runJavascript("onCreate");
127
        runJavascript("onCreate");
128
        qWarning() << "**************************************************";
128
        qWarning() << "**************************************************";
129
        qWarning() << "*** running model for" << years << "years";
129
        qWarning() << "*** running model for" << years << "years";
130
        qWarning() << "**************************************************";
130
        qWarning() << "**************************************************";
131
131
132
        iland_model.run(years + 1);
132
        iland_model.run(years + 1);
133
        if (iland_model.hasError()) {
133
        if (iland_model.hasError()) {
134
            qWarning() << "!!!! ERROR !!!!";
134
            qWarning() << "!!!! ERROR !!!!";
135
            qWarning() << iland_model.lastError();
135
            qWarning() << iland_model.lastError();
136
            qWarning() << "!!!! ERROR !!!!";
136
            qWarning() << "!!!! ERROR !!!!";
137
            QCoreApplication::quit();
137
            QCoreApplication::quit();
138
            return;
138
            return;
139
        }
139
        }
140
        runJavascript("onFinish");
140
        runJavascript("onFinish");
141
141
142
        qWarning() << "**************************************************";
142
        qWarning() << "**************************************************";
143
        qWarning() << "*** model run finished.";
143
        qWarning() << "*** model run finished.";
144
        qWarning() << "*** " << QDateTime::currentDateTime();
144
        qWarning() << "*** " << QDateTime::currentDateTime();
145
        qWarning() << "**************************************************";
145
        qWarning() << "**************************************************";
146
146
147
    } catch (const IException &e) {
147
    } catch (const IException &e) {
148
        qWarning() << "*** An exception occured ***";
148
        qWarning() << "*** An exception occured ***";
149
        qWarning() << e.message();
149
        qWarning() << e.message();
150
    }
150
    }
151
    catch (const std::exception &e) {
151
    catch (const std::exception &e) {
152
        qWarning() << "*** An (std)exception occured ***";
152
        qWarning() << "*** An (std)exception occured ***";
153
        qWarning() << e.what();
153
        qWarning() << e.what();
154
    }
154
    }
155
    QCoreApplication::quit();
155
    QCoreApplication::quit();
156
156
157
157
158
}
158
}
159
159
160
void ConsoleShell::runYear(int year)
160
void ConsoleShell::runYear(int year)
161
{
161
{
162
    printf("simulating year %d ...\n", year-1);
162
    printf("simulating year %d ...\n", year-1);
163
}
163
}
164
164
165
QMutex qdebug_mutex;
165
QMutex qdebug_mutex;
166
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
166
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
167
 {
167
 {
168
    Q_UNUSED(context);
168
    Q_UNUSED(context);
169
    QMutexLocker m(&qdebug_mutex);
169
    QMutexLocker m(&qdebug_mutex);
170
170
171
    switch (type) {
171
    switch (type) {
172
     case QtDebugMsg:
172
     case QtDebugMsg:
173
        *ConsoleShell::logStream() << msg << endl;
173
        *ConsoleShell::logStream() << msg << endl;
174
        if (ConsoleShell::flush())
174
        if (ConsoleShell::flush())
175
            ConsoleShell::logStream()->flush();;
175
            ConsoleShell::logStream()->flush();;
176
         break;
176
         break;
177
     case QtWarningMsg:
177
     case QtWarningMsg:
178
        *ConsoleShell::logStream() << msg << endl;
178
        *ConsoleShell::logStream() << msg << endl;
179
        if (ConsoleShell::flush())
179
        if (ConsoleShell::flush())
180
            ConsoleShell::logStream()->flush();;
180
            ConsoleShell::logStream()->flush();;
181
        printf("Warning: %s\n", msg.toLocal8Bit().data());
181
        printf("Warning: %s\n", msg.toLocal8Bit().data());
182
182
183
         break;
183
         break;
184
     case QtCriticalMsg:
184
     case QtCriticalMsg:
185
        *ConsoleShell::logStream() << msg << endl;
185
        *ConsoleShell::logStream() << msg << endl;
186
        if (ConsoleShell::flush())
186
        if (ConsoleShell::flush())
187
            ConsoleShell::logStream()->flush();;
187
            ConsoleShell::logStream()->flush();;
188
        printf("Critical: %s\n", msg.toLocal8Bit().data());
188
        printf("Critical: %s\n", msg.toLocal8Bit().data());
189
         break;
189
         break;
190
     case QtFatalMsg:
190
     case QtFatalMsg:
191
        *ConsoleShell::logStream() << msg << endl;
191
        *ConsoleShell::logStream() << msg << endl;
192
        if (ConsoleShell::flush())
192
        if (ConsoleShell::flush())
193
            ConsoleShell::logStream()->flush();;
193
            ConsoleShell::logStream()->flush();;
194
        printf("Fatal: %s\n", msg.toLocal8Bit().data());
194
        printf("Fatal: %s\n", msg.toLocal8Bit().data());
195
     }
195
     }
196
 }
196
 }
197
197
198
198
199
void ConsoleShell::setupLogging()
199
void ConsoleShell::setupLogging()
200
{
200
{
201
    if (mLogStream) {
201
    if (mLogStream) {
202
        if (mLogStream->device())
202
        if (mLogStream->device())
203
            delete mLogStream->device();
203
            delete mLogStream->device();
204
        delete mLogStream;
204
        delete mLogStream;
205
        mLogStream = NULL;
205
        mLogStream = NULL;
206
    }
206
    }
207
207
208
    QString fname = GlobalSettings::instance()->settings().value("system.logging.logFile", "logfile.txt");
208
    QString fname = GlobalSettings::instance()->settings().value("system.logging.logFile", "logfile.txt");
209
    mFlushLog = GlobalSettings::instance()->settings().valueBool("system.logging.flush");
209
    mFlushLog = GlobalSettings::instance()->settings().valueBool("system.logging.flush");
210
    QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");
210
    QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");
211
    fname.replace("$date$", timestamp);
211
    fname.replace("$date$", timestamp);
212
    fname = GlobalSettings::instance()->path(fname, "log");
212
    fname = GlobalSettings::instance()->path(fname, "log");
213
    QFile *file = new QFile(fname);
213
    QFile *file = new QFile(fname);
214
214
215
    if (!file->open(QIODevice::WriteOnly)) {
215
    if (!file->open(QIODevice::WriteOnly)) {
216
        qDebug() << "cannot open logfile" << fname;
216
        qDebug() << "cannot open logfile" << fname;
217
    } else {
217
    } else {
218
        qDebug() << "Log output is redirected to logfile" << fname;
218
        qDebug() << "Log output is redirected to logfile" << fname;
219
        mLogStream = new QTextStream(file);
219
        mLogStream = new QTextStream(file);
220
    }
220
    }
221
    qInstallMessageHandler(myMessageOutput);
221
    qInstallMessageHandler(myMessageOutput);
222
222
223
223
224
}
224
}
225
225
226
void ConsoleShell::runJavascript(const QString key)
226
void ConsoleShell::runJavascript(const QString key)
227
{
227
{
228
    for (int i=0;i<mParams.count(); ++i) {
228
    for (int i=0;i<mParams.count(); ++i) {
229
        QString line=mParams[i];
229
        QString line=mParams[i];
230
        QString pkey = line.left(line.indexOf('='));
230
        QString pkey = line.left(line.indexOf('='));
231
        if (pkey == key) {
231
        if (pkey == key) {
232
            QString command = line.mid(line.indexOf('=')+1);
232
            QString command = line.mid(line.indexOf('=')+1);
233
            // execute the function
233
            // execute the function
234
            qWarning() << "executing trigger" << key;
234
            qWarning() << "executing trigger" << key;
235
            qWarning() << GlobalSettings::instance()->executeJavascript(command);
235
            qWarning() << GlobalSettings::instance()->executeJavascript(command);
236
        }
236
        }
237
    }
237
    }
238
238
239
239
240
}
240
}
241
241
242
 
242