Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F375366
DeluxeSensor.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
8 KB
Referenced Files
None
Subscribers
None
DeluxeSensor.hpp
View Options
//===-- rosa/deluxe/DeluxeSensor.hpp ----------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/deluxe/DeluxeSensor.hpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Specialization of \c rosa::Agent for *sensor* role of the the *deluxe
/// interface*.
///
/// \see \c rosa::deluxe::DeluxeContext
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_DELUXE_DELUXESENSOR_HPP
#define ROSA_DELUXE_DELUXESENSOR_HPP
#include
"rosa/core/Agent.hpp"
#include
"rosa/deluxe/DeluxeAtoms.hpp"
namespace
rosa
{
namespace
deluxe
{
/// Specialization of \c rosa::Agent for *sensor* role of the *deluxe
/// interface*.
///
/// \see \c rosa::deluxe::DeluxeContext
class
DeluxeSensor
:
public
Agent
{
public
:
/// Template alias for function objects used as data source for
/// \c rosa::deluxe::DeluxeSensor.
///
/// \note The function used for \c D is to be \c noexcept.
///
/// \tparam T type of data provided by the function
template
<
typename
T
>
using
D
=
std
::
function
<
T
(
void
)
>
;
/// The type of values produced by \p this object.
///
/// That is the type of values \p this object sends to its *master*.
///
/// \see \c rosa::deluxe::DeluxeSensor::master
const
TypeNumber
OutputType
;
private
:
/// Alias for function objects used as trigger handler for
/// \c rosa::deluxe::DeluxeSensor.
///
/// \note The function used for \c H is to be \c noexcept.
///
/// \see \c DeluxeSensorTriggerHandlers
using
H
=
std
::
function
<
void
(
void
)
>
;
/// \defgroup DeluxeSensorTriggerHandlers Trigger handlers of rosa::deluxe::DeluxeSensor
///
/// \brief Trigger handler functions of \c rosa::deluxe::DeluxeSensor
///
/// The actual data source functions are captured in a lambda expression that
/// is in turn wrapped in a \c std::function object. The lambda expression
/// calls the data source function to obtain the next sensory value and sends
/// it to *master* by calling \c rosa::deluxe::DeluxeSensor::sendToMaster. The
/// function \c rosa::deluxe::DeluxeSensor::handleTrigger needs only to call
/// the proper function object.
/// Handles trigger during normal execution.
///
/// \ingroup DeluxeSensorTriggerHandlers
///
/// The function is used during normal execution. During simulation, the
/// simulation environment sets \c rosa::deluxe::DeluxeSensor::SFP, which is
/// used instead of \c rosa::deluxe::DeluxeSensor::FP.
const
H
FP
;
/// Handles trigger during simulation.
///
/// \ingroup DeluxeSensorTriggerHandlers
///
/// The function is empty by default. The simulation environment sets it to be
/// used during simulation.
H
SFP
;
/// The *master* to send values to.
///
/// \note *Masters* are set dynamically, hence it is possible that a
/// \c rosa::deluxe::DeluxeSensor instance does not have any *master* at a
/// given moment.
Optional
<
AgentHandle
>
Master
;
/// Wraps a data source function into a trigger handler.
///
/// \see \c DeluxeSensorTriggerHandlers
///
/// \tparam T type of data provided by \p F
///
/// \param F function to generate value with
///
/// \pre \p T matches \c rosa::deluxe::DeluxeSensor::OutputType: \code
/// OutputType == TypeNumberOf<T>::Value
/// \endcode
template
<
typename
T
>
H
triggerHandlerFromDataSource
(
D
<
T
>
&&
F
)
noexcept
;
public
:
/// Creates a new instance.
///
/// The constructor instantiates the base-class with functions to handle
/// messages as defined for the *deluxe interface*.
///
/// \todo Enforce F does not potentially throw exception.
///
/// \tparam T type of data to operate on
///
/// \param Kind kind of the new \c rosa::Unit instance
/// \param Id unique identifier of the new \c rosa::Unit instance
/// \param Name name of the new \c rosa::Unit instance
/// \param S \c rosa::MessagingSystem owning the new instance
/// \param F function to generate the next value with during normal operation
///
/// \pre Statically, \p T is a built-in type:\code
/// TypeListContains<BuiltinTypes, T>::Value
/// \endcode
/// Dynamically, the instance is created as of kind
/// \c rosa::deluxe::atoms::SensorKind:
/// \code
/// Kind == rosa::deluxe::atoms::SensorKind
/// \endcode
template
<
typename
T
,
typename
=
std
::
enable_if_t
<
TypeListContains
<
BuiltinTypes
,
T
>::
Value
>>
DeluxeSensor
(
const
AtomValue
Kind
,
const
id_t
Id
,
const
std
::
string
&
Name
,
MessagingSystem
&
S
,
D
<
T
>
&&
F
)
noexcept
;
/// Destroys \p this object.
~
DeluxeSensor
(
void
)
noexcept
;
/// The *master* of \p this object, if any.
///
/// \see \c rosa::deluxe::DeluxeSensor::registerMaster
///
/// \return the *master* registered for \p this object
Optional
<
AgentHandle
>
master
(
void
)
const
noexcept
;
/// Registers a *master* for \p this object.
///
/// The new *master* is registered by overwriting the reference to any
/// already registered *master*. One can clear the registered reference by
/// passing an *empty* \c rosa::Optional object as actual argument.
///
/// \note The role of the referred *master* is validated by checking its
/// *kind*.
///
/// \param _Master the *master* to register
///
/// \pre \p Master is empty or of kind \c rosa::deluxe::atoms::AgentKind:
/// \code
/// !_Master || unwrapAgent(*_Master).Kind == rosa::deluxe::atoms::AgentKind
/// \endcode
void
registerMaster
(
const
Optional
<
AgentHandle
>
_Master
)
noexcept
;
/// Clears the simulation trigger handler of \p this object.
///
/// The function assigns \c rosa::deluxe::DeluxeSensor::SFP with \c nullptr.
void
clearSimulationDataSource
(
void
)
noexcept
;
/// Tells whether a simulation trigger handler is set for \p this object.
///
/// The function returns whether \c rosa::deluxe::DeluxeSensor::SFP is not
/// \c nullptr.
///
/// \return if a simulation trigger handler is set for \p this object.
bool
simulationDataSourceIsSet
(
void
)
const
noexcept
;
/// Registers a simulation data source for \p this object.
///
/// A new simulation trigger handler wrapping \p SF is stored in
/// \c rosa::deluxe::DeluxeSensor::SFP by overwriting any already registered
/// simulation data source.
///
/// \todo Enforce SF does not potentially throw exception.
///
/// \tparam T type of data provided by \p SF
///
/// \param SF function to generate value with
///
/// \pre \p T matches \c rosa::deluxe::DeluxeSensor::OutputType: \code
/// OutputType == TypeNumberOf<T>::Value
/// \endcode
template
<
typename
T
>
void
registerSimulationDataSource
(
D
<
T
>
&&
SF
)
noexcept
;
private
:
/// Sends a value to the *master* of \p this object.
///
/// \p Value is getting sent to \c rosa::deluxe::DeluxeSensor::Master if it
/// contains a valid handle for a \c rosa::deluxe::DeluxeAgent. The function
/// does nothing otherwise.
///
/// \tparam T type of the value to send
///
/// \param Value value to send
///
/// \pre \p T matches \c rosa::deluxe::DeluxeSensor::OutputType: \code
/// OutputType == TypeNumberOf<T>::Value
/// \endcode
template
<
typename
T
>
void
sendToMaster
(
const
T
&
Value
)
noexcept
;
/// Generates the next sensory value upon trigger from the system.
///
/// Executes \c rosa::deluxe::DeluxeSensor::FP or
/// \c rosa::deluxe::DeluxeSensor::SFP if set.
///
/// \note The only argument is a \c rosa::AtomConstant, hence its actual
/// value is ignored.
void
handleTrigger
(
atoms
::
Trigger
)
noexcept
;
};
template
<
typename
T
>
DeluxeSensor
::
H
DeluxeSensor
::
triggerHandlerFromDataSource
(
D
<
T
>
&&
F
)
noexcept
{
ASSERT
(
OutputType
==
TypeNumberOf
<
T
>::
Value
);
return
[
this
,
F
](
void
)
noexcept
{
sendToMaster
(
F
());
};
}
template
<
typename
T
,
typename
>
DeluxeSensor
::
DeluxeSensor
(
const
AtomValue
Kind
,
const
id_t
Id
,
const
std
::
string
&
Name
,
MessagingSystem
&
S
,
D
<
T
>
&&
F
)
noexcept
:
Agent
(
Kind
,
Id
,
Name
,
S
,
THISMEMBER
(
handleTrigger
)),
OutputType
(
TypeNumberOf
<
T
>::
Value
),
FP
(
triggerHandlerFromDataSource
(
std
::
move
(
F
))),
SFP
(
nullptr
)
{
ASSERT
(
Kind
==
atoms
::
SensorKind
);
LOG_TRACE
(
"DeluxeSensor is created."
);
}
template
<
typename
T
>
void
DeluxeSensor
::
registerSimulationDataSource
(
D
<
T
>
&&
SF
)
noexcept
{
ASSERT
(
OutputType
==
TypeNumberOf
<
T
>::
Value
);
SFP
=
triggerHandlerFromDataSource
(
std
::
move
(
SF
));
}
template
<
typename
T
>
void
DeluxeSensor
::
sendToMaster
(
const
T
&
Value
)
noexcept
{
ASSERT
(
OutputType
==
TypeNumberOf
<
T
>::
Value
);
// There is a handle and the referred *master* is in a valid state.
if
(
Master
&&
*
Master
)
{
Master
->
sendMessage
(
Message
::
create
(
atoms
::
Slave
::
Value
,
Id
,
Value
));
}
}
}
// End namespace deluxe
}
// End namespace rosa
#endif
// ROSA_DELUXE_DELUXESENSOR_HPP
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sat, Jun 7, 5:57 PM (5 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
150289
Default Alt Text
DeluxeSensor.hpp (8 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment