INode class. Publisher, Subscriber, ServiceServer, ServiceClient now accept INode in constructor instead of the bunch of independent params. Self NodeID now being configured via setNodeID() method instead of constructor param

This commit is contained in:
Pavel Kirienko
2014-03-14 19:54:27 +04:00
parent 15cbf96378
commit 613efa49b9
22 changed files with 211 additions and 181 deletions
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#pragma once
#include <uavcan/node/scheduler.hpp>
#include <uavcan/node/marshal_buffer.hpp>
namespace uavcan
{
class INode
{
public:
virtual ~INode() { }
virtual IAllocator& getAllocator() = 0;
virtual Scheduler& getScheduler() = 0;
virtual const Scheduler& getScheduler() const = 0;
virtual IMarshalBufferProvider& getMarshalBufferProvider() = 0;
Dispatcher& getDispatcher() { return getScheduler().getDispatcher(); }
const Dispatcher& getDispatcher() const { return getScheduler().getDispatcher(); }
ISystemClock& getSystemClock() { return getScheduler().getSystemClock(); }
MonotonicTime getMonotonicTime() const { return getScheduler().getMonotonicTime(); }
UtcTime getUtcTime() const { return getScheduler().getUtcTime(); }
NodeID getNodeID() const { return getScheduler().getDispatcher().getNodeID(); }
bool setNodeID(NodeID nid)
{
return getScheduler().getDispatcher().setNodeID(nid);
}
int spin(MonotonicTime deadline)
{
return getScheduler().spin(deadline);
}
int spin(MonotonicDuration duration)
{
return getScheduler().spin(getMonotonicTime() + duration);
}
};
}
@@ -4,9 +4,8 @@
#pragma once
#include <uavcan/node/scheduler.hpp>
#include <uavcan/node/abstract_node.hpp>
#include <uavcan/data_type.hpp>
#include <uavcan/node/marshal_buffer.hpp>
#include <uavcan/node/global_data_type_registry.hpp>
#include <uavcan/util/lazy_constructor.hpp>
#include <uavcan/debug.hpp>
@@ -30,8 +29,7 @@ class GenericPublisher
const MonotonicDuration max_transfer_interval_; // TODO: memory usage can be reduced
MonotonicDuration tx_timeout_;
Scheduler& scheduler_;
IMarshalBufferProvider& buffer_provider_;
INode& node_;
LazyConstructor<TransferSender> sender_;
bool checkInit()
@@ -50,15 +48,15 @@ class GenericPublisher
return false;
}
sender_.template construct<Dispatcher&, const DataTypeDescriptor&, CanTxQueue::Qos, MonotonicDuration>
(scheduler_.getDispatcher(), *descr, CanTxQueue::Qos(Qos), max_transfer_interval_);
(node_.getDispatcher(), *descr, CanTxQueue::Qos(Qos), max_transfer_interval_);
return true;
}
MonotonicTime getTxDeadline() const { return scheduler_.getMonotonicTimestamp() + tx_timeout_; }
MonotonicTime getTxDeadline() const { return node_.getMonotonicTime() + tx_timeout_; }
IMarshalBuffer* getBuffer()
{
return buffer_provider_.getBuffer(BitLenToByteLen<DataStruct::MaxBitLen>::Result);
return node_.getMarshalBufferProvider().getBuffer(BitLenToByteLen<DataStruct::MaxBitLen>::Result);
}
int genericPublish(const DataStruct& message, TransferType transfer_type, NodeID dst_node_id,
@@ -94,12 +92,11 @@ class GenericPublisher
}
public:
GenericPublisher(Scheduler& scheduler, IMarshalBufferProvider& buffer_provider, MonotonicDuration tx_timeout,
GenericPublisher(INode& node, MonotonicDuration tx_timeout,
MonotonicDuration max_transfer_interval = TransferSender::getDefaultMaxTransferInterval())
: max_transfer_interval_(max_transfer_interval)
, tx_timeout_(tx_timeout)
, scheduler_(scheduler)
, buffer_provider_(buffer_provider)
, node_(node)
{
setTxTimeout(tx_timeout);
#if UAVCAN_DEBUG
@@ -132,7 +129,7 @@ public:
tx_timeout_ = tx_timeout;
}
Scheduler& getScheduler() const { return scheduler_; }
INode& getNode() const { return node_; }
};
}
@@ -4,7 +4,7 @@
#pragma once
#include <uavcan/node/scheduler.hpp>
#include <uavcan/node/abstract_node.hpp>
#include <uavcan/data_type.hpp>
#include <uavcan/node/global_data_type_registry.hpp>
#include <uavcan/util/compile_time.hpp>
@@ -107,8 +107,7 @@ class GenericSubscriber : Noncopyable
using ReceivedDataStructure<DataStruct>::setTransfer;
};
Scheduler& scheduler_;
IAllocator& allocator_;
INode& node_;
LazyConstructor<TransferForwarder> forwarder_;
ReceivedDataStructureSpec message_;
uint32_t failure_count_;
@@ -128,7 +127,8 @@ class GenericSubscriber : Noncopyable
UAVCAN_TRACE("GenericSubscriber", "Type [%s] is not registered", DataSpec::getDataTypeFullName());
return false;
}
forwarder_.template construct<SelfType&, const DataTypeDescriptor&, IAllocator&>(*this, *descr, allocator_);
forwarder_.template construct<SelfType&, const DataTypeDescriptor&, IAllocator&>
(*this, *descr, node_.getAllocator());
return true;
}
@@ -170,7 +170,7 @@ class GenericSubscriber : Noncopyable
return -1;
}
if (!(scheduler_.getDispatcher().*registration_method)(forwarder_))
if (!(node_.getDispatcher().*registration_method)(forwarder_))
{
UAVCAN_TRACE("GenericSubscriber", "Failed to register transfer listener [%s]",
DataSpec::getDataTypeFullName());
@@ -180,9 +180,8 @@ class GenericSubscriber : Noncopyable
}
protected:
GenericSubscriber(Scheduler& scheduler, IAllocator& allocator)
: scheduler_(scheduler)
, allocator_(allocator)
explicit GenericSubscriber(INode& node)
: node_(node)
, failure_count_(0)
{ }
@@ -209,9 +208,9 @@ protected:
{
if (forwarder_)
{
scheduler_.getDispatcher().unregisterMessageListener(forwarder_);
scheduler_.getDispatcher().unregisterServiceRequestListener(forwarder_);
scheduler_.getDispatcher().unregisterServiceResponseListener(forwarder_);
node_.getDispatcher().unregisterMessageListener(forwarder_);
node_.getDispatcher().unregisterServiceRequestListener(forwarder_);
node_.getDispatcher().unregisterServiceResponseListener(forwarder_);
}
}
@@ -222,7 +221,7 @@ protected:
ReceivedDataStructure<DataStruct>& getReceivedStructStorage() { return message_; }
public:
Scheduler& getScheduler() const { return scheduler_; }
INode& getNode() const { return node_; }
};
}
+4 -5
View File
@@ -17,10 +17,9 @@ class Publisher : protected GenericPublisher<DataType_, DataType_>
public:
typedef DataType_ DataType;
Publisher(Scheduler& scheduler, IMarshalBufferProvider& buffer_provider,
MonotonicDuration tx_timeout = getDefaultTxTimeout(),
MonotonicDuration max_transfer_interval = TransferSender::getDefaultMaxTransferInterval())
: BaseType(scheduler, buffer_provider, tx_timeout, max_transfer_interval)
explicit Publisher(INode& node, MonotonicDuration tx_timeout = getDefaultTxTimeout(),
MonotonicDuration max_transfer_interval = TransferSender::getDefaultMaxTransferInterval())
: BaseType(node, tx_timeout, max_transfer_interval)
{
#if UAVCAN_DEBUG
assert(getTxTimeout() == tx_timeout); // Making sure default values are OK
@@ -49,7 +48,7 @@ public:
using BaseType::getMaxTxTimeout;
using BaseType::getTxTimeout;
using BaseType::setTxTimeout;
using BaseType::getScheduler;
using BaseType::getNode;
};
}
+10 -9
View File
@@ -26,7 +26,7 @@ protected:
virtual ~DeadlineHandler() { stop(); }
public:
virtual void handleDeadline(MonotonicTime current_timestamp) = 0;
virtual void handleDeadline(MonotonicTime current) = 0;
void startWithDeadline(MonotonicTime deadline);
void startWithDelay(MonotonicDuration delay);
@@ -50,7 +50,7 @@ public:
bool doesExist(const DeadlineHandler* mdh) const;
unsigned int getNumHandlers() const { return handlers_.getLength(); }
MonotonicTime pollAndGetMonotonicTimestamp(ISystemClock& sysclock);
MonotonicTime pollAndGetMonotonicTime(ISystemClock& sysclock);
MonotonicTime getEarliestDeadline() const;
};
@@ -75,9 +75,8 @@ class Scheduler : Noncopyable
void pollCleanup(MonotonicTime mono_ts, uint32_t num_frames_processed_with_last_spin);
public:
Scheduler(ICanDriver& can_driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr,
NodeID self_node_id)
: dispatcher_(can_driver, allocator, sysclock, otr, self_node_id)
Scheduler(ICanDriver& can_driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr)
: dispatcher_(can_driver, allocator, sysclock, otr)
, prev_cleanup_ts_(sysclock.getMonotonic())
, deadline_resolution_(MonotonicDuration::fromMSec(DefaultDeadlineResolutionMs))
, cleanup_period_(MonotonicDuration::fromMSec(DefaultCleanupPeriodMs))
@@ -86,11 +85,13 @@ public:
int spin(MonotonicTime deadline);
DeadlineScheduler& getDeadlineScheduler() { return deadline_scheduler_; }
Dispatcher& getDispatcher() { return dispatcher_; }
ISystemClock& getSystemClock() { return dispatcher_.getSystemClock(); }
MonotonicTime getMonotonicTimestamp() const { return dispatcher_.getSystemClock().getMonotonic(); }
UtcTime getUtcTimestamp() const { return dispatcher_.getSystemClock().getUtc(); }
Dispatcher& getDispatcher() { return dispatcher_; }
const Dispatcher& getDispatcher() const { return dispatcher_; }
ISystemClock& getSystemClock() { return dispatcher_.getSystemClock(); }
MonotonicTime getMonotonicTime() const { return dispatcher_.getSystemClock().getMonotonic(); }
UtcTime getUtcTime() const { return dispatcher_.getSystemClock().getUtc(); }
MonotonicDuration getDeadlineResolution() const { return deadline_resolution_; }
void setDeadlineResolution(MonotonicDuration res)
@@ -73,7 +73,6 @@ private:
typedef GenericSubscriber<DataType, ResponseType, TransferListenerType> SubscriberType;
PublisherType publisher_;
IAllocator& allocator_;
Callback callback_;
MonotonicDuration request_timeout_;
bool pending_;
@@ -128,12 +127,10 @@ private:
}
public:
ServiceClient(Scheduler& scheduler, IAllocator& allocator, IMarshalBufferProvider& buffer_provider,
const Callback& callback = Callback())
: SubscriberType(scheduler, allocator)
, DeadlineHandler(scheduler)
, publisher_(scheduler, buffer_provider, getDefaultRequestTimeout())
, allocator_(allocator)
explicit ServiceClient(INode& node, const Callback& callback = Callback())
: SubscriberType(node)
, DeadlineHandler(node.getScheduler())
, publisher_(node, getDefaultRequestTimeout())
, callback_(callback)
, request_timeout_(getDefaultRequestTimeout())
, pending_(false)
@@ -177,8 +174,8 @@ public:
*/
const OutgoingTransferRegistryKey otr_key(descr->getID(), TransferTypeServiceRequest, server_node_id);
const MonotonicTime otr_deadline =
SubscriberType::getScheduler().getMonotonicTimestamp() + TransferSender::getDefaultMaxTransferInterval();
TransferID* const otr_tid = SubscriberType::getScheduler().getDispatcher().getOutgoingTransferRegistry()
SubscriberType::getNode().getMonotonicTime() + TransferSender::getDefaultMaxTransferInterval();
TransferID* const otr_tid = SubscriberType::getNode().getDispatcher().getOutgoingTransferRegistry()
.accessOrCreate(otr_key, otr_deadline);
if (!otr_tid)
{
@@ -57,9 +57,9 @@ private:
}
public:
ServiceServer(Scheduler& scheduler, IAllocator& allocator, IMarshalBufferProvider& buffer_provider)
: SubscriberType(scheduler, allocator)
, publisher_(scheduler, buffer_provider, getDefaultTxTimeout())
explicit ServiceServer(INode& node)
: SubscriberType(node)
, publisher_(node, getDefaultTxTimeout())
, callback_()
, response_failure_count_(0)
{
+2 -2
View File
@@ -36,8 +36,8 @@ class Subscriber : public GenericSubscriber<DataType_, DataType_,
public:
typedef DataType_ DataType;
Subscriber(Scheduler& scheduler, IAllocator& allocator)
: BaseType(scheduler, allocator)
explicit Subscriber(INode& node)
: BaseType(node)
, callback_()
{
StaticAssert<DataTypeKind(DataType::DataTypeKind) == DataTypeKindMessage>::check();
+1 -1
View File
@@ -31,7 +31,7 @@ class Timer : private DeadlineHandler
{
MonotonicDuration period_;
void handleDeadline(MonotonicTime current_timestamp);
void handleDeadline(MonotonicTime current);
public:
using DeadlineHandler::stop;
@@ -51,17 +51,15 @@ class Dispatcher : Noncopyable
ListenerRegister lsrv_req_;
ListenerRegister lsrv_resp_;
const NodeID self_node_id_;
NodeID self_node_id_;
void handleFrame(const CanRxFrame& can_frame);
public:
Dispatcher(ICanDriver& driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr,
NodeID self_node_id)
Dispatcher(ICanDriver& driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr)
: canio_(driver, allocator, sysclock)
, sysclock_(sysclock)
, outgoing_transfer_reg_(otr)
, self_node_id_(self_node_id)
{ }
int spin(MonotonicTime deadline);
@@ -87,7 +85,8 @@ public:
IOutgoingTransferRegistry& getOutgoingTransferRegistry() { return outgoing_transfer_reg_; }
NodeID getSelfNodeID() const { return self_node_id_; }
NodeID getNodeID() const { return self_node_id_; }
bool setNodeID(NodeID nid);
const ISystemClock& getSystemClock() const { return sysclock_; }
ISystemClock& getSystemClock() { return sysclock_; }