diff --git a/daisi/src/cpps/common/CMakeLists.txt b/daisi/src/cpps/common/CMakeLists.txt
index 15b2ad59..60c14425 100644
--- a/daisi/src/cpps/common/CMakeLists.txt
+++ b/daisi/src/cpps/common/CMakeLists.txt
@@ -1,21 +1,39 @@
add_subdirectory(scenariofile)
-add_library(daisi_cpps_common_cpps_application STATIC)
-target_sources(daisi_cpps_common_cpps_application
+add_library(daisi_cpps_common_material_flow_logical_agent_application STATIC)
+target_sources(daisi_cpps_common_material_flow_logical_agent_application
PRIVATE
- cpps_application.cpp
- cpps_application.h
+ material_flow_logical_agent_application.h
+ material_flow_logical_agent_application.cpp
)
-target_link_libraries(daisi_cpps_common_cpps_application
+target_link_libraries(daisi_cpps_common_material_flow_logical_agent_application
PUBLIC
- ns3::libapplications
- ns3::libnetwork
- daisi_cpps_amr_physical_amr_physical_asset
- daisi_cpps_logical_amr_amr_logical_agent
- daisi_cpps_common_cpps_logger_ns3
- daisi_cpps_logical_material_flow_material_flow_logical_agent
+ ns3::libapplications
+ daisi_cpps_logical_material_flow_material_flow_logical_agent
+)
+
+add_library(daisi_cpps_common_amr_logical_agent_application STATIC)
+target_sources(daisi_cpps_common_amr_logical_agent_application
+ PRIVATE
+ amr_logical_agent_application.h
+ amr_logical_agent_application.cpp
+)
+target_link_libraries(daisi_cpps_common_amr_logical_agent_application
+ PUBLIC
+ ns3::libapplications
+ daisi_cpps_logical_amr_amr_logical_agent
+)
+
+add_library(daisi_cpps_common_amr_physical_asset_application STATIC)
+target_sources(daisi_cpps_common_amr_physical_asset_application
PRIVATE
- daisi_socket_manager
+ amr_physical_asset_application.h
+ amr_physical_asset_application.cpp
+)
+target_link_libraries(daisi_cpps_common_amr_physical_asset_application
+ PUBLIC
+ ns3::libapplications
+ daisi_cpps_amr_physical_amr_physical_asset
)
add_library(daisi_cpps_common_cpps_logger_ns3 STATIC)
@@ -59,7 +77,9 @@ target_link_libraries(daisi_cpps_common_cpps_manager
daisi_cpps_amr_physical_amr_physical_asset
daisi_cpps_amr_model_amr_static_ability
daisi_cpps_logical_amr_amr_logical_agent
- daisi_cpps_common_cpps_application
+ daisi_cpps_common_material_flow_logical_agent_application
+ daisi_cpps_common_amr_logical_agent_application
+ daisi_cpps_common_amr_physical_asset_application
daisi_cpps_logical_material_flow_material_flow_logical_agent
daisi_manager_sola_helper
ns3::libcore
diff --git a/daisi/src/cpps/common/amr_logical_agent_application.cpp b/daisi/src/cpps/common/amr_logical_agent_application.cpp
new file mode 100644
index 00000000..4b9934f2
--- /dev/null
+++ b/daisi/src/cpps/common/amr_logical_agent_application.cpp
@@ -0,0 +1,26 @@
+// Copyright 2023 The SOLA authors
+//
+// This file is part of DAISI.
+//
+// DAISI is free software: you can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation; version 2.
+//
+// DAISI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with DAISI. If not, see
+// .
+//
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "amr_logical_agent_application.h"
+
+namespace daisi::cpps {
+ns3::TypeId AmrLogicalAgentApplication::GetTypeId() {
+ static ns3::TypeId tid = ns3::TypeId("AmrLogicalAgentApplication")
+ .SetParent()
+ .AddConstructor();
+ return tid;
+}
+} // namespace daisi::cpps
diff --git a/daisi/src/cpps/common/amr_logical_agent_application.h b/daisi/src/cpps/common/amr_logical_agent_application.h
new file mode 100644
index 00000000..25e9796b
--- /dev/null
+++ b/daisi/src/cpps/common/amr_logical_agent_application.h
@@ -0,0 +1,36 @@
+// Copyright 2023 The SOLA authors
+//
+// This file is part of DAISI.
+//
+// DAISI is free software: you can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation; version 2.
+//
+// DAISI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with DAISI. If not, see
+// .
+//
+// SPDX-License-Identifier: GPL-2.0-only
+
+#ifndef DAISI_CPPS_COMMON_AMR_LOGICAL_AGENT_APPLICATION_H_
+#define DAISI_CPPS_COMMON_AMR_LOGICAL_AGENT_APPLICATION_H_
+
+#include
+
+#include "cpps/logical/amr/amr_logical_agent.h"
+#include "ns3/application.h"
+
+namespace daisi::cpps {
+
+/// Wrapper to run an AMR Logical Agent as a ns3::Application
+struct AmrLogicalAgentApplication final : public ns3::Application {
+ static ns3::TypeId GetTypeId();
+
+ std::unique_ptr application;
+};
+
+} // namespace daisi::cpps
+
+#endif
diff --git a/daisi/src/cpps/common/amr_physical_asset_application.cpp b/daisi/src/cpps/common/amr_physical_asset_application.cpp
new file mode 100644
index 00000000..fa86514c
--- /dev/null
+++ b/daisi/src/cpps/common/amr_physical_asset_application.cpp
@@ -0,0 +1,26 @@
+// Copyright 2023 The SOLA authors
+//
+// This file is part of DAISI.
+//
+// DAISI is free software: you can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation; version 2.
+//
+// DAISI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with DAISI. If not, see
+// .
+//
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "amr_physical_asset_application.h"
+
+namespace daisi::cpps {
+ns3::TypeId AmrPhysicalAssetApplication::GetTypeId() {
+ static ns3::TypeId tid = ns3::TypeId("AmrPhysicalAssetApplication")
+ .SetParent()
+ .AddConstructor();
+ return tid;
+}
+} // namespace daisi::cpps
diff --git a/daisi/src/cpps/common/amr_physical_asset_application.h b/daisi/src/cpps/common/amr_physical_asset_application.h
new file mode 100644
index 00000000..6a6fc5c6
--- /dev/null
+++ b/daisi/src/cpps/common/amr_physical_asset_application.h
@@ -0,0 +1,36 @@
+// Copyright 2023 The SOLA authors
+//
+// This file is part of DAISI.
+//
+// DAISI is free software: you can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation; version 2.
+//
+// DAISI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with DAISI. If not, see
+// .
+//
+// SPDX-License-Identifier: GPL-2.0-only
+
+#ifndef DAISI_CPPS_COMMON_AMR_PHYSICAL_ASSET_APPLICATION_H_
+#define DAISI_CPPS_COMMON_AMR_PHYSICAL_ASSET_APPLICATION_H_
+
+#include
+
+#include "cpps/amr/physical/amr_physical_asset.h"
+#include "ns3/application.h"
+
+namespace daisi::cpps {
+
+/// Wrapper to run an AMR Physical Asset as a ns3::Application
+struct AmrPhysicalAssetApplication final : public ns3::Application {
+ static ns3::TypeId GetTypeId();
+
+ std::unique_ptr application;
+};
+
+} // namespace daisi::cpps
+
+#endif
diff --git a/daisi/src/cpps/common/cpps_application.cpp b/daisi/src/cpps/common/cpps_application.cpp
deleted file mode 100644
index 23d327a5..00000000
--- a/daisi/src/cpps/common/cpps_application.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2023 The SOLA authors
-//
-// This file is part of DAISI.
-//
-// DAISI is free software: you can redistribute it and/or modify it under the terms of the GNU
-// General Public License as published by the Free Software Foundation; version 2.
-//
-// DAISI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
-// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-// Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with DAISI. If not, see
-// .
-//
-// SPDX-License-Identifier: GPL-2.0-only
-
-#include "cpps/common/cpps_application.h"
-
-#include "../src/logging/logger.h" // WORKAROUND: private header
-#include "utils/socket_manager.h"
-
-using namespace ns3;
-
-namespace daisi::cpps {
-ns3::TypeId CppsApplication::GetTypeId() {
- static TypeId tid =
- TypeId("CppsApplication").SetParent().AddConstructor();
- return tid;
-}
-
-void CppsApplication::cleanup() {
- application = std::monostate{};
- SocketManager::get().unregisterNode(GetNode());
-}
-
-void CppsApplication::init() {
- if (auto amr_logical_agent =
- std::get_if>(&application)) {
- (*amr_logical_agent)->init();
- } else if (auto mf_logical_agent =
- std::get_if>(&application)) {
- (*mf_logical_agent)->init();
- } else if (auto amr_physical_asset =
- std::get_if>(&application)) {
- (*amr_physical_asset)->init();
- }
-}
-
-void CppsApplication::start() {
- if (auto amr_logical_agent =
- std::get_if>(&application)) {
- (*amr_logical_agent)->start();
- } else if (auto mf_logical_agent =
- std::get_if>(&application)) {
- (*mf_logical_agent)->start();
- }
-}
-
-} // namespace daisi::cpps
diff --git a/daisi/src/cpps/common/cpps_application.h b/daisi/src/cpps/common/cpps_application.h
deleted file mode 100644
index 06d4dd2f..00000000
--- a/daisi/src/cpps/common/cpps_application.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2023 The SOLA authors
-//
-// This file is part of DAISI.
-//
-// DAISI is free software: you can redistribute it and/or modify it under the terms of the GNU
-// General Public License as published by the Free Software Foundation; version 2.
-//
-// DAISI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
-// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-// Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with DAISI. If not, see
-// .
-//
-// SPDX-License-Identifier: GPL-2.0-only
-
-#ifndef SOLA_NS3_CPPS_APPLICATION_H_
-#define SOLA_NS3_CPPS_APPLICATION_H_
-
-#include
-
-#include "cpps/amr/physical/amr_physical_asset.h"
-#include "cpps/common/cpps_logger_ns3.h"
-#include "cpps/logical/amr/amr_logical_agent.h"
-#include "cpps/logical/material_flow/material_flow_logical_agent.h"
-#include "logging/logger_manager.h"
-#include "minhton/logging/logger.h"
-#include "minhton/logging/logger_interface.h"
-#include "natter-ns3/natter_logger_ns3.h"
-#include "natter/logger_interface.h"
-#include "ns3/applications-module.h"
-#include "ns3/network-module.h"
-
-namespace daisi::cpps {
-
-struct CppsApplication final : public ns3::Application {
- static ns3::TypeId GetTypeId();
-
- void init();
- void start();
- void cleanup();
-
- std::shared_ptr logger;
- std::variant,
- std::shared_ptr,
- std::shared_ptr>
- application;
-};
-} // namespace daisi::cpps
-#endif
diff --git a/daisi/src/cpps/common/cpps_manager.cpp b/daisi/src/cpps/common/cpps_manager.cpp
index 84c8f71e..c3814477 100644
--- a/daisi/src/cpps/common/cpps_manager.cpp
+++ b/daisi/src/cpps/common/cpps_manager.cpp
@@ -27,7 +27,9 @@
#include "cpps/amr/model/amr_static_ability.h"
#include "cpps/amr/physical/amr_mobility_model_ns3.h"
#include "cpps/amr/physical/amr_physical_asset.h"
-#include "cpps/common/cpps_application.h"
+#include "cpps/common/amr_logical_agent_application.h"
+#include "cpps/common/amr_physical_asset_application.h"
+#include "cpps/common/material_flow_logical_agent_application.h"
#include "cpps/logical/amr/amr_logical_agent.h"
#include "cpps/logical/material_flow/material_flow_logical_agent.h"
#include "logging/logger_manager.h"
@@ -84,11 +86,15 @@ void CppsManager::spawnAMR(uint32_t amr_index, const AmrDescription &description
throw std::runtime_error("mobility model not empty");
}
- this->amrs_.Get(amr_index)->GetApplication(1)->GetObject()->application =
- std::make_shared(std::move(connector));
- this->amrs_.Get(amr_index)->GetApplication(0)->GetObject()->application =
- std::make_shared(
- scenario_.algorithm.getParticipantAlgorithmConfig(), amr_index == 0);
+ this->amrs_.Get(amr_index)
+ ->GetApplication(1)
+ ->GetObject()
+ ->application = std::make_unique(std::move(connector));
+ this->amrs_.Get(amr_index)
+ ->GetApplication(0)
+ ->GetObject()
+ ->application = std::make_unique(
+ scenario_.algorithm.getParticipantAlgorithmConfig(), amr_index == 0);
}
void CppsManager::setupImpl() {
@@ -126,8 +132,10 @@ uint64_t CppsManager::getNumberOfNodes() const {
}
void CppsManager::checkStarted(uint32_t index) {
- auto cpps_app_logical = std::get>(
- this->amrs_.Get(index)->GetApplication(0)->GetObject()->application);
+ const auto &cpps_app_logical = this->amrs_.Get(index)
+ ->GetApplication(0)
+ ->GetObject()
+ ->application;
if (!cpps_app_logical->isRunning()) {
throw std::runtime_error("storage instance not started yet");
}
@@ -136,61 +144,64 @@ void CppsManager::checkStarted(uint32_t index) {
void CppsManager::initAMR(uint32_t index) {
std::cout << "Init AMR " << index << std::endl;
- auto cpps_app_logical = this->amrs_.Get(index)->GetApplication(0)->GetObject();
- auto cpps_app_physical = this->amrs_.Get(index)->GetApplication(1)->GetObject();
-
- cpps_app_logical->init();
- cpps_app_physical->init();
+ amrs_.Get(index)->GetApplication(0)->GetObject()->application->init();
+ amrs_.Get(index)
+ ->GetApplication(1)
+ ->GetObject()
+ ->application->init();
}
void CppsManager::connectAMR(uint32_t index) {
std::cout << "Connect AMR " << index << std::endl;
// Get address from logical
- auto logical_agent = std::get>(
- this->amrs_.Get(index)->GetApplication(0)->GetObject()->application);
+ const auto &logical_agent =
+ amrs_.Get(index)->GetApplication(0)->GetObject()->application;
const ns3::InetSocketAddress logical_addr = logical_agent->getServerAddress();
// Let physical connect to logical
- auto cpps_app_physical = this->amrs_.Get(index)->GetApplication(1)->GetObject();
- auto amr_physical_asset =
- std::get>(cpps_app_physical->application);
- amr_physical_asset->connect(logical_addr);
+ amrs_.Get(index)
+ ->GetApplication(1)
+ ->GetObject()
+ ->application->connect(logical_addr);
}
void CppsManager::startAMR(uint32_t index) {
std::cout << "Start AMR " << index << std::endl;
- auto cpps_app_logical = this->amrs_.Get(index)->GetApplication(0)->GetObject();
- auto cpps_app_physical = this->amrs_.Get(index)->GetApplication(1)->GetObject();
-
- cpps_app_logical->start();
- cpps_app_physical->start();
+ amrs_.Get(index)
+ ->GetApplication(0)
+ ->GetObject()
+ ->application->start();
}
void CppsManager::initMF(uint32_t index) {
std::cout << "Creating MF Logical Agent " << index << std::endl;
- this->material_flows_.Get(index)->GetApplication(0)->GetObject()->application =
- std::make_shared(
- scenario_.algorithm.getInitiatorAlgorithmConfig(), false);
+ material_flows_.Get(index)
+ ->GetApplication(0)
+ ->GetObject()
+ ->application = std::make_unique(
+ scenario_.algorithm.getInitiatorAlgorithmConfig(), false);
std::cout << "Init MF Logical Agent " << index << std::endl;
- this->material_flows_.Get(index)->GetApplication(0)->GetObject()->init();
- auto mf_app = std::get>(
- this->material_flows_.Get(index)
- ->GetApplication(0)
- ->GetObject()
- ->application);
+ const auto &mf_app = material_flows_.Get(index)
+ ->GetApplication(0)
+ ->GetObject()
+ ->application;
+ mf_app->init();
mf_app->setWaitingForStart();
}
void CppsManager::startMF(uint32_t index) {
std::cout << "Start MF Logical Agent " << index << std::endl;
- this->material_flows_.Get(index)->GetApplication(0)->GetObject()->start();
+ material_flows_.Get(index)
+ ->GetApplication(0)
+ ->GetObject()
+ ->application->start();
}
void CppsManager::setupNodes() {
@@ -205,17 +216,15 @@ void CppsManager::setupNodes() {
// Setup Applications
for (int i = 0; i < amrs_.GetN(); i++) {
- // For logical AMR
- installApplication(amrs_.Get(i));
+ installApplication(amrs_.Get(i));
amrs_.Get(i)->GetApplication(0)->SetStartTime(ns3::MilliSeconds(0));
- // For physical AMR
- installApplication(amrs_.Get(i));
+ installApplication(amrs_.Get(i));
amrs_.Get(i)->GetApplication(1)->SetStartTime(ns3::MilliSeconds(0));
}
for (int i = 0; i < material_flows_.GetN(); i++) {
- installApplication(material_flows_.Get(i));
+ installApplication(material_flows_.Get(i));
material_flows_.Get(i)->GetApplication(0)->SetStartTime(ns3::MilliSeconds(0));
}
@@ -232,35 +241,36 @@ void CppsManager::setupNodes() {
}
void CppsManager::executeMaterialFlow(int index, const std::string & /*friendly_name*/) {
- auto cpps_app = this->material_flows_.Get(index)->GetApplication(0)->GetObject();
- auto mf_app = std::get>(cpps_app->application);
-
// TODO MaterialFlowDescriptionScenario info = material_flow_descriptions_[friendly_name];
-
- mf_app->addMaterialFlow("todo");
+ material_flows_.Get(index)
+ ->GetApplication(0)
+ ->GetObject()
+ ->application->addMaterialFlow("todo");
}
void CppsManager::clearFinishedMaterialFlows() {
bool found_running_matrial_flow_app = false;
for (uint32_t i = 0; i < material_flows_.GetN(); i++) {
- auto cpps_app = this->material_flows_.Get(i)->GetApplication(0)->GetObject();
- if (std::holds_alternative>(
- cpps_app->application)) {
- auto to_app =
- std::get>(cpps_app->application);
- if (to_app) {
- if (scenario_.do_material_flow_agents_leave_after_finish && to_app->canStop()) {
- found_running_matrial_flow_app = true;
- cpps_app->cleanup();
-
- } else if (to_app->isFinished()) {
- number_material_flows_finished_++;
- found_running_matrial_flow_app = true;
-
- if (scenario_.do_material_flow_agents_leave_after_finish) {
- to_app->prepareStop();
- }
+ const auto &mf_app = material_flows_.Get(i)
+ ->GetApplication(0)
+ ->GetObject()
+ ->application;
+
+ if (mf_app) {
+ if (scenario_.do_material_flow_agents_leave_after_finish && mf_app->canStop()) {
+ found_running_matrial_flow_app = true;
+ material_flows_.Get(i)
+ ->GetApplication(0)
+ ->GetObject()
+ ->application.reset();
+
+ } else if (mf_app->isFinished()) {
+ number_material_flows_finished_++;
+ found_running_matrial_flow_app = true;
+
+ if (scenario_.do_material_flow_agents_leave_after_finish) {
+ mf_app->prepareStop();
}
}
}
@@ -284,21 +294,19 @@ void CppsManager::scheduleMaterialFlow(const SpawnInfoScenario &info) {
uint32_t i = 0;
bool init_application = true;
for (; i < material_flows_.GetN(); i++) {
- auto cpps_app = this->material_flows_.Get(i)->GetApplication(0)->GetObject();
+ const auto &mf_app = this->material_flows_.Get(i)
+ ->GetApplication(0)
+ ->GetObject()
+ ->application;
- if (std::holds_alternative(cpps_app->application)) {
+ if (!mf_app) {
init_application = true;
break;
}
- if (std::holds_alternative>(
- cpps_app->application)) {
- auto mf_app =
- std::get>(cpps_app->application);
- if (!mf_app->isBusy()) {
- init_application = false;
- break;
- }
+ if (!mf_app->isBusy()) {
+ init_application = false;
+ break;
}
if (i + 1 == material_flows_.GetN())
diff --git a/daisi/src/cpps/common/material_flow_logical_agent_application.cpp b/daisi/src/cpps/common/material_flow_logical_agent_application.cpp
new file mode 100644
index 00000000..a61468bd
--- /dev/null
+++ b/daisi/src/cpps/common/material_flow_logical_agent_application.cpp
@@ -0,0 +1,26 @@
+// Copyright 2023 The SOLA authors
+//
+// This file is part of DAISI.
+//
+// DAISI is free software: you can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation; version 2.
+//
+// DAISI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with DAISI. If not, see
+// .
+//
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "material_flow_logical_agent_application.h"
+
+namespace daisi::cpps {
+ns3::TypeId MaterialFlowLogicalAgentApplication::GetTypeId() {
+ static ns3::TypeId tid = ns3::TypeId("MaterialFlowLogicalAgentApplication")
+ .SetParent()
+ .AddConstructor();
+ return tid;
+}
+} // namespace daisi::cpps
diff --git a/daisi/src/cpps/common/material_flow_logical_agent_application.h b/daisi/src/cpps/common/material_flow_logical_agent_application.h
new file mode 100644
index 00000000..be5d1aeb
--- /dev/null
+++ b/daisi/src/cpps/common/material_flow_logical_agent_application.h
@@ -0,0 +1,36 @@
+// Copyright 2023 The SOLA authors
+//
+// This file is part of DAISI.
+//
+// DAISI is free software: you can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation; version 2.
+//
+// DAISI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with DAISI. If not, see
+// .
+//
+// SPDX-License-Identifier: GPL-2.0-only
+
+#ifndef DAISI_CPPS_COMMON_MATERIAL_FLOW_LOGICAL_AGENT_APPLICATION_H_
+#define DAISI_CPPS_COMMON_MATERIAL_FLOW_LOGICAL_AGENT_APPLICATION_H_
+
+#include
+
+#include "cpps/logical/material_flow/material_flow_logical_agent.h"
+#include "ns3/application.h"
+
+namespace daisi::cpps {
+
+/// Wrapper to run a Material Flow Logical Agent as a ns3::Application
+struct MaterialFlowLogicalAgentApplication final : public ns3::Application {
+ static ns3::TypeId GetTypeId();
+
+ std::unique_ptr application;
+};
+
+} // namespace daisi::cpps
+
+#endif