|
// Thread Class for Legos
// By Pongsak Suvanpong
// psksvp@ccs.neu.edu
// use it anyway you'd like as long as this comment is here
#ifndef __THREAD_CLASS___
#define __THREAD_CLASS___
#include <unistd.h>
#include <sys/dsensor.h>
#include <sys/battery.h>
#include <dmotor.h>
#include <dsound.h>
#include <dbutton.h>
#include <c++/Sound.H>
#include <c++/TouchSensor.H>
#include <c++/LightSensor.H>
#include <c++/RotationSensor.H>
class Thread;
class Runable
{
friend Thread;
bool m_bIsRunning;
public:
Runable(void)
{
m_bIsRunning = false;
}
virtual ~Runable(void)
{
}
bool IsRunning(void)
{
return m_bIsRunning;
}
virtual int Run(void)=0;
private:
int CallBack(void)
{
m_bIsRunning = true;
Run();
m_bIsRunning = false;
}
};
class Thread
{
protected:
pid_t m_id;
Runable *m_pHandler;
bool m_bCreated;
public:
Thread(void)
{
m_pHandler = (Runable *)NULL;
m_id = 0;
m_bCreated = false;
}
Thread(Runable *pHandler)
{
m_pHandler = pHandler;
m_id = 0;
m_bCreated = false;
}
~Thread(void)
{
Stop();
}
pid_t Id(void)
{
return m_id;
}
void SetRunable(Runable *pHandler)
{
m_pHandler = pHandler;
}
bool Start(priority_t priority = PRIO_NORMAL, size_t stackSize =
DEFAULT_STACK_SIZE)
{
if(NULL != m_pHandler)
{
char *argv[2];
argv[0] = (char *)m_pHandler;
argv[1] = (char *)NULL;
m_id = ::execi(Proc, 2, argv, priority, stackSize);
m_bCreated = ( m_id == -1 ? false : true);
return m_bCreated;
}
else
{
return false;
}
}
void Stop(void)
{
if(true == m_bCreated)
{
::kill(m_id);
m_bCreated = false;
}
}
bool IsRunning(void)
{
return m_pHandler->IsRunning();
}
private:
static int Proc(int argc, char **argv)
{
Runable *pcHandler = reinterpret_cast<Runable*>(argv[0]);
return pcHandler->CallBack();
}
};
class SensorMonitor :public Runable
{
protected:
unsigned char m_iFreq; //millisec
Thread m_myThread;
public:
SensorMonitor(void) :Runable()
{
m_myThread.SetRunable(this);
}
~SensorMonitor(void)
{
StopMonitor();
}
virtual bool StartMonitor(unsigned char iFreq=100)
{
m_iFreq = iFreq;
return m_myThread.Start();
}
virtual void StopMonitor(void)
{
m_myThread.Stop();
}
int Run(void)
{
while(true)
{
if(false == Monitor())
return 1;
else
::msleep(m_iFreq);
}
}
protected:
virtual bool Monitor(void) = 0;
};
class BatteryMonitor :public SensorMonitor
{
int m_iLow;
public:
BatteryMonitor(const int iLowThreadhold=300) :SensorMonitor()
{
m_iLow = iLowThreadhold;
}
int CurrentValue(void)
{
::battery_refresh();
return ::get_battery_mv();
}
virtual bool OnLow(void)
{
return true;
}
protected:
bool Monitor(void)
{
if(m_iLow >= CurrentValue())
return OnLow();
else
return true;
}
};
class TouchSensorMonitor :public SensorMonitor
{
TouchSensor *m_pTheSensor;
public:
TouchSensorMonitor(const Sensor::Port port):SensorMonitor()
{
m_pTheSensor = new TouchSensor(port);
}
~TouchSensorMonitor(void)
{
delete m_pTheSensor;
}
virtual bool OnPressed(void)
{
return true;
}
protected:
bool Monitor(void)
{
if(true == m_pTheSensor->pressed())
return OnPressed();
else
return true;
}
};
class LightSensorMonitor :public SensorMonitor
{
LightSensor *m_pTheSensor;
unsigned int m_iCurValue;
public:
LightSensorMonitor(const Sensor::Port port) :SensorMonitor()
{
m_iCurValue = 0;
m_pTheSensor = new LightSensor(port);
}
~LightSensorMonitor(void)
{
delete m_pTheSensor;
}
unsigned int CurrentValue(void)
{
return m_pTheSensor->get();
}
virtual bool OnChange(const unsigned int iNewValue)
{
return true;
}
protected:
bool Monitor(void)
{
unsigned int iNewValue = m_pTheSensor->get();
if(m_iCurValue != iNewValue)
{
m_iCurValue = iNewValue;
return OnChange(m_iCurValue);
}
else
return true;
}
};
class RotationSensorMonitor :public SensorMonitor
{
RotationSensor *m_pTheSensor;
int m_iCurValue;
protected:
RotationSensorMonitor(const Sensor::Port port, const int pos=0)
:SensorMonitor()
{
m_iCurValue = 0;
m_pTheSensor = new RotationSensor(port, pos);
}
~RotationSensorMonitor(void)
{
delete m_pTheSensor;
}
int CurrentValue(void)
{
return m_pTheSensor->pos() % 16;
}
virtual bool OnRotate(const int iNewValue)
{
return true;
}
bool Monitor(void)
{
int iNewValue = CurrentValue();
if(m_iCurValue != iNewValue)
{
m_iCurValue = iNewValue;
return OnRotate(m_iCurValue);
}
else
return true;
}
};
#endif
///////////////////////////////////////////////
//// example
//////////////////////////////////////////////
#include <c++/Thread.H>
/////////////////////////////////////////////////
class MyTouchMonitor :public TouchSensorMonitor
{
public:
MyTouchMonitor(const Sensor::Port port)
:TouchSensorMonitor(port)
{
}
bool OnPressed(void)
{
Sound::beep();
return true;
}
};
/////////////////////////////////////////////////
class MyLightMonitor :public LightSensorMonitor
{
public:
MyLightMonitor(const Sensor::Port port)
:LightSensorMonitor(port)
{
}
bool OnChange(const unsigned int iNewValue)
{
::cputw(iNewValue);
return true;
}
};
/////////////////////////////////////////////////
class MyRotMonitor :public RotationSensorMonitor
{
public:
MyRotMonitor(const Sensor::Port port, const int pos=0)
:RotationSensorMonitor(port, pos)
{
}
virtual bool OnRotate(const int iNewValue)
{
::cputw(iNewValue);
return true;
}
};
int main(int argc, char *argv[])
{
//MyLightMonitor mon1(TouchSensor::S3);
//mon1.StartMonitor();
MyRotMonitor mon1(Sensor::S3);
mon1.StartMonitor();
MyTouchMonitor mon(Sensor::S1);
mon.StartMonitor();
::getchar();
return 0;
}
|
|
1 Message in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|