Free Electron
Scope.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __data_Scope_h__
8 #define __data_Scope_h__
9 
10 #define FE_SCOPE_SUPPORT_WATCHERS FALSE
11 #define FE_SCOPE_GETRECORD FALSE
12 
13 namespace fe
14 {
15 
16 class RecordFactoryI;
17 class WatcherI;
18 class RecordCookbook;
19 class AccessorSet;
20 
21 typedef AutoHashMap< String, Array<String> > StringStringsMap;
22 typedef AutoHashMap< hp<Layout>, sp<StoreI> > layout_store_map;
23 
24 /** Attribute collection */
26 /** Depend collection */
27 typedef std::list< sp<Depend> > t_depends;
28 /** Layout collection */
30 #if FE_SCOPE_SUPPORT_WATCHERS
31 /** Watcher collection */
32 typedef std::list<sp<WatcherI> > t_watchers;
33 #endif
34 typedef std::map<String, unsigned int> t_indexmap;
35 typedef std::map<Attribute *, unsigned int> t_attrmap;
36 
37 template <class T> class Accessor;
38 
39 #if 0
40 class OffsetTable : public Counted
41 {
42  public:
43  OffsetTable(void);
44  ~OffsetTable(void);
45 
46 
47  Offset *table(void) { return m_table; }
48 
49  void resize(unsigned int a_size);
50 
51  void attach(sp<Layout> a_layout);
52  private:
53  Array< hp<Layout> > m_layouts;
54  Offset *m_table;
55  unsigned int m_size;
56 };
57 #endif
58 
59 /** @brief Layout namespace
60 
61  @ingroup data
62 
63  Every Layout must be associated with a single
64  Scope. Every Record layout is defined by a single Layout, therefore
65  every Record is associated with a single Scope.
66 
67  Scope is therefore the main class for state based activity. Records
68  are defined (via Layout), created, and destroyed using Scope.
69 
70  */
71 class FE_DL_EXPORT Scope: public Component, public Initialize<Scope>,
72  public ObjectSafe<Scope>
73 {
74  public:
75 #if 1
76  /** @brief Create a scope from within the fe::Registry
77 
78  This function will assert if called outside the registry
79  which supplies the fe::Master information.
80 
81  @internal */
82  Scope(void);
83 #endif
84  /** Construct a Scope bound to the the TypeMaster and Allocator
85  within @em master. */
86  Scope(Master &master);
87  Scope(sp<Master> &spMaster);
88  /** Construct a Scope bound to the given TypeMaster and Allocator. */
89  Scope(sp<TypeMaster> spTypeMaster,
90  sp<Allocator> allocator);
91  Scope(const Scope &other);
92 virtual ~Scope(void);
93  Scope &operator=(const Scope &other);
94 
95 virtual void setName(const String& name);
96 
97 #if 1
98  /// @brief Post construction step (last chance to find Master)
99  void initialize(void);
100 #endif
101 
102  /** Validate that there are no dependency conflicts and remove
103  dependency duplicates. This is mainly for internal use. */
104  void layoutValidate(void);
105 
106  /** Specify if select methods should be protected with a mutex. */
107  void setLocking(BWORD a_locking)
108  { m_locking=a_locking; }
109  BWORD isLocking(void)
110  { return m_locking; }
111 
112 private:
113  /** Release references to all Layout, Depend, and Store instances.
114  This may be necessary to break dependency cycles.
115  @todo create and reference dependency graph
116  */
117  bool shutdown(void);
118 public:
119 
120  /** Declare a new layout
121 
122  This will create an empty and unlocked layout.
123 
124  An empty layout name is not permitted
125  (an invalid sp<> would be returned).
126  */
127  sp<Layout> declare(const String &name);
128  /** Lock a layout. Finalize the structure that the layout represents.
129  This must happen before records of this layout are created.
130  If not done before a call to createRecord or createRecordArray
131  then the layout is automatically locked upon these calls. */
132  //void lockLayout(sp<Layout> spLayout);
133  /** Return the layout with the given name
134 
135  This first attempts to lookup an existing Layout.
136  If that fails, it will then try to instantiate a layout from
137  a RecordFactoryI registered under the same name.
138 
139  If no layout is found, an invalid sp<> is returned. */
140  sp<Layout> lookupLayout(const String &name);
141 #if 0
142  /** Return the Store for @em spLayout in @em spStore. Return true
143  upon success, otherwise return false. */
144  bool lookupStore(sp<Layout> spLayout,
145  sp<StoreI> &spStore);
146 #endif
147 
148  /** Specify who can produce a named layout. */
149  void registerFactory(String name,
150  sp<RecordFactoryI> spRecordFactoryI);
151  /// Create and return a new Record from registered RecordFactoryI.
152  Record produceRecord(String name);
153  /// Run post-initialization on Record using registered RecordFactoryI.
154  void finalize(Record& rRecord);
155 
156  /** Create and return a new Record of layout @em spLayout. */
157  Record createRecord(sp<Layout> spLayout);
158  Record createRecord(const String layout);
159  /** Create and return a new RecordArray of layout @em spLayout. */
160  sp<RecordArray> createRecordArray(String layout,
161  FE_UWORD count);
162  sp<RecordArray> createRecordArray(sp<Layout> spLayout,
163  FE_UWORD count);
164  /** Free the given record. This will throw an Exception if
165  @em record is reference counted. All records with the
166  Attribute FE_C are reference counted. This is the default for
167  all records (Scope has populate("", FE_C) in its constructor). */
168  //void freeRecord(Record record);
169 
170  /** Add a dependency. This is mainly for internal use by support,
171  enforce, populate, and share. */
172  sp<Attribute> addDepend(sp<Depend> &depend);
173  /** Return the total number of Attributes in this Scope. */
174  FE_UWORD getAttributeCount(void) const;
175  /** Return the Attribute with the given name.
176  The index of the Attribute is returned in @em index. */
177  sp<Attribute>& findAttribute(const String &name, FE_UWORD &index);
178  /** Return the Attribute with the given name.*/
179  sp<Attribute>& findAttribute(const String &name);
180  /** Return the Attribute at the given index. */
181  sp<Attribute> attribute(FE_UWORD index);
182  /** Return the index of the given Attribute. */
183  FE_UWORD attributeIndex(sp<Attribute> spAttribute);
184 
185  /** Add a support for a Attribute with name @mayHave and type of name
186  @em ofType. */
187  sp<Attribute> support( const String &mayHave,
188  const String &ofType);
189  /** Enforce a Attribute dependency. If a Layout has a Attribute named
190  @em ifHas, it will also have a Attribute of name @em mustHave. */
191  bool enforce( const String &ifHas,
192  const String &mustHave);
193  bool enforce( const Array<String> &ifHas,
194  const String &mustHave);
195  /** Add a Attribute to a Layout. If a Layout is named @em ifIs, then
196  it will have a Attribute of name @em mustHave. */
197  bool populate( const String &ifIs,
198  const String &mustHave);
199  // seems too brittle while also being unnecessary
200  // /** Clear all populate dependencies for Layout of name @em name. */
201  //bool clear( const String &ifIs);
202  /** Specify a Attribute share.
203  This means that two Attributes will actually
204  be the same instance (same piece of memory) for a particular
205  Layout. If a Layout is named @em ifIs, then treat Attributes
206  of names @em share1 and @em share2 as the same. */
207  bool share( const String &ifIs,
208  const String &share1,
209  const String &share2);
210 
211 #ifdef DEPRECATE
212  bool within( const String &ifIs,
213  const String &child,
214  const String &parent,
215  const size_t &offset);
216 #endif
217 
218  void clonePopulate( const String &ifThisHas,
219  const String &thenThisDoes);
220 
221  /** Return the associated TypeMaster. */
222  sp<TypeMaster> typeMaster(void);
223 
224  /** Return an Accessor for the Record reference count Attribute. */
225  Accessor< std::atomic<int> > &refCount(void);
226 
227  void resizeLayoutLocators(void) const;
228 
229 #if 0
230  /** Specify a store to use by name and registry for creating
231  state blocks. */
232  void specifyStore( sp<Registry> spRegistry,
233  const String &storeName);
234 #endif
235 
236 #if FE_SCOPE_SUPPORT_WATCHERS
237  void addWatcher( sp<WatcherI> spWatch);
238  bool removeWatcher( sp<WatcherI> spWatch);
239 #endif
240 
241  /** For debugging. */
242  void peek(Peeker &peeker);
243 
244  U32 serialIndex(void) { return m_serialIndex; }
245  template <typename R>
246  void assignIDNumber( const R &record);
247  template <typename R>
248  void freeIDNumber( const R &r_old);
249 
250  // This is not the IDs above. This is for generated layout names.
251  FE_UWORD getNextUniqueLayoutID(void)
252  {return m_nextUniqueLayoutID++;}
253 
254  FE_UWORD getNextUniqueIDR(void)
255  {return m_nextUniqueIDR++;}
256 
257 #if FE_SCOPE_GETRECORD
258  Record getRecord( IWORD id);
259 #endif
260 
261  void addAccessorSet(AccessorSet *a_as);
262  void removeAccessorSet(AccessorSet *a_as);
263  public:
264  /** Direct access to the attribute table. Use with care. */
265  t_attributes &attributes(void);
266  /** Direct access to the layout table. Use with care. */
267  t_layouts &layouts(void);
268  /** Direct access to the depend list. Use with care. */
269  t_depends &depends(void);
270  /** Direct access to the allocator. Use with care. */
271  sp<Allocator> allocator(void);
272  sp<RecordCookbook> cookbook(void);
273 
274  private:
275  void construct(sp<TypeMaster> spTypeMaster,
276  sp<Allocator> allocator);
277  void prepareCookbook(sp<Master>& rspMaster);
278  void depAttributeCheck(sp<Depend> &depend);
279  void depRecordCheck(sp<Depend> &depend);
280  sp<Attribute> dynamicAddAttribute(const String &typeName,
281  const String &attributeName);
282  sp<Attribute> addAttribute(const String &typeName,
283  const String &attributeName);
284 
285  //sp<StoreI> createStore(sp<Layout> spLayout) const;
286 
287  void notifyLayoutsOfAttributeChange(
288  sp<Depend> &depend);
289 
290 #if FE_SCOPE_SUPPORT_WATCHERS
291  void watch(const Record &record);
292  void unwatch(const Record &record);
293 #endif
294 
295  private:
296  sp<TypeMaster> m_spTypeMaster;
297  t_layouts m_layouts;
298  t_attributes m_attributes;
299  t_indexmap m_indexmap;
300  //t_attrmap m_attrmap;
301  t_depends m_depend;
302 #if FE_SCOPE_SUPPORT_WATCHERS
303  t_watchers m_watchers;
304 #endif
305  //layout_store_map m_storeMap;
306 
307  sp<Allocator> m_spAllocator;
308  sp<RecordCookbook> m_spRecordCookbook;
309 
310  std::set<AccessorSet *> m_accessorSets;
311 
312  bool m_looking;
313  bool m_locking;
314  I32 m_serialCount;
315  U32 m_serialIndex;
316 
317  Accessor< std::atomic<int> > *m_paCount;
318  Accessor< std::atomic<int> > *m_paSerialNumber;
319  hp<Registry> m_hpRegistry;
320  String m_storeName;
321 
322 #if FE_SCOPE_GETRECORD
323  Accessor<int> *m_paIDNumber;
324  Array<WeakRecord> m_idNumbered;
325  Array<int> m_freeIDNumbers;
326 #endif
327 
328  //Array< sp<OffsetTable> > m_offsetTables;
329 
330 typedef HashMap< String,
332  hash_string,
333  eq_string > StringRecordFactoryMap;
334 
335  StringRecordFactoryMap m_factoryMap;
336  StringStringsMap& factoryMultiMap(void);
337 
338  sp<Attribute> m_nullAttribute;
339  FE_UWORD m_nextUniqueLayoutID;
340  FE_UWORD m_nextUniqueIDR;
341 };
342 
343 FE_DL_EXPORT void assertData(sp<TypeMaster> spTypeMaster);
344 
346 {
347  return m_spTypeMaster;
348 }
349 
350 inline t_attributes &Scope::attributes(void)
351 {
352  return m_attributes;
353 }
354 
355 inline t_layouts &Scope::layouts(void)
356 {
357  return m_layouts;
358 }
359 
360 inline t_depends &Scope::depends(void)
361 {
362  return m_depend;
363 }
364 
366 {
367  return m_spAllocator;
368 }
369 
370 
371 
372 } /* namespace */
373 
374 #endif /* __data_Scope_h__ */
375 
sp< Allocator > allocator(void)
Direct access to the allocator.
Definition: Scope.h:365
Object level locking for thread safety.
Definition: Safe.h:216
Set of accessors.
Definition: AccessorSet.h:18
Heap-based support for classes participating in fe::ptr <>
Definition: Counted.h:35
kernel
Definition: namespace.dox:3
sp< TypeMaster > typeMaster(void)
Return the associated TypeMaster.
Definition: Scope.h:345
std::list< sp< Depend > > t_depends
Depend collection.
Definition: Scope.h:27
Per-class participation in the Initialized <> mechanism.
Definition: Initialized.h:117
The main data access class for the data system.
Definition: Accessor.h:128
t_depends & depends(void)
Direct access to the depend list.
Definition: Scope.h:360
Array< hp< Layout > > t_layouts
Layout collection.
Definition: Scope.h:29
Array< sp< Attribute > > t_attributes
Attribute collection.
Definition: Scope.h:25
t_attributes & attributes(void)
Direct access to the attribute table.
Definition: Scope.h:350
Automatically reference-counted string container.
Definition: String.h:128
void setLocking(BWORD a_locking)
Specify if select methods should be protected with a mutex.
Definition: Scope.h:107
Wrapper for std::vector.
Definition: Array.h:21
Reference to an instance of a Layout.
Definition: RecordSB.h:35
t_layouts & layouts(void)
Direct access to the layout table.
Definition: Scope.h:355
Base for all interfacable components.
Definition: Component.h:20
Layout namespace.
Definition: Scope.h:71
Central access point for key pseudo-global objects.
Definition: Master.h:21