/*

ARIA header files for use with ARNL 1.7.1

Copyright(C) 2004, 2005 ActivMedia Robotics, LLC. 
Copyright(C) 2006, 2007, 2008, 2009 MobileRobots Inc.
All rights reserved.

This copy of Aria was relicensed for use with Arnl and the Arnl
license by MobileRobots Inc.  If you wish to download a seperate
distribution of Aria licensed under the GPL or a commercial license go to
http://www.mobilerobots.com/SOFTWARE/aria.html or contact MobileRobots
Inc, at robots@mobilerobots.com or MobileRobots Inc,
10 Columbia Drive, Amherst, NH 03031; 800-639-9481

MobileRobots Inc hereby grants to other individuals or
organizations permission to use this software with Arnl and in
compliance with the Arnl license.  This software may not be
distributed to others except by MobileRobots Inc.

MobileRobots Inc does not make any representations about the
suitability of this software for any purpose.  It is provided "as is"
without express or implied warranty.

*/
#ifndef ARRANGEDEVICETHREADED_H
#define ARRANGEDEVICETHREADED_H

#include "ariaTypedefs.h"
#include "ArRangeDevice.h"
#include "ArFunctorASyncTask.h"

/// A range device which can run in its own thread
/** 
    This is a range device thats threaded, it doesn't do
    multipleInheritance from both ArASyncTask and ArRangeDevice any
    more since JAVA doesn't support this and the wrapper software
    can't deal with it.  Its still functionally the same however.
 **/
class ArRangeDeviceThreaded : public ArRangeDevice
{
public:
  /// Constructor
  AREXPORT ArRangeDeviceThreaded(size_t currentBufferSize, 
				 size_t cumulativeBufferSize,
				 const char *name, unsigned int maxRange,
				 int maxSecondsTokeepCurrent = 0,
				 int maxSecondsToKeepCumulative = 0,
				 double maxDistToKeepCumulative = 0,
				 bool locationDependent = false);
  /// Destructor
  AREXPORT virtual ~ArRangeDeviceThreaded();
  /// The functor you need to implement that will be the one executed by the thread
  AREXPORT virtual void * runThread(void *arg) = 0;
  /// Run in this thread
  AREXPORT virtual void run(void) { myTask.run(); }
  /// Run in its own thread
  AREXPORT virtual void runAsync(void) { myTask.runAsync(); }
  /// Stop the thread
  AREXPORT virtual void stopRunning(void) { myTask.stopRunning(); }
  /// Get the running status of the thread
  AREXPORT virtual bool getRunning(void) { return myTask.getRunning();}
  /// Get the running status of the thread, locking around the variable
  AREXPORT virtual bool getRunningWithLock(void) 
    { return myTask.getRunningWithLock(); }

  AREXPORT virtual int lockDevice(void) { return myTask.lock(); }
  AREXPORT virtual int tryLockDevice(void) { return myTask.tryLock(); }
  AREXPORT virtual int unlockDevice(void) { return myTask.unlock(); }
protected:
  ArRetFunctor1C<void *, ArRangeDeviceThreaded, void *> myRunThreadCB;
  ArFunctorASyncTask myTask;

};

#endif // ARRANGEDEVICETHREADED_H
