Rev 1221 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/********************************************************************************************
** iLand - an individual based forest landscape and disturbance model
** http://iland.boku.ac.at
** Copyright (C) 2009- Werner Rammer, Rupert Seidl
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
********************************************************************************************/
#include "global.h"
#include "modules.h"
#include "plugin_interface.h"
#include "globalsettings.h"
#include "debugtimer.h"
#include "exception.h"
#include <QtPlugin>
// include the static modules here in the code:
#if QT_VERSION >= 0x050000
Q_IMPORT_PLUGIN(FirePlugin)
Q_IMPORT_PLUGIN(WindPlugin)
Q_IMPORT_PLUGIN(BarkBeetlePlugin)
#else
Q_IMPORT_PLUGIN(iland_fire)
Q_IMPORT_PLUGIN(iland_wind)
Q_IMPORT_PLUGIN(iland_barkbeetle)
#endif
Modules::Modules()
{
init();
}
// load the static plugins
void Modules::init()
{
foreach (QObject *plugin, QPluginLoader::staticInstances()) {
DisturbanceInterface *di = qobject_cast<DisturbanceInterface *>(plugin);
if (di) {
qDebug() << di->name();
// check xml file
if (GlobalSettings::instance()->settings().valueBool(QString("modules.%1.enabled").arg(di->name()))) {
// plugin is enabled: store in list of active modules
mInterfaces.append(di);
// check for other interfaces
SetupResourceUnitInterface *si=qobject_cast<SetupResourceUnitInterface *>(plugin);
if (si)
mSetupRUs.append(si);
WaterInterface *wi = qobject_cast<WaterInterface *>(plugin);
if (wi)
mWater.append(wi);
TreeDeathInterface *td = qobject_cast<TreeDeathInterface*>(plugin);
if (td)
mTreeDeath.append(td);
}
}
}
// fix the order of modules: make sure that "barkbeetle" is after "wind"
DisturbanceInterface *wind = module(QStringLiteral("wind"));
DisturbanceInterface *bb = module(QStringLiteral("barkbeetle"));
if (wind && bb) {
int iw = mInterfaces.indexOf(wind), ib = mInterfaces.indexOf(bb);
if (ib<iw)
mInterfaces.swap(iw, ib);
}
}
DisturbanceInterface * Modules::module(const QString &module_name)
{
foreach(DisturbanceInterface *di, mInterfaces)
if (di->name() == module_name)
return di;
return 0;
}
void Modules::setupResourceUnit(const ResourceUnit *ru)
{
foreach(SetupResourceUnitInterface *si, mSetupRUs)
si->setupResourceUnit(ru);
}
void Modules::setup()
{
foreach(DisturbanceInterface *di, mInterfaces)
di->setup();
// set up the scripting (i.e., Javascript)
QJSEngine *engine = GlobalSettings::instance()->scriptEngine();
foreach(DisturbanceInterface *di, mInterfaces)
di->setupScripting(engine);
}
void Modules::calculateWater(const ResourceUnit *resource_unit, const WaterCycleData *water_data)
{
foreach(WaterInterface *wi, mWater)
wi->calculateWater(resource_unit, water_data);
}
void Modules::treeDeath(const Tree *tree, int removal_type)
{
if (mTreeDeath.isEmpty())
return;
for (QList<TreeDeathInterface*>::const_iterator it=mTreeDeath.constBegin(); it!=mTreeDeath.constEnd(); ++it)
(*it)->treeDeath(tree, removal_type);
}
void Modules::run()
{
DebugTimer t("modules");
// *** run in fixed order ***
foreach(DisturbanceInterface *di, mInterfaces) {
try {
di->run();
} catch (const IException &e) {
qWarning() << "ERROR: uncaught exception in module '" << di->name() << "':";
qWarning() << "ERROR:" << e.message();
qWarning() << " **************************************** ";
}
}
// *** run in random order ****
// QList<DisturbanceInterface*> run_list = mInterfaces;
// // execute modules in random order
// while (!run_list.isEmpty()) {
// int idx = irandom(0, run_list.size()-1);
// if (logLevelDebug())
// qDebug() << "executing disturbance module: " << run_list[idx]->name();
// try {
// run_list[idx]->run();
// } catch (const IException &e) {
// qWarning() << "ERROR: uncaught exception in module '" << run_list[idx]->name() << "':";
// qWarning() << "ERROR:" << e.message();
// qWarning() << " **************************************** ";
// }
// // remove from list
// run_list.removeAt(idx);
// }
}
void Modules::yearBegin()
{
foreach(DisturbanceInterface *di, mInterfaces)
di->yearBegin();
}