1 /*=========================================================================
2
3 Program: Visualization Toolkit
4
5 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
6 All rights reserved.
7 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
8
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the above copyright notice for more information.
12
13 =========================================================================*/
14 /**
15 * @class vtkStateStorage
16 * @brief Class to make storing and comparing state quick and easy
17 *
18 * vtkStateStorage is just a thin wrapper around std::vector<unsigned char>
19 * It is best to use this class as an ivar so that allocs do not happen
20 * too often.
21 *
22 * Example usage:
23 * @code
24 *
25 * // compute the new state in a temp ivar
26 * // note that clear does not free memory
27 * this->TempState.Clear();
28 * this->TempState.Append(act->GetProperty()->GetMTime(), "property mtime");
29 * this->TempState.Append(
30 * this->CurrentInput ? this->CurrentInput->GetMTime() : 0, "input mtime");
31 * this->TempState.Append(
32 * act->GetTexture() ? act->GetTexture()->GetMTime() : 0, "texture mtime");
33 *
34 * // now compare against the last state value
35 *
36 * if (this->VBOBuildState != this->TempState)
37 * {
38 * // set the ivar to the new state
39 * this->VBOBuildState = this->TempState;
40 * do something...
41 * }
42 *
43 * @endcode
44 *
45 */
46
47 #ifndef vtkStateStorage_h
48 #define vtkStateStorage_h
49
50 #include <algorithm>
51 #include <string>
52 #include <vector>
53
54 // uncomment the following line to add in state debugging information
55 //#define USE_STATE_DEBUGGING 1
56 #ifdef USE_STATE_DEBUGGING
57
58 class vtkStateStorage
59 {
60 public:
vtkStateStorage()61 vtkStateStorage() {}
62
63 // clear the storage
Clear()64 void Clear()
65 {
66 this->Storage.clear();
67 this->StorageOffsets.clear();
68 this->StorageNames.clear();
69 }
70
71 // append a data item to the state
72 template <class T>
73 void Append(const T& value, const char* name);
74
75 bool operator!=(const vtkStateStorage& b) const
76 {
77 // for debug we also lookup the name of what was different
78 this->WhatWasDifferent = "";
79 if (this->Storage.size() != b.Storage.size())
80 {
81 this->WhatWasDifferent = "Different state sizes";
82 return true;
83 }
84 for (size_t i = 0; i < this->Storage.size(); ++i)
85 {
86 if (this->Storage[i] != b.Storage[i])
87 {
88 size_t block = 0;
89 while (this->StorageOffsets.size() > block + 1 && this->StorageOffsets[block + 1] >= i)
90 {
91 block++;
92 }
93 this->WhatWasDifferent = this->StorageNames[block] + " was different";
94 return true;
95 }
96 }
97 return false;
98 }
99
100 vtkStateStorage& operator=(const vtkStateStorage& b)
101 {
102 this->Storage = b.Storage;
103 this->StorageNames = b.StorageNames;
104 this->StorageOffsets = b.StorageOffsets;
105 return *this;
106 }
107
108 protected:
109 std::vector<unsigned char> Storage;
110 std::vector<std::string> StorageNames;
111 std::vector<size_t> StorageOffsets;
112 mutable std::string WhatWasDifferent;
113
114 private:
115 vtkStateStorage(const vtkStateStorage&) = delete;
116 };
117
118 template <class T>
Append(const T & value,const char * name)119 inline void vtkStateStorage::Append(const T& value, const char* name)
120 {
121 this->StorageOffsets.push_back(this->Storage.size());
122 this->StorageNames.push_back(name);
123 const char* start = reinterpret_cast<const char*>(&value);
124 this->Storage.insert(this->Storage.end(), start, start + sizeof(T));
125 }
126
127 #else // normal implementation
128
129 class vtkStateStorage
130 {
131 public:
132 vtkStateStorage() = default;
133
134 // clear the storage
Clear()135 void Clear() { this->Storage.clear(); }
136
137 // append a data item to the state
138 template <class T>
139 void Append(const T& value, const char* name);
140
141 bool operator!=(const vtkStateStorage& b) const { return this->Storage != b.Storage; }
142
143 vtkStateStorage& operator=(const vtkStateStorage& b) = default;
144
145 protected:
146 std::vector<unsigned char> Storage;
147
148 private:
149 vtkStateStorage(const vtkStateStorage&) = delete;
150 };
151
152 template <class T>
Append(const T & value,const char *)153 inline void vtkStateStorage::Append(const T& value, const char*)
154 {
155 const char* start = reinterpret_cast<const char*>(&value);
156 this->Storage.insert(this->Storage.end(), start, start + sizeof(T));
157 }
158
159 #endif // normal implementation
160
161 #endif // vtkStateStorage_h
162
163 // VTK-HeaderTest-Exclude: vtkStateStorage.h
164