fpmas 1.5
spatial_model.h
Go to the documentation of this file.
1#ifndef FPMAS_ENVIRONMENT_H
2#define FPMAS_ENVIRONMENT_H
3
8#include "dist_move_algo.h"
10#include "../serializer.h"
11#include <type_traits>
12
13
27#define FPMAS_MOBILITY_RANGE(RANGE)\
28 const decltype(RANGE)& mobilityRange() const override {return RANGE;}
29
44#define FPMAS_PERCEPTION_RANGE(RANGE)\
45 const decltype(RANGE)& perceptionRange() const override {return RANGE;}
46
47namespace fpmas { namespace model {
49 using api::model::DistributedId;
50
54 static const api::model::GroupId CELL_GROUP_ID = -1;
55
60 static const bool EXCLUDE_LOCATION = false;
65 static const bool INCLUDE_LOCATION = true;
66
70 template<typename CellType>
72 public api::model::MoveAgentGroup<CellType>,
74 private:
77
78 public:
93 api::model::GroupId group_id,
97 AgentGroupBase(group_id, model.graph(), behavior),
98 model(model),
99 dist_move_algo(model, *this, model.getGroup(CELL_GROUP_ID), end_condition) {
100 }
101
119 api::scheduler::JobList jobs() const override;
120
122 return dist_move_algo;
123 }
124 };
125
126 template<typename CellType>
129 job_list.push_back(this->agentExecutionJob());
130
131 for(auto job : dist_move_algo.jobs())
132 job_list.push_back(job);
133 return job_list;
134 }
135
136 namespace detail {
142 private:
143 api::model::Agent* _agent;
144 fpmas::graph::LayerId layer_id;
145 std::vector<DistributedId> current_layer_ids;
146
147 public:
156 : _agent(agent), layer_id(layer_id) {
157 auto edges = agent->node()->getOutgoingEdges(layer_id);
158 current_layer_ids.resize(edges.size());
159
160 for(std::size_t i = 0; i < edges.size(); i++)
161 current_layer_ids[i] = edges[i]->getTargetNode()->getId();
162 }
163
173 return std::find(
174 current_layer_ids.begin(),
175 current_layer_ids.end(),
176 agent->node()->getId()
177 ) != current_layer_ids.end();
178 }
179
189 void link(fpmas::api::model::Agent* other_agent) {
190 current_layer_ids.push_back(other_agent->node()->getId());
191 _agent->model()->link(_agent, other_agent, layer_id);
192 }
193 };
194 }
195
214 template<typename CellInterface, typename CellType, typename TypeIdBase = CellType>
215 class CellBase : public detail::AgentBase<CellInterface, CellType, TypeIdBase> {
216 private:
217 /*
218 * Some profiling analysis show that the successors() method calls,
219 * have a significant performance cost.
220 * The purpose of the following structures is to drastically reduce
221 * the call to the successors() method, buffering the result only
222 * when required.
223 * This is safe, since the Cell network can't be modified during
224 * the DistributedMoveAlgorithm execution.
225 * The buffer is safely used by init(), handleNewLocation(),
226 * handleMove() and handlePerceive(), but is not safe for a generic
227 * use since new CELL_SUCCESSOR edges might be deleted or created
228 * at any time, out of the DistributedMoveAlgorithm context.
229 */
230 std::vector<CellType*> successors_buffer;
231 std::vector<api::model::AgentEdge*> raw_successors_buffer;
232 const std::vector<CellType*>& bufferedSuccessors();
233
234
235 void updateLocation(
236 api::model::Agent* agent, api::model::AgentEdge* new_location_edge
237 );
238
239 void growMobilityField(api::model::Agent* agent);
240 void growPerceptionField(api::model::Agent* agent);
241
242 protected:
249 std::set<DistributedId> no_move_flags;
257 std::set<DistributedId> move_flags;
265 std::set<DistributedId> perception_flags;
266
267 public:
271 CellBase() = default;
272
287 CellBase(const CellBase&) = default;
288
303 CellBase& operator=(const CellBase&) = default;
304
319 CellBase(CellBase&&) = default;
320
333 return *this;
334 }
335
341 std::vector<api::model::Cell*> successors() override;
347 void handleNewLocation() override;
348
354 void handleMove() override;
355
361 void handlePerceive() override;
362
369
375 void init() override;
376
377
378 };
379
380 template<typename CellInterface, typename CellType, typename TypeIdBase>
382 return this->successors_buffer;
383 }
384
385 template<typename CellInterface, typename CellType, typename TypeIdBase>
387 bool init_successors;
388
389 // This has no performance impact
390 auto current_successors
391 = this->node()->getOutgoingEdges(SpatialModelLayers::CELL_SUCCESSOR);
392 // Checks if the currently buffered successors are stricly equal to the
393 // current_successors. In this case, there is no need to update the
394 // successors() list
395 if(current_successors.size() == 0 ||
396 current_successors.size() != raw_successors_buffer.size()) {
397 init_successors = false;
398 } else {
399 auto it = current_successors.begin();
400 auto raw_it = raw_successors_buffer.begin();
401 while(it != current_successors.end() && (*it) == *raw_it) {
402 it++;
403 raw_it++;
404 }
405 if(it == current_successors.end()) {
406 init_successors = true;
407 } else {
408 init_successors = false;
409 }
410 }
411
412 if(!init_successors) {
413 raw_successors_buffer = current_successors;
414 successors_buffer.resize(raw_successors_buffer.size());
415 for(std::size_t i = 0; i < raw_successors_buffer.size(); i++)
416 successors_buffer[i] = static_cast<CellType*>(
417 raw_successors_buffer[i]->getTargetNode()->data().get()
418 );
419 }
420
421 std::set<DistributedId> new_location_layer;
422 for(auto agent_edge
423 : this->node()->getIncomingEdges(SpatialModelLayers::NEW_LOCATION))
424 new_location_layer.insert(agent_edge->getSourceNode()->getId());
425
426 // The location of agents that are still linked on the MOVE /
427 // PERCEIVE layer has not been updated, since those layers are
428 // unlinked by SpatialAgent::updateLocation(), unless the current
429 // cell is actually their NEW_LOCATION.
430 for(auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::MOVE)) {
431 if(new_location_layer.count(agent_edge->getSourceNode()->getId())==0)
432 this->no_move_flags.insert(agent_edge->getSourceNode()->getId());
433 }
434 for(auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::PERCEIVE)) {
435 if(new_location_layer.count(agent_edge->getSourceNode()->getId())==0)
436 this->no_move_flags.insert(agent_edge->getSourceNode()->getId());
437 }
438 // All agents already linked on the LOCATION layer didn't update
439 // their location, since LOCATION links are unlinked by
440 // SpatialAgent::updateLocation().
441 for(auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::LOCATION)) {
442 this->no_move_flags.insert(agent_edge->getSourceNode()->getId());
443 }
444 }
445
446 template<typename CellInterface, typename CellType, typename TypeIdBase>
448 if(agent->node()->state() == api::graph::LOCAL) {
449 // There is no need to create a temporary NEW_MOVE
450 // link, since the mobilityRange() of the agent is
451 // directly available on the current process.
452 auto* spatial_agent
453 = static_cast<api::model::SpatialAgent<CellType>*>(agent);
454
455 // Valid, since the agent is LOCAL
456 auto location = spatial_agent->locationCell();
457
458 fpmas::model::ReadGuard read_location(location);
459
460 // Cells currently in the move_layer
461 detail::CurrentOutLayer move_layer(agent, SpatialModelLayers::MOVE);
462 for(auto cell : this->bufferedSuccessors()) {
463 if(!move_layer.contains(cell)) {
464 // The cell as not already been linked in the
465 // MOVE layer
466 fpmas::model::ReadGuard read_cell(cell);
467
468 if(spatial_agent->mobilityRange().contains(
469 location,
470 cell
471 )) {
472 // The cell is contained in the agent
473 // mobility range: add it to its mobility
474 // field
475 move_layer.link(cell);
476 }
477 }
478 }
479 } else {
480 // In this case, the mobility range of the agent is not
481 // available on the current process, so a temporary
482 // NEW_MOVE edge must be created and handled later by
483 // the agent in the SpatialAgent::handleNewMove()
484 // method
485 for(auto cell : this->bufferedSuccessors())
486 this->model()->link(
487 agent,
488 cell,
489 SpatialModelLayers::NEW_MOVE
490 );
491 }
492 }
493
494 template<typename CellInterface, typename CellType, typename TypeIdBase>
496 std::vector<api::model::Cell*> neighbors;
497 for(auto edge : this->node()->getOutgoingEdges(SpatialModelLayers::CELL_SUCCESSOR)) {
498 // Assumes that agents on the CELL_SUCCESSOR layer are necessarily
499 // api::model::Cell, so there is no runtime check on the actuel
500 // Agent type (prevents a dynamic_cast)
501 neighbors.push_back(static_cast<api::model::Cell*>(edge->getTargetNode()->data().get()));
502 }
503 return neighbors;
504 }
505
510 template<typename CellInterface, typename CellType, typename TypeIdBase>
512 api::model::Agent* agent,
513 api::model::AgentEdge* new_location_edge
514 ) {
515 FPMAS_LOGD(this->model()->graph().getMpiCommunicator().getRank(), "[CELL]",
516 "%s Setting this Cell as %s location.",
517 FPMAS_C_STR(this->node()->getId()),
518 FPMAS_C_STR(agent->node()->getId()));
519 if(new_location_edge->state() == api::graph::LOCAL) {
520 agent->model()->graph().switchLayer(
521 new_location_edge, SpatialModelLayers::LOCATION
522 );
523 } else {
524 this->model()->link(agent, this, SpatialModelLayers::LOCATION);
525 this->model()->unlink(new_location_edge);
526 }
527 }
528
529 template<typename CellInterface, typename CellType, typename TypeIdBase>
531 FPMAS_LOGD(this->model()->graph().getMpiCommunicator().getRank(), "[CELL]",
532 "%s Updating ranges...",
533 FPMAS_C_STR(this->node()->getId()));
534
535 for(auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::NEW_LOCATION)) {
536 AgentPtr& agent = agent_edge->getSourceNode()->data();
537 updateLocation(agent, agent_edge);
538 growMobilityField(agent);
539 growPerceptionField(agent);
540
541 // If this node is to be linked in the MOVE or PERCEPTION
542 // field, this has already been done by
543 // LocatedAgent::moveToCell(), so this current location does
544 // not need to be explored for this agent.
545 move_flags.insert(agent->node()->getId());
546 perception_flags.insert(agent->node()->getId());
547 }
548 }
549
550 template<typename CellInterface, typename CellType, typename TypeIdBase>
552 for(auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::MOVE)) {
553 auto agent = agent_edge->getSourceNode();
554 if(
555 // The agent updated its location since the last
556 // DistributedMoveAlgorithm execution
557 no_move_flags.count(agent->getId()) == 0 &&
558 // The current cell was not explored yet
559 move_flags.count(agent->getId()) == 0) {
560 growMobilityField(agent->data());
561 move_flags.insert(agent->getId());
562 }
563 }
564 }
565
566 template<typename CellInterface, typename CellType, typename TypeIdBase>
568 for(auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::PERCEIVE)) {
569 auto agent = agent_edge->getSourceNode();
570 if(
571 // The agent updated its location since the last
572 // DistributedMoveAlgorithm execution
573 no_move_flags.count(agent->getId()) == 0 &&
574 // The current cell was not explored yet
575 perception_flags.count(agent->getId()) == 0) {
576 growPerceptionField(agent->data());
577 perception_flags.insert(agent->getId());
578 }
579 }
580 }
581
582 template<typename CellInterface, typename CellType, typename TypeIdBase>
584 FPMAS_LOGD(this->model()->graph().getMpiCommunicator().getRank(), "[CELL]",
585 "%s Updating perceptions...",
586 FPMAS_C_STR(this->node()->getId()));
587
588 move_flags.clear();
589 perception_flags.clear();
590 std::vector<api::model::AgentEdge*> perceived_agent_edges =
591 this->node()->getIncomingEdges(SpatialModelLayers::LOCATION);
592 for(auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::PERCEIVE)) {
593 auto agent = agent_edge->getSourceNode();
594 for(auto perceived_agent_edge : perceived_agent_edges) {
595 auto perceived_agent = perceived_agent_edge->getSourceNode();
596 // Perceptions need to be updated only if either the perceivee
597 // or the perceiver location has been updated since the last
598 // DistributedMoveAlgorithm execution
599 if(
600 this->no_move_flags.count(agent->getId()) == 0 ||
601 this->no_move_flags.count(perceived_agent->getId()) == 0
602 )
603 if(perceived_agent->getId() != agent->getId())
604 this->model()->graph().link(
605 agent, perceived_agent,
606 SpatialModelLayers::PERCEPTION
607 );
608 }
609 }
610 no_move_flags.clear();
611 }
612
613 template<typename CellInterface, typename CellType, typename TypeIdBase>
615 // Exactly the same process as growMobilityField().
616 if(agent->node()->state() == api::graph::LOCAL) {
617 auto* spatial_agent
618 = static_cast<api::model::SpatialAgent<CellType>*>(agent);
619
620 auto location = spatial_agent->locationCell();
621 fpmas::model::ReadGuard read_location(location);
622
623 detail::CurrentOutLayer perceive_layer(agent, SpatialModelLayers::PERCEIVE);
624 for(auto cell : this->bufferedSuccessors()) {
625 if(!perceive_layer.contains(cell)) {
626 fpmas::model::ReadGuard read_cell(cell);
627 if(spatial_agent->perceptionRange().contains(
628 location,
629 cell
630 )) {
631 perceive_layer.link(cell);
632 }
633 }
634 }
635 } else {
636 for(auto cell : this->bufferedSuccessors())
637 this->model()->link(
638 agent,
639 cell,
640 SpatialModelLayers::NEW_PERCEIVE
641 );
642 }
643 }
644
656 template<typename CellType, typename TypeIdBase = CellType>
658
668 template<
669 template<typename> class SyncMode,
670 typename CellType = api::model::Cell,
671 typename EndCondition = DynamicEndCondition<CellType>>
673 public virtual api::model::SpatialModel<CellType>,
674 public Model<SyncMode> {
675 private:
676 AgentGroup& cell_group {this->buildGroup(CELL_GROUP_ID)};
677 EndCondition dist_move_algo_end_condition;
678
679 public:
681
685 void add(CellType* cell) override;
686 std::vector<CellType*> cells() override;
690 const api::model::Behavior& behavior) override;
691 };
692
693 template<template<typename> class SyncMode, typename CellType, typename EndCondition>
695 cell_group.add(cell);
696 }
697
698 template<template<typename> class SyncMode, typename CellType, typename EndCondition>
700 std::vector<CellType*> cells;
701 for(auto agent : cell_group.localAgents())
702 cells.push_back(static_cast<CellType*>(agent));
703 return cells;
704 }
705
706 template<template<typename> class SyncMode, typename CellType, typename EndCondition>
708 return cell_group;
709 }
710
711 template<template<typename> class SyncMode, typename CellType, typename EndCondition>
713 api::model::GroupId id, const api::model::Behavior& behavior) {
714 auto* group = new MoveAgentGroup<CellType>(
715 id, behavior, *this, dist_move_algo_end_condition);
716 this->insert(id, group);
717 return *group;
718 }
719
744 template<typename SpatialAgentInterface, typename AgentType, typename CellType, typename Derived = AgentType>
746 public detail::AgentBase<
747 SpatialAgentInterface, // Interface implemented by this base
748 AgentType, // Final agent type
749 SpatialAgentBase<SpatialAgentInterface, AgentType, CellType, Derived> // Serialization base
750 > {
751 friend nlohmann::adl_serializer<
755
756 public:
784
785 private:
786 mutable CellType* location_cell_buffer = nullptr;
787 DistributedId location_id;
788
789 protected:
803 void updateLocation(CellType* cell);
804
808 void handleNewMove() override;
812 void handleNewPerceive() override;
813
814 // Imports other moveTo overloads
815 using SpatialAgentInterface::moveTo;
819 void moveTo(DistributedId id) override;
820
828 return this->template outNeighbors<CellType>(SpatialModelLayers::MOVE);
829 }
830
840 template<typename NeighborType = api::model::Agent>
842 return this->template outNeighbors<NeighborType>(SpatialModelLayers::PERCEPTION);
843 }
844
845 public:
849 void initLocation(CellType* cell) override {
850 this->moveTo(cell);
851 }
852
856 DistributedId locationId() const override {
857 return location_id;
858 }
859
863 CellType* locationCell() const override;
864 };
865
866 template<typename SpatialAgentInterface, typename AgentType, typename CellType, typename Derived>
868 // Links to new location
869 this->model()->link(this, cell, SpatialModelLayers::NEW_LOCATION);
870
871 // Unlinks obsolete location
872 auto location = this->node()->getOutgoingEdges(SpatialModelLayers::LOCATION);
873 if(location.size() > 0)
874 this->model()->unlink(location[0]);
875
876 // Unlinks obsolete mobility field
877 for(auto cell_edge :
878 this->node()->getOutgoingEdges(SpatialModelLayers::MOVE)) {
879 this->model()->unlink(cell_edge);
880 }
881
882 // Unlinks obsolete perception field
883 for(auto cell_edge
884 : this->node()->getOutgoingEdges(SpatialModelLayers::PERCEIVE))
885 this->model()->unlink(cell_edge);
886
887 // Unlinks obsolete perceptions
888 for(auto perception
889 : this->node()->getOutgoingEdges(fpmas::api::model::PERCEPTION))
890 this->model()->unlink(perception);
891
892
893 {
894 // The cell must be read before checking mobility ranges, to
895 // ensure cell data are available (e.g. cell->location())
896 fpmas::model::ReadGuard read(cell);
897
898 // Adds the NEW_LOCATION to the mobility/perceptions fields
899 // depending on the current ranges
900 if(this->mobilityRange().contains(cell, cell))
901 this->model()->link(this, cell, SpatialModelLayers::MOVE);
902 if(this->perceptionRange().contains(cell, cell))
903 this->model()->link(this, cell, SpatialModelLayers::PERCEIVE);
904 }
905
906 this->location_id = cell->node()->getId();
907 this->location_cell_buffer = cell;
908 }
909
910 template<typename SpatialAgentInterface, typename AgentType, typename CellType, typename Derived>
912 if(location_cell_buffer != nullptr) {
913 return location_cell_buffer;
914 } else {
915 auto edges = this->node()->getOutgoingEdges(SpatialModelLayers::LOCATION);
916 if(!edges.empty())
917 location_cell_buffer = static_cast<CellType*>(
918 edges[0]->getTargetNode()->data().get()
919 );
920 else
921 location_cell_buffer = nullptr;
922 }
923
924 return location_cell_buffer;
925 }
926
927 template<typename SpatialAgentInterface, typename AgentType, typename CellType, typename Derived>
929
930 detail::CurrentOutLayer move_layer(this, SpatialModelLayers::MOVE);
931
932 auto location = this->locationCell();
933 fpmas::model::ReadGuard read_location(location);
934 for(auto cell_edge : this->node()->getOutgoingEdges(SpatialModelLayers::NEW_MOVE)) {
935 auto* agent = cell_edge->getTargetNode()->data().get();
936 fpmas::model::ReadGuard read_cell(agent);
937 if(!move_layer.contains(agent)
938 && this->mobilityRange().contains(location, static_cast<CellType*>(agent)))
939 move_layer.link(agent);
940 this->model()->unlink(cell_edge);
941 }
942 }
943
944 template<typename SpatialAgentInterface, typename AgentType, typename CellType, typename Derived>
946 detail::CurrentOutLayer perceive_layer(this, SpatialModelLayers::PERCEIVE);
947
948 auto location = this->locationCell();
949 fpmas::model::ReadGuard read_location(location);
950 for(auto cell_edge : this->node()->getOutgoingEdges(SpatialModelLayers::NEW_PERCEIVE)) {
951 auto* agent = cell_edge->getTargetNode()->data().get();
952 fpmas::model::ReadGuard read_cell(agent);
953 if(!perceive_layer.contains(agent)
954 && this->perceptionRange().contains(location, static_cast<CellType*>(agent)))
955 perceive_layer.link(agent);
956 this->model()->unlink(cell_edge);
957 }
958 }
959
960 template<typename SpatialAgentInterface, typename AgentType, typename CellType, typename Derived>
962 bool found = false;
963 auto mobility_field = this->template outNeighbors<CellType>(SpatialModelLayers::MOVE);
964 auto it = mobility_field.begin();
965 while(!found && it != mobility_field.end()) {
966 if((*it)->node()->getId() == cell_id) {
967 found=true;
968 } else {
969 it++;
970 }
971 }
972 if(found)
973 this->moveTo(*it);
974 else
975 throw api::model::OutOfMobilityFieldException(this->node()->getId(), cell_id);
976 }
977
978
988 template<typename AgentType, typename CellType = api::model::Cell, typename Derived = AgentType>
990 public SpatialAgentBase<api::model::SpatialAgent<CellType>, AgentType, CellType, Derived> {
991 protected:
992 using SpatialAgentBase<api::model::SpatialAgent<CellType>, AgentType, CellType, Derived>::moveTo;
993 using SpatialAgentBase<api::model::SpatialAgent<CellType>, AgentType, CellType, Derived>::SpatialAgentBase;
994
998 void moveTo(CellType* cell) override {
999 this->updateLocation(cell);
1000 }
1001 };
1002
1008 template<typename CellType>
1009 struct VoidRange : public api::model::Range<CellType> {
1013 bool contains(CellType*, CellType*) const override {
1014 return false;
1015 }
1016
1020 std::size_t radius(CellType*) const override {
1021 return 0;
1022 }
1023 };
1024
1031 template<typename CellType>
1032 struct LocationRange : public api::model::Range<CellType> {
1036 bool contains(CellType* location, CellType* cell) const override {
1037 return location->node()->getId() == cell->node()->getId();
1038 }
1039
1043 std::size_t radius(CellType*) const override {
1044 return 0;
1045 }
1046 };
1047
1052 template<typename AgentType>
1053 class DefaultSpatialAgentFactory : public api::model::SpatialAgentFactory<typename AgentType::Cell> {
1054 public:
1061 AgentType* build() override {
1062 return new AgentType;
1063 }
1064 };
1065
1080 template<typename CellType, typename MappingCellType>
1081 class SpatialAgentBuilderBase : public api::model::SpatialAgentBuilder<CellType, MappingCellType> {
1082 public:
1088
1089 protected:
1095 api::model::GroupList groups,
1098 );
1099
1100
1107 api::model::GroupList groups,
1108 std::function<api::model::SpatialAgent<CellType>*()> factory,
1110 );
1111 };
1112
1113 template<typename CellType, typename MappingCellType>
1116 api::model::GroupList groups,
1119 ) {
1120 build_agents(model, groups, [&factory] () {return factory.build();}, agent_mapping);
1121 }
1122
1123 template<typename CellType, typename MappingCellType>
1126 api::model::GroupList groups,
1127 std::function<api::model::SpatialAgent<CellType>*()> factory,
1129 ) {
1132 = model.buildMoveGroup(TEMP_GROUP_ID, _);
1133 std::vector<api::model::SpatialAgent<CellType>*> agents;
1134 for(auto cell : model.cells()) {
1135 for(std::size_t i = 0; i < agent_mapping.countAt(cell); i++) {
1136 auto agent = factory();
1137 agents.push_back(agent);
1138 temp_group.add(agent);
1139 for(api::model::AgentGroup& group : groups)
1140 group.add(agent);
1141 agent->initLocation(cell);
1142 }
1143 }
1144
1145 model.runtime().execute(
1146 temp_group.distributedMoveAlgorithm().jobs()
1147 );
1148 model.removeGroup(temp_group);
1149 }
1150
1158 template<typename CellType, typename MappingCellType = api::model::Cell>
1159 class SpatialAgentBuilder : public SpatialAgentBuilderBase<CellType, MappingCellType> {
1160 public:
1164 void build(
1166 api::model::GroupList groups,
1169 ) override {
1170 this->build_agents(model, groups, factory, agent_mapping);
1171 }
1172
1176 void build(
1178 api::model::GroupList groups,
1179 std::function<api::model::SpatialAgent<CellType>*()> factory,
1181 ) override {
1182 this->build_agents(model, groups, factory, agent_mapping);
1183 }
1184 };
1185}}
1186
1187namespace nlohmann {
1191 template<typename SpatialAgentInterface, typename AgentType, typename CellType, typename Derived>
1192 struct adl_serializer<fpmas::api::utils::PtrWrapper<fpmas::model::SpatialAgentBase<SpatialAgentInterface, AgentType, CellType, Derived>>> {
1212 static void to_json(nlohmann::json& j, const Ptr& ptr) {
1213 // Derived serialization
1215 const_cast<Derived*>(static_cast<const Derived*>(ptr.get())));
1216 j[1] = ptr->location_id;
1217 }
1218
1237 static Ptr from_json(const nlohmann::json& j) {
1238 // Derived unserialization.
1239 // The current base is implicitly default initialized
1242
1243 derived_ptr->location_id = j[1].get<fpmas::api::graph::DistributedId>();
1244 return derived_ptr.get();
1245 }
1246 };
1247}
1248
1249namespace fpmas { namespace io { namespace json {
1261 template<typename SpatialAgentInterface, typename AgentType, typename CellType, typename Derived>
1262 struct light_serializer<PtrWrapper<fpmas::model::SpatialAgentBase<SpatialAgentInterface, AgentType, CellType, Derived>>> {
1267
1280 static void to_json(light_json& j, const Ptr& agent) {
1281 // Derived serialization
1283 j,
1284 const_cast<Derived*>(static_cast<const Derived*>(agent.get()))
1285 );
1286 }
1287
1300 static Ptr from_json(const light_json& j) {
1301 // Derived unserialization.
1302 // The current base is implicitly default initialized
1303 PtrWrapper<Derived> derived_ptr
1305 return derived_ptr.get();
1306 }
1307 };
1308
1309}}}
1310
1311namespace fpmas { namespace io { namespace datapack {
1330 template<typename SpatialAgentInterface, typename AgentType, typename CellType, typename Derived>
1331 struct Serializer<PtrWrapper<fpmas::model::SpatialAgentBase<SpatialAgentInterface, AgentType, CellType, Derived>>> {
1336
1341 static std::size_t size(const ObjectPack& p, const Ptr& ptr) {
1343 const_cast<Derived*>(static_cast<const Derived*>(ptr.get())));
1344 return p.size(derived) + p.size<DistributedId>();
1345 }
1346
1354 static void to_datapack(ObjectPack& pack, const Ptr& ptr) {
1355 // Derived serialization
1357 const_cast<Derived*>(static_cast<const Derived*>(ptr.get())));
1358 pack.put(derived);
1359 pack.put(ptr->locationId());
1360 }
1361
1379 static Ptr from_datapack(const ObjectPack& pack) {
1380 // Derived unserialization.
1381 // The current base is implicitly default initialized
1382 PtrWrapper<Derived> derived_ptr = pack
1384
1385 derived_ptr->location_id = pack.get<fpmas::api::graph::DistributedId>();
1386 return derived_ptr.get();
1387 }
1388 };
1389
1410 template<typename SpatialAgentInterface, typename AgentType, typename CellType, typename Derived>
1411 struct LightSerializer<PtrWrapper<fpmas::model::SpatialAgentBase<SpatialAgentInterface, AgentType, CellType, Derived>>> {
1416
1421 static std::size_t size(const LightObjectPack& p, const Ptr& ptr) {
1422 return p.size(PtrWrapper<Derived>(
1423 const_cast<Derived*>(
1424 static_cast<const Derived*>(ptr.get())
1425 )
1426 ));
1427 }
1428
1441 static void to_datapack(LightObjectPack& o, const Ptr& agent) {
1442 // Derived serialization
1444 o,
1445 const_cast<Derived*>(static_cast<const Derived*>(agent.get()))
1446 );
1447 }
1448
1462 // Derived unserialization.
1463 // The current base is implicitly default initialized
1464 PtrWrapper<Derived> derived_ptr
1466 return derived_ptr.get();
1467 }
1468 };
1469}}}
1470#endif
Definition: distributed_edge.h:91
virtual LocationState state() const =0
virtual void switchLayer(DistributedEdge< T > *edge, LayerId layer_id)=0
Definition: distributed_id.h:89
virtual LocationState state() const =0
virtual IdType getId() const =0
virtual const std::vector< EdgeType * > getOutgoingEdges() const =0
Definition: model.h:547
virtual void add(Agent *agent)=0
Definition: model.h:92
Definition: model.h:174
virtual Model * model()=0
virtual AgentNode * node()=0
Definition: model.h:520
Definition: spatial_model.h:90
Definition: spatial_model.h:425
Definition: spatial_model.h:376
virtual void removeGroup(AgentGroup &group)=0
virtual api::runtime::Runtime & runtime()=0
virtual AgentEdge * link(Agent *src_agent, Agent *tgt_agent, api::graph::LayerId layer)=0
virtual AgentGroup & buildGroup(GroupId id)=0
Definition: spatial_model.h:455
virtual DistributedMoveAlgorithm< CellType > & distributedMoveAlgorithm()=0
Definition: spatial_model.h:121
Definition: spatial_model.h:675
Definition: spatial_model.h:597
virtual SpatialAgent< CellType > * build()=0
Definition: spatial_model.h:646
virtual std::size_t countAt(CellType *cell)=0
Definition: spatial_model.h:234
virtual CellType * locationCell() const =0
Definition: spatial_model.h:479
virtual std::vector< CellType * > cells()=0
virtual MoveAgentGroup< CellType > & buildMoveGroup(GroupId id, const Behavior &behavior)=0
virtual void execute(const scheduler::Job &job)=0
Definition: ptr_wrapper.h:21
T * get()
Definition: ptr_wrapper.h:58
Definition: datapack.h:275
std::size_t size() const
Definition: datapack.h:341
void put(const T &item)
Definition: datapack.h:421
T get() const
Definition: datapack.h:433
Definition: spatial_model.h:215
void init() override
Definition: spatial_model.h:386
CellBase & operator=(const CellBase &)=default
std::set< DistributedId > move_flags
Definition: spatial_model.h:257
void handleNewLocation() override
Definition: spatial_model.h:530
void updatePerceptions(api::model::AgentGroup &group) override
Definition: spatial_model.h:583
CellBase(CellBase &&)=default
void handleMove() override
Definition: spatial_model.h:551
CellBase< CellInterface, CellType, TypeIdBase > & operator=(CellBase< CellInterface, CellType, TypeIdBase > &&)
Definition: spatial_model.h:331
CellBase(const CellBase &)=default
std::vector< api::model::Cell * > successors() override
Definition: spatial_model.h:495
std::set< DistributedId > perception_flags
Definition: spatial_model.h:265
void handlePerceive() override
Definition: spatial_model.h:567
std::set< DistributedId > no_move_flags
Definition: spatial_model.h:249
Definition: model.h:30
Definition: spatial_model.h:1053
AgentType * build() override
Definition: spatial_model.h:1061
Definition: dist_move_algo.h:145
Definition: dist_move_algo.h:99
Definition: spatial_model.h:73
MoveAgentGroup(api::model::GroupId group_id, const api::model::Behavior &behavior, api::model::SpatialModel< CellType > &model, api::model::EndCondition< CellType > &end_condition)
Definition: spatial_model.h:92
api::model::DistributedMoveAlgorithm< CellType > & distributedMoveAlgorithm() override
Definition: spatial_model.h:121
api::scheduler::JobList jobs() const override
Definition: spatial_model.h:127
Definition: model.h:225
Definition: guards.h:19
Definition: spatial_model.h:750
Neighbors< CellType > mobilityField() const
Definition: spatial_model.h:827
CellType * locationCell() const override
Definition: spatial_model.h:911
void handleNewMove() override
Definition: spatial_model.h:928
void handleNewPerceive() override
Definition: spatial_model.h:945
DistributedId locationId() const override
Definition: spatial_model.h:856
void moveTo(DistributedId id) override
Definition: spatial_model.h:961
void initLocation(CellType *cell) override
Definition: spatial_model.h:849
SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > JsonBase
Definition: spatial_model.h:783
Neighbors< NeighborType > perceptions() const
Definition: spatial_model.h:841
void updateLocation(CellType *cell)
Definition: spatial_model.h:867
Definition: spatial_model.h:1081
void build_agents(api::model::SpatialModel< CellType > &model, api::model::GroupList groups, api::model::SpatialAgentFactory< CellType > &factory, api::model::SpatialAgentMapping< MappingCellType > &agent_mapping)
Definition: spatial_model.h:1114
static const api::model::GroupId TEMP_GROUP_ID
Definition: spatial_model.h:1087
void build_agents(api::model::SpatialModel< CellType > &model, api::model::GroupList groups, std::function< api::model::SpatialAgent< CellType > *()> factory, api::model::SpatialAgentMapping< MappingCellType > &agent_mapping)
Definition: spatial_model.h:1124
Definition: spatial_model.h:1159
void build(api::model::SpatialModel< CellType > &model, api::model::GroupList groups, std::function< api::model::SpatialAgent< CellType > *()> factory, api::model::SpatialAgentMapping< MappingCellType > &agent_mapping) override
Definition: spatial_model.h:1176
void build(api::model::SpatialModel< CellType > &model, api::model::GroupList groups, api::model::SpatialAgentFactory< CellType > &factory, api::model::SpatialAgentMapping< MappingCellType > &agent_mapping) override
Definition: spatial_model.h:1164
Definition: spatial_model.h:990
void moveTo(CellType *cell) override
Definition: spatial_model.h:998
Definition: spatial_model.h:674
fpmas::api::model::AgentGroup & cellGroup() override
Definition: spatial_model.h:707
void add(CellType *cell) override
Definition: spatial_model.h:694
MoveAgentGroup< CellType > & buildMoveGroup(api::model::GroupId id, const api::model::Behavior &behavior) override
Definition: spatial_model.h:712
std::vector< CellType * > cells() override
Definition: spatial_model.h:699
Definition: model.h:702
api::model::AgentGroup * group() override
Definition: model.h:831
AgentGroupBase(GroupId group_id, api::model::AgentGraph &agent_graph)
Definition: model.cpp:142
const api::model::Behavior & behavior() override
Definition: model.h:400
Definition: spatial_model.h:141
CurrentOutLayer(api::model::Agent *agent, fpmas::graph::LayerId layer_id)
Definition: spatial_model.h:155
bool contains(fpmas::api::model::Agent *agent)
Definition: spatial_model.h:172
void link(fpmas::api::model::Agent *other_agent)
Definition: spatial_model.h:189
Definition: model.h:638
api::model::AgentGraph & graph() override
Definition: model.h:487
#define FPMAS_C_STR(arg)
Definition: macros.h:24
@ LOCAL
Definition: location_state.h:21
int LayerId
Definition: edge.h:13
int GroupId
Definition: model.h:78
SpatialModelLayers
Definition: spatial_model.h:17
std::vector< std::reference_wrapper< AgentGroup > > GroupList
Definition: model.h:833
std::vector< std::reference_wrapper< const Job > > JobList
Definition: scheduler.h:215
nlohmann::basic_json< std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, light_serializer > light_json
Definition: json.h:14
CellBase< api::model::Cell, CellType, TypeIdBase > Cell
Definition: spatial_model.h:657
Definition: fpmas.cpp:3
static std::size_t size(const LightObjectPack &p, const Ptr &ptr)
Definition: spatial_model.h:1421
PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1415
Definition: datapack.h:1382
static void to_datapack(LightObjectPack &pack, const T &item)
Definition: datapack.h:1409
static T from_datapack(const LightObjectPack &pack)
Definition: datapack.h:1422
PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1335
Definition: datapack.h:55
PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1266
static void from_json(const light_json &j, T &data)
Definition: json.h:123
static void to_json(light_json &j, const T &data)
Definition: json.h:107
Definition: spatial_model.h:1032
std::size_t radius(CellType *) const override
Definition: spatial_model.h:1043
bool contains(CellType *location, CellType *cell) const override
Definition: spatial_model.h:1036
Definition: spatial_model.h:1009
bool contains(CellType *, CellType *) const override
Definition: spatial_model.h:1013
std::size_t radius(CellType *) const override
Definition: spatial_model.h:1020
fpmas::api::utils::PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1196