Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F5277041
Application.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
7 KB
Referenced Files
None
Subscribers
None
Application.cpp
View Options
//===-- app/Application.cpp -------------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
// Distributed under the terms and conditions of the Boost Software License 1.0.
// See accompanying file LICENSE.
//
// If you did not receive a copy of the license file, see
// http://www.boost.org/LICENSE_1_0.txt.
//
//===----------------------------------------------------------------------===//
///
/// \file app/Application.cpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2020
///
/// \brief Implementation for rosa/app/Application.hpp.
///
//===----------------------------------------------------------------------===//
#define ROSA_LIB_APP_APPLICATION_CPP
// For including helper macros.
#include
"rosa/app/Application.hpp"
#include
<algorithm>
#include
<sstream>
namespace
rosa
{
namespace
app
{
std
::
unique_ptr
<
Application
>
Application
::
create
(
const
std
::
string
&
Name
)
noexcept
{
return
std
::
unique_ptr
<
Application
>
(
new
Application
(
Name
));
}
Application
::
Application
(
const
std
::
string
&
Name
)
noexcept
:
System
(
AppSystem
::
createSystem
(
Name
))
{
LOG_TRACE
(
"Application for '"
+
System
->
name
()
+
"' is created."
);
}
Application
::~
Application
(
void
)
noexcept
{
// \c rosa::app::Application::System is not used outside, just clean it.
for
(
auto
U
:
AppUnits
)
{
System
->
destroyAgent
(
U
);
}
// \note \c System will be marked clean by SystemImpl::~SystemImpl.
LOG_TRACE
(
"Application for '"
+
System
->
name
()
+
"' prepared for destruction."
);
}
Optional
<
const
AppExecutionPolicy
&>
Application
::
getExecutionPolicy
(
AgentHandle
Unit
)
const
noexcept
{
if
(
System
->
isAppSensor
(
Unit
))
{
return
{
System
->
getAppSensor
(
Unit
)
->
executionPolicy
()};
}
else
if
(
System
->
isAppAgent
(
Unit
))
{
return
{
System
->
getAppAgent
(
Unit
)
->
executionPolicy
()};
}
else
{
return
{};
}
}
Application
::
ErrorCode
Application
::
setExecutionPolicy
(
AgentHandle
Unit
,
std
::
unique_ptr
<
AppExecutionPolicy
>
&&
ExecutionPolicy
)
noexcept
{
// Generate trace log.
auto
&
Trace
=
LOG_TRACE_STREAM
;
Trace
<<
"Setting execution policy of "
<<
System
->
unwrapAgent
(
Unit
).
FullName
<<
" to "
;
if
(
ExecutionPolicy
)
{
Trace
<<
"'"
<<
ExecutionPolicy
->
dump
()
<<
"'
\n
"
;
}
else
{
Trace
<<
"[]
\n
"
;
APPRETERROR
(
ErrorCode
::
UnsuitableExecutionPolicy
);
}
if
(
System
->
isAppSensor
(
Unit
))
{
const
bool
Success
=
System
->
getAppSensor
(
Unit
)
->
setExecutionPolicy
(
std
::
move
(
ExecutionPolicy
));
if
(
!
Success
)
{
APPRETERROR
(
ErrorCode
::
UnsuitableExecutionPolicy
);
}
else
{
return
ErrorCode
::
NoError
;
}
}
else
if
(
System
->
isAppAgent
(
Unit
))
{
const
bool
Success
=
System
->
getAppAgent
(
Unit
)
->
setExecutionPolicy
(
std
::
move
(
ExecutionPolicy
));
if
(
!
Success
)
{
APPRETERROR
(
ErrorCode
::
UnsuitableExecutionPolicy
);
}
else
{
return
ErrorCode
::
NoError
;
}
}
else
{
APPRETERROR
(
ErrorCode
::
NotUnit
);
}
}
Application
::
ErrorCode
Application
::
connectSensor
(
AgentHandle
Agent
,
const
size_t
Pos
,
AgentHandle
Sensor
,
const
std
::
string
&
Description
)
noexcept
{
// Generate trace log.
auto
&
Trace
=
LOG_TRACE_STREAM
;
Trace
<<
"Establishing connection"
;
if
(
!
Description
.
empty
())
{
Trace
<<
" '"
<<
Description
<<
"'"
;
}
Trace
<<
" between '"
<<
System
->
unwrapAgent
(
Sensor
).
FullName
<<
"' and '"
<<
System
->
unwrapAgent
(
Agent
).
FullName
<<
"'
\n
"
;
// Make sure preconditions are met.
if
(
!
System
->
isAppAgent
(
Agent
))
{
APPRETERROR
(
ErrorCode
::
NotAgent
);
}
else
if
(
!
System
->
isAppSensor
(
Sensor
))
{
APPRETERROR
(
ErrorCode
::
NotSensor
);
}
auto
A
=
System
->
getAppAgent
(
Agent
);
auto
S
=
System
->
getAppSensor
(
Sensor
);
ASSERT
(
A
&&
S
);
// Sanity check.
if
(
Pos
>=
A
->
NumberOfInputs
)
{
APPRETERROR
(
ErrorCode
::
WrongPosition
);
}
else
if
(
A
->
inputType
(
Pos
)
!=
S
->
OutputType
||
(
!
emptyToken
(
A
->
masterOutputType
(
Pos
))
&&
A
->
masterOutputType
(
Pos
)
!=
S
->
MasterInputType
))
{
APPRETERROR
(
ErrorCode
::
TypeMismatch
);
}
else
if
(
A
->
slave
(
Pos
))
{
APPRETERROR
(
ErrorCode
::
AlreadyHasSlave
);
}
else
if
(
S
->
master
())
{
APPRETERROR
(
ErrorCode
::
AlreadyHasMaster
);
}
// Do register.
A
->
registerSlave
(
Pos
,
{
Sensor
});
S
->
registerMaster
({
Agent
});
return
ErrorCode
::
NoError
;
}
Application
::
ErrorCode
Application
::
connectAgents
(
AgentHandle
Master
,
const
size_t
Pos
,
AgentHandle
Slave
,
const
std
::
string
&
Description
)
noexcept
{
// Generate trace log.
auto
&
Trace
=
LOG_TRACE_STREAM
;
Trace
<<
"Establishing connection"
;
if
(
!
Description
.
empty
())
{
Trace
<<
" '"
<<
Description
<<
"'"
;
}
Trace
<<
" between '"
<<
System
->
unwrapAgent
(
Slave
).
FullName
<<
"' and '"
<<
System
->
unwrapAgent
(
Master
).
FullName
<<
"'
\n
"
;
// Make sure preconditions are met.
if
(
!
(
System
->
isAppAgent
(
Master
)
&&
System
->
isAppAgent
(
Slave
)))
{
APPRETERROR
(
ErrorCode
::
NotAgent
);
}
auto
M
=
System
->
getAppAgent
(
Master
);
auto
S
=
System
->
getAppAgent
(
Slave
);
ASSERT
(
M
&&
S
);
// Sanity check.
if
(
Pos
>=
M
->
NumberOfInputs
)
{
APPRETERROR
(
ErrorCode
::
WrongPosition
);
}
else
if
(
M
->
inputType
(
Pos
)
!=
S
->
OutputType
||
(
!
emptyToken
(
M
->
masterOutputType
(
Pos
))
&&
M
->
masterOutputType
(
Pos
)
!=
S
->
MasterInputType
))
{
APPRETERROR
(
ErrorCode
::
TypeMismatch
);
}
else
if
(
M
->
slave
(
Pos
))
{
APPRETERROR
(
ErrorCode
::
AlreadyHasSlave
);
}
else
if
(
S
->
master
())
{
APPRETERROR
(
ErrorCode
::
AlreadyHasMaster
);
}
// Do register.
M
->
registerSlave
(
Pos
,
{
Slave
});
S
->
registerMaster
({
Master
});
return
ErrorCode
::
NoError
;
}
std
::
weak_ptr
<
MessagingSystem
>
Application
::
getSystem
(
void
)
const
noexcept
{
return
std
::
weak_ptr
<
MessagingSystem
>
(
System
);
}
void
Application
::
initializeSimulation
(
void
)
noexcept
{
LOG_INFO_STREAM
<<
"Initializing simulation for "
<<
System
->
name
()
<<
". Clearing all data sources.
\n
"
;
// Clear simulation data sources from sensors.
for
(
auto
U
:
AppUnits
)
{
if
(
auto
S
=
System
->
getAppSensor
(
U
))
{
S
->
clearSimulationDataSource
();
}
}
}
void
Application
::
simulate
(
const
size_t
NumCycles
)
const
noexcept
{
DEBUG
(
for
(
auto
H
:
AppUnits
)
{
std
::
stringstream
Message
;
Message
<<
System
->
unwrapAgent
(
H
).
FullName
<<
" is an App "
<<
" "
<<
(
System
->
isAppSensor
(
H
)
?
"Sensor"
:
"Agent"
);
if
(
System
->
isAppSensor
(
H
))
Message
<<
" with it's data source "
<<
(
!
System
->
getAppSensor
(
H
)
->
simulationDataSourceIsSet
()
?
"not "
:
"set"
);
Message
<<
'\n'
;
LOG_TRACE_STREAM
<<
Message
.
str
();
});
ASSERT
(
std
::
all_of
(
AppUnits
.
begin
(),
AppUnits
.
end
(),
[
&
](
const
AgentHandle
&
H
)
{
return
System
->
isAppAgent
(
H
)
||
System
->
isAppSensor
(
H
)
&&
System
->
getAppSensor
(
H
)
->
simulationDataSourceIsSet
();
}));
for
(
size_t
I
=
1
;
I
<=
NumCycles
;
++
I
)
{
LOG_TRACE
(
"Simulation cycle: "
+
std
::
to_string
(
I
));
for
(
auto
U
:
AppUnits
)
{
U
.
sendMessage
(
Message
::
create
(
atoms
::
Trigger
::
Value
));
}
}
}
}
// End namespace app
}
// End namespace rosa
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, Apr 12, 4:34 AM (3 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
277664
Default Alt Text
Application.cpp (7 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment