Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions inc/osvr/Common/RegisteredStringMap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/** @file
@brief Header

@date 2015

@author
Sensics, Inc.
<http://sensics.com/osvr>
*/

// Copyright 2015 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef INCLUDED_RegisteredStringMap_h_GUID_066235BE_3687_44AD_C2A4_593D6E6780F3
#define INCLUDED_RegisteredStringMap_h_GUID_066235BE_3687_44AD_C2A4_593D6E6780F3

// Internal Includes
#include <osvr/Common/Export.h>
#include <osvr/Util/StringIds.h>

// Library/third-party includes
#include <json/value.h>

// Standard includes
#include <vector>

namespace osvr {
namespace common {

/// Centralize a string registry. Basically, the server side, and part
/// of the client side internals.
class RegisteredStringMap {
public:
/// retrieve the ID for the current name or register new ID and return
/// that
OSVR_COMMON_EXPORT util::StringID getStringID(std::string const &str);

/// retrieve the name of the string given the ID
/// returns empty string if nothing found
OSVR_COMMON_EXPORT std::string getStringFromId(util::StringID id) const;

/// Has a new entry been added since the flag was last cleared?
OSVR_COMMON_EXPORT bool isModified() const;
/// Clear the modified flag
OSVR_COMMON_EXPORT void clearModifiedFlag();

OSVR_COMMON_EXPORT void printCurrentMap();

OSVR_COMMON_EXPORT std::vector<std::string> getEntries() const;

protected:
std::vector<std::string> m_regEntries;

/// special flag that gets switched whenever new element is inserted;
bool m_modified = false;
};

/// This is like a RegisteredStringMap, except it also knows that some peer
/// also has a string map, likely with some of the same strings, but with
/// different ids. Used in reconciliation between server and client since
/// they are separate entities
class CorrelatedStringMap {
public:
/// retrieve the ID for the current name or register new ID and return
/// that
OSVR_COMMON_EXPORT util::StringID getStringID(std::string const &str);

/// retrieve the name of the string given the ID
/// returns empty string if nothing found
OSVR_COMMON_EXPORT std::string getStringFromId(util::StringID id) const;

/// This is the extra method used by clients, to convert from server's
/// ids. Will return NULL if peerID to Local ID mapping doesn't exist
OSVR_COMMON_EXPORT util::StringID
convertPeerToLocalID(util::PeerStringID peerID) const;

/// This populates the data structure used by the above method.
OSVR_COMMON_EXPORT void
setupPeerMappings(std::vector<std::string> const &peerEntries);

private:
RegisteredStringMap m_local;
/// keeps the peer to local string ID mappings
std::vector<uint32_t> m_remoteToLocal;
};
} // namespace common
} // namespace osvr
#endif // INCLUDED_RegisteredStringMap_h_GUID_066235BE_3687_44AD_C2A4_593D6E6780F3
56 changes: 56 additions & 0 deletions inc/osvr/Common/SerializationTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
#include <osvr/Util/BoolC.h>
#include <osvr/Util/Vec2C.h>
#include <osvr/Util/Vec3C.h>
#include <osvr/Util/TypeSafeId.h>

// Library/third-party includes
#include <boost/call_traits.hpp>
#include <boost/noncopyable.hpp>

// Standard includes
#include <string>
#include <vector>
#include <type_traits>

namespace osvr {
Expand Down Expand Up @@ -492,6 +494,51 @@ namespace common {
}
};

template <typename ValueType>
struct SerializationTraits<
DefaultSerializationTag<std::vector<ValueType>>, void>
: BaseSerializationTraits<std::vector<ValueType>> {
using value_type = std::vector<ValueType>;
using param_type = value_type const &;
using reference_type = value_type &;
typedef BaseSerializationTraits<std::vector<ValueType>> Base;
typedef DefaultSerializationTag<std::vector<ValueType>> tag_type;

template <typename BufferType>
static void serialize(BufferType &buf, param_type val,
tag_type const &) {
serializeRaw(buf, static_cast<uint32_t>(val.size()));
for (auto &elt : val) {
serializeRaw(buf, elt);
}
}

template <typename BufferReaderType>
static void deserialize(BufferReaderType &buf, reference_type val,
tag_type const &) {
uint32_t n;
deserializeRaw(buf, n);
val.clear();
val.reserve(n);
for (uint32_t i = 0; i < n; ++i) {
ValueType elt;
deserializeRaw(buf, elt);
val.push_back(elt);
}
}

static size_t spaceRequired(size_t existingBytes, param_type val,
tag_type const &) {
size_t bytes = existingBytes;
bytes += getBufferSpaceRequiredRaw(
bytes, static_cast<uint32_t>(val.size()));
for (auto &elt : val) {
bytes += getBufferSpaceRequiredRaw(bytes, elt);
}
return bytes - existingBytes;
}
};

template <>
struct SimpleStructSerialization<OSVR_Vec2>
: SimpleStructSerializationBase {
Expand All @@ -510,6 +557,15 @@ namespace common {
f(val.data[2]);
}
};

template <typename Tag>
struct SimpleStructSerialization<util::TypeSafeId<Tag>>
: SimpleStructSerializationBase {
template <typename F, typename T> static void apply(F &f, T &val) {
f(val.value());
}
};

} // namespace serialization

} // namespace common
Expand Down
46 changes: 46 additions & 0 deletions inc/osvr/Util/StringIds.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/** @file
@brief Header

@date 2015

@author
Sensics, Inc.
<http://sensics.com/osvr>
*/

// Copyright 2015 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef INCLUDED_StringIds_h_GUID_080FD2D7_0F0B_438B_E71E_7D2836C8921B
#define INCLUDED_StringIds_h_GUID_080FD2D7_0F0B_438B_E71E_7D2836C8921B

// Internal Includes
#include <osvr/Util/TypeSafeId.h>

// Library/third-party includes
// - none

// Standard includes
// - none

namespace osvr {
namespace util {
struct LocalStringIdTag;
struct PeerStringIdTag;
typedef TypeSafeId<LocalStringIdTag> StringID;
typedef TypeSafeId<PeerStringIdTag> PeerStringID;
} // namespace util
} // namespace osvr

#endif // INCLUDED_StringIds_h_GUID_080FD2D7_0F0B_438B_E71E_7D2836C8921B
124 changes: 124 additions & 0 deletions inc/osvr/Util/TypeSafeId.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/** @file
@brief Header

@date 2015

@author
Sensics, Inc.
<http://sensics.com/osvr>
*/

// Copyright 2015 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef INCLUDED_TypeSafeId_h_GUID_137CA336_382A_4796_7735_4521F02D5AC2
#define INCLUDED_TypeSafeId_h_GUID_137CA336_382A_4796_7735_4521F02D5AC2

// Internal Includes
#include <osvr/Util/StdInt.h>

// Library/third-party includes
// - none

// Standard includes
#include <limits>

namespace osvr {
namespace util {
/// @brief Namespace for traits templates associated with
/// ::osvr::util::TypeSafeId
namespace typesafeid_traits {
/// @brief Explicitly specialize for your tag type if you want a
/// different
/// underlying type.
template <typename Tag> struct WrappedType { typedef uint32_t type; };

/// @brief Explicitly specialize for your tag type if you want a
/// different signal value for invalid/empty: default is the maximum
/// representable value for your type.
template <typename Tag> struct SentinelValue {
typedef typename WrappedType<Tag>::type wrapped_type;
static wrapped_type get() {
return std::numeric_limits<wrapped_type>::max();
}
};

} // namespace typesafeid_traits

/// @brief A generic typesafe (as long as you use differing tag types)
/// wrapper for identifiers (typically integers).
///
/// @tparam Tag any type - does not have to be defined, just declared (so
/// `struct mytag;` somewhere is fine). The tag serves to make integer IDs
/// have distinct types, and also serves as a look-up key in the
/// ::osvr::util::typesafeid_traits classes for underlying integer type and
/// sentinel empty/invalid value.
///
/// Initial implementation inspired by
/// http://www.ilikebigbits.com/blog/2014/5/6/type-safe-identifiers-in-c
/// though this version now strays quite far by strengthening type-safety
/// and encapsulation, and by using traits classes to specify details based
/// on tag type alone.
template <class Tag> class TypeSafeId {
public:
/// @brief The type of the current class.
typedef TypeSafeId<Tag> type;

/// @brief The contained/wrapped type.
typedef typename typesafeid_traits::WrappedType<Tag>::type wrapped_type;

/// @brief Static factory method to return an invalid/empty ID.
static type invalid() { return type(); }

// Default constructor which will set m_val to the empty/invalid value.
TypeSafeId() : m_val(sentinel()) {}

// Explicit constructor from the wrapped type
explicit TypeSafeId(wrapped_type val) : m_val(val) {}

/// @brief Check whether the ID is empty/invalid
bool empty() const { return m_val == sentinel(); }

/// @brief Read-only accessor to the (non-type-safe!) wrapped value
wrapped_type value() const { return m_val; }

/// @brief Reference accessor to the (non-type-safe!) wrapped value
wrapped_type & value() { return m_val; }

private:
/// @brief Utility function to access the SentinelValue trait.
static wrapped_type sentinel() {
return typesafeid_traits::SentinelValue<Tag>::get();
}
wrapped_type m_val;
};

/// @brief Equality comparison operator for type-safe IDs
/// @relates ::osvr::util::TypeSafeId
template <typename Tag>
inline bool operator==(TypeSafeId<Tag> const a, TypeSafeId<Tag> const b) {
return a.value() == b.value();
}

/// @brief Inequality comparison operator for type-safe IDs
/// @relates ::osvr::util::TypeSafeId
template <typename Tag>
inline bool operator!=(TypeSafeId<Tag> const a, TypeSafeId<Tag> const b) {
return a.value() != b.value();
}

} // namespace util
} // namespace osvr

#endif // INCLUDED_TypeSafeId_h_GUID_137CA336_382A_4796_7735_4521F02D5AC2
2 changes: 2 additions & 0 deletions src/osvr/Common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ set(API
"${HEADER_LOCATION}/ProcessDeviceDescriptor.h"
"${HEADER_LOCATION}/RawMessageType.h"
"${HEADER_LOCATION}/RawSenderType.h"
"${HEADER_LOCATION}/RegisteredStringMap.h"
"${HEADER_LOCATION}/ReportFromCallback.h"
"${HEADER_LOCATION}/ReportMap.h"
"${HEADER_LOCATION}/ReportState.h"
Expand Down Expand Up @@ -152,6 +153,7 @@ set(SOURCE
ProcessDeviceDescriptor.cpp
RawMessageType.cpp
RawSenderType.cpp
RegisteredStringMap.cpp
ResolveFullTree.cpp
ResolveTreeNode.cpp
RouteContainer.cpp
Expand Down
Loading