Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F1494128
DeluxeAgent.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
5 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 container sizes.
if
(
!
(
InputTypes
.
size
()
==
NumberOfInputs
&&
InputChanged
.
size
()
==
NumberOfInputs
&&
InputValues
->
size
()
==
NumberOfInputs
&&
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
];
if
(
InputValues
->
typeAt
(
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
;
// \c Slave is not empty here.
// Check the `OutputType` of the registered *slave*.
const
auto
&
A
=
unwrapAgent
(
*
Slave
);
if
(
!
((
A
.
Kind
==
atoms
::
SensorKind
&&
static_cast
<
const
DeluxeSensor
&>
(
A
).
OutputType
==
T
)
||
(
A
.
Kind
==
atoms
::
AgentKind
&&
static_cast
<
const
DeluxeAgent
&>
(
A
).
OutputType
==
T
)))
{
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.
}
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
];
}
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
])
||
(
unwrapAgent
(
*
Slave
).
Kind
==
atoms
::
AgentKind
&&
static_cast
<
const
DeluxeAgent
&>
(
unwrapAgent
(
*
Slave
)).
OutputType
==
InputTypes
[
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, Mar 1, 6:32 PM (1 d, 22 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
281818
Default Alt Text
DeluxeAgent.cpp (5 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment