00001 // PTF - Psychological Test Framework 00002 // http://ptf.sourceforge.net 00003 // 00004 // This program is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU Library General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 00018 #include <ptf/core/ptfcore.hpp> 00019 #include <ptf/environment/clock.hpp> 00020 #include <ptf/environment/graphic.hpp> 00021 #include <ptf/environment/audio.hpp> 00022 #include <ptf/environment/parallel.hpp> 00023 #include <stdlib.h> 00024 #include <stdexcept> 00025 00029 PtfCore::PtfCore(int argc, char** argv) { 00030 try { 00031 // set to null pointer 00032 scheduler = 0; 00033 handler = 0; 00034 iterator = 0; 00035 // fullscreen flag 00036 bool fullscreen = false; 00037 // parse arguments 00038 for(int i = 0; i < argc; i++){ 00039 if (argv[i][0]=='-'){ 00040 if(argv[i][1]=='f'){ 00041 fullscreen = true; 00042 messageLog << MESSAGE("Using Fullscreen\n"); 00043 } 00044 else { 00045 messageLog << ERROR("Unkown command line option: ") << argv[i] ; 00046 throw std::runtime_error("Unknown command line option"); 00047 } 00048 } 00049 } 00050 // create libraries 00051 new Clock(); 00052 new Audio(); 00053 new Graphic(); 00054 new Parallel(); 00055 // open a window 00056 Graphic::getSingleton().createWindow(500, 500, fullscreen); 00057 } 00058 catch(std::runtime_error& x) { 00059 messageLog << ERROR("Unhandled error caught: ") << x.what() << " "; 00060 messageLog << "Exiting now.\n"; 00061 exit(1); 00062 } 00063 catch(...) { 00064 messageLog << ERROR("Unknown error encountered. Exiting now.\n"); 00065 exit(1); 00066 } 00067 } 00068 00072 PtfCore::~PtfCore() { 00073 // clean up graphic library 00074 delete Graphic::getSingletonPtr(); 00075 // clean up audio library 00076 delete Audio::getSingletonPtr(); 00077 // clean up clock 00078 delete Clock::getSingletonPtr(); 00079 // clean up parallel port 00080 delete Parallel::getSingletonPtr(); 00081 // clean up SDL lib 00082 SDL_Quit(); 00083 } 00084 00088 void PtfCore::run() { 00089 try { 00090 // prevent output to screen 00091 machineLog.setSilent(true); 00092 // check for needed things 00093 if (scheduler == 0){ 00094 messageLog << WARNING("No Scheduler specified, using default.\n"); 00095 scheduler = new Scheduler(); 00096 } 00097 if (handler == 0){ 00098 messageLog << WARNING("No ReactionHandler specified. Reactions will not be handled.\n"); 00099 handler = new ReactionHandler(); 00100 } 00101 if (iterator == 0){ 00102 messageLog << WARNING("No SequenceIterator specified, using default.\n"); 00103 iterator = new DefaultSequenceIterator(); 00104 } 00105 if (inputDevices.size() == 0){ 00106 messageLog << WARNING("No InputDevice specified. No reactions will be generated.\n"); 00107 } 00108 // start all input devices 00109 for (int i = 0; i < (int)inputDevices.size(); i++) { 00110 inputDevices[i]->startPolling(); 00111 } 00112 // start scheduling 00113 scheduler->schedule(); 00114 // stop all input devices 00115 for (int i = 0; i < (int)inputDevices.size(); i++) { 00116 inputDevices[i]->stopPolling(); 00117 } 00118 // save log files 00119 taskLog.saveToFile("task.log"); 00120 messageLog.saveToFile("message.log"); 00121 handlerLog.saveToFile("handler.log"); 00122 eventLog.saveToFile("event.log"); 00123 machineLog.saveToFile("machine.log"); 00124 } 00125 catch(std::runtime_error& x) { 00126 messageLog << ERROR("Unhandled error caught: " << x.what() << " "); 00127 messageLog << "Exiting now.\n"; 00128 exit(1); 00129 } 00130 catch(...) { 00131 messageLog << ERROR("Unknown error encountered. Exiting now.\n"); 00132 exit(1); 00133 } 00134 } 00135 00140 void PtfCore::setScheduler(Scheduler* taskScheduler){ 00141 scheduler = taskScheduler; 00142 } 00143 00148 void PtfCore::setReactionHandler(ReactionHandler* reactionHandler){ 00149 handler = reactionHandler; 00150 } 00151 00156 void PtfCore::setSequenceIterator(SequenceIterator* sequenceIterator){ 00157 iterator = sequenceIterator; 00158 } 00159 00164 Scheduler& PtfCore::getScheduler() { 00165 return *scheduler; 00166 } 00167 00173 ReactionHandler& PtfCore::getReactionHandler() { 00174 return *handler; 00175 } 00176 00181 SequenceIterator& PtfCore::getSequenceIterator() { 00182 return *iterator; 00183 } 00184 00189 vector<Sequence*>& PtfCore::getSequences() { 00190 return sequences; 00191 } 00192 00197 vector<ReactionRecord*>& PtfCore::getReactionRecords() { 00198 return reactionRecords; 00199 } 00200 00205 vector<TaskRecord*>& PtfCore::getTaskRecords() { 00206 return taskRecords; 00207 } 00208 00213 vector<InputDevice*>& PtfCore::getInputDevices() { 00214 return inputDevices; 00215 } 00216 00221 Mutex& PtfCore::getReactionRecordsMutex() { 00222 return reactionRecordsMutex; 00223 } 00224 00229 Mutex& PtfCore::getTaskRecordsMutex() { 00230 return taskRecordsMutex; 00231 } 00232 00237 const vector<Task*>& PtfCore::getTasks() const { 00238 return tasks; 00239 } 00240 00247 void PtfCore::taskRegistrationHelper(Task* task) { 00248 // get id of task to add 00249 int id = task->getId(); 00250 // fill tasks vector with null pointers so that we can add the task safely (only if necessary) 00251 if ((int)tasks.size() <= id) { 00252 int n = id - (int)tasks.size() + 1; 00253 for (int i = 0; i < n; i++) { 00254 tasks.push_back(0); 00255 } 00256 00257 } 00258 // set entry to task 00259 tasks[id] = task; 00260 } 00261 00266 Log& PtfCore::getMessageLog() { 00267 return messageLog; 00268 } 00269 00274 Log& PtfCore::getHandlerLog() { 00275 return handlerLog; 00276 } 00277 00282 Log& PtfCore::getTaskLog() { 00283 return taskLog; 00284 } 00285 00290 Log& PtfCore::getEventLog() { 00291 return eventLog; 00292 } 00293 00298 Log& PtfCore::getMachineLog() { 00299 return machineLog; 00300 }