Merge with 4060002ace66b81caef7ac32c598c42aa4e5123c

This commit is contained in:
miha_vitorovic
2010-12-21 10:07:05 +01:00
2 changed files with 333 additions and 19 deletions

View File

@@ -32,6 +32,8 @@ namespace epics { namespace pvAccess {
enum ConnectionState {
NEVER_CONNECTED, CONNECTED, DISCONNECTED, DESTROYED
};
const char* ConnectionStateNames[] = { "NEVER_CONNECTED", "CONNECTED", "DISCONNECTED", "DESTROYED" };
class Channel;
@@ -118,7 +120,7 @@ namespace epics { namespace pvAccess {
* @author mrk
*
*/
class ChannelFind {
class ChannelFind : public epics::pvData::Destroyable, private epics::pvData::NoDefaultMethods {
public:
virtual ChannelProvider* getChannelProvider() = 0;
virtual void cancelChannelFind() = 0;
@@ -403,7 +405,7 @@ namespace epics { namespace pvAccess {
* @param status Completion status.
* @param field The Structure for the request.
*/
virtual void getDone(epics::pvData::Status *status,epics::pvData::Field *field) = 0;
virtual void getDone(epics::pvData::Status *status,epics::pvData::FieldConstPtr field) = 0;
};
@@ -592,6 +594,7 @@ namespace epics { namespace pvAccess {
*/
class ChannelAccess : private epics::pvData::NoDefaultMethods {
public:
virtual ~ChannelAccess() {};
/**
* Get the provider with the specified name.
@@ -617,7 +620,7 @@ namespace epics { namespace pvAccess {
* @author mrk
*
*/
class ChannelProvider : private epics::pvData::NoDefaultMethods {
class ChannelProvider : public epics::pvData::Destroyable, private epics::pvData::NoDefaultMethods {
public:
/** Minimal priority. */
@@ -633,11 +636,6 @@ namespace epics { namespace pvAccess {
/** OPI priority. */
static const short PRIORITY_OPI = PRIORITY_MIN;
/**
* Terminate.
*/
virtual void destroy() = 0;
/**
* Get the provider name.
* @return The name.
@@ -659,7 +657,7 @@ namespace epics { namespace pvAccess {
* @param priority channel priority, must be <code>PRIORITY_MIN</code> <= priority <= <code>PRIORITY_MAX</code>.
* @return <code>Channel</code> instance. If channel does not exist <code>null</code> is returned and <code>channelRequester</code> notified.
*/
virtual Channel* createChannel(epics::pvData::String channelName,ChannelRequester *channelRequester,short priority) = 0;
virtual Channel* createChannel(epics::pvData::String channelName,ChannelRequester *channelRequester,short priority = PRIORITY_DEFAULT) = 0;
/**
* Create a channel.
@@ -684,7 +682,7 @@ namespace epics { namespace pvAccess {
* Get context implementation version.
* @return version of the context implementation.
*/
virtual const Version* getVersion() = 0;
virtual Version* getVersion() = 0;
/**
* Initialize client context. This method is called immediately after instance construction (call of constructor).
@@ -695,7 +693,7 @@ namespace epics { namespace pvAccess {
* Get channel provider implementation.
* @return the channel provider.
*/
virtual const ChannelProvider* getProvider() = 0;
virtual ChannelProvider* getProvider() = 0;
/**
* Prints detailed information about the context to the standard output stream.

View File

@@ -4,14 +4,242 @@
#include <pvAccess.h>
#include <iostream>
#include <showConstructDestruct.h>
#include <lock.h>
#include <standardPVField.h>
using namespace epics::pvData;
using namespace epics::pvAccess;
static volatile int64 mockChannel_totalConstruct = 0;
static volatile int64 mockChannel_totalDestruct = 0;
static Mutex *mockChannel_globalMutex = 0;
static int64 mockChannel_getTotalConstruct()
{
Lock xx(mockChannel_globalMutex);
return mockChannel_totalConstruct;
}
static int64 mockChannel_getTotalDestruct()
{
Lock xx(mockChannel_globalMutex);
return mockChannel_totalDestruct;
}
static ConstructDestructCallback *mockChannel_pConstructDestructCallback;
static void mockChannel_init()
{
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(mockChannel_globalMutex==0) {
mockChannel_globalMutex = new Mutex();
mockChannel_pConstructDestructCallback = new ConstructDestructCallback(
String("mockChannel"),
mockChannel_getTotalConstruct,mockChannel_getTotalDestruct,0);
}
}
class MockChannel : public Channel {
private:
ChannelProvider* m_provider;
ChannelRequester* m_requester;
String m_name;
String m_remoteAddress;
PVStructure* pvStructure;
private:
~MockChannel()
{
delete pvStructure;
Lock xx(mockChannel_globalMutex);
mockChannel_totalDestruct++;
}
public:
MockChannel(
ChannelProvider* provider,
ChannelRequester* requester,
String name,
String remoteAddress) :
m_provider(provider),
m_requester(requester),
m_name(name),
m_remoteAddress(remoteAddress)
{
mockChannel_init();
Lock xx(mockChannel_globalMutex);
mockChannel_totalConstruct++;
ScalarType stype = pvDouble;
String allProperties("alarm,timeStamp,display,control,valueAlarm");
pvStructure = getStandardPVField()->scalar(
0,name,stype,allProperties);
PVDouble *pvField = pvStructure->getDoubleField(String("value"));
pvField->put(1.123e35);
// already connected, report state
m_requester->channelStateChange(this, CONNECTED);
}
virtual void destroy()
{
delete this;
};
virtual String getRequesterName()
{
return getChannelName();
};
virtual void message(String message,MessageType messageType)
{
std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
}
virtual ChannelProvider* getProvider()
{
return m_provider;
}
virtual epics::pvData::String getRemoteAddress()
{
return m_remoteAddress;
}
virtual epics::pvData::String getChannelName()
{
return m_name;
}
virtual ChannelRequester* getChannelRequester()
{
return m_requester;
}
virtual ConnectionState getConnectionState()
{
return CONNECTED;
}
virtual bool isConnected()
{
return getConnectionState() == CONNECTED;
}
virtual AccessRights getAccessRights(epics::pvData::PVField *pvField)
{
return readWrite;
}
virtual void getField(GetFieldRequester *requester,epics::pvData::String subField)
{
requester->getDone(getStatusCreate()->getStatusOK(),pvStructure->getSubField(subField)->getField());
}
virtual ChannelProcess* createChannelProcess(
ChannelProcessRequester *channelProcessRequester,
epics::pvData::PVStructure *pvRequest)
{
// TODO
return 0;
}
virtual ChannelGet* createChannelGet(
ChannelGetRequester *channelGetRequester,
epics::pvData::PVStructure *pvRequest)
{
// TODO
return 0;
}
virtual ChannelPut* createChannelPut(
ChannelPutRequester *channelPutRequester,
epics::pvData::PVStructure *pvRequest)
{
// TODO
return 0;
}
virtual ChannelPutGet* createChannelPutGet(
ChannelPutGetRequester *channelPutGetRequester,
epics::pvData::PVStructure *pvRequest)
{
// TODO
return 0;
}
virtual ChannelRPC* createChannelRPC(ChannelRPCRequester *channelRPCRequester,
epics::pvData::PVStructure *pvRequest)
{
// TODO
return 0;
}
virtual epics::pvData::Monitor* createMonitor(
epics::pvData::MonitorRequester *monitorRequester,
epics::pvData::PVStructure *pvRequest)
{
// TODO
return 0;
}
virtual ChannelArray* createChannelArray(
ChannelArrayRequester *channelArrayRequester,
epics::pvData::PVStructure *pvRequest)
{
// TODO
return 0;
}
};
class MockChannelProvider;
class MockChannelFind : public ChannelFind
{
public:
MockChannelFind(ChannelProvider* provider) : m_provider(provider)
{
}
virtual void destroy()
{
// one instance for all, do not delete at all
}
virtual ChannelProvider* getChannelProvider()
{
return m_provider;
};
virtual void cancelChannelFind()
{
throw std::runtime_error("not supported");
}
private:
// only to be destroyed by it
friend class MockChannelProvider;
virtual ~MockChannelFind() {}
ChannelProvider* m_provider;
};
class MockChannelProvider : public ChannelProvider {
public:
public:
MockChannelProvider() : m_mockChannelFind(new MockChannelFind(this)) {
}
virtual epics::pvData::String getProviderName()
{
@@ -20,6 +248,7 @@ public:
virtual void destroy()
{
delete m_mockChannelFind;
delete this;
}
@@ -27,9 +256,8 @@ public:
epics::pvData::String channelName,
ChannelFindRequester *channelFindRequester)
{
ChannelFind* channelFind = 0; // TODO
channelFindRequester->channelFindResult(getStatusCreate()->getStatusOK(), channelFind, true);
return channelFind;
channelFindRequester->channelFindResult(getStatusCreate()->getStatusOK(), m_mockChannelFind, true);
return m_mockChannelFind;
}
virtual Channel* createChannel(
@@ -48,15 +276,15 @@ public:
{
if (address == "local")
{
Channel* channel = 0;
Channel* channel = new MockChannel(this, channelRequester, channelName, address);
channelRequester->channelCreated(getStatusCreate()->getStatusOK(), channel);
// TODO state change
return channel;
}
else
{
Status* errorStatus = getStatusCreate()->createStatus(STATUSTYPE_ERROR, "only local supported", 0);
channelRequester->channelCreated(errorStatus, 0);
delete errorStatus; // TODO guard from CB
return 0;
}
}
@@ -64,6 +292,8 @@ public:
private:
~MockChannelProvider() {};
MockChannelFind* m_mockChannelFind;
};
@@ -78,11 +308,11 @@ class MockClientContext : public ClientContext
initialize();
}
virtual const Version* getVersion() {
virtual Version* getVersion() {
return m_version;
}
virtual const ChannelProvider* getProvider() {
virtual ChannelProvider* getProvider() {
return m_provider;
}
@@ -120,12 +350,98 @@ class MockClientContext : public ClientContext
};
class ChannelFindRequesterImpl : public ChannelFindRequester
{
virtual void channelFindResult(epics::pvData::Status *status,ChannelFind *channelFind,bool wasFound)
{
std::cout << "[ChannelFindRequesterImpl] channelFindResult(";
String str;
status->toString(&str);
std::cout << str << ", ..., " << wasFound << ")" << std::endl;
}
};
class ChannelRequesterImpl : public ChannelRequester
{
virtual String getRequesterName()
{
return "ChannelRequesterImpl";
};
virtual void message(String message,MessageType messageType)
{
std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
}
virtual void channelCreated(epics::pvData::Status* status, Channel *channel)
{
std::cout << "channelCreated(";
String str;
status->toString(&str);
std::cout << str << ", " << (channel ? channel->getChannelName() : "(null)") << ")" << std::endl;
}
virtual void channelStateChange(Channel *c, ConnectionState connectionState)
{
std::cout << "channelStateChange(" << c->getChannelName() << ", " << ConnectionStateNames[connectionState] << ")" << std::endl;
}
};
class GetFieldRequesterImpl : public GetFieldRequester
{
virtual String getRequesterName()
{
return "GetFieldRequesterImpl";
};
virtual void message(String message,MessageType messageType)
{
std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
}
virtual void getDone(epics::pvData::Status *status,epics::pvData::FieldConstPtr field)
{
std::cout << "getDone(";
String str;
status->toString(&str);
std::cout << str << ", ";
if (field)
{
str.clear();
field->toString(&str);
std::cout << str;
}
else
std::cout << "(null)";
std::cout << ")" << std::endl;
}
};
int main(int argc,char *argv[])
{
MockClientContext* context = new MockClientContext();
context->printInfo();
ChannelFindRequesterImpl findRequester;
context->getProvider()->channelFind("something", &findRequester);
ChannelRequesterImpl channelRequester;
/*Channel* noChannel =*/ context->getProvider()->createChannel("test", &channelRequester, ChannelProvider::PRIORITY_DEFAULT, "over the rainbow");
Channel* channel = context->getProvider()->createChannel("test", &channelRequester);
std::cout << channel->getChannelName() << std::endl;
GetFieldRequesterImpl getFieldRequesterImpl;
channel->getField(&getFieldRequesterImpl, "timeStamp.secondsPastEpoch");
channel->destroy();
context->destroy();
std::cout << "-----------------------------------------------------------------------" << std::endl;
getShowConstructDestruct()->constuctDestructTotals(stdout);
return(0);
}