#include "areatime.h"
#include "actionattimes.h"
#include "errorhandler.h"
#include "gadget.h"
#include "global.h"
int ActionAtTimes::readFromFile(CommentStream& infile, const TimeClass* const TimeInfo) {
/* File format is:
* y1 s1
* ...
* yN sN
* where y1, ..., yN are either a year or the text 'all'
* and s1, ..., sN are either a step or the text 'all'
*/
infile >> ws;
if (infile.fail())
return 0;
int check = 0; //check = 0 continue reading, check = 1 quit
int year, step, column;
year = step = column = 0;
IntVector readtext(2, 0);
char text[MaxStrLength];
strncpy(text, "", MaxStrLength);
streampos pos = infile.tellg();
while (!infile.eof() && (check == 0)) {
//update the value of pos
pos = infile.tellg();
if (isdigit(infile.peek())) {
//OK, we are about to read a number ...
readtext[column] = 0;
if (column == 0)
infile >> year >> ws;
else
infile >> step >> ws;
} else {
//OK, we are about to read a word that should be 'all'
infile >> text >> ws;
readtext[column] = 1;
if (strcasecmp(text, "all") != 0)
check = 1; //we want to exit this while loop
}
//now we have read from infile the second column we store the data
if (column == 1) {
if ((readtext[0]) && (readtext[1])) {
//we have read 'all' 'all'
everyStep = 1;
//check = 1; //we want to exit this while loop
} else if ((readtext[0]) && !(readtext[1])) {
//we have read 'all' step
if ((TimeInfo->getLastYear() != TimeInfo->getFirstYear()) ||
(TimeInfo->getFirstStep() <= step && step <= TimeInfo->getLastStep()))
Steps.resize(1, step);
} else if (!(readtext[0]) && (readtext[1])) {
//we have read year 'all''
if (TimeInfo->getFirstYear() <= year && year <= TimeInfo->getLastYear())
Years.resize(1, year);
} else {
//we have read year step
if (TimeInfo->isWithinPeriod(year, step))
TimeSteps.resize(1, TimeInfo->calcSteps(year, step));
}
}
column = !column; //change column to be read
}
if (!infile.eof())
infile.seekg(pos);
return 1;
}
void ActionAtTimes::addActions(const IntVector& years,
const IntVector& steps, const TimeClass* const TimeInfo) {
if (years.Size() != steps.Size())
handle.logMessage(LOGFAIL, "Error in actionattimes - different number of years and steps");
if (everyStep)
return;
int i;
for (i = 0; i < years.Size(); i++)
if (TimeInfo->isWithinPeriod(years[i], steps[i]))
TimeSteps.resize(1, TimeInfo->calcSteps(years[i], steps[i]));
}
void ActionAtTimes::addActionsAllYears(const IntVector& steps, const TimeClass* const TimeInfo) {
if (everyStep)
return;
int i;
for (i = 0; i < steps.Size(); i++)
if ((TimeInfo->getLastYear() != TimeInfo->getFirstYear()) ||
(TimeInfo->getFirstStep() <= steps[i] && steps[i] <= TimeInfo->getLastStep()))
Steps.resize(1, steps[i]);
}
void ActionAtTimes::addActionsAllSteps(const IntVector& years, const TimeClass* const TimeInfo) {
if (everyStep)
return;
int i;
for (i = 0; i < years.Size(); i++)
if (TimeInfo->getFirstYear() <= years[i] && years[i] <= TimeInfo->getLastYear())
Years.resize(1, years[i]);
}
/* This function could be better implemented -- e.g. sort the vectors
* TimeSteps, Years and Steps and use that to increase speed. That
* could be done by insisting that TimeInfo's time is not decreasing
* between calls, so that we can keep three indices, one for each
* vector, telling us where we quit our search in the last call */
int ActionAtTimes::atCurrentTime(const TimeClass* const TimeInfo) const {
if (everyStep)
return 1;
int i;
for (i = 0; i < Steps.Size(); i++)
if (Steps[i] == TimeInfo->getStep())
return 1;
for (i = 0; i < Years.Size(); i++)
if (Years[i] == TimeInfo->getYear())
return 1;
for (i = 0; i < TimeSteps.Size(); i++)
if (TimeSteps[i] == TimeInfo->getTime())
return 1;
return 0;
}