📄 agents.h
字号:
{
_M_pNetwork_link->release();
}
}
/// <summary>
/// Copy construct an iterator
/// </summary>
/**/
_Source_link_iterator(_Myt const& _Right)
{
_M_pNetwork_link = _Right._M_pNetwork_link;
_M_index = _Right._M_index;
_M_array = _Right._M_array;
_M_pNetwork_link->reference();
}
/// <summary>
/// Copy assign an iterator
/// </summary>
/**/
_Myt const& operator=(_Myt const& _Right)
{
_MyContainer * _OldContainer = _M_pNetwork_link;
_ASSERTE(_OldContainer != NULL);
_M_pNetwork_link = _Right._M_pNetwork_link;
_M_index = _Right._M_index;
_M_array = _Right._M_array;
if (_OldContainer != _M_pNetwork_link)
{
_OldContainer->release();
_M_pNetwork_link->reference();
}
return *this;
}
/// <summary>
/// Returns the object pointed to by the iterator
/// </summary>
/// <returns>
/// Reference to the object pointed to by the iterator
/// </returns>
/**/
const_reference operator*()
{
return _Get(0);
}
/// <summary>
/// Returns a pointer to the class object
/// </summary>
/// <returns>
/// Returns a pointer to the class object
/// </returns>
/**/
const_pointer operator->() const
{
return (&**this);
}
/// <summary>
/// Index operation. Retrieve an element at the specified index.
/// </summary>
/**/
const_reference operator[](size_t _Pos) const
{
return _Get(_Pos);
}
/// <summary>
/// Pre-increment the iterator to point to the next element
/// </summary>
/// <returns>
/// Reference to the object pointer to by the iterator after incrementing it
/// </returns>
/**/
_Myt& operator++()
{
++_M_index;
return (*this);
}
/// <summary>
/// Post-increment the iterator to point to the next element
/// </summary>
/// <returns>
/// Reference to the object pointer to by the iterator before incrementing it
/// </returns>
/**/
_Myt operator++(int)
{
_Myt _Tmp = *this;
++*this;
return (_Tmp);
}
private:
// Get the element at the given offset.
const_reference _Get(size_t _Pos) const
{
size_t _Index = _M_index + _Pos;
if (_Index >= _M_array._Size())
{
return _M_sentinel;
}
return _M_array[_Index];
}
// Array to hold the snapshot of the link registry
::Concurrency::details::_Dynamic_array<_EType> _M_array;
// Pointer to the underlying container (network link registry)
_MyContainer * _M_pNetwork_link;
// Current index
size_t _M_index;
// Sentinel value to return on bounds overflow
_EType _M_sentinel;
};
/// <summary>
/// The <c>source_link_manager</c> object manages messaging block network links
/// to <c>ISource</c> blocks.
/// </summary>
/// <typeparam name="_LinkRegistry">
/// The network link registry.
/// </typeparam>
/// <remarks>
/// Currently, the source blocks are reference counted. This is a wrapper on a
/// <c>network_link_registry</c> object that allows concurrent access to the links and
/// provides the ability to reference the links through callbacks. Message
/// blocks (<c>target_block</c>s or <c>propagator_block</c>s) should use this class
/// for their source links.
/// </remarks>
/// <seealso cref="single_link_registry Class"/>
/// <seealso cref="multi_link_registry Class"/>
/**/
template<class _LinkRegistry>
class source_link_manager
{
public:
/// <summary>
/// The type of link registry being managed by the <c>source_link_manager</c> object.
/// </summary>
/**/
typedef _LinkRegistry type;
/// <summary>
/// The type of the blocks being managed by the <c>source_link_manager</c> object.
/// </summary>
/**/
typedef typename _LinkRegistry::type _Block;
/// <summary>
/// The method signature for a callback method for this <c>source_link_manager</c> object.
/// </summary>
/**/
typedef std::tr1::function<void(_Block *, bool)> _Callback_method;
/// <summary>
/// A type that represents a pointer to an element stored in the <c>source_link_manager</c> object.
/// </summary>
/**/
typedef _Block * _EType;
/// <summary>
/// A type that provides a reference to a <c>const</c> element stored in a <c>source_link_manager</c> object
/// for reading and performing const operations.
/// </summary>
/**/
typedef _EType const& const_reference;
/// <summary>
/// A type that provides a pointer to a <c>const</c> element in a <c>source_link_manager</c> object.
/// </summary>
/**/
typedef _EType const* const_pointer;
// Iterator
friend class _Source_link_iterator<_LinkRegistry>;
/// <summary>
/// A type that provides an iterator that can read or modify any element in the
/// <c>source_link_manager</c> object.
/// </summary>
/**/
typedef _Source_link_iterator<_LinkRegistry> iterator;
/// <summary>
/// A type that provides a reentrant lock for the <c>source_link_manager</c> object.
/// </summary>
/**/
typedef ::Concurrency::details::_ReentrantPPLLock _LockType;
/// <summary>
/// A type that provides a RAII scoped lock holder for a lock.
/// </summary>
/**/
typedef _LockType::_Scoped_lock _LockHolder;
/// <summary>
/// Constructs a <c>source_link_manager</c> object.
/// </summary>
/**/
source_link_manager() : _M_iteratorCount(0), _M_pLinkedTarget(NULL)
{
}
/// <summary>
/// Destroys the <c>source_link_manager</c> object.
/// </summary>
/**/
~source_link_manager()
{
_ASSERTE(_M_pendingRemove._Size() == 0);
}
/// <summary>
/// Registers the target block that holds this <c>source_link_manager</c> object.
/// </summary>
/// <param name="_PTarget">
/// The target block holding this <c>source_link_manager</c> object.
/// </param>
/**/
void register_target_block(ITarget<typename _Block::source_type> * _PTarget)
{
_M_pLinkedTarget = _PTarget;
}
/// <summary>
/// Sets the maximum number of source links that can be added to this
/// <c>source_link_manager</c> object.
/// </summary>
/// <param name="_MaxLinks">
/// The maximum number of links.
/// </param>
/**/
void set_bound(size_t _MaxLinks)
{
_M_links.set_bound(_MaxLinks);
}
/// <summary>
/// Adds a source link to the <c>source_link_manager</c> object.
/// </summary>
/// <param name="_Link">
/// A pointer to a block to be added.
/// </param>
/**/
void add(_EType _Link)
{
if (_Link == NULL)
{
return;
}
{
_LockHolder _Lock(_M_lock);
_M_links.add(_Link);
// We need to add the _Link first and then invoke the
// callback since _Add could throw.
// As soon as the above lock is released, remove would
// find the link that was added and could unlink it before
// we are able to invoke the notification below. Keeping an
// active iterator would prevent that from happening.
_M_iteratorCount++;
}
// Acquire a reference on this link by the target
_Link->acquire_ref(_M_pLinkedTarget);
// Release the active iterator
release();
}
/// <summary>
/// Removes a link from the <c>source_link_manager</c> object.
/// </summary>
/// <param name="_Link">
/// A pointer to a block to be removed, if found.
/// </param>
/// <returns>
/// <c>true</c> if the link was found and removed, <c>false</c> otherwise.
/// </returns>
/**/
bool remove(_EType _Link)
{
bool _Removed = false;
_EType _RemovedLink = NULL;
ITarget<typename _Block::source_type> * _LinkedTarget = _M_pLinkedTarget;
if (_Link == NULL)
{
return false;
}
{
_LockHolder _Lock(_M_lock);
_Removed = _M_links.remove(_Link);
if (!_Removed)
{
// No change was made
return _Removed;
}
if (_M_iteratorCount == 0)
{
// Set the removed link to indicate that
// notification callback needs to be invoked.
_RemovedLink = _Link;
}
else
{
// The iterator will complete the pending operation
_M_pendingRemove._Push_back(_Link);
}
}
// NOTE: touching "this" pointer is dangerous as soon as the above lock is released
// Release the reference for this link
if (_RemovedLink != NULL)
{
_RemovedLink->release_ref(_LinkedTarget);
}
return _Removed;
}
/// <summary>
/// Acquires a reference on the <c>source_link_manager</c> object.
/// </summary>
/**/
void reference()
{
_LockHolder _Lock(_M_lock);
_M_iteratorCount++;
}
/// <summary>
/// Releases the reference on the <c>source_link_manager</c> object.
/// </summary>
/**/
void release()
{
ITarget<typename _Block::source_type> * _LinkedTarget = _M_pLinkedTarget;
::Concurrency::details::_Dynamic_array<_EType> _LinksToRemove;
{
_LockHolder _Lock(_M_lock);
_ASSERTE(_M_iteratorCount > 0);
_M_iteratorCount--;
if (_M_iteratorCount == 0)
{
if (_M_pendingRemove._Size() > 0)
{
// Snap the pending remove list with the lock held
_M_pendingRemove._Swap(_LinksToRemove);
}
}
}
// NOTE: touching "this" pointer is dangerous as soon as the above lock is released
// Release the references
size_t _Size = _LinksToRemove._Size();
for (size_t _I=0; _I < _Size; _I++)
{
_LinksToRemove[_I]->release_ref(_LinkedTarget);
}
}
/// <summary>
/// Searches the <c>network_link_registry</c> within this <c>source_link_manager</c>
/// object for a specified block.
/// </summary>
/// <param name="_Link">
/// A pointer to a block that is to be searched for in the <c>source_link_manager</c> object.
/// </param>
/// <returns>
/// <c>true</c> if the specified block was found, <c>false</c> otherwise.
/// </returns>
/**/
bool contains(_EType _Link)
{
_LockHolder _Lock(_M_lock);
return _M_links.contains(_Link);
}
/// <summary>
/// Counts the number of linked blocks in the <c>source_link_manager</c> object.
/// </summary>
/// <returns>
/// The number of linked blocks in the <c>source_link_manager</c> object.
/// </returns>
/**/
size_t count()
{
_LockHolder _Lock(_M_lock);
return _M_links.count();
}
/// <summary>
/// Returns an iterator to the first element in the <c>source_link_manager</c> object.
/// </summary>
/// <remarks>
/// The end state of the iterator is indicated by a <c>NULL</c> link.
/// </remarks>
/// <returns>
/// An iterator addressing the first element in the <c>source_link_manager</c> object.
/// </returns>
/**/
iterator begin()
{
return (iterator(this, 0));
}
private:
// Called by the iterator. This routine takes a snapshot of the links
// in the registry and copies it to the array provided.
void _To_array(::Concurrency::details::_Dynamic_array<_EType>& _Array)
{
_LockHolder _Lock(_M_lock);
_M_iteratorCount++;
for(_LinkRegistry::iterator _Link = _M_links.begin(); *_Link != NULL; _Link++)
{
_Array._Push_back(*_Link);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -