source: cpp/frams/util/usertags.h @ 1040

Last change on this file since 1040 was 844, checked in by Maciej Komosinski, 2 years ago

Initialization of static fields in a template conforming to the C++17 standard

  • Property svn:eol-style set to native
File size: 2.4 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#ifndef _USERTAGS_H_
6#define _USERTAGS_H_
7
8/**
9  UserTags is the fast way to associate custom data with general purpose objects.
10  Objects don't have to know about their users and we can add more users later without recompilation.
11  For example: MechObject is general physical object in MechaStick engine.
12  In Framsticks simulator every MechObject is connected with Model object, MechParts and MechJoints are
13  connected with their counterparts in the Model as well, but the MechObject doesn't even know about it.
14  If the SSG visualisation is used, the same MechObject is also connected with SSGFramObject.
15  UserTags class is implemented as array, therefore the access is very fast but we have to define
16  maximum possible number of tags for every object:
17
18  UserTags<anyclass,datatype,maximumtags> object;
19  (all UserTags object for a given 'anyclass' will share registered id's)
20
21  usage:
22    1.allocate private id:
23       int id=object->userdata.newID();
24    'id' is shared across all objects of that class (in this example)
25    and therefore you need to allocate it only once.
26    0 is illegal here and means that we run out of id values.
27       
28    2.now you can use id to access your private data inside UserTags:
29       object->userdata[id]=...;
30       ...=object->userdata[id];
31       ...
32    3.you can also assign/access object->userdata (which is a shortcut for
33    object->userdata[0]). no id here, so in that case it is your responsibility
34    to avoid conflicts.
35       object->userdata=...;
36       ...=object->userdata;
37       ...
38
39    4.free your id when finished:
40       object->userdata.freeID(id);
41 */
42
43template<class ID, class T, int N> class UserTags
44{
45        static char reg[N];
46        T data[N];
47public:
48        UserTags() { memset(data, 0, sizeof(data)); }
49
50        /** allocate new id */
51        static int newID()
52        {
53                for (int i = 1; i < N; i++) if (!reg[i]) { reg[i] = 1; return i; }
54                DB(printf("Warning: UserTags run out of ids!\n"));
55                return 0;
56        }
57        static void freeID(int id)
58        {
59                reg[id] = 0;
60        }
61        T& operator[](int id)
62        {
63                DB(if (!id) printf("Warning: UserTags @ %p is using id=0\n", this);)
64                        return data[id];
65        }
66        operator T() { return data[0]; }
67        void operator=(T x) { data[0] = x; }
68};
69
70template<class ID, class T, int N> char UserTags<ID,T,N>::reg[N]={0};
71
72#endif
Note: See TracBrowser for help on using the repository browser.