Merge with 4060002ace66b81caef7ac32c598c42aa4e5123c
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user