Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F10704986
DeluxeAgent.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
7 KB
Referenced Files
None
Subscribers
None
DeluxeAgent.cpp
View Options
//===-- deluxe/DeluxeAgent.cpp ----------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file deluxe/DeluxeAgent.cpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Implementation of rosa/deluxe/DeluxeAgent.hpp.
///
//===----------------------------------------------------------------------===//
#include
"rosa/deluxe/DeluxeAgent.hpp"
#include
"rosa/deluxe/DeluxeSensor.hpp"
#include
<algorithm>
namespace
rosa
{
namespace
deluxe
{
bool
DeluxeAgent
::
inv
(
void
)
const
noexcept
{
// Check number of inputs and master-outputs.
if
(
NumberOfInputs
!=
NumberOfMasterOutputs
)
{
return
false
;
}
// Check container sizes.
if
(
!
(
InputTypes
.
size
()
==
NumberOfInputs
&&
InputChanged
.
size
()
==
NumberOfInputs
&&
InputValues
->
size
()
==
NumberOfInputs
&&
MasterOutputTypes
.
size
()
==
NumberOfInputs
// == NumberOfMasterOutputs
&&
Slaves
.
size
()
==
NumberOfInputs
))
{
return
false
;
}
// Check *slave* types and validate *slave* registrations and reverse lookup
// information.
std
::
map
<
id_t
,
size_t
>
RefIds
;
// Build up a reference of SlaveIds in this.
for
(
size_t
I
=
0
;
I
<
NumberOfInputs
;
++
I
)
{
// First, validate input types at position \c I.
const
TypeNumber
T
=
InputTypes
[
I
];
// The assert must hold if \p this object was successfuuly constructed.
ASSERT
(
static_cast
<
size_t
>
(
static_cast
<
token_size_t
>
(
I
))
==
I
);
if
(
InputValues
->
typeAt
(
static_cast
<
token_size_t
>
(
I
))
!=
T
)
{
return
false
;
}
// Check the registered *slave* at position \c I.
const
auto
&
Slave
=
Slaves
[
I
];
// If \c Slave is empty, nothing to check.
if
(
!
Slave
)
continue
;
// Prepare master-output related info for the *slave*.
const
TypeNumber
MT
=
MasterOutputTypes
[
I
];
const
bool
hasMT
=
MT
!=
TypeNumberOf
<
unit_t
>::
Value
;
// \c Slave is not empty here.
// Check the `OutputType` and `MasterInputType` of the registered *slave*.
const
auto
&
A
=
unwrapAgent
(
*
Slave
);
if
(
!
((
A
.
Kind
==
atoms
::
SensorKind
&&
static_cast
<
const
DeluxeSensor
&>
(
A
).
OutputType
==
T
&&
(
!
hasMT
||
static_cast
<
const
DeluxeSensor
&>
(
A
).
MasterInputType
==
MT
))
||
(
A
.
Kind
==
atoms
::
AgentKind
&&
static_cast
<
const
DeluxeAgent
&>
(
A
).
OutputType
==
T
&&
(
!
hasMT
||
static_cast
<
const
DeluxeAgent
&>
(
A
).
MasterInputType
==
MT
))))
{
return
false
;
}
// Validate that the *slave* is not registered more than once.
if
(
std
::
any_of
(
Slaves
.
begin
()
+
I
+
1
,
Slaves
.
end
(),
[
&
Slave
](
const
Optional
<
AgentHandle
>
&
O
)
{
return
O
&&
*
Slave
==
*
O
;
}))
{
return
false
;
}
// Build the content of \c RefIds.
RefIds
.
emplace
(
A
.
Id
,
I
);
}
// Validate *slave* reverse lookup information against our reference.
if
(
RefIds
!=
SlaveIds
)
{
return
false
;
}
// All checks were successful, the invariant is held.
return
true
;
}
DeluxeAgent
::~
DeluxeAgent
(
void
)
noexcept
{
ASSERT
(
inv
());
LOG_TRACE
(
"Destroying DeluxeAgent..."
);
// Make sure \p this object is not a registered *slave*.
if
(
Master
)
{
ASSERT
(
unwrapAgent
(
*
Master
).
Kind
==
atoms
::
AgentKind
);
// Sanity check.
DeluxeAgent
&
M
=
static_cast
<
DeluxeAgent
&>
(
unwrapAgent
(
*
Master
));
ASSERT
(
M
.
positionOfSlave
(
self
())
!=
M
.
NumberOfInputs
);
// Sanity check.
M
.
registerSlave
(
M
.
positionOfSlave
(
self
()),
{});
Master
=
{};
}
// Also, make sure \p this object is no acting *master*.
for
(
size_t
Pos
=
0
;
Pos
<
NumberOfInputs
;
++
Pos
)
{
registerSlave
(
Pos
,
{});
}
// Now there is no connection with other entities, safe to destroy.
}
id_t
DeluxeAgent
::
masterId
(
void
)
const
noexcept
{
ASSERT
(
inv
()
&&
Master
);
return
unwrapAgent
(
*
Master
).
Id
;
}
Optional
<
AgentHandle
>
DeluxeAgent
::
master
(
void
)
const
noexcept
{
ASSERT
(
inv
());
return
Master
;
}
void
DeluxeAgent
::
registerMaster
(
const
Optional
<
AgentHandle
>
_Master
)
noexcept
{
ASSERT
(
inv
()
&&
(
!
_Master
||
unwrapAgent
(
*
_Master
).
Kind
==
atoms
::
AgentKind
));
Master
=
_Master
;
ASSERT
(
inv
());
}
TypeNumber
DeluxeAgent
::
inputType
(
const
size_t
Pos
)
const
noexcept
{
ASSERT
(
inv
()
&&
Pos
<
NumberOfInputs
);
return
InputTypes
[
Pos
];
}
TypeNumber
DeluxeAgent
::
masterOutputType
(
const
size_t
Pos
)
const
noexcept
{
ASSERT
(
inv
()
&&
Pos
<
NumberOfMasterOutputs
);
return
MasterOutputTypes
[
Pos
];
}
Optional
<
AgentHandle
>
DeluxeAgent
::
slave
(
const
size_t
Pos
)
const
noexcept
{
ASSERT
(
inv
()
&&
Pos
<
NumberOfInputs
);
return
Slaves
[
Pos
];
}
void
DeluxeAgent
::
registerSlave
(
const
size_t
Pos
,
const
Optional
<
AgentHandle
>
Slave
)
noexcept
{
ASSERT
(
inv
()
&&
Pos
<
NumberOfInputs
&&
(
!
Slave
||
(
unwrapAgent
(
*
Slave
).
Kind
==
atoms
::
SensorKind
&&
static_cast
<
const
DeluxeSensor
&>
(
unwrapAgent
(
*
Slave
)).
OutputType
==
InputTypes
[
Pos
]
&&
(
MasterOutputTypes
[
Pos
]
==
TypeNumberOf
<
unit_t
>::
Value
||
static_cast
<
const
DeluxeSensor
&>
(
unwrapAgent
(
*
Slave
))
.
MasterInputType
==
MasterOutputTypes
[
Pos
]))
||
(
unwrapAgent
(
*
Slave
).
Kind
==
atoms
::
AgentKind
&&
static_cast
<
const
DeluxeAgent
&>
(
unwrapAgent
(
*
Slave
)).
OutputType
==
InputTypes
[
Pos
]
&&
(
MasterOutputTypes
[
Pos
]
==
TypeNumberOf
<
unit_t
>::
Value
||
static_cast
<
const
DeluxeAgent
&>
(
unwrapAgent
(
*
Slave
))
.
MasterInputType
==
MasterOutputTypes
[
Pos
]))));
// If registering an actual *slave*, not just clearing the slot, make sure
// the same *slave* is not registered to another slot.
if
(
Slave
)
{
auto
It
=
SlaveIds
.
find
(
unwrapAgent
(
*
Slave
).
Id
);
if
(
It
!=
SlaveIds
.
end
())
{
Slaves
[
It
->
second
]
=
{};
//Optional<AgentHandle>();
SlaveIds
.
erase
(
It
);
}
}
// Obtain the place whose content is to be replaced with \p Slave
auto
&
OldSlave
=
Slaves
[
Pos
];
// If there is already a *slave* registered at \p Pos, clear reverse lookup
// information for it, and make sure it no longer has \p this object as
// *master*.
if
(
OldSlave
)
{
auto
&
A
=
unwrapAgent
(
*
OldSlave
);
ASSERT
(
SlaveIds
.
find
(
A
.
Id
)
!=
SlaveIds
.
end
());
// Sanity check.
SlaveIds
.
erase
(
A
.
Id
);
if
(
A
.
Kind
==
atoms
::
AgentKind
)
{
static_cast
<
DeluxeAgent
&>
(
A
).
registerMaster
({});
}
else
{
ASSERT
(
A
.
Kind
==
atoms
::
SensorKind
);
// Sanity check.
static_cast
<
DeluxeSensor
&>
(
A
).
registerMaster
({});
}
}
// Register \p Slave at \p Pos.
OldSlave
=
Slave
;
// If registering an actual *slave*, not just clearing the slot, register
// reverse lookup information for the new *slave*.
if
(
Slave
)
{
SlaveIds
.
emplace
(
unwrapAgent
(
*
Slave
).
Id
,
Pos
);
}
ASSERT
(
inv
());
}
size_t
DeluxeAgent
::
positionOfSlave
(
const
AgentHandle
Slave
)
const
noexcept
{
ASSERT
(
inv
());
bool
Found
=
false
;
size_t
Pos
=
0
;
while
(
!
Found
&&
Pos
<
NumberOfInputs
)
{
auto
&
ExistingSlave
=
Slaves
[
Pos
];
if
(
ExistingSlave
&&
*
ExistingSlave
==
Slave
)
{
Found
=
true
;
}
else
{
++
Pos
;
}
}
ASSERT
(
Found
||
Pos
==
NumberOfInputs
);
// Sanity check.
return
Pos
;
}
void
DeluxeAgent
::
handleTrigger
(
atoms
::
Trigger
)
noexcept
{
ASSERT
(
inv
());
FP
();
ASSERT
(
inv
());
}
}
// End namespace deluxe
}
// End namespace rosa
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, May 31, 4:36 PM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
321358
Default Alt Text
DeluxeAgent.cpp (7 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment