#line 1 "/user/cvsspst/ees1cg/RAVL/RAVL-0.7/Core/IO/Multiplex.hh"
// This file is part of RAVL, Recognition And Vision Library
// Copyright (C) 2001, University of Surrey
// This code may be redistributed under the terms of the GNU Lesser
// General Public License (LGPL). See the lgpl.licence file for details or
// see http://www.gnu.org/copyleft/lesser.html
// file-header-ends-here
#ifndef RAVL_DPMULTIPLEX_HEADER
#define RAVL_DPMULTIPLEX_HEADER 1
////////////////////////////////////////////////////////
//! rcsid="$Id: Multiplex.hh,v 1.7 2002/07/31 07:44:54 craftit Exp $"
//! example=exDPMultiplex.cc
//! docentry="Ravl.Core.Data Processing.Multiplexer"
//! file="Ravl/Core/IO/Multiplex.hh"
//! lib=RavlIO
//! author="Charles Galambos"
//! date="04/07/1998"
#include "Ravl/DP/Port.hh"
#include "Ravl/DP/IOPort.hh"
#include "Ravl/SArray1d.hh"
#define DPMDEBUG 0
#if DPMDEBUG
#define ONDEBUG(x) x
#else
#define ONDEBUG(x)
#endif
namespace RavlN {
////////////////////////////////
//! userlevel=Develop
//: Multiplex an operation body.
// This is indended to be used with DPThreadC to
// do multiprocessing.
// This will preserve the order of the data in the
// stream.
template
class DPMultiplexBodyC
: public DPIOPortBodyC
{
public:
DPMultiplexBodyC(IntT num,const DPIOPortC & nproc);
//: Constructor.
// NB. This only uses nproc as a template, it is not actually
// used for processing. This avoids possible problems of copying
// data out of a running thread.
// ** nproc MUST not have a running thread **.
DPMultiplexBodyC(const SArray1dC > &nprocs)
: in(0),
out(0),
procs(nprocs)
{}
//: Constructor.
DPMultiplexBodyC(istream &in)
: DPIOPortBodyC(strmin)
{ strmin >> in >> out >> procs; }
//: Stream constructor.
DPMultiplexBodyC(const DPMultiplexBodyC &oth);
//: Copy constructor.
// Makes a deep copy of procs array.
virtual bool IsPutReady() const
{ return procs[in].IsPutReady(); }
//: Is some data ready ?
// true = yes.
virtual bool IsGetReady() const
{ return procs[out].IsGetReady(); }
//: Is some data ready ?
// true = yes.
virtual void PutEOS();
//: Put End Of Stream marker.
virtual bool Put(const OutT &dat);
//: Put data.
virtual IntT PutArray(const SArray1dC &data);
//: Put an array of data to stream.
// returns the number of elements processed.
virtual InT Get();
//: Get next piece of data.
// May block if not ready, or it will return a constructed
// with the default constructor.
inline IntT GetArray(SArray1dC &data);
//: Get an array of data from stream.
// returns the number of elements processed.
virtual bool Get(InT &buff);
//: Get next piece of data.
// May block if not ready, or it will return a constructed
// with the default constructor.
virtual bool IsGetEOS() const {
// No point in advancing the stream ptr.
return procs[out].IsGetEOS();
}
//: Is get EOS ?
virtual RCBodyVC &Copy() const
{ return *new DPMultiplexBodyC(*this); }
//: Make a deep copy of object.
virtual bool Save(ostream &out) const;
//: Save to ostream.
private:
IntT in,out;
SArray1dC > procs;
};
//////////////////////////////////
//! userlevel=Normal
//: Multiplex an operation.
// This is indended to be used with DPThreadC to
// do multiprocessing.
template
class DPMultiplexC : public DPIOPortC
{
public:
DPMultiplexC()
{}
//: Default constructor.
DPMultiplexC(IntT num,const DPIOPortC & nproc)
: DPEntityC(*new DPMultiplexBodyC(num,nproc))
{}
//: Constructor.
DPMultiplexC(const SArray1dC > &procs)
: DPEntityC(*new DPMultiplexBodyC(procs))
{}
//: Constructor.
};
///////////////////////////////
template
DPMultiplexC DPMultiplex(IntT num,const DPIOPortC & nproc)
{ return DPMultiplexC(num,nproc); }
//: Create a multiplexer.
// Helper function.
template
DPMultiplexC DPMultiplex(const SArray1dC > &procs)
{ return DPMultiplexC(procs); }
//: Create a multiplexer.
// Helper function.
////////////////////////////////////
template
DPMultiplexBodyC::DPMultiplexBodyC(IntT num,const DPIOPortC & nproc)
: in(0),
out(0),
procs(num)
{
RavlAssert(nproc.IsValid());
for(IntT i = 0;i < num;i++)
procs[i] = nproc.Copy();
}
template
DPMultiplexBodyC::DPMultiplexBodyC(const DPMultiplexBodyC &oth)
: in(oth.in),
out(oth.out),
procs(oth.procs.Size())
{
for(IntT i = 0;i < (IntT) oth.procs.Size();i++)
procs[i] = oth.procs[i].Copy();
}
template
void DPMultiplexBodyC::PutEOS() {
IntT i;
// Put EOS's in proper sequence.
for(i = in;i < (IntT) procs.Size();i++)
procs[i].PutEOS();
for(i = 0;i < in;i++)
procs[i].PutEOS();
}
template
bool DPMultiplexBodyC::Put(const OutT &dat) {
ONDEBUG(cerr << "DPMultiplexBodyC::Put(), in:" << in << " Started\n");
if(!procs[in].Put(dat)) {
cerr << "WARNING: DPMultiplexBodyC::Put(), Failed. \n";
return false;
}
ONDEBUG(cerr << "DPMultiplexBodyC::Put(), in:" << in << " Done\n");
in++;
if(in >= (IntT) procs.Size())
in = 0;
return true;
}
template
IntT DPMultiplexBodyC::PutArray(const SArray1dC &data) {
for(SArray1dIterC it(data);it;it++) {
if(!procs[in].Put(*it)) {
cerr << "WARNING: DPMultiplexBodyC::PutArray(), Failed. \n";
return it.Index().V();
}
in++;
if(in >= (IntT) procs.Size())
in = 0;
}
return data.Size();
}
template
InT DPMultiplexBodyC::Get() {
ONDEBUG(cerr << "DPMultiplexBodyC::Get(), out:" << out << " Started\n");
InT ret = procs[out].Get();
ONDEBUG(cerr << "DPMultiplexBodyC::Get(), out:" << out << " Done.\n");
out++;
if(out >= (IntT) procs.Size())
out = 0;
return ret;
}
template
bool DPMultiplexBodyC::Get(InT &buff) {
ONDEBUG(cerr << "DPMultiplexBodyC::Get(), out:" << out << " Started\n");
if(!procs[out].Get(buff)) {
cerr << "WARNING: DPMultiplexBodyC::Get(), Failed. \n";
return false;
}
ONDEBUG(cerr << "DPMultiplexBodyC::Get(), out:" << out << " Done.\n");
out++;
if(out >= (IntT) procs.Size())
out = 0;
return true;
}
template
IntT DPMultiplexBodyC::GetArray(SArray1dC &data) {
for(SArray1dIterC it(data);it;it++) {
if(!procs[out].Get(*it)) {
cerr << "WARNING: DPMultiplexBodyC::PutArray(), Failed. \n";
return it.Index().V();
}
out++;
if(out >= (IntT) procs.Size())
out = 0;
}
return data.Size();
}
template
bool DPMultiplexBodyC::Save(ostream &out) const {
DPIOPortBodyC::Save(out);
out << in << " " << out << " " << procs;
return true;
}
}
#ifdef ONDEBUG
#undef ONDEBUG
#endif
#endif