55#pragma once
66
77#include < longeron/containers/intarray_multimap.hpp>
8+ #include < longeron/id_management/id_set_stl.hpp>
9+ #include < longeron/id_management/keyed_vec_stl.hpp>
810#include < longeron/id_management/registry_stl.hpp>
911
1012#include < algorithm>
1315namespace circuits
1416{
1517
16- using ElementId = uint32_t ;
17- using ElemLocalId = uint32_t ;
18- using ElemTypeId = uint8_t ;
19- using NodeId = uint32_t ;
18+
19+ // Enum classes used as integer "strong typedef" and can't be implicitly casted to each other,
20+ // preventing logic errors and cognative load from accidentally mixing them up.
21+ enum class ElemLocalId : std::uint32_t { };
22+ enum class ElemTypeId : std::uint8_t { };
23+
24+ // lgrn::IntArrayMultiMap does not (yet?) support strongly typedefed ID types
25+ using ElementId = std::uint32_t ;
26+ using NodeId = std::uint32_t ;
27+
2028
2129/* *
2230 * @brief Keeps track of which circuit elements of a certain type exists
2331 */
2432struct PerElemType
2533{
26- lgrn::IdRegistryStl<ElemLocalId> m_localIds;
27- std::vector< ElementId> m_localToElem;
34+ lgrn::IdRegistryStl<ElemLocalId> m_localIds;
35+ lgrn::KeyedVec<ElemLocalId, ElementId> m_localToElem;
2836};
2937
3038/* *
3139 * @brief Keeps track of which circuit elements exist and what type they are
3240 */
3341struct Elements
3442{
35- lgrn::IdRegistryStl<ElementId> m_ids;
43+ lgrn::IdRegistryStl<ElementId> m_ids;
3644
37- std::vector< ElemTypeId> m_elemTypes;
38- std::vector< ElemLocalId> m_elemToLocal;
45+ lgrn::KeyedVec<ElementId, ElemTypeId> m_elemTypes;
46+ lgrn::KeyedVec<ElementId, ElemLocalId> m_elemToLocal;
3947
40- std::vector< PerElemType> m_perType;
48+ lgrn::KeyedVec<ElemTypeId, PerElemType> m_perType;
4149};
4250
4351/* *
@@ -49,6 +57,7 @@ struct ElementPair
4957 ElemTypeId m_type;
5058};
5159
60+
5261/* *
5362 * @brief Connects cirucit elements together as Nodes
5463 */
@@ -64,7 +73,7 @@ struct Nodes
6473 // Node-to-Element connections
6574 // Each node can have multiple subscribers, but only one publisher
6675 Subscribers_t m_nodeSubscribers;
67- std::vector< ElementId> m_nodePublisher;
76+ lgrn::KeyedVec<NodeId, ElementId> m_nodePublisher;
6877
6978 // Corresponding Element-to-Node connections
7079 // [ElementId][PortId] -> NodeId
@@ -80,7 +89,7 @@ struct Nodes
8089template <typename VALUE_T>
8190struct NodeValues
8291{
83- std::vector< VALUE_T> m_nodeValues;
92+ lgrn::KeyedVec<NodeId, VALUE_T> m_nodeValues;
8493};
8594
8695// -----------------------------------------------------------------------------
@@ -102,33 +111,31 @@ struct CombinationalGates
102111 bool m_invert;
103112 };
104113
105- std::vector< GateDesc> m_localGates;
114+ lgrn::KeyedVec<ElemLocalId, GateDesc> m_localGates;
106115};
107116
108117// -----------------------------------------------------------------------------
109118
110119// Updating
111120
112- using BitVector_t = lgrn::BitView< std::vector<uint64_t > >;
113-
114121constexpr std::size_t const gc_bitVecIntSize = 64 ;
115122
116123struct UpdateElem
117124{
118- BitVector_t m_localDirty;
125+ lgrn::IdSetStl<ElemLocalId> m_localDirty;
119126};
120127
121- using UpdateElemTypes_t = std::vector< UpdateElem>;
128+ using UpdateElemTypes_t = lgrn::KeyedVec<ElemTypeId, UpdateElem>;
122129
123130template <typename VALUE_T>
124131struct UpdateNodes
125132{
126- BitVector_t m_nodeDirty;
127- std::vector< VALUE_T> m_nodeNewValues;
133+ lgrn::IdSetStl<NodeId> m_nodeDirty;
134+ lgrn::KeyedVec<NodeId, VALUE_T> m_nodeNewValues;
128135
129136 void assign (NodeId node, VALUE_T&& value)
130137 {
131- m_nodeDirty.set (node);
138+ m_nodeDirty.insert (node);
132139 m_nodeNewValues[node] = std::forward<VALUE_T>(value);
133140 }
134141};
@@ -147,26 +154,26 @@ struct UpdateNodes
147154 */
148155template <typename RANGE_T>
149156bool update_combinational (
150- RANGE_T&& toUpdate,
151- ElementId const * pLocalToElem ,
152- Nodes::Connections_t const & elemConnect,
153- ELogic const * pNodeValues ,
154- CombinationalGates const & gates,
155- UpdateNodes<ELogic>& rUpdNodes) noexcept
157+ RANGE_T&& toUpdate,
158+ lgrn::KeyedVec<ElemLocalId, ElementId> const &localToElem ,
159+ Nodes::Connections_t const & elemConnect,
160+ lgrn::KeyedVec<NodeId, ELogic> &nodeValues ,
161+ CombinationalGates const & gates,
162+ UpdateNodes<ELogic> & rUpdNodes) noexcept
156163{
157164 using Op = CombinationalGates::Op;
158165
159- auto const is_logic_high = [pNodeValues ] (NodeId in) noexcept -> bool
166+ auto const is_logic_high = [&nodeValues ] (NodeId in) noexcept -> bool
160167 {
161- return pNodeValues [in] == ELogic::High;
168+ return nodeValues [in] == ELogic::High;
162169 };
163170
164171 bool nodeUpdated = false ;
165172
166173 for (ElemLocalId local : toUpdate)
167174 {
168- ElementId const elem = pLocalToElem [local];
169- CombinationalGates::GateDesc const & desc = gates.m_localGates [local];
175+ ElementId const elem = localToElem [local];
176+ CombinationalGates::GateDesc const & desc = gates.m_localGates [local];
170177
171178 auto connectedNodes = elemConnect[elem];
172179 auto inFirst = connectedNodes.begin () + 1 ;
@@ -197,10 +204,10 @@ bool update_combinational(
197204 NodeId out = *connectedNodes.begin ();
198205
199206 // Request to write changes to node if value is changed
200- if (pNodeValues [out] != outLogic)
207+ if (nodeValues [out] != outLogic)
201208 {
202209 nodeUpdated = true ;
203- rUpdNodes.m_nodeDirty .set (out);
210+ rUpdNodes.m_nodeDirty .insert (out);
204211 rUpdNodes.m_nodeNewValues [out] = outLogic;
205212 }
206213 }
@@ -222,25 +229,24 @@ bool update_combinational(
222229 */
223230template <typename VALUE_T, typename RANGE_T>
224231bool update_nodes (
225- RANGE_T&& toUpdate,
226- Nodes::Subscribers_t const & nodeSubs,
227- Elements const & elements,
228- VALUE_T const * pNewValues,
229- VALUE_T* pValues,
230- UpdateElemTypes_t& rUpdElem)
232+ RANGE_T &&toUpdate,
233+ Nodes::Subscribers_t const &nodeSubs,
234+ lgrn::KeyedVec<NodeId, VALUE_T> const &newValues,
235+ lgrn::KeyedVec<NodeId, VALUE_T> &values,
236+ UpdateElemTypes_t &rUpdElem)
231237{
232238 bool elemNotified = false ;
233239
234- for (uint32_t node : toUpdate)
240+ for (NodeId node : toUpdate)
235241 {
236242 // Apply node value changes
237- pValues [node] = pNewValues [node];
243+ values [node] = newValues [node];
238244
239245 // Notify subscribed elements
240246 for (ElementPair subElem : nodeSubs[node])
241247 {
242248 elemNotified = true ;
243- rUpdElem[subElem.m_type ].m_localDirty .set (subElem.m_id );
249+ rUpdElem[subElem.m_type ].m_localDirty .insert (subElem.m_id );
244250 }
245251 }
246252
0 commit comments