00001 #include "LCDWidget.h"
00002 #include "LCDUtils.h"
00003 #include "LCDSensor.h"
00004
00005 #include <string>
00006 #include <stdio.h>
00007 #include <unistd.h>
00008 #include <pthread.h>
00009
00010 using namespace std;
00011
00012 const int LCDSensor::MAX_CMD_RESULT_LINE_SIZE = 255;
00013
00014 LCDSensor::LCDSensor()
00015 {
00016 _exist = true;
00017 _onChangeThreadStarted = false;
00018 }
00019
00020 LCDSensor::~LCDSensor()
00021 {
00022 _exist = false;
00023 if (_onChangeThreadStarted)
00024 {
00025 if (::pthread_cancel(_onChangeThread) == 0)
00026 {
00027 ::pthread_join(_onChangeThread, 0);
00028 }
00029 _onChangeThreadStarted = false;
00030 }
00031
00032 WidgetTimeOutList::iterator it;
00033 for (it = _onTimeOutList.begin(); it != _onTimeOutList.end(); it++)
00034 {
00035 if (::pthread_cancel(it->second._thread) == 0)
00036 {
00037 ::pthread_join(it->second._thread, 0);
00038 }
00039 }
00040 }
00041
00042 bool LCDSensor::exists()
00043 {
00044 return _exist;
00045 }
00046
00047 void LCDSensor::fireChanged()
00048 {
00049 string value = getCurrentValue();
00050 WidgetList::iterator it;
00051 for (it = _onChangeList.begin(); it != _onChangeList.end(); it++)
00052 {
00053 if (LCDElement::exists(it->first))
00054 {
00055 it->second->valueCallback(value);
00056 }
00057 else
00058 {
00059 removeOnChangeWidget(it->first);
00060 }
00061 }
00062 }
00063
00064 const LCDWidgetTimeOut &LCDSensor::getThreadWidgetInfo(const ::pthread_t &thread)
00065 {
00066 WidgetTimeOutList::iterator it;
00067
00068 for (it = _onTimeOutList.begin(); it != _onTimeOutList.end(); it++)
00069 {
00070 if (::pthread_equal(thread, it->second._thread))
00071 {
00072 return it->second;
00073 }
00074 }
00075
00076 static LCDWidgetTimeOut dummy;
00077 dummy._timeOut=0;
00078 dummy._widget = 0;
00079
00080 return dummy;
00081 }
00082
00083 string LCDSensor::intToString(int value)
00084 {
00085 return LCDUtils::toString(value);
00086 }
00087
00088 string LCDSensor::executeCommand(const string &cmd)
00089 {
00090 string silentCmd = cmd + " 2>/dev/null";
00091 char buf[MAX_CMD_RESULT_LINE_SIZE + 1];
00092 buf[0]='\0';
00093 FILE *ptr;
00094
00095 if ((ptr = popen(silentCmd.c_str(), "r")) != NULL)
00096 {
00097 fgets(buf, MAX_CMD_RESULT_LINE_SIZE, ptr);
00098 pclose(ptr);
00099 }
00100
00101 int len = strlen(buf);
00102
00103 string result(buf, (len > 0) ? (len - 1) : 0);
00104
00105 return result;
00106 }
00107
00108 void LCDSensor::addOnChangeWidget(LCDWidget *widget)
00109 {
00110 if (!_onChangeThreadStarted)
00111 {
00112 ::pthread_create(&_onChangeThread, 0, (ThreadFunction)updateWhenChanged, (void *)this);
00113 _onChangeThreadStarted = true;
00114 }
00115
00116 _onChangeList[widget->getId()] = widget;
00117 }
00118
00119 void LCDSensor::removeOnChangeWidget(LCDWidget *widget)
00120 {
00121 removeOnChangeWidget(widget->getId());
00122 }
00123
00124 void LCDSensor::removeOnChangeWidget(string id)
00125 {
00126 _onChangeList.erase(id);
00127 if (_onChangeList.empty() && _onChangeThreadStarted)
00128 {
00129 if (::pthread_cancel(_onChangeThread) == 0)
00130 {
00131 ::pthread_join(_onChangeThread, 0);
00132 }
00133 _onChangeThreadStarted = false;
00134 }
00135 }
00136
00137 void LCDSensor::addOnTimeOutWidget(LCDWidget *widget, int timeout)
00138 {
00139 LCDWidgetTimeOut tmpWidget;
00140
00141 tmpWidget._timeOut = timeout;
00142 tmpWidget._widget = widget;
00143 tmpWidget._widgetId = widget->getId();
00144
00145 _onTimeOutList[widget->getId()] = tmpWidget;
00146
00147 ::pthread_create(&(_onTimeOutList[widget->getId()]._thread), 0, (ThreadFunction)updateEach, (void *)this);
00148 }
00149
00150 void LCDSensor::removeOnTimeOutWidget(LCDWidget *widget)
00151 {
00152 removeOnTimeOutWidget(widget->getId());
00153 }
00154
00155 void LCDSensor::removeOnTimeOutWidget(string id)
00156 {
00157 if (::pthread_cancel(_onTimeOutList[id]._thread) == 0)
00158 {
00159 ::pthread_join(_onTimeOutList[id]._thread, 0);
00160 }
00161 _onTimeOutList.erase(id);
00162 }
00163
00164 void *updateWhenChanged(void *param)
00165 {
00166 ::pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
00167
00168 LCDSensor *daddy = (LCDSensor *)param;
00169
00170 while (daddy->exists())
00171 {
00172 daddy->waitForChange();
00173 daddy->fireChanged();
00174 }
00175 }
00176
00177 void *updateEach(void *param)
00178 {
00179 ::pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
00180
00181 LCDSensor *daddy = (LCDSensor *)param;
00182
00183 LCDWidgetTimeOut widgetInfo;
00184
00185 while (!widgetInfo.isValid())
00186 {
00187 widgetInfo = daddy->getThreadWidgetInfo(::pthread_self());
00188 usleep(10);
00189 }
00190
00191 while (daddy->exists())
00192 {
00193 if (LCDElement::exists(widgetInfo._widgetId))
00194 {
00195 widgetInfo._widget->valueCallback(daddy->getCurrentValue());
00196 usleep(widgetInfo._timeOut * 100000);
00197 ::pthread_testcancel();
00198 }
00199 else
00200 {
00201 daddy->removeOnTimeOutWidget(widgetInfo._widgetId);
00202 }
00203 }
00204 }