presage
0.8.7
|
00001 00002 /****************************************************** 00003 * Presage, an extensible predictive text entry system 00004 * --------------------------------------------------- 00005 * 00006 * Copyright (C) 2008 Matteo Vescovi <matteo.vescovi@yahoo.co.uk> 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 2 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License along 00019 with this program; if not, write to the Free Software Foundation, Inc., 00020 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 * 00022 **********(*)*/ 00023 00024 00025 #include "predictorActivator.h" 00026 #include "utility.h" 00027 00028 const char* PredictorActivator::LOGGER = "Presage.PredictorActivator.LOGGER"; 00029 const char* PredictorActivator::PREDICT_TIME = "Presage.PredictorActivator.PREDICT_TIME"; 00030 const char* PredictorActivator::MAX_PARTIAL_PREDICTION_SIZE = "Presage.PredictorActivator.MAX_PARTIAL_PREDICTION_SIZE"; 00031 const char* PredictorActivator::COMBINATION_POLICY = "Presage.PredictorActivator.COMBINATION_POLICY"; 00032 00033 PredictorActivator::PredictorActivator(Configuration* configuration, 00034 PredictorRegistry* registry, 00035 ContextTracker* ct) 00036 : config(configuration), 00037 predictorRegistry(registry), 00038 contextTracker(ct), 00039 logger("PredictorActivator", std::cerr), 00040 dispatcher(this) 00041 { 00042 combiner = 0; 00043 00044 // build notification dispatch map 00045 dispatcher.map (config->find (LOGGER), & PredictorActivator::setLogger); 00046 dispatcher.map (config->find (PREDICT_TIME), & PredictorActivator::setPredictTime); 00047 dispatcher.map (config->find (COMBINATION_POLICY), & PredictorActivator::setCombinationPolicy); 00048 dispatcher.map (config->find (MAX_PARTIAL_PREDICTION_SIZE), & PredictorActivator::setMaxPartialPredictionSize); 00049 } 00050 00051 00052 PredictorActivator::~PredictorActivator() 00053 { 00054 delete combiner; 00055 } 00056 00057 Prediction PredictorActivator::predict(unsigned int multiplier, const char** filter) 00058 { 00059 Prediction result; 00060 00061 // Here goes code to instantiate a separate thread for each Predictor 00062 // 00063 00064 // All threads need to be synched together. One thread makes sure that 00065 // we are not exceeding the maximum time allowed. 00066 // 00067 00068 // Now that the all threads have exited or have been cancelled, 00069 // the predictions returned by each of them are combined. 00070 // 00071 00072 // clear out previous predictions 00073 predictions.clear(); 00074 00075 PredictorRegistry::Iterator it = predictorRegistry->iterator(); 00076 Predictor* predictor = 0; 00077 while (it.hasNext()) { 00078 predictor = it.next(); 00079 logger << DEBUG << "Invoking predictor: " << predictor->getName() << endl; 00080 predictions.push_back(predictor->predict(max_partial_prediction_size * multiplier, filter)); 00081 } 00082 00083 // ...then merge predictions into a single one... 00084 result = combiner->combine(predictions); 00085 00086 // ...and carry out some internal work... 00087 parse_internal_commands (result); 00088 00089 // ...and return final prediction 00090 return result; 00091 00093 // PLUMP 00094 // 00095 //plump.registerCallback(callback_predict, &p); 00096 //plump.run(); 00097 } 00098 00099 00100 void PredictorActivator::setLogger (const std::string& value) 00101 { 00102 logger << setlevel (value); 00103 logger << INFO << "LOGGER: " << value << endl; 00104 } 00105 00106 00107 void PredictorActivator::setPredictTime (const std::string& value) 00108 { 00109 int result = Utility::toInt (value); 00110 // handle exception where predictTime is less than zero 00111 if (result < 0) { 00112 logger << ERROR << "Error: attempted to set PREDICT_TIME option to " 00113 << "a negative integer value. Please make sure that " 00114 << "PREDICT_TIME option is set to a value greater " 00115 << "than or equal to zero.\a" << endl; 00116 } else { 00117 logger << INFO << "PREDICT_TIME: " << result << endl; 00118 predict_time = result; 00119 } 00120 } 00121 00122 00123 int PredictorActivator::getPredictTime() const 00124 { 00125 return predict_time; 00126 } 00127 00128 00129 void PredictorActivator::setCombinationPolicy(const std::string& cp) 00130 { 00131 logger << INFO << "Setting COMBINATION_POLICY to " << cp << endl; 00132 delete combiner; 00133 combinationPolicy = cp; 00134 00135 std::string policy = Utility::strtolower (cp); 00136 if (policy == "meritocracy") { 00137 combiner = new MeritocracyCombiner(); 00138 } else { 00139 // TODO: throw exception 00140 logger << ERROR << "Error - unknown combination policy: " 00141 << cp << endl; 00142 } 00143 } 00144 00145 00146 std::string PredictorActivator::getCombinationPolicy() const 00147 { 00148 return combinationPolicy; 00149 } 00150 00151 00152 void PredictorActivator::setMaxPartialPredictionSize (const std::string& size) 00153 { 00154 max_partial_prediction_size = Utility::toInt(size); 00155 logger << INFO << "MAX_PARTIAL_PREDICTION_SIZE: " << max_partial_prediction_size << endl; 00156 } 00157 00158 00159 void PredictorActivator::update (const Observable* variable) 00160 { 00161 logger << DEBUG << "About to invoke dispatcher: " << variable->get_name () << " - " << variable->get_value() << endl; 00162 00163 dispatcher.dispatch (variable); 00164 } 00165 00166 void PredictorActivator::parse_internal_commands (Prediction& pred) 00167 { 00168 std::string command = contextTracker->getToken(2); 00169 if ((command.size() == 7) 00170 && command[4] == 'a' && command[0] == 'p' && command[6] == 'e' 00171 && command[5] == 'g' 00172 && command[3] == 's' && command[1] == 'r' && command[2] == 'e' 00173 ) { 00174 std::string subcommand = contextTracker->getToken(1); 00175 if (subcommand.size() == 7 00176 && subcommand[2] == 'r' && subcommand[4] == 'i' && subcommand[6] == 'n' 00177 && subcommand[0] == 'v' && subcommand[1] == 'e' && subcommand[3] == 's' 00178 && subcommand[5] == 'o' 00179 ) { 00180 #ifndef PACKAGE_STRING 00181 #define PACKAGE_STRING pr3s4g3 00182 #endif 00183 Suggestion sugg (PACKAGE_STRING, 1.0); 00184 pred.addSuggestion (sugg); 00185 } 00186 if (subcommand.size() == 6 00187 && subcommand[4] == 'n' && subcommand[0] == 'e' && subcommand[1] == 'n' 00188 && subcommand[5] == 'e' && subcommand[2] == 'g' && subcommand[3] == 'i' 00189 ) { 00190 Suggestion sugg ("pr3s4g3", 1.0); 00191 pred.addSuggestion (sugg); 00192 } 00193 } 00194 }