You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
4.4 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/**
* @class vtkStateStorage
* @brief Class to make storing and comparing state quick and easy
*
* vtkStateStorage is just a thin wrapper around std::vector<unsigned char>
* It is best to use this class as an ivar so that allocs do not happen
* too often.
*
* Example usage:
* @code
*
* // compute the new state in a temp ivar
* // note that clear does not free memory
* this->TempState.Clear();
* this->TempState.Append(act->GetProperty()->GetMTime(), "property mtime");
* this->TempState.Append(
* this->CurrentInput ? this->CurrentInput->GetMTime() : 0, "input mtime");
* this->TempState.Append(
* act->GetTexture() ? act->GetTexture()->GetMTime() : 0, "texture mtime");
*
* // now compare against the last state value
*
* if (this->VBOBuildState != this->TempState)
* {
* // set the ivar to the new state
* this->VBOBuildState = this->TempState;
* do something...
* }
*
* @endcode
*
*/
#ifndef vtkStateStorage_h
#define vtkStateStorage_h
#include "vtkRenderingOpenGL2Module.h" // for export macro
#include <algorithm>
#include <string>
#include <vector>
// uncomment the following line to add in state debugging information
//#define USE_STATE_DEBUGGING 1
#ifdef USE_STATE_DEBUGGING
class VTKRENDERINGOPENGL2_EXPORT vtkStateStorage
{
public:
vtkStateStorage() {}
// clear the storage
void Clear()
{
this->Storage.clear();
this->StorageOffsets.clear();
this->StorageNames.clear();
}
// append a data item to the state
template <class T>
void Append(const T& value, const char* name);
bool operator!=(const vtkStateStorage& b) const
{
// for debug we also lookup the name of what was different
this->WhatWasDifferent = "";
if (this->Storage.size() != b.Storage.size())
{
this->WhatWasDifferent = "Different state sizes";
return true;
}
for (size_t i = 0; i < this->Storage.size(); ++i)
{
if (this->Storage[i] != b.Storage[i])
{
size_t block = 0;
while (this->StorageOffsets.size() > block + 1 && this->StorageOffsets[block + 1] >= i)
{
block++;
}
this->WhatWasDifferent = this->StorageNames[block] + " was different";
return true;
}
}
return false;
}
vtkStateStorage& operator=(const vtkStateStorage& b)
{
this->Storage = b.Storage;
this->StorageNames = b.StorageNames;
this->StorageOffsets = b.StorageOffsets;
return *this;
}
protected:
std::vector<unsigned char> Storage;
std::vector<std::string> StorageNames;
std::vector<size_t> StorageOffsets;
mutable std::string WhatWasDifferent;
private:
vtkStateStorage(const vtkStateStorage&) = delete;
};
template <class T>
inline void vtkStateStorage::Append(const T& value, const char* name)
{
this->StorageOffsets.push_back(this->Storage.size());
this->StorageNames.push_back(name);
const char* start = reinterpret_cast<const char*>(&value);
this->Storage.insert(this->Storage.end(), start, start + sizeof(T));
}
#else // normal implementation
class VTKRENDERINGOPENGL2_EXPORT vtkStateStorage
{
public:
vtkStateStorage() {}
// clear the storage
void Clear() { this->Storage.clear(); }
// append a data item to the state
template <class T>
void Append(const T& value, const char* name);
bool operator!=(const vtkStateStorage& b) const { return this->Storage != b.Storage; }
vtkStateStorage& operator=(const vtkStateStorage& b)
{
this->Storage = b.Storage;
return *this;
}
protected:
std::vector<unsigned char> Storage;
private:
vtkStateStorage(const vtkStateStorage&) = delete;
};
template <class T>
inline void vtkStateStorage::Append(const T& value, const char*)
{
const char* start = reinterpret_cast<const char*>(&value);
this->Storage.insert(this->Storage.end(), start, start + sizeof(T));
}
#endif // normal implementation
#endif // vtkStateStorage_h
// VTK-HeaderTest-Exclude: vtkStateStorage.h