Merge remote-tracking branch 'origin/master' into feature/missions

# Conflicts:
#	data/assets/scene/solarsystem/missions/newhorizons/newhorizons.asset
#	data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset
#	data/assets/scene/solarsystem/missions/osirisrex/osirisrex.mission
#	data/assets/scene/solarsystem/missions/perseverance/perseverance.asset
#	include/openspace/mission/missionmanager.h
#	modules/server/src/connection.cpp
#	src/mission/missionmanager.cpp
#	src/mission/missionmanager_lua.inl
This commit is contained in:
Ylva Selling
2023-03-21 12:03:10 -04:00
3829 changed files with 169534 additions and 143316 deletions

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -31,6 +31,7 @@
namespace openspace {
struct CameraPose;
class SceneGraphNode;
/**
@@ -67,11 +68,14 @@ public:
~Camera() = default;
// Mutators
void setPose(CameraPose pose);
void setPositionVec3(glm::dvec3 pos);
void setRotation(glm::dquat rotation);
void setScaling(float scaling);
void setMaxFov(float fov);
void setParent(SceneGraphNode* parent);
// Atmosphere dimming factor determines how much an atmosphere dims objects
void setAtmosphereDimmingFactor(float atmosphereDimmingFactor);
// Relative mutators
void rotate(glm::dquat rotation);
@@ -91,6 +95,7 @@ public:
float sinMaxFov() const;
SceneGraphNode* parent() const;
float scaling() const;
float atmosphereDimmingFactor() const;
// @TODO this should simply be called viewMatrix!
// Or it needs to be changed so that it actually is combined. Right now it is
@@ -140,11 +145,13 @@ public:
// [[deprecated("Replaced by Camera::SgctInternal::viewProjectionMatrix()")]]
const glm::mat4& viewProjectionMatrix() const;
std::vector<Syncable*> getSyncables();
std::vector<Syncable*> syncables();
// Static constants
static const glm::dvec3 ViewDirectionCameraSpace;
static const glm::dvec3 UpDirectionCameraSpace;
// (2021-07-16, emmbr) Note that this hard coded vector for the view direction is also
// used in a qauternion -> view direction helper function in ghoul/glm.h
static constexpr glm::dvec3 ViewDirectionCameraSpace = glm::dvec3(0.0, 0.0, -1.0);
static constexpr glm::dvec3 UpDirectionCameraSpace = glm::dvec3(0.0, 1.0, 0.0);
private:
@@ -153,6 +160,8 @@ private:
SyncData<float> _scaling = 1.f;
SceneGraphNode* _parent = nullptr;
float _atmosphereDimmingFactor = 1.f;
// _focusPosition to be removed
glm::dvec3 _focusPosition = glm::dvec3(0.0);
float _maxFov = 0.f;

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -22,21 +22,18 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___ASSETLISTENER___H__
#define __OPENSPACE_CORE___ASSETLISTENER___H__
#ifndef __OPENSPACE_CORE___CAMERAPOSE___H__
#define __OPENSPACE_CORE___CAMERAPOSE___H__
#include <openspace/scene/asset.h>
#include <ghoul/glm.h>
namespace openspace {
class AssetListener {
public:
virtual ~AssetListener() = default;
virtual void assetStateChanged(Asset* asset, Asset::State state) = 0;
virtual void assetRequested(Asset* parent, std::shared_ptr<Asset> child) = 0;
virtual void assetUnrequested(Asset* parent, std::shared_ptr<Asset> child) = 0;
struct CameraPose {
glm::dvec3 position = glm::dvec3(0.0);
glm::dquat rotation = glm::dquat(1.0, 0.0, 0.0, 0.0);
};
} // namespace openspace
#endif // __OPENSPACE_CORE___ASSETLISTENER___H__
#endif // __OPENSPACE_CORE___CAMERAPOSE___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -92,10 +92,10 @@ struct TestResult {
};
/// Is \c true if the TestResult is positive, \c false otherwise
bool success;
/// Is `true` if the TestResult is positive, `false` otherwise
bool success = false;
/// Contains a list of offenses that were found in the test. Is empty if
/// TestResult::Success is \c true
/// TestResult::Success `true`
std::vector<Offense> offenses;
/// Contains a list of warnings that were found in the test
std::vector<Warning> warnings;
@@ -113,7 +113,7 @@ struct SpecificationError : public ghoul::RuntimeError {
* \param res The offending TestResult that is passed on
* \param comp The component that initiated the specification test
*
* \pre \p res%'s TestResult::success must be \c false
* \pre \p res%'s TestResult::success must be `false`
*/
SpecificationError(TestResult res, std::string comp);
@@ -121,6 +121,8 @@ struct SpecificationError : public ghoul::RuntimeError {
TestResult result;
};
void logError(const SpecificationError& error, std::string component = "");
struct Verifier;
/**
@@ -136,7 +138,7 @@ DocumentationEntry e = { "key", new IntVerifier, "Documentation text", Optional:
\endverbatim
* Furthermore, these initializer lists can be crated all at once for a Documentation.
* Even if the Verifier%s are specified using the \c new operators, they will not leak
* Even if the Verifier%s are specified using the `new` operators, they will not leak
* memory as the DocumentationEntry takes ownership of them in the constructor.
*/
struct DocumentationEntry {
@@ -210,7 +212,7 @@ struct DocumentationEntry {
* used to impose restrictions on keys and values and determine whether a given
* ghoul::Dictionary adheres to these specifications (see #testSpecification and
* #testSpecificationAndThrow methods). Each Documentation consists of a human-readable
* \c name, and a list of DocumentationEntry%s that each describe a single key value. The
* `name`, and a list of DocumentationEntry%s that each describe a single key value. The
* most convenient way of creating a Documentation is by using nested initializer lists:
*\verbatim
Documentation doc = {

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -101,9 +101,9 @@ public:
* in it: HandlebarJS Templates (from _handlebarTemplates) and json (from
* \p data) along with the base template and js/css files from the source
* directory ${WEB}/documentation
* \param templates Vector of templates to add. Most of the time this list
* will just contain one item, but some modules may wish to provide
* multiple templates for subtypes, etc
*
* \param path The path to add
* \param data The JSON data that is written to the documentation
*/
void writeDocumentationHtml(const std::string& path, std::string data);

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -48,22 +48,22 @@ class DocumentationGenerator {
public:
/// This struct contains a single Handlebar template, with the name and the filename
struct HandlebarTemplate {
std::string name; ///< The name of the Handlebar template defined in \m filename
std::string filename; ///< The filename referenced in the \m name
std::string name; ///< The name of the Handlebar template defined in #filename
std::string filename; ///< The filename referenced in the #name
};
/**
* The constructor that is used to set the member variables later used in the
* writeDocumentation method.
*
* \param name The name of the written documentation
* \param jsonName The variable name of the value generated by the generateJson
* \param handlebarTemplates A list of Handlebar templates that is added to the
* documentation file
* \param javascriptFilename The path to a Javascript source file that is added to the
* documentation and that can contain additional functionality
*
* \pre name must not be empty
* \pre jsonName must not be empty
* \pre Each handlebarTemplates' \c name must not be empty
* \pre Each handlebarTemplates' `name` must not be empty
* \pre javascriptFilename must not be empty
*/
DocumentationGenerator(std::string name, std::string jsonName,
@@ -82,7 +82,8 @@ public:
* This abstract method is used by concrete subclasses to provide the actual data that
* is used in the documentation written by this DocumentationGenerator class. The JSON
* string returned by this function will be stored in the variable with the
* \c jsonName as passed in the constructor.
* `jsonName` as passed in the constructor.
*
* \return A JSON script that is parsed and stored in the variable passed in the
* DocumentationGenerator constructor
*/

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -59,7 +59,7 @@ struct Verifier {
* TestResult::offenders will either contain \p key or, in the case of a
* TableVerifier, a list of all offending subkeys as fully qualified names.
*
* \post If the return values' TestResult::success is \c true, its
* \post If the return values' TestResult::success is `true`, its
* TestResult::offenders is empty
*/
virtual TestResult operator()(const ghoul::Dictionary& dictionary,
@@ -96,7 +96,7 @@ struct Verifier {
/**
* The base class Verifier for all Verifier%s that have to test against a specific value
* type. This Verifier tests whether a given key exists and whether it has the same type
* as the template parameter \c T.
* as the template parameter `T`.
* \tparam T The type against which the key's value is tested
*/
template <typename T>
@@ -105,15 +105,15 @@ struct TemplateVerifier : public Verifier {
/**
* Tests whether the \p key contained in the ghoul::Dictionary \p dictionary exists
* and has the same type as \c T.
* and has the same type as `T`.
*
* \param dictionary The ghoul::Dictionary that contains the \p key to be tested
* \param key The key inside the \p dictinoary that is to be tested
* \return A TestResult that contains the information whether the \p key exists in the
* \p dictionary and whether the key's value's type agrees with \c T.
* \p dictionary and whether the key's value's type agrees with `T`.
*
* \post The return values' TestResult::success is either \c true and
* TestResult::offenders is empty, or it is \c false and TestResult::offenders
* \post The return values' TestResult::success is either `true` and
* TestResult::offenders is empty, or it is `false` and TestResult::offenders
* contains \p key
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
@@ -124,7 +124,7 @@ struct TemplateVerifier : public Verifier {
/**
* A Verifier that checks whether a given key inside a ghoul::Dictionary is of type
* \c bool. No implicit conversion is considered in this testing.
* `bool`. No implicit conversion is considered in this testing.
*/
struct BoolVerifier : public TemplateVerifier<bool> {
std::string type() const override;
@@ -132,7 +132,7 @@ struct BoolVerifier : public TemplateVerifier<bool> {
/**
* A Verifier that checks whether a given key inside a ghoul::Dictionary is of type
* \c double. No implicit conversion is considered in this testing.
* `double`. No implicit conversion is considered in this testing.
*/
struct DoubleVerifier : public TemplateVerifier<double> {
std::string type() const override;
@@ -140,9 +140,8 @@ struct DoubleVerifier : public TemplateVerifier<double> {
/**
* A Verifier that checks whether a given key inside a ghoul::Dictionary is of type
* \c int. It will also return \c true if the key's value is of type \c double, but is a
* integer value (for example, <code>0.0</code>, <code>12.0</code>, but not
* <code>0.5</code>).
* `int`. It will also return `true` if the key's value is of type `double`, but is a
* integer value (for example, `0.0`, `12.0`, but not `0.5`).
*/
struct IntVerifier : public TemplateVerifier<int> {
TestResult operator()(const ghoul::Dictionary& dict,
@@ -153,7 +152,7 @@ struct IntVerifier : public TemplateVerifier<int> {
/**
* A Verifier that checks whether a given key inside a ghoul::Dictionary is of type
* <code>std::string</code>. No implicit conversion is considered in this testing.
* `std::string`. No implicit conversion is considered in this testing.
*/
struct StringVerifier : public TemplateVerifier<std::string> {
StringVerifier(bool mustBeNotEmpty = false);
@@ -169,11 +168,28 @@ private:
bool _mustBeNotEmpty = false;
};
/**
* A Verifier that checks whether a given string is a valid identifier, meaning that is
* does not contain any whitespaces or dots
*/
struct IdentifierVerifier : public StringVerifier {
IdentifierVerifier();
TestResult operator()(const ghoul::Dictionary& dict,
const std::string& key) const override;
std::string documentation() const override;
std::string type() const override;
};
/**
* A Verifier that checks whether a given key inside a ghoul::Dictionary is a string and
* refers to an existing file on disk.
*/
struct FileVerifier : public StringVerifier {
FileVerifier();
TestResult operator()(const ghoul::Dictionary& dict,
const std::string& key) const override;
@@ -185,6 +201,8 @@ struct FileVerifier : public StringVerifier {
* refers to an existing directory on disk.
*/
struct DirectoryVerifier : public StringVerifier {
DirectoryVerifier();
TestResult operator()(const ghoul::Dictionary& dict,
const std::string& key) const override;
@@ -196,6 +214,8 @@ struct DirectoryVerifier : public StringVerifier {
* a valid date time
*/
struct DateTimeVerifier : public StringVerifier {
DateTimeVerifier();
TestResult operator()(const ghoul::Dictionary& dict,
const std::string& key) const override;
@@ -208,9 +228,9 @@ struct DateTimeVerifier : public StringVerifier {
* recursively to check the contained table. If this list is empty, a simple type testing
* is performed instead. If the testing finds any offending keys, it will return those
* keys with fully qualified names, that is, the name of the table will be prepended to
* the offending keys. Example: If the key \c Table is tested and a passed
* DocumentationEntry checks for a nested key \c a and this does not comply, this Verifier
* will return <code>Table.a</code> as an offender.
* the offending keys. Example: If the key `Table` is tested and a passed
* DocumentationEntry checks for a nested key `a` and this does not comply, this Verifier
* will return `Table.a` as an offender.
*/
struct TableVerifier : public TemplateVerifier<ghoul::Dictionary> {
/**
@@ -236,7 +256,7 @@ struct TableVerifier : public TemplateVerifier<ghoul::Dictionary> {
* \return A TestResult containing the results of the testing. If DocumentationEntry%s
* were specified in the constructor and one of those values find an offending
* key inside the table, it's name will be returned with a fully qualified
* name by prepending the name (= \key) of the table.
* name by prepending the name (= \p key) of the table.
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
@@ -248,7 +268,7 @@ struct TableVerifier : public TemplateVerifier<ghoul::Dictionary> {
};
/**
* A Verifier that checks whether all values contained in a Table are of type \c string.
* A Verifier that checks whether all values contained in a Table are of type `string`.
*/
struct StringListVerifier : public TableVerifier {
/**
@@ -262,7 +282,7 @@ struct StringListVerifier : public TableVerifier {
};
/**
* A Verifier that checks whether all values contained in a Table are of type \c int.
* A Verifier that checks whether all values contained in a Table are of type `int`.
*/
struct IntListVerifier : public TableVerifier {
/**
@@ -280,26 +300,26 @@ struct IntListVerifier : public TableVerifier {
//----------------------------------------------------------------------------------------
/**
* This struct is the base class for all Verifier%s that check for \c glm vector types.
* This struct is the base class for all Verifier%s that check for `glm` vector types.
* The template parameter for the subclasses is the containing type, not the full vector
* type. For example to check for <code>glm::dvec3</code>, one would create a
* <code>Vector3Verifier<double></code>.
* type. For example to check for `glm::dvec3`, one would create a
* `Vector3Verifier<double>`.
*/
struct VectorVerifier {};
/// This Verifier checks whether the value is of type <code>glm::tvec2<T></code>
/// This Verifier checks whether the value is of type `glm::tvec2<T>`
template <typename T>
struct Vector2Verifier : public TemplateVerifier<glm::tvec2<T>>, public VectorVerifier {
std::string type() const override;
};
/// This Verifier checks whether the value is of type <code>glm::tvec3<T></code>
/// This Verifier checks whether the value is of type `glm::tvec3<T>`
template <typename T>
struct Vector3Verifier : public TemplateVerifier<glm::tvec3<T>>, public VectorVerifier {
std::string type() const override;
};
/// This Verifier checks whether the value is of type <code>glm::tvec4<T></code>
/// This Verifier checks whether the value is of type `glm::tvec4<T>`
template <typename T>
struct Vector4Verifier : public TemplateVerifier<glm::tvec4<T>>, public VectorVerifier {
std::string type() const override;
@@ -321,7 +341,7 @@ struct Color4Verifier : public Vector4Verifier<double> {
/**
* A Verifier that checks whether all values contained in a Table are of
* type <code>glm::tvec2<T></code>
* type `glm::tvec2<T>`
*/
template <typename T>
struct Vector2ListVerifier : public TableVerifier {
@@ -338,7 +358,7 @@ struct Vector2ListVerifier : public TableVerifier {
/**
* A Verifier that checks whether all values contained in a Table are of
* type <code>glm::tvec3<T></code>
* type `glm::tvec3<T>`
*/
template <typename T>
struct Vector3ListVerifier : public TableVerifier {
@@ -355,7 +375,7 @@ struct Vector3ListVerifier : public TableVerifier {
/**
* A Verifier that checks whether all values contained in a Table are of
* type <code>glm::tvec4<T></code>
* type `glm::tvec4<T>`
*/
template <typename T>
struct Vector4ListVerifier : public TableVerifier {
@@ -375,15 +395,15 @@ struct Vector4ListVerifier : public TableVerifier {
//----------------------------------------------------------------------------------------
/**
* This struct is the base class for all Verifier%s that check for \c glm matrix types.
* This struct is the base class for all Verifier%s that check for `glm` matrix types.
* The template parameter for the subclasses is the containing type, not the full matrix
* type. For example to check for <code>glm::dmat4x3</code>, one would create a
* <code>Matrix4x3Verifier<double></code>.
* type. For example to check for `glm::dmat4x3`, one would create a
* `Matrix4x3Verifier<double>`.
*/
struct MatrixVerifier {};
/**
* This Verifier checks whether the value is of type <code>glm::mat2x2<T></code>
* This Verifier checks whether the value is of type `glm::mat2x2<T>`
*/
template <typename T>
struct Matrix2x2Verifier : public TemplateVerifier<glm::tmat2x2<T>>, public MatrixVerifier
@@ -392,7 +412,7 @@ struct Matrix2x2Verifier : public TemplateVerifier<glm::tmat2x2<T>>, public Matr
};
/**
* This Verifier checks whether the value is of type <code>glm::mat2x3<T></code>
* This Verifier checks whether the value is of type `glm::mat2x3<T>`
*/
template <typename T>
struct Matrix2x3Verifier : public TemplateVerifier<glm::tmat2x3<T>>, public MatrixVerifier
@@ -401,7 +421,7 @@ struct Matrix2x3Verifier : public TemplateVerifier<glm::tmat2x3<T>>, public Matr
};
/**
* This Verifier checks whether the value is of type <code>glm::mat2x4<T></code>
* This Verifier checks whether the value is of type `glm::mat2x4<T>`
*/
template <typename T>
struct Matrix2x4Verifier : public TemplateVerifier<glm::tmat2x4<T>>, public MatrixVerifier
@@ -410,7 +430,7 @@ struct Matrix2x4Verifier : public TemplateVerifier<glm::tmat2x4<T>>, public Matr
};
/**
* This Verifier checks whether the value is of type <code>glm::mat3x2<T></code>
* This Verifier checks whether the value is of type `glm::mat3x2<T>`
*/
template <typename T>
struct Matrix3x2Verifier : public TemplateVerifier<glm::tmat3x2<T>>, public MatrixVerifier
@@ -419,7 +439,7 @@ struct Matrix3x2Verifier : public TemplateVerifier<glm::tmat3x2<T>>, public Matr
};
/**
* This Verifier checks whether the value is of type <code>glm::mat3x3<T></code>
* This Verifier checks whether the value is of type `glm::mat3x3<T>`
*/
template <typename T>
struct Matrix3x3Verifier : public TemplateVerifier<glm::tmat3x3<T>>, public MatrixVerifier
@@ -428,7 +448,7 @@ struct Matrix3x3Verifier : public TemplateVerifier<glm::tmat3x3<T>>, public Matr
};
/**
* This Verifier checks whether the value is of type <code>glm::mat3x4<T></code>
* This Verifier checks whether the value is of type `glm::mat3x4<T>`
*/
template <typename T>
struct Matrix3x4Verifier : public TemplateVerifier<glm::tmat3x4<T>>, public MatrixVerifier
@@ -437,7 +457,7 @@ struct Matrix3x4Verifier : public TemplateVerifier<glm::tmat3x4<T>>, public Matr
};
/**
* This Verifier checks whether the value is of type <code>glm::mat4x2<T></code>
* This Verifier checks whether the value is of type `glm::mat4x2<T>`
*/
template <typename T>
struct Matrix4x2Verifier : public TemplateVerifier<glm::tmat4x2<T>>, public MatrixVerifier
@@ -446,7 +466,7 @@ struct Matrix4x2Verifier : public TemplateVerifier<glm::tmat4x2<T>>, public Matr
};
/**
* This Verifier checks whether the value is of type <code>glm::mat4x3<T></code>
* This Verifier checks whether the value is of type `glm::mat4x3<T>`
*/
template <typename T>
struct Matrix4x3Verifier : public TemplateVerifier<glm::tmat4x3<T>>, public MatrixVerifier
@@ -455,7 +475,7 @@ struct Matrix4x3Verifier : public TemplateVerifier<glm::tmat4x3<T>>, public Matr
};
/**
* This Verifier checks whether the value is of type <code>glm::mat4x4<T></code>
* This Verifier checks whether the value is of type `glm::mat4x4<T>`
*/
template <typename T>
struct Matrix4x4Verifier : public TemplateVerifier<glm::tmat4x4<T>>, public MatrixVerifier
@@ -471,15 +491,15 @@ struct Matrix4x4Verifier : public TemplateVerifier<glm::tmat4x4<T>>, public Matr
* This is the abstract base class of all binary operator-based verifiers. This class
* takes two template parameters. The first is the Verifier that one would use to only
* check for the type of the object, for example IntVerifier. The second argument is a
* function object that has its <code>operator()</code> function overloaded and returns a
* boolean value. In these cases, the \c std function objects <code>std::less</code>,
* <code>std::equal_to</code>, etc are used.
* function object that has its `operator()` function overloaded and returns a boolean
* value. In these cases, the `std` function objects `std::less`, `std::equal_to, etc are
* used.
*
* This verifier will apply the \c Operator to the stored value and the incoming value
* (after type checking) and will check if the \c Operator returns \c true or \c false.
* This verifier will apply the `Operator` to the stored value and the incoming value
* (after type checking) and will check if the `Operator` returns `true` or `false`.
* The incoming value is used as the first argument and the stored value as the second
* argument to the \c Operator. If the type checking fails, the offense reason
* TestResult::Offense::Reason::WrongType is returned. If the \c Operator fails, the
* argument to the `Operator`. If the type checking fails, the offense reason
* TestResult::Offense::Reason::WrongType is returned. If the `Operator` fails, the
* reason TestResult::Offense::Verification is returned instead.
*/
template <typename T, typename Operator>
@@ -488,34 +508,34 @@ struct OperatorVerifier : public T {
* Constructor for an OperatorVerifier. As all operators need to compare the incoming
* value to a stored value, we require the comparison \p value to be passed in here.
* \param value The value against which the tested value is compared using the
* \c Operator
* `Operator`
*/
OperatorVerifier(typename T::Type value);
/**
* First checks whether the \p dictionary contains the passed \p key and whether the
* \p key%'s value is correct using the template paramater \c T as a verifier. Then,
* \p key%'s value is correct using the template paramater `T` as a verifier. Then,
* the \p key%'s value is checked against the stored OperatorVerifier::value using the
* \c Operator.
* `Operator`.
*
* \param dictionary The ghoul::Dictionary that contains the \p key to be tested
* \param key The key inside the \p dictinoary that is to be tested
* \return A TestResult containing the results of the specification testing. If the
* \p key%'s value has the wrong type, it will be added to the TestResult's
* offense list with the reason TestResult::Offense::Reason::WrongType; if the
* \c Operator returns false, it will be added with the reason
* `Operator` returns false, it will be added with the reason
* TestResult::Offense::Verification instead.
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
/// The stored value which is passed to the \c Operator as a second argument
/// The stored value which is passed to the `Operator` as a second argument
typename T::Type value;
};
/**
* This Verifier checks whether the incoming value is strictly smaller than the stored
* value. Due to the operator type restrictions, \c T cannot be a subclass of (or the same
* value. Due to the operator type restrictions, `T` cannot be a subclass of (or the same
* as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
*/
template <typename T>
@@ -525,10 +545,6 @@ struct LessVerifier : public OperatorVerifier<T, std::less<typename T::Type>> {
!std::is_base_of<StringVerifier, T>::value, "T cannot be StringVerifier"
);
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
static_assert(
!std::is_base_of<VectorVerifier, T>::value,
"T cannot be VectorVerifier"
);
using OperatorVerifier<T, std::less<typename T::Type>>::OperatorVerifier;
@@ -539,7 +555,7 @@ struct LessVerifier : public OperatorVerifier<T, std::less<typename T::Type>> {
/**
* This Verifier checks whether the incoming value is smaller than or equal to the stored
* value. Due to the operator type restrictions, \c T cannot be a subclass of (or the same
* value. Due to the operator type restrictions, `T` cannot be a subclass of (or the same
* as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
*/
template <typename T>
@@ -550,10 +566,6 @@ struct LessEqualVerifier : public OperatorVerifier<T, std::less_equal<typename T
"T cannot be StringVerifier"
);
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
static_assert(
!std::is_base_of<VectorVerifier, T>::value,
"T cannot be VectorVerifier"
);
using OperatorVerifier<T, std::less_equal<typename T::Type>>::OperatorVerifier;
@@ -564,7 +576,7 @@ struct LessEqualVerifier : public OperatorVerifier<T, std::less_equal<typename T
/**
* This Verifier checks whether the incoming value is strictly greater than the stored
* value. Due to the operator type restrictions, \c T cannot be a subclass of (or the same
* value. Due to the operator type restrictions, `T` cannot be a subclass of (or the same
* as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
*/
template <typename T>
@@ -575,10 +587,6 @@ struct GreaterVerifier : public OperatorVerifier<T, std::greater<typename T::Typ
"T cannot be StringVerifier"
);
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
static_assert(
!std::is_base_of<VectorVerifier, T>::value,
"T cannot be VectorVerifier"
);
using OperatorVerifier<T, std::greater<typename T::Type>>::OperatorVerifier;
@@ -589,7 +597,7 @@ struct GreaterVerifier : public OperatorVerifier<T, std::greater<typename T::Typ
/**
* This Verifier checks whether the incoming value is greater than or equal to the stored
* value. Due to the operator type restrictions, \c T cannot be a subclass of (or the same
* value. Due to the operator type restrictions, `T` cannot be a subclass of (or the same
* as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
*/
template <typename T>
@@ -602,10 +610,6 @@ struct GreaterEqualVerifier : public OperatorVerifier<T,
"T cannot be StringVerifier"
);
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
static_assert(
!std::is_base_of<VectorVerifier, T>::value,
"T cannot be VectorVerifier"
);
using OperatorVerifier<T, std::greater_equal<typename T::Type>>::OperatorVerifier;
@@ -616,7 +620,7 @@ struct GreaterEqualVerifier : public OperatorVerifier<T,
/**
* This Verifier checks whether the incoming value is equal to the stored value. Due to
* the operator type restrictions, \c T cannot be a subclass of (or the same as)
* the operator type restrictions, `T` cannot be a subclass of (or the same as)
* TableVerifier.
*/
template <typename T>
@@ -632,7 +636,7 @@ struct EqualVerifier : public OperatorVerifier<T, std::equal_to<typename T::Type
/**
* This Verifier checks whether the incoming value is unequal to the store value. Due to
* the operator type restrictions, \c T cannot be a subclass of (or the same as)
* the operator type restrictions, `T` cannot be a subclass of (or the same as)
* TableVerifier.
*/
template <typename T>
@@ -652,8 +656,8 @@ struct UnequalVerifier : public OperatorVerifier<T, std::not_equal_to<typename T
/**
* This Verifier checks whether the incoming value is of the correct type, using the
* Verifier passed as a template parameter \c T and then checks whether it is part of a
* list that is passed to the constructor. To the missing equality operator, \c T cannot
* Verifier passed as a template parameter `T` and then checks whether it is part of a
* list that is passed to the constructor. To the missing equality operator, `T` cannot
* be a subclass of (or the same as) TableVerifier.
*/
template <typename T>
@@ -670,7 +674,7 @@ struct InListVerifier : public T {
/**
* Tests whether the \p key exists in the \p dictionary, whether it has the correct
* type by invoking the template parameter \c T, and then tests if the \p key's value
* type by invoking the template parameter `T`, and then tests if the \p key's value
* is part of the list passed to the constructor.
*
* \param dictionary The ghoul::Dictionary that contains the \p key
@@ -692,8 +696,8 @@ struct InListVerifier : public T {
/**
* This Verifier checks whether the incoming value is of the correct type, using the
* Verifier passed as a template parameter \c T and then checks whether it is not part of
* a list that is passed to the constructor. To the missing equality operator, \c T cannot
* Verifier passed as a template parameter `T` and then checks whether it is not part of
* a list that is passed to the constructor. To the missing equality operator, `T` cannot
* be a subclass of (or the same as) TableVerifier.
*/
template <typename T>
@@ -710,7 +714,7 @@ struct NotInListVerifier : public T {
/**
* Tests whether the \p key exists in the \p dictionary, whether it has the correct
* type by invoking the template parameter \c T, and then tests if the \p key's value
* type by invoking the template parameter `T`, and then tests if the \p key's value
* is not part of the list passed to the constructor.
*
* \param dictionary The ghoul::Dictionary that contains the \p key
@@ -735,9 +739,9 @@ struct NotInListVerifier : public T {
/**
* This Verifier checks whether the incoming value is of the correct type, using the
* Verifier passed as a template parameter \c T and then checks whether it is greater or
* Verifier passed as a template parameter `T` and then checks whether it is greater or
* equal to a lower limit and less or equal to a higher limit. To the missing comparison
* operators, \c T cannot be a subclass of (or the same as) BoolVerifier, StringVerifier,
* operators, `T` cannot be a subclass of (or the same as) BoolVerifier, StringVerifier,
* TableVerifier, or VectorVerifier. Both the lower and the higher limit are inclusive).
*/
template <typename T>
@@ -754,15 +758,11 @@ struct InRangeVerifier : public T {
!std::is_base_of<TableVerifier, T>::value,
"T cannot be TableVerifier"
);
static_assert(
!std::is_base_of<VectorVerifier, T>::value,
"T cannot be VectorVerifier"
);
/**
* Constructs a InRangeVerifier that checks whether the incoming value is of the
* correct type and whether the value is greater or equal to \p lower and less or
* equal to \upper.
* equal to \p upper.
*
* \param lower The (inclusive) lower limit of the range
* \param upper The (inclusive) upper limit of the range
@@ -773,7 +773,7 @@ struct InRangeVerifier : public T {
/**
* Tests whether the \p key exists in the \p dictionary, whether it has the correct
* type by invoking the template parameter \c T, and then tests if the \p key's value
* type by invoking the template parameter `T`, and then tests if the \p key's value
* is between the lower and upper limits (both inclusive) that were passed to the
* constructor.
*
@@ -797,9 +797,9 @@ struct InRangeVerifier : public T {
/**
* This Verifier checks whether the incoming value is of the correct type, using the
* Verifier passed as a template parameter \c T and then checks whether it is outside the
* Verifier passed as a template parameter `T` and then checks whether it is outside the
* (exclusive) range defined by a lower and upper limit. To the missing comparison
* operators, \c T cannot be a subclass of (or the same as) BoolVerifier, StringVerifier,
* operators, `T` cannot be a subclass of (or the same as) BoolVerifier, StringVerifier,
* TableVerifier, or VectorVerifier. Both the lower and the higher limit are exclusive).
*/
template <typename T>
@@ -816,10 +816,6 @@ struct NotInRangeVerifier : public T {
!std::is_base_of<TableVerifier, T>::value,
"T cannot be TableVerifier"
);
static_assert(
!std::is_base_of<VectorVerifier, T>::value,
"T cannot be VectorVerifier"
);
/**
* Constructs a InRangeVerifier that checks whether the incoming value is of the
@@ -834,7 +830,7 @@ struct NotInRangeVerifier : public T {
/**
* Tests whether the \p key exists in the \p dictionary, whether it has the correct
* type by invoking the template parameter \c T, and then tests if the \p key's value
* type by invoking the template parameter `T`, and then tests if the \p key's value
* is outside the lower and upper limits (both exclusive) that were passed to the
* constructor.
*
@@ -888,16 +884,16 @@ struct AnnotationVerifier : public T {
};
/**
* This Verifier is a marker that performs the same testing as the \c T parameter, but
* This Verifier is a marker that performs the same testing as the `T` parameter, but
* also adds a warning to the test result informing the user of the deprecation.
* Furthermore, the documentation will contain the word <code>(deprecated)</code> in
* addition to the documentation returned by \c T
* Furthermore, the documentation will contain the word `(deprecated)` in
* addition to the documentation returned by `T`
* \tparam T The Verifier that is to be marked deprecated
*/
template <typename T>
struct DeprecatedVerifier : public T {
/**
* Tests the \p dictionary%s \p key using the Verifier \c T and adds a warning to the
* Tests the \p dictionary%s \p key using the Verifier `T` and adds a warning to the
* TestResult informing the caller of the deprecation.
*
* \param dictionary The ghoul::Dictionary whose \p key should be tested
@@ -908,9 +904,9 @@ struct DeprecatedVerifier : public T {
const std::string& key) const override;
/**
* Returns the documentation as reported by \c T and adds the word
* <code>(deprecated)</code> to it.
* \return The deprecated version of \c T%'s documentation
* Returns the documentation as reported by `T` and adds the word
* `(deprecated)` to it.
* \return The deprecated version of `T`%'s documentation
*/
std::string documentation() const override;
};
@@ -926,12 +922,13 @@ struct DeprecatedVerifier : public T {
struct ReferencingVerifier : public TableVerifier {
/**
* Creates a ReferencingVerifier that references a documentation with the provided
* identifier \p id. The ReferencingVerifier will use the static DocumentationEngine
* to retrieve Documentation%s and find the \p identifier among them.
* identifier \p identifier. The ReferencingVerifier will use the static
* DocumentationEngine to retrieve Documentation%s and find the \p identifier among
* them.
*
* \param identifier The identifier of the Documentation that this Verifier references
*/
ReferencingVerifier(std::string id);
ReferencingVerifier(std::string identifier);
/**
* Checks whether the \p key in the \p dictionary exists and is of type Table (similar
@@ -962,9 +959,9 @@ struct ReferencingVerifier : public TableVerifier {
//----------------------------------------------------------------------------------------
/**
* This Verifier takes two Verifiers and performs a boolean \c and operation on their
* This Verifier takes two Verifiers and performs a boolean `and` operation on their
* results. In essence, a value only passes this Verifier if it passes both Verifier%s
* that are passed in the constructor. Opposed to the <code>C++</code> <code>&&</code>
* that are passed in the constructor. Opposed to the `C++` `&&`
* operator, the AndVerifier does not perform any short-circut evaluation.
*/
struct AndVerifier : public Verifier {
@@ -987,10 +984,10 @@ struct AndVerifier : public Verifier {
* \param dictionary The ghoul::Dictionary that is to be tested
* \param key The key contained in \p dictionary that is to be tested
* \return A TestResult object that contains the test results. If the value fails
* any passed Verifiers, TestResult::success is \c false and the
* any passed Verifiers, TestResult::success is `false` and the
* TestResult::offenses list contains \p with a reason of
* TestResult::Offense::Reason::Verification. If \p key%'s value passes both
* Verifier%s, the result's TestResult::success is \c true and the
* Verifier%s, the result's TestResult::success is `true` and the
* TestResult::offenses is empty.
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
@@ -1003,10 +1000,10 @@ struct AndVerifier : public Verifier {
};
/**
* This Verifier takes two Verifiers and performs a boolean \c or operation on their
* This Verifier takes two Verifiers and performs a boolean `or` operation on their
* results. In essence, a value only passes this Verifier if it passes either of the two
* Verifier%s that are passed in the constructor. Opposed to the <code>C++</code>
* <code>||</code> operator, the OrVerifier does not perform any short-circut evaluation.
* Verifier%s that are passed in the constructor. Opposed to the `C++` `||` operator, the
* OrVerifier does not perform any short-circut evaluation.
*/
struct OrVerifier : public Verifier {
/**
@@ -1017,11 +1014,11 @@ struct OrVerifier : public Verifier {
*
* \pre values must contain at least two values
*
* \todo: The use of the variant to use both raw pointers and shared pointers is
* definitely undesired. At the momement we are not handling the ownership of
* the verifiers very well and this must be cleaned up when doing a pass over
* the entire ownership model of the documentation/verifiers. For now it was
* necessary to make the codegen work in all cases without complications there
* \todo The use of the variant to use both raw pointers and shared pointers is
* definitely undesired. At the momement we are not handling the ownership of
* the verifiers very well and this must be cleaned up when doing a pass over
* the entire ownership model of the documentation/verifiers. For now it was
* necessary to make the codegen work in all cases without complications there
*/
OrVerifier(const std::vector<std::variant<Verifier*,
std::shared_ptr<Verifier>>> values);
@@ -1035,10 +1032,10 @@ struct OrVerifier : public Verifier {
* \param dictionary The ghoul::Dictionary that is to be tested
* \param key The key contained in \p dictionary that is to be tested
* \return A TestResult object that contains the test results. If the value fails
* all Verifiers, TestResult::success is \c false and the
* all Verifiers, TestResult::success is `false` and the
* TestResult::offenses list contains \p with a reason of
* TestResult::Offense::Reason::Verification. If \p key%'s value passes either
* of the two Verifier%s, the result's TestResult::success is \c true and the
* of the two Verifier%s, the result's TestResult::success is `true` and the
* TestResult::offenses is empty.
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
@@ -1050,128 +1047,130 @@ struct OrVerifier : public Verifier {
std::vector<std::shared_ptr<Verifier>> values;
};
/// A short-hand definition for a Verifier checking for <code>glm::bvec2</code>
/// A short-hand definition for a Verifier checking for `glm::bvec2`
using BoolVector2Verifier = Vector2Verifier<bool>;
/// A short-hand definition for a Verifier checking for <code>glm::ivec2</code>
/// A short-hand definition for a Verifier checking for `glm::ivec2`
using IntVector2Verifier = Vector2Verifier<int>;
/// A short-hand definition for a Verifier checking for <code>glm::dvec2</code>
/// A short-hand definition for a Verifier checking for `glm::dvec2`
using DoubleVector2Verifier = Vector2Verifier<double>;
/// A short-hand definition for a Verifier checking for <code>glm::bvec3</code>
/// A short-hand definition for a Verifier checking for `glm::bvec3`
using BoolVector3Verifier = Vector3Verifier<bool>;
/// A short-hand definition for a Verifier checking for <code>glm::ivec3</code>
/// A short-hand definition for a Verifier checking for `glm::ivec3`
using IntVector3Verifier = Vector3Verifier<int>;
/// A short-hand definition for a Verifier checking for <code>glm::dvec3</code>
/// A short-hand definition for a Verifier checking for `glm::dvec3`
using DoubleVector3Verifier = Vector3Verifier<double>;
/// A short-hand definition for a Verifier checking for <code>glm::bvec4</code>
/// A short-hand definition for a Verifier checking for `glm::bvec4`
using BoolVector4Verifier = Vector4Verifier<bool>;
/// A short-hand definition for a Verifier checking for <code>glm::ivec4</code>
/// A short-hand definition for a Verifier checking for `glm::ivec4`
using IntVector4Verifier = Vector4Verifier<int>;
/// A short-hand definition for a Verifier checking for <code>glm::dvec4</code>
/// A short-hand definition for a Verifier checking for `glm::dvec4`
using DoubleVector4Verifier = Vector4Verifier<double>;
/// A short-hand definition for a Verifier checking for <code>glm::dmat2x2</code>
/// A short-hand definition for a Verifier checking for `glm::dmat2x2`
using DoubleMatrix2x2Verifier = Matrix2x2Verifier<double>;
using DoubleMatrix2Verifier = DoubleMatrix2x2Verifier;
/// A short-hand definition for a Verifier checking for <code>glm::dmat2x3</code>
/// A short-hand definition for a Verifier checking for `glm::dmat2x3`
using DoubleMatrix2x3Verifier = Matrix2x3Verifier<double>;
/// A short-hand definition for a Verifier checking for <code>glm::dmat2x4</code>
/// A short-hand definition for a Verifier checking for `glm::dmat2x4`
using DoubleMatrix2x4Verifier = Matrix2x4Verifier<double>;
/// A short-hand definition for a Verifier checking for <code>glm::dmat3x2</code>
/// A short-hand definition for a Verifier checking for `glm::dmat3x2`
using DoubleMatrix3x2Verifier = Matrix3x2Verifier<double>;
/// A short-hand definition for a Verifier checking for <code>glm::dmat3x3</code>
/// A short-hand definition for a Verifier checking for `glm::dmat3x3`
using DoubleMatrix3x3Verifier = Matrix3x3Verifier<double>;
using DoubleMatrix3Verifier = DoubleMatrix3x3Verifier;
/// A short-hand definition for a Verifier checking for <code>glm::dmat3x4</code>
/// A short-hand definition for a Verifier checking for `glm::dmat3x4`
using DoubleMatrix3x4Verifier = Matrix3x4Verifier<double>;
/// A short-hand definition for a Verifier checking for <code>glm::dmat4x2</code>
/// A short-hand definition for a Verifier checking for `glm::dmat4x2`
using DoubleMatrix4x2Verifier = Matrix4x2Verifier<double>;
/// A short-hand definition for a Verifier checking for <code>glm::dmat4x3</code>
/// A short-hand definition for a Verifier checking for `glm::dmat4x3`
using DoubleMatrix4x3Verifier = Matrix4x3Verifier<double>;
/// A short-hand definition for a Verifier checking for <code>glm::dmat4x4</code>
/// A short-hand definition for a Verifier checking for `glm::dmat4x4`
using DoubleMatrix4x4Verifier = Matrix4x4Verifier<double>;
using DoubleMatrix4Verifier = DoubleMatrix4x4Verifier;
/// A short-hand definition for a LessVerifier with a type check for \c int
/// A short-hand definition for a LessVerifier with a type check for `int`
using IntLessVerifier = LessVerifier<IntVerifier>;
/// A short-hand definition for a LessVerifier with a type check for \c double
/// A short-hand definition for a LessVerifier with a type check for `double`
using DoubleLessVerifier = LessVerifier<DoubleVerifier>;
/// A short-hand definition for a LessEqualVerifier with a type check for \c int
/// A short-hand definition for a LessEqualVerifier with a type check for `int`
using IntLessEqualVerifier = LessEqualVerifier<IntVerifier>;
/// A short-hand definition for a LessEqualVerifier with a type check for \c double
/// A short-hand definition for a LessEqualVerifier with a type check for `double`
using DoubleLessEqualVerifier = LessEqualVerifier<DoubleVerifier>;
/// A short-hand definition for a GreaterVerifier with a type check for \c int
/// A short-hand definition for a GreaterVerifier with a type check for `int`
using IntGreaterVerifier = GreaterVerifier<IntVerifier>;
/// A short-hand definition for a GreaterVerifier with a type check for \c double
/// A short-hand definition for a GreaterVerifier with a type check for `double`
using DoubleGreaterVerifier = GreaterVerifier<DoubleVerifier>;
/// A short-hand definition for a GreaterEqualVerifier with a type check for \c int
/// A short-hand definition for a GreaterEqualVerifier with a type check for `int`
using IntGreaterEqualVerifier = GreaterEqualVerifier<IntVerifier>;
/// A short-hand definition for a GreaterEqualVerifier with a type check for \c double
/// A short-hand definition for a GreaterEqualVerifier with a type check for `double`
using DoubleGreaterEqualVerifier = GreaterEqualVerifier<DoubleVerifier>;
/// A short-hand definition for a EqualVerifier with a type check for \c bool
/// A short-hand definition for a EqualVerifier with a type check for `bool`
using BoolEqualVerifier = EqualVerifier<BoolVerifier>;
/// A short-hand definition for a EqualVerifier with a type check for \c int
/// A short-hand definition for a EqualVerifier with a type check for `int`
using IntEqualVerifier = EqualVerifier<IntVerifier>;
/// A short-hand definition for a EqualVerifier with a type check for \c double
/// A short-hand definition for a EqualVerifier with a type check for `double`
using DoubleEqualVerifier = EqualVerifier<DoubleVerifier>;
/// A short-hand definition for a EqualVerifier with a type check for \c string
/// A short-hand definition for a EqualVerifier with a type check for `string`
using StringEqualVerifier = EqualVerifier<StringVerifier>;
/// A short-hand definition for a UnequalVerifier with a type check for \c bool
/// A short-hand definition for a UnequalVerifier with a type check for `bool`
using BoolUnequalVerifier = UnequalVerifier<BoolVerifier>;
/// A short-hand definition for a UnequalVerifier with a type check for \c int
/// A short-hand definition for a UnequalVerifier with a type check for `int`
using IntUnequalVerifier = UnequalVerifier<IntVerifier>;
/// A short-hand definition for a UnequalVerifier with a type check for \c double
/// A short-hand definition for a UnequalVerifier with a type check for `double`
using DoubleUnequalVerifier = UnequalVerifier<DoubleVerifier>;
/// A short-hand definition for a UnequalVerifier with a type check for \c string
/// A short-hand definition for a UnequalVerifier with a type check for `string`
using StringUnequalVerifier = UnequalVerifier<StringVerifier>;
/// A short-hand definition for a InListVerifier with a type check for \c bool
/// A short-hand definition for a InListVerifier with a type check for `bool`
using BoolInListVerifier = InListVerifier<BoolVerifier>;
/// A short-hand definition for a InListVerifier with a type check for \c int
/// A short-hand definition for a InListVerifier with a type check for `int`
using IntInListVerifier = InListVerifier<IntVerifier>;
/// A short-hand definition for a InListVerifier with a type check for \c double
/// A short-hand definition for a InListVerifier with a type check for `double`
using DoubleInListVerifier = InListVerifier<DoubleVerifier>;
/// A short-hand definition for a InListVerifier with a type check for \c string
/// A short-hand definition for a InListVerifier with a type check for `string`
using StringInListVerifier = InListVerifier<StringVerifier>;
/// A short-hand definition for a NotInListVerifier with a type check for \c bool
/// A short-hand definition for a NotInListVerifier with a type check for `bool`
using BoolNotInListVerifier = NotInListVerifier<BoolVerifier>;
/// A short-hand definition for a NotInListVerifier with a type check for \c int
/// A short-hand definition for a NotInListVerifier with a type check for `int`
using IntNotInListVerifier = NotInListVerifier<IntVerifier>;
/// A short-hand definition for a NotInListVerifier with a type check for \c double
/// A short-hand definition for a NotInListVerifier with a type check for `double`
using DoubleNotInListVerifier = NotInListVerifier<DoubleVerifier>;
/// A short-hand definition for a NotInListVerifier with a type check for \c string
/// A short-hand definition for a NotInListVerifier with a type check for `string`
using StringNotInListVerifier = NotInListVerifier<StringVerifier>;
/// A short-hand definition for a InRangeVerifier with a type check for \c int
/// A short-hand definition for a InRangeVerifier with a type check for `int`
using IntInRangeVerifier = InRangeVerifier<IntVerifier>;
/// A short-hand definition for a InRangeVerifier with a type check for \c double
/// A short-hand definition for a InRangeVerifier with a type check for `double`
using DoubleInRangeVerifier = InRangeVerifier<DoubleVerifier>;
/// A short-hand definition for a NotInRangeVerifier with a type check for \c int
/// A short-hand definition for a InRangeVerifier with a type check for `vec2`
using Vec2InRangeVerifier = InRangeVerifier<DoubleVector2Verifier>;
/// A short-hand definition for a NotInRangeVerifier with a type check for `int`
using IntNotInRangeVerifier = NotInRangeVerifier<IntVerifier>;
/// A short-hand definition for a NotInRangeVerifier with a type check for \c double
/// A short-hand definition for a NotInRangeVerifier with a type check for `double`
using DoubleNotInRangeVerifier = NotInRangeVerifier<DoubleVerifier>;
/// A short-hand definition for a AnnotationVerifier with a type check for \c bool
/// A short-hand definition for a AnnotationVerifier with a type check for `bool`
using BoolAnnotationVerifier = AnnotationVerifier<BoolVerifier>;
/// A short-hand definition for a AnnotationVerifier with a type check for \c int
/// A short-hand definition for a AnnotationVerifier with a type check for `int`
using IntAnnotationVerifier = AnnotationVerifier<IntVerifier>;
/// A short-hand definition for a AnnotationVerifier with a type check for \c double
/// A short-hand definition for a AnnotationVerifier with a type check for `double`
using DoubleAnnotationVerifier = AnnotationVerifier<DoubleVerifier>;
/// A short-hand definition for a AnnotationVerifier with a type check for \c string
/// A short-hand definition for a AnnotationVerifier with a type check for `string`
using StringAnnotationVerifier = AnnotationVerifier<StringVerifier>;
/// A short-hand definition for a AnnotationVerifier with a type check for
/// <code>ghoul::Dictionary</code>
/// `ghoul::Dictionary`
using TableAnnotationVerifier = AnnotationVerifier<TableVerifier>;
/// A short-hand definition for a DeprecatedVerifier with a type check for \c bool
/// A short-hand definition for a DeprecatedVerifier with a type check for `bool`
using BoolDeprecatedVerifier = DeprecatedVerifier<BoolVerifier>;
/// A short-hand definition for a DeprecatedVerifier with a type check for \c int
/// A short-hand definition for a DeprecatedVerifier with a type check for `int`
using IntDeprecatedVerifier = DeprecatedVerifier<IntVerifier>;
/// A short-hand definition for a DeprecatedVerifier with a type check for \c double
/// A short-hand definition for a DeprecatedVerifier with a type check for `double`
using DoubleDeprecatedVerifier = DeprecatedVerifier<DoubleVerifier>;
/// A short-hand definition for a DeprecatedVerifier with a type check for \c string
/// A short-hand definition for a DeprecatedVerifier with a type check for `string`
using StringDeprecatedVerifier = DeprecatedVerifier<StringVerifier>;
/// A short-hand definition for a DeprecatedVerifier with a type check for
/// <code>ghoul::Dictionary</code>
/// `ghoul::Dictionary`
using TableDeprecatedVerifier = DeprecatedVerifier<TableVerifier>;
// Definitions of external templates that are instantiated in the cpp file

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -24,9 +24,388 @@
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/assert.h>
#include <iterator>
#include <sstream>
template <>
struct std::less<glm::vec2> {
bool operator()(const glm::vec2& a, const glm::vec2& b) const {
return a.x < b.x && a.x < b.y;
}
};
template <>
struct std::less<glm::vec3> {
bool operator()(const glm::vec3& a, const glm::vec3& b) const {
return a.x < b.x && a.x < b.y && a.z < b.z;
}
};
template <>
struct std::less<glm::vec4> {
bool operator()(const glm::vec4& a, const glm::vec4& b) const {
return a.x < b.x && a.x < b.y && a.z < b.z && a.w < b.w;
}
};
template <>
struct std::less<glm::ivec2> {
bool operator()(const glm::ivec2& a, const glm::ivec2& b) const {
return a.x < b.x && a.x < b.y;
}
};
template <>
struct std::less<glm::ivec3> {
bool operator()(const glm::ivec3& a, const glm::ivec3& b) const {
return a.x < b.x && a.x < b.y && a.z < b.z;
}
};
template <>
struct std::less<glm::ivec4> {
bool operator()(const glm::ivec4& a, const glm::ivec4& b) const {
return a.x < b.x && a.x < b.y && a.z < b.z && a.w < b.w;
}
};
template <>
struct std::less<glm::dvec2> {
bool operator()(const glm::dvec2& a, const glm::dvec2& b) const {
return a.x < b.x && a.x < b.y;
}
};
template <>
struct std::less<glm::dvec3> {
bool operator()(const glm::dvec3& a, const glm::dvec3& b) const {
return a.x < b.x && a.x < b.y && a.z < b.z;
}
};
template <>
struct std::less<glm::dvec4> {
bool operator()(const glm::dvec4& a, const glm::dvec4& b) const {
return a.x < b.x && a.x < b.y && a.z < b.z && a.w < b.w;
}
};
template <>
struct std::less_equal<glm::vec2> {
bool operator()(const glm::vec2& a, const glm::vec2& b) const {
return a.x <= b.x && a.x <= b.y;
}
};
template <>
struct std::less_equal<glm::vec3> {
bool operator()(const glm::vec3& a, const glm::vec3& b) const {
return a.x <= b.x && a.x <= b.y && a.z <= b.z;
}
};
template <>
struct std::less_equal<glm::vec4> {
bool operator()(const glm::vec4& a, const glm::vec4& b) const {
return a.x <= b.x && a.x <= b.y && a.z <= b.z && a.w <= b.w;
}
};
template <>
struct std::less_equal<glm::ivec2> {
bool operator()(const glm::ivec2& a, const glm::ivec2& b) const {
return a.x <= b.x && a.x <= b.y;
}
};
template <>
struct std::less_equal<glm::ivec3> {
bool operator()(const glm::ivec3& a, const glm::ivec3& b) const {
return a.x <= b.x && a.x <= b.y && a.z <= b.z;
}
};
template <>
struct std::less_equal<glm::ivec4> {
bool operator()(const glm::ivec4& a, const glm::ivec4& b) const {
return a.x <= b.x && a.x <= b.y && a.z <= b.z && a.w <= b.w;
}
};
template <>
struct std::less_equal<glm::dvec2> {
bool operator()(const glm::dvec2& a, const glm::dvec2& b) const {
return a.x <= b.x && a.x <= b.y;
}
};
template <>
struct std::less_equal<glm::dvec3> {
bool operator()(const glm::dvec3& a, const glm::dvec3& b) const {
return a.x <= b.x && a.x <= b.y && a.z <= b.z;
}
};
template <>
struct std::less_equal<glm::dvec4> {
bool operator()(const glm::dvec4& a, const glm::dvec4& b) const {
return a.x <= b.x && a.x <= b.y && a.z <= b.z && a.w <= b.w;
}
};
template <>
struct std::greater<glm::vec2> {
bool operator()(const glm::vec2& a, const glm::vec2& b) const {
return a.x > b.x && a.x > b.y;
}
};
template <>
struct std::greater<glm::vec3> {
bool operator()(const glm::vec3& a, const glm::vec3& b) const {
return a.x > b.x && a.x > b.y && a.z > b.z;
}
};
template <>
struct std::greater<glm::vec4> {
bool operator()(const glm::vec4& a, const glm::vec4& b) const {
return a.x > b.x && a.x > b.y && a.z > b.z && a.w > b.w;
}
};
template <>
struct std::greater<glm::ivec2> {
bool operator()(const glm::ivec2& a, const glm::ivec2& b) const {
return a.x > b.x && a.x > b.y;
}
};
template <>
struct std::greater<glm::ivec3> {
bool operator()(const glm::ivec3& a, const glm::ivec3& b) const {
return a.x > b.x && a.x > b.y && a.z > b.z;
}
};
template <>
struct std::greater<glm::ivec4> {
bool operator()(const glm::ivec4& a, const glm::ivec4& b) const {
return a.x > b.x && a.x > b.y && a.z > b.z && a.w > b.w;
}
};
template <>
struct std::greater<glm::dvec2> {
bool operator()(const glm::dvec2& a, const glm::dvec2& b) const {
return a.x > b.x && a.x > b.y;
}
};
template <>
struct std::greater<glm::dvec3> {
bool operator()(const glm::dvec3& a, const glm::dvec3& b) const {
return a.x > b.x && a.x > b.y && a.z > b.z;
}
};
template <>
struct std::greater<glm::dvec4> {
bool operator()(const glm::dvec4& a, const glm::dvec4& b) const {
return a.x > b.x && a.x > b.y && a.z > b.z && a.w > b.w;
}
};
template <>
struct std::greater_equal<glm::vec2> {
bool operator()(const glm::vec2& a, const glm::vec2& b) const {
return a.x >= b.x && a.x >= b.y;
}
};
template <>
struct std::greater_equal<glm::vec3> {
bool operator()(const glm::vec3& a, const glm::vec3& b) const {
return a.x >= b.x && a.x >= b.y && a.z >= b.z;
}
};
template <>
struct std::greater_equal<glm::vec4> {
bool operator()(const glm::vec4& a, const glm::vec4& b) const {
return a.x >= b.x && a.x >= b.y && a.z >= b.z && a.w >= b.w;
}
};
template <>
struct std::greater_equal<glm::ivec2> {
bool operator()(const glm::ivec2& a, const glm::ivec2& b) const {
return a.x >= b.x && a.x >= b.y;
}
};
template <>
struct std::greater_equal<glm::ivec3> {
bool operator()(const glm::ivec3& a, const glm::ivec3& b) const {
return a.x >= b.x && a.x >= b.y && a.z >= b.z;
}
};
template <>
struct std::greater_equal<glm::ivec4> {
bool operator()(const glm::ivec4& a, const glm::ivec4& b) const {
return a.x >= b.x && a.x >= b.y && a.z >= b.z && a.w >= b.w;
}
};
template <>
struct std::greater_equal<glm::dvec2> {
bool operator()(const glm::dvec2& a, const glm::dvec2& b) const {
return a.x >= b.x && a.x >= b.y;
}
};
template <>
struct std::greater_equal<glm::dvec3> {
bool operator()(const glm::dvec3& a, const glm::dvec3& b) const {
return a.x >= b.x && a.x >= b.y && a.z >= b.z;
}
};
template <>
struct std::greater_equal<glm::dvec4> {
bool operator()(const glm::dvec4& a, const glm::dvec4& b) const {
return a.x >= b.x && a.x >= b.y && a.z >= b.z && a.w >= b.w;
}
};
template <>
struct std::equal_to<glm::vec2> {
bool operator()(const glm::vec2& a, const glm::vec2& b) const {
return a.x == b.x && a.x == b.y;
}
};
template <>
struct std::equal_to<glm::vec3> {
bool operator()(const glm::vec3& a, const glm::vec3& b) const {
return a.x == b.x && a.x == b.y && a.z == b.z;
}
};
template <>
struct std::equal_to<glm::vec4> {
bool operator()(const glm::vec4& a, const glm::vec4& b) const {
return a.x == b.x && a.x == b.y && a.z == b.z && a.w == b.w;
}
};
template <>
struct std::equal_to<glm::ivec2> {
bool operator()(const glm::ivec2& a, const glm::ivec2& b) const {
return a.x == b.x && a.x == b.y;
}
};
template <>
struct std::equal_to<glm::ivec3> {
bool operator()(const glm::ivec3& a, const glm::ivec3& b) const {
return a.x == b.x && a.x == b.y && a.z == b.z;
}
};
template <>
struct std::equal_to<glm::ivec4> {
bool operator()(const glm::ivec4& a, const glm::ivec4& b) const {
return a.x == b.x && a.x == b.y && a.z == b.z && a.w == b.w;
}
};
template <>
struct std::equal_to<glm::dvec2> {
bool operator()(const glm::dvec2& a, const glm::dvec2& b) const {
return a.x == b.x && a.x == b.y;
}
};
template <>
struct std::equal_to<glm::dvec3> {
bool operator()(const glm::dvec3& a, const glm::dvec3& b) const {
return a.x == b.x && a.x == b.y && a.z == b.z;
}
};
template <>
struct std::equal_to<glm::dvec4> {
bool operator()(const glm::dvec4& a, const glm::dvec4& b) const {
return a.x == b.x && a.x == b.y && a.z == b.z && a.w == b.w;
}
};
template <>
struct std::not_equal_to<glm::vec2> {
bool operator()(const glm::vec2& a, const glm::vec2& b) const {
return a.x != b.x && a.x != b.y;
}
};
template <>
struct std::not_equal_to<glm::vec3> {
bool operator()(const glm::vec3& a, const glm::vec3& b) const {
return a.x != b.x && a.x != b.y && a.z != b.z;
}
};
template <>
struct std::not_equal_to<glm::vec4> {
bool operator()(const glm::vec4& a, const glm::vec4& b) const {
return a.x != b.x && a.x != b.y && a.z != b.z && a.w != b.w;
}
};
template <>
struct std::not_equal_to<glm::ivec2> {
bool operator()(const glm::ivec2& a, const glm::ivec2& b) const {
return a.x != b.x && a.x != b.y;
}
};
template <>
struct std::not_equal_to<glm::ivec3> {
bool operator()(const glm::ivec3& a, const glm::ivec3& b) const {
return a.x != b.x && a.x != b.y && a.z != b.z;
}
};
template <>
struct std::not_equal_to<glm::ivec4> {
bool operator()(const glm::ivec4& a, const glm::ivec4& b) const {
return a.x != b.x && a.x != b.y && a.z != b.z && a.w != b.w;
}
};
template <>
struct std::not_equal_to<glm::dvec2> {
bool operator()(const glm::dvec2& a, const glm::dvec2& b) const {
return a.x != b.x && a.x != b.y;
}
};
template <>
struct std::not_equal_to<glm::dvec3> {
bool operator()(const glm::dvec3& a, const glm::dvec3& b) const {
return a.x != b.x && a.x != b.y && a.z != b.z;
}
};
template <>
struct std::not_equal_to<glm::dvec4> {
bool operator()(const glm::dvec4& a, const glm::dvec4& b) const {
return a.x != b.x && a.x != b.y && a.z != b.z && a.w != b.w;
}
};
namespace openspace::documentation {
template <>
@@ -75,62 +454,158 @@ std::string TemplateVerifier<T>::documentation() const {
template <typename T>
std::string Vector2Verifier<T>::type() const {
return std::string("Vector2<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Vector2<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Vector2<double>";
}
else {
return std::string("Vector2<") + typeid(T).name() + ">";
}
}
template <typename T>
std::string Vector3Verifier<T>::type() const {
return std::string("Vector3<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Vector3<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Vector3<double>";
}
else {
return std::string("Vector3<") + typeid(T).name() + ">";
}
}
template <typename T>
std::string Vector4Verifier<T>::type() const {
return std::string("Vector4<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Vector4<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Vector4<double>";
}
else {
return std::string("Vector4<") + typeid(T).name() + ">";
}
}
template <typename T>
std::string Matrix2x2Verifier<T>::type() const {
return std::string("Matrix2x2<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Matrix2x2<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Matrix2x2<double>";
}
else {
return std::string("Matrix2x2<") + typeid(T).name() + ">";
}
}
template <typename T>
std::string Matrix2x3Verifier<T>::type() const {
return std::string("Matrix2x3<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Matrix2x3<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Matrix2x3<double>";
}
else {
return std::string("Matrix2x3<") + typeid(T).name() + ">";
}
}
template <typename T>
std::string Matrix2x4Verifier<T>::type() const {
return std::string("Matrix2x4<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Matrix2x4<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Matrix2x4<double>";
}
else {
return std::string("Matrix2x4<") + typeid(T).name() + ">";
}
}
template <typename T>
std::string Matrix3x2Verifier<T>::type() const {
return std::string("Matrix3x2<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Matrix3x2<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Matrix3x2<double>";
}
else {
return std::string("Matrix3x2<") + typeid(T).name() + ">";
}
}
template <typename T>
std::string Matrix3x3Verifier<T>::type() const {
return std::string("Matrix3x3<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Matrix3x3<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Matrix3x3<double>";
}
else {
return std::string("Matrix3x3<") + typeid(T).name() + ">";
}
}
template <typename T>
std::string Matrix3x4Verifier<T>::type() const {
return std::string("Matrix3x4<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Matrix3x4<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Matrix3x4<double>";
}
else {
return std::string("Matrix3x4<") + typeid(T).name() + ">";
}
}
template <typename T>
std::string Matrix4x2Verifier<T>::type() const {
return std::string("Matrix4x2<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Matrix4x2<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Matrix4x2<double>";
}
else {
return std::string("Matrix4x2<") + typeid(T).name() + ">";
}
}
template <typename T>
std::string Matrix4x3Verifier<T>::type() const {
return std::string("Matrix4x3<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Matrix4x3<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Matrix4x3<double>";
}
else {
return std::string("Matrix4x3<") + typeid(T).name() + ">";
}
}
template <typename T>
std::string Matrix4x4Verifier<T>::type() const {
return std::string("Matrix4x4<") + typeid(T).name() + ">";
if constexpr (std::is_same_v<T, int>) {
return "Matrix4x4<int>";
}
else if constexpr (std::is_same_v<T, double>) {
return "Matrix4x4<double>";
}
else {
return std::string("Matrix4x4<") + typeid(T).name() + ">";
}
}
template <typename T, typename Operator>
@@ -145,7 +620,16 @@ TestResult OperatorVerifier<T, Operator>::operator()(const ghoul::Dictionary& di
TestResult res = T::operator()(dict, key);
if (res.success) {
typename T::Type val;
if constexpr (std::is_same_v<typename T::Type, int>) {
if constexpr (std::is_same_v<typename T::Type, glm::ivec2>) {
val = dict.value<glm::dvec2>(key);
}
else if constexpr (std::is_same_v<typename T::Type, glm::ivec3>) {
val = dict.value<glm::dvec3>(key);
}
else if constexpr (std::is_same_v<typename T::Type, glm::ivec4>) {
val = dict.value<glm::dvec4>(key);
}
else if constexpr (std::is_same_v<typename T::Type, int>) {
const double d = dict.value<double>(key);
double intPart;
bool isInt = modf(d, &intPart) == 0.0;
@@ -165,6 +649,7 @@ TestResult OperatorVerifier<T, Operator>::operator()(const ghoul::Dictionary& di
else {
val = dict.value<typename T::Type>(key);
}
if (Operator()(val, value)) {
return { true, {}, {} };
}
@@ -175,7 +660,7 @@ TestResult OperatorVerifier<T, Operator>::operator()(const ghoul::Dictionary& di
o.offender = key;
o.reason = TestResult::Offense::Reason::Verification;
r.offenses.push_back(o);
return r;
return r;
}
}
else {
@@ -224,10 +709,38 @@ TestResult InListVerifier<T>::operator()(const ghoul::Dictionary& dict,
{
TestResult res = T::operator()(dict, key);
if (res.success) {
typename T::Type value = dict.value<typename T::Type>(key);
auto it = std::find(values.begin(), values.end(), value);
typename T::Type val;
if constexpr (std::is_same_v<typename T::Type, glm::ivec2>) {
val = dict.value<glm::dvec2>(key);
}
else if constexpr (std::is_same_v<typename T::Type, glm::ivec3>) {
val = dict.value<glm::dvec3>(key);
}
else if constexpr (std::is_same_v<typename T::Type, glm::ivec4>) {
val = dict.value<glm::dvec4>(key);
}
else if constexpr (std::is_same_v<typename T::Type, int>) {
const double d = dict.value<double>(key);
double intPart;
bool isInt = modf(d, &intPart) == 0.0;
if (isInt) {
val = static_cast<int>(d);
}
else {
TestResult r;
r.success = false;
TestResult::Offense o;
o.offender = key;
o.reason = TestResult::Offense::Reason::WrongType;
r.offenses.push_back(o);
return r;
}
}
else {
val = dict.value<typename T::Type>(key);
}
auto it = std::find(values.begin(), values.end(), val);
if (it != values.end()) {
return { true, {}, {} };
}
@@ -276,10 +789,38 @@ TestResult NotInListVerifier<T>::operator()(const ghoul::Dictionary& dict,
{
TestResult res = T::operator()(dict, key);
if (res.success) {
typename T::Type value = dict.value<typename T::Type>(key);
auto it = std::find(values.begin(), values.end(), value);
typename T::Type val;
if constexpr (std::is_same_v<typename T::Type, glm::ivec2>) {
val = dict.value<glm::dvec2>(key);
}
else if constexpr (std::is_same_v<typename T::Type, glm::ivec3>) {
val = dict.value<glm::dvec3>(key);
}
else if constexpr (std::is_same_v<typename T::Type, glm::ivec4>) {
val = dict.value<glm::dvec4>(key);
}
else if constexpr (std::is_same_v<typename T::Type, int>) {
const double d = dict.value<double>(key);
double intPart;
bool isInt = modf(d, &intPart) == 0.0;
if (isInt) {
val = static_cast<int>(d);
}
else {
TestResult r;
r.success = false;
TestResult::Offense o;
o.offender = key;
o.reason = TestResult::Offense::Reason::WrongType;
r.offenses.push_back(o);
return r;
}
}
else {
val = dict.value<typename T::Type>(key);
}
auto it = std::find(values.begin(), values.end(), val);
if (it == values.end()) {
return { true, {}, {} };
}
@@ -290,7 +831,7 @@ TestResult NotInListVerifier<T>::operator()(const ghoul::Dictionary& dict,
o.offender = key;
o.reason = TestResult::Offense::Reason::Verification;
r.offenses.push_back(o);
return r;
return r;
}
}
else {
@@ -322,7 +863,30 @@ InRangeVerifier<T>::InRangeVerifier(typename T::Type l, typename T::Type u)
: lower(std::move(l))
, upper(std::move(u))
{
ghoul_assert(lower <= upper, "lower must be smaller or equal to upper");
if constexpr (std::is_same_v<IntVector2Verifier, T> ||
std::is_same_v<DoubleVector2Verifier, T>)
{
ghoul_assert(lower.x <= upper.x, "lower must be smaller or equal to upper for x");
ghoul_assert(lower.y <= upper.y, "lower must be smaller or equal to upper for y");
}
else if constexpr (std::is_same_v<IntVector3Verifier, T> ||
std::is_same_v<DoubleVector3Verifier, T>)
{
ghoul_assert(lower.x <= upper.x, "lower must be smaller or equal to upper for x");
ghoul_assert(lower.y <= upper.y, "lower must be smaller or equal to upper for y");
ghoul_assert(lower.z <= upper.z, "lower must be smaller or equal to upper for z");
}
else if constexpr (std::is_same_v<IntVector4Verifier, T> ||
std::is_same_v<DoubleVector4Verifier, T>)
{
ghoul_assert(lower.x <= upper.x, "lower must be smaller or equal to upper for x");
ghoul_assert(lower.y <= upper.y, "lower must be smaller or equal to upper for y");
ghoul_assert(lower.z <= upper.z, "lower must be smaller or equal to upper for z");
ghoul_assert(lower.w <= upper.w, "lower must be smaller or equal to upper for w");
}
else {
ghoul_assert(lower <= upper, "lower must be smaller or equal to upper");
}
}
template <typename T>
@@ -332,7 +896,16 @@ TestResult InRangeVerifier<T>::operator()(const ghoul::Dictionary& dict,
TestResult res = T::operator()(dict, key);
if (res.success) {
typename T::Type val;
if constexpr (std::is_same_v<typename T::Type, int>) {
if constexpr (std::is_same_v<typename T::Type, glm::ivec2>) {
val = dict.value<glm::dvec2>(key);
}
else if constexpr (std::is_same_v<typename T::Type, glm::ivec3>) {
val = dict.value<glm::dvec3>(key);
}
else if constexpr (std::is_same_v<typename T::Type, glm::ivec4>) {
val = dict.value<glm::dvec4>(key);
}
else if constexpr (std::is_same_v<typename T::Type, int>) {
const double d = dict.value<double>(key);
double intPart;
bool isInt = modf(d, &intPart) == 0.0;
@@ -346,14 +919,16 @@ TestResult InRangeVerifier<T>::operator()(const ghoul::Dictionary& dict,
o.offender = key;
o.reason = TestResult::Offense::Reason::WrongType;
r.offenses.push_back(o);
return r;
return r;
}
}
else {
val = dict.value<typename T::Type>(key);
}
if (val >= lower && val <= upper) {
if (std::greater_equal<typename T::Type>()(val, lower) &&
std::less_equal<typename T::Type>()(val, upper))
{
return { true, {}, {} };
}
else {
@@ -363,7 +938,7 @@ TestResult InRangeVerifier<T>::operator()(const ghoul::Dictionary& dict,
o.offender = key;
o.reason = TestResult::Offense::Reason::Verification;
r.offenses.push_back(o);
return r;
return r;
}
}
else {
@@ -382,7 +957,30 @@ NotInRangeVerifier<T>::NotInRangeVerifier(typename T::Type l, typename T::Type u
: lower(std::move(l))
, upper(std::move(u))
{
ghoul_assert(lower <= upper, "lower must be smaller or equal to upper");
if constexpr (std::is_same_v<IntVector2Verifier, T> ||
std::is_same_v<DoubleVector2Verifier, T>)
{
ghoul_assert(lower.x <= upper.x, "lower must be smaller or equal to upper for x");
ghoul_assert(lower.y <= upper.y, "lower must be smaller or equal to upper for y");
}
else if constexpr (std::is_same_v<IntVector3Verifier, T> ||
std::is_same_v<DoubleVector3Verifier, T>)
{
ghoul_assert(lower.x <= upper.x, "lower must be smaller or equal to upper for x");
ghoul_assert(lower.y <= upper.y, "lower must be smaller or equal to upper for y");
ghoul_assert(lower.z <= upper.z, "lower must be smaller or equal to upper for z");
}
else if constexpr (std::is_same_v<IntVector4Verifier, T> ||
std::is_same_v<DoubleVector4Verifier, T>)
{
ghoul_assert(lower.x <= upper.x, "lower must be smaller or equal to upper for x");
ghoul_assert(lower.y <= upper.y, "lower must be smaller or equal to upper for y");
ghoul_assert(lower.z <= upper.z, "lower must be smaller or equal to upper for z");
ghoul_assert(lower.w <= upper.w, "lower must be smaller or equal to upper for w");
}
else {
ghoul_assert(lower <= upper, "lower must be smaller or equal to upper");
}
}
template <typename T>
@@ -391,7 +989,16 @@ TestResult NotInRangeVerifier<T>::operator()(const ghoul::Dictionary& dict,
TestResult res = T::operator()(dict, key);
if (res.success) {
typename T::Type val;
if constexpr (std::is_same_v<typename T::Type, int>) {
if constexpr (std::is_same_v<typename T::Type, glm::ivec2>) {
val = dict.value<glm::dvec2>(key);
}
else if constexpr (std::is_same_v<typename T::Type, glm::ivec3>) {
val = dict.value<glm::dvec3>(key);
}
else if constexpr (std::is_same_v<typename T::Type, glm::ivec4>) {
val = dict.value<glm::dvec4>(key);
}
else if constexpr (std::is_same_v<typename T::Type, int>) {
const double d = dict.value<double>(key);
double intPart;
bool isInt = modf(d, &intPart) == 0.0;
@@ -405,24 +1012,26 @@ TestResult NotInRangeVerifier<T>::operator()(const ghoul::Dictionary& dict,
o.offender = key;
o.reason = TestResult::Offense::Reason::WrongType;
r.offenses.push_back(o);
return r;
return r;
}
}
else {
val = dict.value<typename T::Type>(key);
}
if (val >= lower && val <= upper) {
if (std::less<typename T::Type>()(val, lower) ||
std::greater<typename T::Type>()(val, upper))
{
return { true, {}, {} };
}
else {
TestResult r;
r.success = false;
TestResult::Offense o;
o.offender = key;
o.reason = TestResult::Offense::Reason::Verification;
r.offenses.push_back(o);
return r;
}
else {
return { true, {}, {} };
return r;
}
}
else {

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -53,6 +53,15 @@ struct Configuration {
};
std::map<std::string, std::string> fonts;
struct FontSizes {
float frameInfo;
float shutdown;
float log;
float cameraInfo;
float versionInfo;
};
FontSizes fontSize;
struct Logging {
std::string level = "Info";
bool forceImmediateFlush = false;
@@ -80,6 +89,7 @@ struct Configuration {
bool isCheckingOpenGLState = false;
bool isLoggingOpenGLCalls = false;
bool isPrintingEvents = false;
float shutdownCountdown = 0.f;
@@ -89,18 +99,17 @@ struct Configuration {
bool usePerProfileCache = false;
bool isRenderingOnMasterDisabled = false;
glm::dvec3 globalRotation = glm::dvec3(0.0);
glm::dvec3 screenSpaceRotation = glm::dvec3(0.0);
glm::dvec3 masterRotation = glm::dvec3(0.0);
glm::vec3 globalRotation = glm::vec3(0.0);
glm::vec3 screenSpaceRotation = glm::vec3(0.0);
glm::vec3 masterRotation = glm::vec3(0.0);
bool isConsoleDisabled = false;
bool bypassLauncher = false;
std::map<std::string, ghoul::Dictionary> moduleConfigurations;
std::string renderingMethod = "Framebuffer";
struct OpenGLDebugContext {
bool isActive = false;
bool printStacktrace = false;
bool isSynchronous = true;
struct IdentifierFilter {
std::string type;
@@ -123,7 +132,6 @@ struct Configuration {
HTTPProxy httpProxy;
// Values not read from the openspace.cfg file
bool usingProfile = false;
std::string sgctConfigNameInitialized;
static documentation::Documentation Documentation;
@@ -133,7 +141,7 @@ struct Configuration {
std::filesystem::path findConfiguration(const std::string& filename = "openspace.cfg");
Configuration loadConfigurationFromFile(const std::filesystem::path& filename,
const std::string& overrideScript);
const glm::ivec2& primaryMonitorResolution, std::string_view overrideScript);
} // namespace openspace::configuration

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -61,10 +61,10 @@ public:
};
struct MemoryFile {
char* buffer;
size_t size;
char* buffer = nullptr;
size_t size = 0;
std::string format;
bool corrupted;
bool corrupted = false;
};
BooleanType(UseMultipleThreads);

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -36,6 +36,7 @@ namespace openspace {
class Dashboard;
class DeferredcasterManager;
class DownloadManager;
class EventEngine;
class LuaConsole;
class MemoryManager;
class MissionManager;
@@ -48,12 +49,12 @@ class ScreenSpaceRenderable;
class SyncEngine;
class TimeManager;
class VersionChecker;
class VirtualPropertyManager;
struct WindowDelegate;
namespace configuration { struct Configuration; }
namespace interaction {
struct JoystickInputStates;
struct WebsocketInputStates;
class ActionManager;
class InteractionMonitor;
class KeybindingManager;
class NavigationHandler;
@@ -73,6 +74,7 @@ inline ghoul::fontrendering::FontManager* fontManager;
inline Dashboard* dashboard;
inline DeferredcasterManager* deferredcasterManager;
inline DownloadManager* downloadManager;
inline EventEngine* eventEngine;
inline LuaConsole* luaConsole;
inline MemoryManager* memoryManager;
inline MissionManager* missionManager;
@@ -85,9 +87,9 @@ inline std::vector<std::unique_ptr<ScreenSpaceRenderable>>* screenSpaceRenderabl
inline SyncEngine* syncEngine;
inline TimeManager* timeManager;
inline VersionChecker* versionChecker;
inline VirtualPropertyManager* virtualPropertyManager;
inline WindowDelegate* windowDelegate;
inline configuration::Configuration* configuration;
inline interaction::ActionManager* actionManager;
inline interaction::InteractionMonitor* interactionMonitor;
inline interaction::JoystickInputStates* joystickInputStates;
inline interaction::WebsocketInputStates* websocketInputStates;
@@ -97,6 +99,7 @@ inline interaction::SessionRecording* sessionRecording;
inline interaction::ShortcutManager* shortcutManager;
inline properties::PropertyOwner* rootPropertyOwner;
inline properties::PropertyOwner* screenSpaceRootPropertyOwner;
inline properties::PropertyOwner* userPropertyOwner;
inline scripting::ScriptEngine* scriptEngine;
inline scripting::ScriptScheduler* scriptScheduler;
inline Profile* profile;

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -28,11 +28,23 @@
#include <openspace/util/keys.h>
#include <openspace/util/mouse.h>
#include <openspace/util/touch.h>
#include <ghoul/misc/boolean.h>
#include <functional>
#include <vector>
namespace openspace {
BooleanType(IsGuiWindow);
} // namespace openspace
namespace openspace::global::callback {
using KeyboardCallback = std::function<bool(Key, KeyModifier, KeyAction, IsGuiWindow)>;
using CharacterCallback = std::function<bool(unsigned int, KeyModifier, IsGuiWindow)>;
using MouseButtonCallback =
std::function<bool(MouseButton, MouseAction, KeyModifier, IsGuiWindow)>;
using MousePositionCallback = std::function<void(double, double, IsGuiWindow)>;
using MouseScrollWheelCallback = std::function<bool(double, double, IsGuiWindow)>;
inline std::vector<std::function<void()>>* initialize;
inline std::vector<std::function<void()>>* deinitialize;
inline std::vector<std::function<void()>>* initializeGL;
@@ -42,12 +54,11 @@ inline std::vector<std::function<void()>>* postSyncPreDraw;
inline std::vector<std::function<void()>>* render;
inline std::vector<std::function<void()>>* draw2D;
inline std::vector<std::function<void()>>* postDraw;
inline std::vector<std::function<bool(Key, KeyModifier, KeyAction)>>* keyboard;
inline std::vector<std::function<bool(unsigned int, KeyModifier)>>* character;
inline std::vector<std::function<bool(MouseButton, MouseAction, KeyModifier)>>*
mouseButton;
inline std::vector<std::function<void(double, double)>>* mousePosition;
inline std::vector<std::function<bool(double, double)>>* mouseScrollWheel;
inline std::vector<KeyboardCallback>* keyboard;
inline std::vector<CharacterCallback>* character;
inline std::vector<MouseButtonCallback>* mouseButton;
inline std::vector<MousePositionCallback>* mousePosition;
inline std::vector<MouseScrollWheelCallback>* mouseScrollWheel;
inline std::vector<std::function<bool(TouchInput)>>* touchDetected;
inline std::vector<std::function<bool(TouchInput)>>* touchUpdated;
inline std::vector<std::function<void(TouchInput)>>* touchExit;

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -36,18 +36,16 @@ namespace documentation { struct Documentation; }
/**
* This function provides the capabilities to create a new ghoul::logging::Log from the
* provided ghoul::Dictionary%. The Dictionary must at least contain a <code>Type</code>
* value that determines the type of the created Log. Currently the types
* <code>HTML</code> and <code>Text</code> are supported which create a
* ghoul::logging::TextLog%, and ghoul::logging::HTMLLog respectively with both also
* require the <code>FileName</code> value for the location at which the logfile should be
* created . Both logs can be customized using the <code>Append</code>,
* <code>TimeStamping</code>, <code>DateStamping</code>, <code>CategoryStamping</code>,
* and <code>LogLevelStamping</code> values.
* provided ghoul::Dictionary%. The Dictionary must at least contain a `Type` value that
* determines the type of the created Log. Currently the types `HTML` and `Text` are
* supported which create a ghoul::logging::TextLog%, and ghoul::logging::HTMLLog
* respectively with both also require the `FileName` value for the location at which the
* logfile should be created. Both logs can be customized using the `Append`,
* `TimeStamping`, `DateStamping`, `CategoryStamping`, and `LogLevelStamping` values.
*
* \param dictionary The dictionary from which the ghoul::logging::Log should be created
* \return The created ghoul::logging::Log
* \post The return value will not be <code>nullptr</code>
* \post The return value will not be `nullptr`
* \throw ghoul::RuntimeError If there was an error creating the ghoul::logging::Log
* \sa ghoul::logging::TextLog
* \sa ghoul::logging::HTMLLog

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -27,6 +27,7 @@
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/list/stringlistproperty.h>
#include <map>
#include <memory>
#include <vector>
@@ -44,7 +45,7 @@ namespace scripting { struct LuaLibrary; }
* The ModuleEngine is the central repository for registering and accessing
* OpenSpaceModule for the current application run. By initializing (#initialize) the
* ModuleEngine, the default set of OpenSpaceModule%s as generated by CMake in the
* <code>moduleregistration.h</code> file is automatically registered and created.
* `moduleregistration.h` file is automatically registered and created.
* Additional OpenSpaceModule%s can be registered with the #registerModule function, which
* will internally call the OpenSpaceModule::initialize method.
*/
@@ -54,7 +55,7 @@ public:
/**
* Registers all of the OpenSpaceModule%s which are created by the CMake configuration
* and stored in the <code>moduleregistration.h</code> file. For all of those modules
* and stored in the `moduleregistration.h` file. For all of those modules
* the OpenSpaceModule::initialize method with will called.
*
* \throw ghoul::RuntimeError If two modules in the default modules have the same
@@ -100,7 +101,7 @@ public:
/**
* Get the module subclass with given template argument. Requires the module subclass
* to have the public static member variable <code>name</code> which must be equal to
* to have the public static member variable `name` which must be equal to
* the name of the module used in its constructor.
*
* \return a pointer to the module of the given subclass
@@ -123,7 +124,10 @@ public:
static scripting::LuaLibrary luaLibrary();
private:
/// The list of all registered OpenSpaceModule%s
/// The list of all names of all registered OpenSpaceModules
properties::StringListProperty _allModules;
/// The list of all registered OpenSpaceModules
std::vector<std::unique_ptr<OpenSpaceModule>> _modules;
};

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,7 +25,13 @@
#ifndef __OPENSPACE_CORE___OPENSPACEENGINE___H__
#define __OPENSPACE_CORE___OPENSPACEENGINE___H__
#include <openspace/engine/globalscallbacks.h>
#include <openspace/properties/optionproperty.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/property.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/scene/profile.h>
#include <openspace/util/keys.h>
#include <openspace/util/mouse.h>
#include <openspace/util/touch.h>
@@ -58,13 +64,22 @@ struct ShutdownInformation {
struct CommandlineArguments {
std::string configurationName;
std::string configurationOverride;
std::vector<std::string> configurationOverride;
};
class OpenSpaceEngine {
class OpenSpaceEngine : public properties::PropertyOwner {
public:
// A mode that specifies which part of the system is currently in control.
// The mode can be used to limit certain features, like setting time, navigation
// or triggering scripts
enum class Mode {
UserControl = 0,
SessionRecordingPlayback,
CameraPath
};
OpenSpaceEngine();
~OpenSpaceEngine();
~OpenSpaceEngine() override;
void registerPathTokens();
void initialize();
@@ -78,27 +93,40 @@ public:
void drawOverlays();
void postDraw();
void resetPropertyChangeFlags();
void keyboardCallback(Key key, KeyModifier mod, KeyAction action);
void charCallback(unsigned int codepoint, KeyModifier modifier);
void mouseButtonCallback(MouseButton button, MouseAction action, KeyModifier mods);
void mousePositionCallback(double x, double y);
void mouseScrollWheelCallback(double posX, double posY);
void keyboardCallback(Key key, KeyModifier mod, KeyAction action,
IsGuiWindow isGuiWindow);
void charCallback(unsigned int codepoint, KeyModifier modifier,
IsGuiWindow isGuiWindow);
void mouseButtonCallback(MouseButton button, MouseAction action,
KeyModifier mods, IsGuiWindow isGuiWindow);
void mousePositionCallback(double x, double y, IsGuiWindow isGuiWindow);
void mouseScrollWheelCallback(double posX, double posY, IsGuiWindow isGuiWindow);
void touchDetectionCallback(TouchInput input);
void touchUpdateCallback(TouchInput input);
void touchExitCallback(TouchInput input);
void handleDragDrop(const std::string& file);
void handleDragDrop(std::filesystem::path file);
std::vector<std::byte> encode();
void decode(std::vector<std::byte> data);
void scheduleLoadSingleAsset(std::string assetPath);
properties::Property::Visibility visibility() const;
bool showHiddenSceneGraphNodes() const;
void toggleShutdownMode();
Mode currentMode() const;
bool setMode(Mode newMode);
void resetMode();
using CallbackHandle = int;
using ModeChangeCallback = std::function<void()>;
CallbackHandle addModeChangeCallback(ModeChangeCallback cb);
void removeModeChangeCallback(CallbackHandle handle);
// Guaranteed to return a valid pointer
AssetManager& assetManager();
LoadingScreen* loadingScreen();
void writeSceneDocumentation();
void writeStaticDocumentation();
void writeDocumentation();
void createUserDirectoriesIfNecessary();
/**
@@ -108,27 +136,24 @@ public:
static scripting::LuaLibrary luaLibrary();
private:
void loadSingleAsset(const std::string& assetPath);
void loadAssets();
void loadFonts();
void runGlobalCustomizationScripts();
void configureLogging();
std::string generateFilePath(std::string openspaceRelativePath);
void resetPropertyChangeFlagsOfSubowners(openspace::properties::PropertyOwner* po);
properties::BoolProperty _printEvents;
properties::OptionProperty _visibility;
properties::BoolProperty _showHiddenSceneGraphNodes;
properties::BoolProperty _disableAllMouseInputs;
std::unique_ptr<Scene> _scene;
std::unique_ptr<AssetManager> _assetManager;
bool _shouldAbortLoading = false;
std::unique_ptr<LoadingScreen> _loadingScreen;
std::unique_ptr<VersionChecker> _versionChecker;
bool _hasScheduledAssetLoading = false;
std::string _scheduledAssetPathToLoad;
glm::vec2 _mousePosition;
//grabs json from each module to pass to the documentation engine.
std::string _documentationJson;
glm::vec2 _mousePosition = glm::vec2(0.f);
std::future<void> _writeDocumentationTask;
@@ -136,16 +161,65 @@ private:
// The first frame might take some more time in the update loop, so we need to know to
// disable the synchronization; otherwise a hardware sync will kill us after 1 minute
bool _isFirstRenderingFirstFrame = true;
bool _isRenderingFirstFrame = true;
Mode _currentMode = Mode::UserControl;
Mode _modeLastFrame = Mode::UserControl;
int _nextCallbackHandle = 0;
std::vector<std::pair<CallbackHandle, ModeChangeCallback>> _modeChangeCallbacks;
};
/**
* Sets the camera position using the time contents of a profile. The function will
* set an absolute position or a go-to-geolocation command using the globebrowsing
* module.
* \param p The Profile to be read.
*/
void setCameraFromProfile(const Profile& p);
/**
* Reads a list of modules from a profile, and executes scripts based on whether or
* not the corresponding module is loaded.
*
* \param p The Profile to be read.
*/
void setModulesFromProfile(const Profile& p);
/**
* Registers actions from the contents of a profile.
*
* \param p The Profile to be read.
*/
void setActionsFromProfile(const Profile& p);
/**
* Registers keybindings from the contents of a profile.
*
* \param p The Profile to be read.
*/
void setKeybindingsFromProfile(const Profile& p);
/**
* Reads list of nodes from profile to be marked as interesting nodes.
* If any nodes are listed, a script to mark these will be queued with the
* script engine.
*
* \param p The Profile to be read.
*/
void setMarkInterestingNodesFromProfile(const Profile& p);
/**
* Reads list of "additional scripts" that are added to the profile to be run
* at the end of the initialization. Any openspace lua commands are allowed,
* and will be added to the script queue.
*
* \param p The Profile to be read.
*/
void setAdditionalScriptsFromProfile(const Profile& p);
} // namespace openspace
// Lua functions - exposed for testing
namespace openspace::luascriptfunctions {
int createSingleColorImage(lua_State* L);
} // openspace::luascriptfunctions
std::filesystem::path createSingleColorImage(std::string name, glm::dvec3 color);
#endif // __OPENSPACE_CORE___OPENSPACEENGINE___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -36,7 +36,7 @@ namespace openspace {
class Syncable;
/**
* Manages a collection of <code>Syncable</code>s and ensures they are synchronized
* Manages a collection of `Syncable`s and ensures they are synchronized
* over SGCT nodes. Encoding/Decoding order is handles internally.
*/
class SyncEngine {
@@ -50,14 +50,14 @@ public:
SyncEngine(unsigned int syncBufferSize);
/**
* Encodes all added Syncables in the injected <code>SyncBuffer</code>.
* Encodes all added Syncables in the injected `SyncBuffer`.
* This method is only called on the SGCT master node
*/
std::vector<std::byte> encodeSyncables();
/**
* Decodes the <code>SyncBuffer</code> into the added Syncables.
* This method is only called on the SGCT slave nodes
* Decodes the `SyncBuffer` into the added Syncables.
* This method is only called on the SGCT client nodes
*/
void decodeSyncables(std::vector<std::byte> data);

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -64,6 +64,8 @@ struct WindowDelegate {
glm::vec2 (*dpiScaling)() = []() { return glm::vec2(1.f); };
float (*osDpiScaling)() = []() { return 1.f; };
bool (*hasGuiWindow)() = []() { return false; };
bool (*isGuiWindow)() = []() { return false; };
@@ -76,7 +78,10 @@ struct WindowDelegate {
bool (*isFisheyeRendering)() = []() { return false; };
unsigned int (*takeScreenshot)(bool applyWarping) = [](bool) { return 0u; };
unsigned int (*takeScreenshot)(bool applyWarping, std::vector<int> windowIds) =
[](bool, std::vector<int>) { return 0u; };
void (*resetScreenshotNumber)() = []() {};
void (*swapBuffer)() = []() {};
@@ -102,6 +107,12 @@ struct WindowDelegate {
uint64_t (*swapGroupFrameNumber)() = []() { return uint64_t(0); };
void (*setScreenshotFolder)(std::string) = [](std::string) {};
void (*showStatistics)(bool) = [](bool) {};
int (*numberOfNodes)() = []() { return 0; };
int (*currentNode)() = []() { return 0; };
};
} // namespace openspace

View File

@@ -0,0 +1,573 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___EVENT___H__
#define __OPENSPACE_CORE___EVENT___H__
#include <openspace/util/tstring.h>
#include <ghoul/misc/assert.h>
#include <ghoul/misc/dictionary.h>
namespace openspace {
namespace properties { class Property; }
class Camera;
class Layer;
class Profile;
class Renderable;
class SceneGraphNode;
class ScreenSpaceRenderable;
class Time;
} // namespace openspace
namespace openspace::events {
struct Event {
// Steps to add a new event type:
// 1. Add a new entry into this enum list
// 2. Create a new subclass of Event in this file with a constructor that sets the
// Event's `type` to this new enum entry
// 3. In the cpp file, add a new `log` message that takes the new type as an argument
// and that prints something useful when the log is encountered and the user wants
// to see all events.
// 4. Add a new case into the logAllEvents function that handles the new enum entry
// 5. If the new event type has any parameters it takes in its constructor, go into
// the `toParameter` function and add a case label for the new enum type and
// return a dictionary with these parameters. This dictionary is passed to actions
// if they are triggered by events
// 6. Add the new enum entry into the `toString` and `fromString` methods
enum class Type : uint8_t {
SceneGraphNodeAdded,
SceneGraphNodeRemoved,
ParallelConnection,
ProfileLoadingFinished,
ApplicationShutdown,
ScreenSpaceRenderableAdded,
ScreenSpaceRenderableRemoved,
CameraFocusTransition,
TimeOfInterestReached,
MissionEventReached,
PlanetEclipsed,
InterpolationFinished,
FocusNodeChanged,
LayerAdded,
LayerRemoved,
SessionRecordingPlayback,
PointSpacecraft,
RenderableEnabled,
RenderableDisabled,
CameraPathStarted,
CameraPathFinished,
Custom
};
constexpr explicit Event(Type type_) : type(type_) {}
const Type type;
const Event* next = nullptr;
};
template <typename T>
T* asType(Event* e) {
ghoul_assert(e->type == T::Type, "Wrong type requested, check 'isType'");
return static_cast<T*>(e);
}
template <typename T>
bool isType(Event* e) {
return e->type == T::Type;
}
std::string_view toString(Event::Type type);
Event::Type fromString(std::string_view str);
ghoul::Dictionary toParameter(const Event& e);
void logAllEvents(const Event* e);
//
// Events
//
/**
* This event is created whenever a new scene graph node is added to the system. By the
* time this event is signalled, the scene graph node has already been created and added
* to the scene.
*/
struct EventSceneGraphNodeAdded : public Event {
static constexpr Type Type = Event::Type::SceneGraphNodeAdded;
/**
* Creates an instance of an EventSceneGraphNodeAdded event.
*
* \param node_ The identifier of the node that was added
*
* \pre node_ must not be nullptr
*/
explicit EventSceneGraphNodeAdded(const SceneGraphNode* node_);
const tstring node;
};
/**
* This event is created whenever a scene graph node was removed. By the time this event
* is signalled, the scene graph node has already been removed.
*/
struct EventSceneGraphNodeRemoved : public Event {
static constexpr Type Type = Event::Type::SceneGraphNodeRemoved;
/**
* Creates an instance of an EventSceneGraphNodeRemoved event.
*
* \param node_ The identifier of the node that was removed
*
* \pre node_ must not be nullptr
*/
explicit EventSceneGraphNodeRemoved(const SceneGraphNode* node_);
const tstring node;
};
/**
* This event is created whenever something in the parallel connection subsystem changes.
* The new state is sent as an argument with this event.
*/
struct EventParallelConnection : public Event {
static constexpr Type Type = Event::Type::ParallelConnection;
enum class State : uint8_t {
Established,
Lost,
HostshipGained,
HostshipLost
};
/**
* Creates an instance of an EventParallelConnection event.
*
* \param state_ The new state of the parallel connection system; is one of
* `Established`, `Lost`, `HostshipGained`, or `HostshipLost`
*/
explicit EventParallelConnection(State state_);
State state;
};
/**
* This event is created when the loading of a profile is finished. This is emitted
* regardless of whether it is the initial profile, or any subsequent profile is loaded.
*/
struct EventProfileLoadingFinished : public Event {
static constexpr Type Type = Event::Type::ProfileLoadingFinished;
/**
* Creates an instance of an EventProfileLoadingFinished event.
*/
EventProfileLoadingFinished();
};
/**
* This event is created whenever some information about the application shutdown sequence
* changes. This can either be that the seqeuence started, was aborted, or is finished,
* which means that OpenSpace is just about the shutdown.
*/
struct EventApplicationShutdown : public Event {
static constexpr Type Type = Event::Type::ApplicationShutdown;
enum class State : uint8_t {
Started,
Aborted,
Finished
};
/**
* Creates an instance of an EventApplicationShutdown event.
*
* \param state_ The next state of the application shutdown sequence; is one of
* `Started`, `Aborted`, or `Finished`
*/
explicit EventApplicationShutdown(State state_);
const State state;
};
/**
* This event is created when a new screenspace renderable has been created. By the time
* this event is craeted, the screenspace renderable is already registered and available.
*/
struct EventScreenSpaceRenderableAdded : public Event {
static constexpr Type Type = Event::Type::ScreenSpaceRenderableAdded;
/**
* Creates an instance of an EventScreenSpaceRenderableAdded event.
*
* \param renderable_ The the new screenspace renderable that was added to the system
*
* \pre renderable_ must not be nullptr
*/
explicit EventScreenSpaceRenderableAdded(const ScreenSpaceRenderable* renderable_);
const tstring renderable;
};
/**
* This event is created when a screenspace renderable has been removed from the system.
* When this event is created, the screenspace renderable has already been removed and is
* no longer available
*/
struct EventScreenSpaceRenderableRemoved : public Event {
static constexpr Type Type = Event::Type::ScreenSpaceRenderableRemoved;
/**
* Creates an instance of an EventScreenSpaceRenderableRemoved event.
*
* \param renderable_ The the new screenspace renderable that was removed
*/
explicit EventScreenSpaceRenderableRemoved(const ScreenSpaceRenderable* renderable_);
const tstring renderable;
};
/**
* This event is created when the camera transitions between different interaction sphere
* distances. Right now, only movement relative to camera's focus node is considered.
* Each scene graph node has an interaction sphere radius that serves as the reference
* distance for all spheres.
```
Diagram of events for a camera moving from right-to-left. Interaction sphere is 'O' in
middle, and ')' are spherical boundaries. The approach factor, reach factor, and
interaction sphere radius are all taken from the current focus node.
|<------------------->| Approach factor * Interaction sphere
|<------>| Reach Factor * Interaction sphere
( ( O ) )
^ ^ ^ ^
Exiting Receding Reaching Approaching
```
*/
struct EventCameraFocusTransition : public Event {
static constexpr Type Type = Event::Type::CameraFocusTransition;
enum class Transition {
Approaching,
Reaching,
Receding,
Exiting
};
/**
* Creates an instance of an EventCameraFocusTransition event.
*
* \param camera_ The camera object that caused the transition
* \param node_ The name of the node the camera is transitioning relative to.
* Currently is always the same as the camera's focus node
* \param transition_ The transition type that the camera just finished; is one of
* `Approaching`, `Reaching`, `Receding`, or `Exiting`
*
* \pre camera_ must not be nullptr
* \pre node_ must not be nullptr
*/
EventCameraFocusTransition(const Camera* camera_, const SceneGraphNode* node_,
Transition transition_);
const Camera* camera = nullptr;
const tstring node;
const Transition transition;
};
/**
* This event is created with a specific time of interest is reached. This event is
* currently unused.
*/
struct EventTimeOfInterestReached : public Event {
static constexpr Type Type = Event::Type::TimeOfInterestReached;
/**
* Creates an instance of an EventTimeOfInterestReached event.
*
* \param time_ The time of interest that has been reached
* \param camera_ Information about the camera for the specific transition
*/
EventTimeOfInterestReached(const Time* time_, const Camera* camera_);
const Time* time = nullptr;
const Camera* camera = nullptr;
};
/**
* This event is created when the end of a mission phase is reached. This event is
* currently unused.
*/
struct EventMissionEventReached : public Event {
static constexpr Type Type = Event::Type::MissionEventReached;
// Not sure which kind of parameters we want to pass here
EventMissionEventReached();
};
/**
* This event is created when a planet is eclipsed by a moon or a different planet. This
* event is currently unused.
*/
struct EventPlanetEclipsed : public Event {
static constexpr Type Type = Event::Type::PlanetEclipsed;
/**
* Creates an instance of an EventPlanetEclipsed event.
*
* \param eclipsee_ The scene graph node that is eclipsed by another object
* \param eclipser_ The scene graph node that is eclipsing the other object
*
* \pre eclipsee_ must not be nullptr
* \pre eclipser_ must not be nullptr
*/
EventPlanetEclipsed(const SceneGraphNode* eclipsee_, const SceneGraphNode* eclipser_);
const tstring eclipsee;
const tstring eclipser;
};
/**
* This event is created when the interpolation of a property value is finished. If the
* interpolation time of a property change is 0s, this event is not fired
*/
struct EventInterpolationFinished : public Event {
static constexpr Type Type = Event::Type::InterpolationFinished;
/**
* Creates an instance of an EventInterpolationFinished event.
*
* \param property_ The property whose interpolation has finished
*
* \pre property_ must not be nullptr
*/
EventInterpolationFinished(const properties::Property* property_);
const tstring property;
};
/**
* This event is created when the camera changes focus nodes. Even if the camera position
* is interpolated, the node change happens instantaneously and the event is fired at the
* same time.
*/
struct EventFocusNodeChanged : public Event {
static constexpr Type Type = Event::Type::FocusNodeChanged;
/**
* Creates an instance of an EventFocusNodeChanged event.
*
* \param oldNode_ The scene graph node which was the old focus node
* \param newNode_ The scene graph node that is the new focus node
*
* \pre oldNode_ must not be nullptr
* \pre newNode_ must not be nullptr
*/
EventFocusNodeChanged(const SceneGraphNode* oldNode_, const SceneGraphNode* newNode_);
const tstring oldNode;
const tstring newNode;
};
/**
* This event is created when a layer is added to to a globe.
*/
struct EventLayerAdded : public Event {
static constexpr Type Type = Event::Type::LayerAdded;
/**
* Creates an instance of an EventLayerAdded event.
*
* \param node_ The identifier of the globe to which the layer is added
* \param layerGroup_ The identifier of the layer group to which the layer is added
* \param layer_ The identifier of the layer that was added
*
* \pre node_ must not be empty
* \pre layerGroup_ must not be empty
* \pre layer_ must not be empty
*/
explicit EventLayerAdded(std::string_view node_, std::string_view layerGroup_,
std::string_view layer_);
const tstring node;
const tstring layerGroup;
const tstring layer;
};
/**
* This event is created when a layer is removed from a globe.
*/
struct EventLayerRemoved : public Event {
static constexpr Type Type = Event::Type::LayerRemoved;
/**
* Creates an instance of an EventLayerRemoved event.
*
* \param node_ The identifier of the globe to which the layer is removed
* \param layerGroup_ The identifier of the layer group to which the layer is removed
* \param layer_ The identifier of the layer that was removed
*
* \pre node_ must not be empty
* \pre layerGroup_ must not be empty
* \pre layer_ must not be empty
*/
explicit EventLayerRemoved(std::string_view node_, std::string_view layerGroup_,
std::string_view layer_);
const tstring node;
const tstring layerGroup;
const tstring layer;
};
/**
* This event is created when something regarding a session recording playback changes.
* The event contains information about the new state of the session recording subsystem.
*/
struct EventSessionRecordingPlayback : public Event {
static constexpr Type Type = Event::Type::SessionRecordingPlayback;
enum class State {
Started,
Paused,
Resumed,
Finished
};
/**
* Creates an instance of an EventSessionRecordingPlayback event.
*
* \param state_ The new state of the session recording; one of `Started`, `Paused`,
* `Resumed`, `Finished`
*/
EventSessionRecordingPlayback(State state_);
const State state;
};
/**
* This event is created when a request for pointing a spacecraft towards a Ra Dec
* coordinate in the sky is issued. The event contains information about the sky
* coordinate to point the spacecraft towards, and an optional argument for the duration
* it should do the pointing.
*/
struct EventPointSpacecraft : public Event {
static constexpr Type Type = Event::Type::PointSpacecraft;
/**
* Creates an instance of an EventSessionRecordingPlayback event.
*
* \param ra_ The Ra part of the sky coordinate in decimal degrees to point towards
* \param dec_ The Dec part of the sky coordinate in decimal degrees to point towards
* \param duration_ The duration of time in seconds that the spacecraft should
* redirect itself to the coordinate. Default is 3 seconds
*/
EventPointSpacecraft(double ra_, double dec_, double duration_ = 3.0);
const double ra;
const double dec;
const double duration;
};
/**
* This event is created whenever a renderable is enabled. By the time this event is
* signalled, the renderable has already been enabled.
*/
struct EventRenderableEnabled : public Event {
static constexpr Type Type = Event::Type::RenderableEnabled;
/**
* Creates an instance of an EventRenderableEnabled event.
*
* \param node_ The identifier of the node that contains the renderable
*
* \pre node_ must not be nullptr
*/
explicit EventRenderableEnabled(const SceneGraphNode* node_);
const tstring node;
};
/**
* This event is created whenever a renderable is disabled. By the time this event is
* signalled, the renderable has already been disabled.
*/
struct EventRenderableDisabled : public Event {
static constexpr Type Type = Event::Type::RenderableDisabled;
/**
* Creates an instance of an EventRenderableDisabled event.
*
* \param node_ The identifier of that node that contains the renderable
*
* \pre node_ must not be nullptr
*/
explicit EventRenderableDisabled(const SceneGraphNode* node_);
const tstring node;
};
/**
* This event is created when the a camera path is started
*/
struct EventCameraPathStarted : public Event {
static constexpr Type Type = Event::Type::CameraPathStarted;
/**
* Creates an instance of an EventCameraPathStarted event.
*/
EventCameraPathStarted();
};
/**
* This event is created when the a camera path is finished
*/
struct EventCameraPathFinished : public Event {
static constexpr Type Type = Event::Type::CameraPathFinished;
/**
* Creates an instance of an EventCameraPathStarted event.
*/
EventCameraPathFinished();
};
/**
* A custom event type that can be used in a pinch when no explicit event type is
* available. This should only be used in special circumstances and it should be
* transitioned to a specific event type, if it is deemed to be useful.
*/
struct CustomEvent : public Event {
static constexpr Type Type = Event::Type::Custom;
/**
* Creates an instance of a CustomEvent event.
*
* \param subtype_ A textual description of the custom subtype that is emitted
* \param payload_ The payload in a string form
*
* \pre subtype_ must not be empty
*/
CustomEvent(std::string_view subtype_, std::string_view payload_);
const tstring subtype;
const tstring payload;
};
} // namespace openspace::events
#endif // __OPENSPACE_CORE___EVENT___H__

View File

@@ -0,0 +1,165 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___EVENTENGINE___H__
#define __OPENSPACE_CORE___EVENTENGINE___H__
#include <openspace/events/event.h>
#include <openspace/scripting/lualibrary.h>
#include <ghoul/misc/memorypool.h>
#include <unordered_map>
namespace openspace {
namespace events { struct Event; }
class EventEngine {
public:
struct ActionInfo {
events::Event::Type type;
uint32_t id = std::numeric_limits<uint32_t>::max();
bool isEnabled = true;
std::string action;
std::optional<ghoul::Dictionary> filter;
};
/**
* This function returns the first event stored in the EventEngine, or `nullptr` if
* no event exists. To navigate the full list of events, you can access the returned
* Event's next function. If the end of the list is reached, the next pointer will be
* a nullptr
*
* \return The first event stored in the EventEngine or nullptr if no event exists
*/
events::Event* firstEvent() const;
/**
* Publish a new event of type T by providing optional arguments Args to the Event's
* constructor. An example of usage is
* `engine.publishEvent<MyEvent>("a", 2.0);` which would call the
* constructor of `MyEvent` with a `const char*` and `double` parameter.
*
* \param args The arguments that are passed to the constructor of T
* \tparam T The subclass of Event that is to be published
*/
template <typename T, typename... Args>
void publishEvent(Args&&... args);
/**
* This function cleans up the memory for all published events.After this function
* has been called, no previously published events are valid any longer. This means
* that pointers retrieved from events before this call must be kept beyond this call.
*/
void postFrameCleanup();
/**
* Registers a new action for a specific event type.
*
* \param type The type for which a new action is registered
* \param identifier The identifier of the action that will be triggered the
* identifier must not exist at this moment, but must exist by the time the
* event is encountered next
* \param filter If the filter is provided, it describes the event parameters that are
* checked and only if an event passes the filter, the corresponding action is
* triggered
*/
void registerEventAction(events::Event::Type type, std::string identifier,
std::optional<ghoul::Dictionary> filter = std::nullopt);
/**
* Removing registration for a type/action combination.
*
* \param type The type of the action that should be unregistered
* \param identifier The identifier of the action that should be unregistered
* \param filter The optional filter applied to the event-action combination
*/
void unregisterEventAction(events::Event::Type type,
const std::string& identifier,
std::optional<ghoul::Dictionary> filter = std::nullopt);
/**
* Removing registration for a specific event identified by the \p identifier.
*
* \param identifier The unique identifier of the event that should be removed.
*/
void unregisterEventAction(uint32_t identifier);
/**
* Returns the list of all registered actions, sorted by their identifiers.
*
* \return The list of all registered actions
*/
std::vector<ActionInfo> registeredActions() const;
/**
* Enables the event identified by the \p identifier. If the event is already enabled,
* this function does nothing.
*
* \param identifier The identifier of the event that should be enabled
*/
void enableEvent(uint32_t identifier);
/**
* Disables the event identified by the \p identifier. If the event is already
* disabled, this function does nothing.
*
* \param identifier The identifier of the event that should be disabled
*/
void disableEvent(uint32_t identifier);
/**
* Triggers all actions that are registered for events that are in the current event
* queue
*/
void triggerActions() const;
static scripting::LuaLibrary luaLibrary();
private:
/// The storage space in which Events are stored
ghoul::MemoryPool<4096> _memory;
/// The first event in the chain of events stored in the memory pool
events::Event* _firstEvent = nullptr;
/// The last event in the chain of events stored in the memory pool
events::Event* _lastEvent = nullptr;
// The type is duplicated in the ActionInfo as well, but we want it in the ActionInfo
// to be able to return them to a caller and we want it in this unordered_map to make
// the lookup really fast. So having this extra wasted memory is probably worth it
std::unordered_map<events::Event::Type, std::vector<ActionInfo>> _eventActions;
static uint32_t nextRegisteredEventId;
#ifdef _DEBUG
/// Stores the total number of events during this frame for debugging purposes
static uint64_t nEvents;
#endif // _DEBUG
};
} // namespace openspace
#include "eventengine.inl"
#endif // __OPENSPACE_CORE___EVENTENGINE___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -22,29 +22,30 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___VIRTUALPROPERTYMANAGER___H__
#define __OPENSPACE_CORE___VIRTUALPROPERTYMANAGER___H__
#include <openspace/properties/propertyowner.h>
#include <memory>
#include <vector>
#include <type_traits>
namespace openspace {
class Property;
template <typename T, typename... Args>
void EventEngine::publishEvent(Args&&... args) {
static_assert(
std::is_base_of<events::Event, T>::value,
"T must be a subclass of Event"
);
class VirtualPropertyManager : public properties::PropertyOwner {
public:
VirtualPropertyManager();
T* e = _memory.alloc<T>(args...);
if (!_firstEvent) {
_firstEvent = e;
_lastEvent = e;
}
else {
_lastEvent->next = e;
_lastEvent = e;
}
void addProperty(std::unique_ptr<properties::Property> prop);
void removeProperty(properties::Property* prop);
private:
std::vector<std::unique_ptr<properties::Property>> _properties;
};
#ifdef _DEBUG
nEvents++;
#endif // _DEBUG
}
} // namespace openspace
#endif // __OPENSPACE_CORE___VIRTUALPROPERTYMANAGER___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -22,62 +22,49 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___RENDERER___H__
#define __OPENSPACE_CORE___RENDERER___H__
#ifndef __OPENSPACE_CORE___ACTION___H__
#define __OPENSPACE_CORE___ACTION___H__
#include <ghoul/glm.h>
#include <vector>
#include <ghoul/misc/boolean.h>
#include <string>
namespace ghoul { class Dictionary; }
namespace ghoul::filesystem { class File; }
namespace ghoul::opengl {
class ProgramObject;
class Texture;
} // namespace ghoul::opengl
namespace openspace::interaction {
namespace openspace {
struct Action {
BooleanType(IsSynchronized);
class RenderableVolume;
class Camera;
class Scene;
/// Unique identifier that identifies this action. There is no special naming scheme
/// that we enforce, we are trying to stick to the same . separated structure that
/// hopefully provides some protection against accidentally reusing identifiers
std::string identifier;
class Renderer {
public:
virtual ~Renderer() = default;
/// The Lua script that gets executed whenever this action is triggered. Optional
/// parameters can be passed to actions which are accessible through an `args`
/// variable that contains all of the arguments passed into the action. This means
/// that the provided script must not use this variable name itself or the script will
/// not successfully execute
std::string command;
virtual void initialize() = 0;
virtual void deinitialize() = 0;
/// The human-readable name of this action. This name must not be unique, but it is
/// recommended that the combination of GuiPath + name should be unique to prevent
/// user confusion
std::string name;
virtual void setResolution(glm::ivec2 res) = 0;
virtual void setHDRExposure(float hdrExposure) = 0;
virtual void setGamma(float gamma) = 0;
virtual void setHue(float hue) = 0;
virtual void setValue(float value) = 0;
virtual void setSaturation(float sat) = 0;
virtual void enableFXAA(bool enable) = 0;
virtual void setDisableHDR(bool disable) = 0;
/// A user-facing description of what the action does when it gets triggered. If the
/// action uses optional arguments, they should be described in here, too
std::string documentation;
/**
* Set raycasting uniforms on the program object, and setup raycasting.
*/
virtual void preRaycast(ghoul::opengl::ProgramObject& /*programObject*/) {};
/// This variable defines a subdivision of where this action is placed in a user
/// interface. The individual path components are separated by '/' with a leading '/'
/// for the root path
std::string guiPath = "/";
/**
* Tear down raycasting for the specified program object.
*/
virtual void postRaycast(ghoul::opengl::ProgramObject& /*programObject*/) {};
virtual void update() = 0;
virtual void render(Scene* scene, Camera* camera, float blackoutFactor) = 0;
/**
* Update render data
* Responsible for calling renderEngine::setRenderData
*/
virtual void updateRendererData() = 0;
/// If this value is set to `Yes`, the execution of this action is synchronized to
/// other OpenSpace instances, for example other nodes in a cluster environment, or
/// to other OpenSpace instances using a parallel connection
IsSynchronized synchronization = IsSynchronized::Yes;
};
} // openspace
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___RENDERER___H__
#endif // __OPENSPACE_CORE___ACTION___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -22,39 +22,33 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___SHORTCUTMANAGER___H__
#define __OPENSPACE_CORE___SHORTCUTMANAGER___H__
#ifndef __OPENSPACE_CORE___ACTIONMANAGER___H__
#define __OPENSPACE_CORE___ACTIONMANAGER___H__
#include <ghoul/misc/boolean.h>
#include <string>
#include <vector>
#include <openspace/interaction/action.h>
#include <unordered_map>
namespace ghoul { class Dictionary; }
namespace openspace::scripting { struct LuaLibrary; }
namespace openspace::interaction {
class ShortcutManager {
class ActionManager {
public:
BooleanType(IsSynchronized);
struct ShortcutInformation {
std::string name;
std::string script;
IsSynchronized synchronization;
std::string documentation;
std::string guiPath;
};
void resetShortcuts();
void addShortcut(ShortcutInformation info);
const std::vector<ShortcutInformation>& shortcuts() const;
bool hasAction(const std::string& identifier) const;
void registerAction(Action action);
void removeAction(const std::string& identifier);
const Action& action(const std::string& identifier) const;
std::vector<Action> actions() const;
void triggerAction(const std::string& identifier,
const ghoul::Dictionary& arguments) const;
static scripting::LuaLibrary luaLibrary();
private:
std::vector<ShortcutInformation> _shortcuts;
std::unordered_map<unsigned int, Action> _actions;
};
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___SHORTCUTMANAGER___H__
#endif // __OPENSPACE_CORE___ACTIONMANAGER___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -30,8 +30,6 @@
namespace openspace::interaction {
class InputState;
class CameraInteractionStates {
public:
/**
@@ -42,8 +40,6 @@ public:
CameraInteractionStates(double sensitivity, double velocityScaleFactor);
virtual ~CameraInteractionStates() = default;
virtual void updateStateFromInput(const InputState& inputState, double deltaTime) = 0;
void setRotationalFriction(double friction);
void setHorizontalFriction(double friction);
void setVerticalFriction(double friction);
@@ -58,6 +54,12 @@ public:
void resetVelocities();
/*
* Returns true if any of the velocities are larger than zero,
* i.e. wether an interaction happened
*/
bool hasNonZeroVelocities();
protected:
struct InteractionState {
InteractionState(double scaleFactor);

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *

View File

@@ -1,82 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___EXTERNINTERACTION___H__
#define __OPENSPACE_CORE___EXTERNINTERACTION___H__
#include <openspace/network/messagestructures.h>
#include <openspace/properties/propertyowner.h>
#include <ghoul/io/socket/tcpsocket.h>
#include <vector>
namespace openspace {
class ExternInteraction : public properties::PropertyOwner {
public:
ExternInteraction();
/**
* Method that generates a keyframeNavigator CameraPose from a CameraKeyframe
* object, and then adds this to the navigationHandler's keyframe navigator.
* \param kf The camera keyframe to add.
*/
void cameraInteraction(datamessagestructures::CameraKeyframe kf);
/**
* Method that generates a TimeKeyframeData from a TimeKeyframe object, and
* then adds this to the timeManager.
* \param kf The time keyframe to add.
*/
void timeInteraction(datamessagestructures::TimeKeyframe kf);
/**
* Method that passes a ScriptMessage object to the script engine, calling its
* queueScript method to add it for execution.
* \param sm The ScriptMessage object to queue in the script engine.
*/
void scriptInteraction(datamessagestructures::ScriptMessage sm);
/**
* Method that accepts a reference to a CameraKeyframe object, and populates
* it with the current properties of the camera from the navigation handler.
* \returns CameraKeyframe with current state from NavigationHandler.
*/
datamessagestructures::CameraKeyframe generateCameraKeyframe();
/**
* Method that accepts a reference to a TimeKeyframe object, and populates
* it with the current time values from the application time manager.
* \returns TimeKeyframe The time keyframe.
*/
datamessagestructures::TimeKeyframe generateTimeKeyframe();
/**
* Method that accepts a reference to a ScriptMessage object and a script
* string, and populates the ScriptMessage with the script and timestamp
* of the current application time.
* \param script The script to execute in std::string form.
* \returns ScriptMessage The ScriptMessage data structure with script.
*/
datamessagestructures::ScriptMessage generateScriptMessage(std::string script);
private:
};
} // namespace openspace
#endif // __OPENSPACE_CORE___EXTERNINTERACTION___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -43,62 +43,113 @@ public:
OrbitY,
ZoomIn,
ZoomOut,
Zoom,
LocalRollX,
LocalRollY,
GlobalRollX,
GlobalRollY,
PanX,
PanY
PanY,
Property
};
enum class JoystickType {
JoystickLike,
TriggerLike
};
BooleanType(AxisInvert);
BooleanType(AxisNormalize);
BooleanType(ButtonCommandRemote);
struct AxisInformation {
AxisType type = AxisType::None;
AxisInvert invert = AxisInvert::No;
AxisNormalize normalize = AxisNormalize::No;
JoystickType joystickType = JoystickType::JoystickLike;
// The axis values can either go back to 0 when the joystick is released or it can
// stay at the value it was before the joystick was released.
// The latter is called a sticky axis, when the values don't go back to 0.
bool isSticky = false;
float deadzone = 0.f;
// Every axis can have their own sensitivity
double sensitivity = 0.0;
// The property info if the type is Property
std::string propertyUri;
float minValue = 0.f;
float maxValue = 1.f;
bool isRemote = true;
};
JoystickCameraStates(double sensitivity, double velocityScaleFactor);
void updateStateFromInput(const InputState& inputState, double deltaTime) override;
void updateStateFromInput(
const JoystickInputStates& joystickInputStates, double deltaTime);
void setAxisMapping(int axis, AxisType mapping,
void setAxisMapping(std::string joystickName, int axis, AxisType mapping,
AxisInvert shouldInvert = AxisInvert::No,
AxisNormalize shouldNormalize = AxisNormalize::No
JoystickType joystickType = JoystickType::JoystickLike,
bool isSticky = false, double sensitivity = 0.0
);
AxisInformation axisMapping(int axis) const;
void setAxisMappingProperty(std::string joystickName, int axis,
std::string propertyUri, float min = 0.f, float max = 1.f,
AxisInvert shouldInvert = AxisInvert::No, bool isRemote = true
);
void setDeadzone(int axis, float deadzone);
float deadzone(int axis) const;
AxisInformation axisMapping(const std::string& joystickName, int axis) const;
void setDeadzone(const std::string& joystickName, int axis, float deadzone);
float deadzone(const std::string& joystickName, int axis) const;
void bindButtonCommand(int button, std::string command, JoystickAction action,
ButtonCommandRemote remote, std::string documentation);
void clearButtonCommand(int button);
std::vector<std::string> buttonCommand(int button) const;
void bindButtonCommand(const std::string& joystickName, int button,
std::string command, JoystickAction action, ButtonCommandRemote remote,
std::string documentation);
void clearButtonCommand(const std::string& joystickName, int button);
std::vector<std::string> buttonCommand(const std::string& joystickName,
int button) const;
private:
// We use an array for the axes and a map for the buttons since the axis are going to
// be accessed much more often and thus have to be more efficient. And storing a few
// extra AxisInformation that are not used will not matter that much; finding an axis
// location in a potential map each frame, however, would
struct JoystickCameraState {
std::string joystickName;
std::array<AxisInformation, JoystickInputState::MaxAxes> _axisMapping;
// We use a vector for the axes and a map for the buttons since the axis are going
// to be accessed much more often and thus have to be more efficient
std::vector<AxisInformation> axisMapping;
struct ButtonInformation {
std::string command;
JoystickAction action;
ButtonCommandRemote synchronization;
std::string documentation;
// This vector is used to store the old axis values from the previous frame, it is
// used to calculate the difference in the values in the case of a sticky axis
std::vector<float> prevAxisValues;
struct ButtonInformation {
// The script that is run when the button is activated
std::string command;
// When is the button considered activated
JoystickAction action;
// If the script should be syncronised to other remote sessions or not
ButtonCommandRemote synchronization;
// Short documentation on what the script of this button does
std::string documentation;
};
std::multimap<int, ButtonInformation> buttonMapping;
};
std::multimap<int, ButtonInformation> _buttonMapping;
std::vector<JoystickCameraState> _joystickCameraStates;
// Find the item in _joystickCameraStates that corresponds to the given joystickName
// return a pointer to the item, if not found then return nullptr
JoystickCameraState* joystickCameraState(const std::string& joystickName);
const JoystickCameraState* joystickCameraState(const std::string& joystickName) const;
// Ues getJoystickCameraState(name) to find the joystickCameraState that
// corresponds to the given joystickName. If not found then add a new item if possible
JoystickCameraState* findOrAddJoystickCameraState(const std::string& joystickName);
};
} // namespace openspace::interaction
@@ -116,12 +167,14 @@ inline std::string to_string(
case T::OrbitY: return "Orbit Y";
case T::ZoomIn: return "Zoom In";
case T::ZoomOut: return "Zoom Out";
case T::Zoom: return "Zoom In and Out";
case T::LocalRollX: return "LocalRoll X";
case T::LocalRollY: return "LocalRoll Y";
case T::GlobalRollX: return "GlobalRoll X";
case T::GlobalRollY: return "GlobalRoll Y";
case T::PanX: return "Pan X";
case T::PanY: return "Pan Y";
case T::Property: return "Property";
default: return "";
}
}
@@ -137,16 +190,42 @@ from_string(std::string_view string)
if (string == "Orbit Y") { return T::OrbitY; }
if (string == "Zoom In") { return T::ZoomIn; }
if (string == "Zoom Out") { return T::ZoomOut; }
if (string == "Zoom") { return T::Zoom; }
if (string == "LocalRoll X") { return T::LocalRollX; }
if (string == "LocalRoll Y") { return T::LocalRollY; }
if (string == "GlobalRoll X") { return T::GlobalRollX; }
if (string == "GlobalRoll Y") { return T::GlobalRollY; }
if (string == "Pan X") { return T::PanX; }
if (string == "Pan Y") { return T::PanY; }
if (string == "Property") { return T::Property; }
throw RuntimeError("Unkonwn axis type '" + std::string(string) + "'");
}
template <>
inline std::string to_string(
const openspace::interaction::JoystickCameraStates::JoystickType& value)
{
using T = openspace::interaction::JoystickCameraStates::JoystickType;
switch (value) {
case T::JoystickLike: return "JoystickLike";
case T::TriggerLike: return "TriggerLike";
default: return "";
}
}
template <>
constexpr openspace::interaction::JoystickCameraStates::JoystickType
from_string(std::string_view string)
{
using T = openspace::interaction::JoystickCameraStates::JoystickType;
if (string == "JoystickLike") { return T::JoystickLike; }
if (string == "TriggerLike") { return T::TriggerLike; }
throw RuntimeError("Unkonwn joystick type '" + std::string(string) + "'");
}
} // namespace ghoul
#endif // __OPENSPACE_CORE___JOYSTICKCAMERASTATES___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -28,6 +28,7 @@
#include <ghoul/misc/assert.h>
#include <ghoul/misc/exception.h>
#include <ghoul/misc/stringconversion.h>
#include <ghoul/fmt.h>
#include <array>
#include <memory>
#include <string>
@@ -53,12 +54,7 @@ enum class JoystickAction : uint8_t {
* The input state of a single joystick.
*/
struct JoystickInputState {
/// The maximum number of supported axes
static constexpr const int MaxAxes = 8;
/// The maximum number of supported buttons
static constexpr const int MaxButtons = 32;
/// Marks whether this joystick is connected. If this value is \c false, all other
/// Marks whether this joystick is connected. If this value is `false`, all other
/// members of this struct are undefined
bool isConnected = false;
@@ -67,47 +63,69 @@ struct JoystickInputState {
/// The number of axes that this joystick supports
int nAxes = 0;
/// The values for each axis. Each value is in the range [-1, 1]. Only the first
/// \c nAxes values are defined values, the rest are undefined
std::array<float, MaxAxes> axes;
/// The values for each axis. Each value is in the range [-1, 1]
std::vector<float> axes;
/// The number of buttons that this joystick possesses
int nButtons = 0;
/// The status of each button. Only the first \c nButtons values are defined, the rest
/// are undefined
std::array<JoystickAction, MaxButtons> buttons;
/// The status of each button
std::vector<JoystickAction> buttons;
};
/// The maximum number of joysticks that are supported by this system. This number is
/// derived from the available GLFW constants
constexpr const int MaxJoysticks = 16;
constexpr int MaxJoysticks = 16;
struct JoystickInputStates : public std::array<JoystickInputState, MaxJoysticks> {
/// The maximum number of joysticks that are supported by this system. This number is
/// derived from the available GLFW constants
static constexpr int MaxNumJoysticks = 16;
/**
* This function return the number of axes the joystick with the given name has
*
* \param joystickName The name of the joystick to check how many axes it has,
* if empty the max number of axes for all joysticks are returned
* \return The number of axes for the joystick with the given name
*/
int numAxes(const std::string& joystickName = "") const;
/**
* This function return the number of buttons the joystick with the given name has
*
* \param joystickName The name of the joystick to check how many buttons it has,
* if empty the max number of buttons for all joysticks are returned
* \return The number of buttons for the joystick with the given name
*/
int numButtons(const std::string& joystickName = "") const;
/**
* This function adds the contributions of all connected joysticks for the provided
* \p axis. After adding each joysticks contribution, the result is clamped to [-1,1].
* If a joystick does not possess a particular axis, it's does not contribute to the
* sum.
*
* \param joystickName The name of the joystick, if empty all joysticks are combined
* \param axis The numerical axis for which the values are added
* \return The summed axis values of all connected joysticks
*
* \pre \p axis must be 0 or positive
*/
float axis(int axis) const;
float axis(const std::string& joystickName, int axis) const;
/**
* This functions checks whether any connected joystick has its \p button in the
* passed \p action. Any joystick that does not posses the \p button, it will be
* ignored.
*
* \param joystickName The name of the joystick, if empty all joysticks are combined
* \param button The button that is to be checked
* \param action The action which is checked for each button
* \return \c true if there is at least one joystick whose \param button is in the
* \return `true` if there is at least one joystick whose \p button is in the
* \p action state
*
* \pre \p button must be 0 or positive
*/
bool button(int button, JoystickAction action) const;
bool button(const std::string& joystickName, int button, JoystickAction action) const;
};
} // namespace openspace::interaction
@@ -121,18 +139,18 @@ inline std::string to_string(const openspace::interaction::JoystickAction& value
case openspace::interaction::JoystickAction::Press: return "Press";
case openspace::interaction::JoystickAction::Repeat: return "Repeat";
case openspace::interaction::JoystickAction::Release: return "Release";
default: throw MissingCaseException();
default: throw MissingCaseException();
}
}
template <>
constexpr openspace::interaction::JoystickAction from_string(std::string_view string) {
if (string == "Idle") { return openspace::interaction::JoystickAction::Idle; }
if (string == "Press") { return openspace::interaction::JoystickAction::Press; }
if (string == "Repeat") { return openspace::interaction::JoystickAction::Repeat; }
if (string == "Idle") { return openspace::interaction::JoystickAction::Idle; }
if (string == "Press") { return openspace::interaction::JoystickAction::Press; }
if (string == "Repeat") { return openspace::interaction::JoystickAction::Repeat; }
if (string == "Release") { return openspace::interaction::JoystickAction::Release; }
throw RuntimeError("Unknown action '" + std::string(string) + "'");
throw RuntimeError(fmt::format("Unknown action '{}'", string));
}
} // namespace ghoul

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -28,7 +28,6 @@
#include <openspace/documentation/documentationgenerator.h>
#include <openspace/util/keys.h>
#include <ghoul/misc/boolean.h>
namespace openspace {
class Camera;
@@ -41,33 +40,15 @@ namespace openspace::interaction {
class KeybindingManager : public DocumentationGenerator {
public:
BooleanType(IsSynchronized);
struct KeyInformation {
std::string command;
IsSynchronized synchronization;
std::string documentation;
std::string name;
std::string guiPath;
};
KeybindingManager();
void resetKeyBindings();
void bindKeyLocal(Key key, KeyModifier modifier, std::string luaCommand,
std::string documentation = "", std::string name = "", std::string guiPath = "");
void bindKey(Key key, KeyModifier modifier, std::string action);
void bindKey(Key key, KeyModifier modifier, std::string luaCommand,
std::string documentation = "", std::string name = "", std::string guiPath = "");
void removeKeyBinding(const std::string& key);
void removeKeyBinding(const KeyWithModifier& key);
std::vector<std::pair<KeyWithModifier, KeyInformation>> keyBinding(
const std::string& key) const;
std::vector<std::pair<KeyWithModifier, KeyInformation>> keyBinding(
std::vector<std::pair<KeyWithModifier, std::string>> keyBinding(
const KeyWithModifier& key) const;
static scripting::LuaLibrary luaLibrary();
@@ -76,10 +57,10 @@ public:
std::string generateJson() const override;
const std::multimap<KeyWithModifier, KeyInformation>& keyBindings() const;
const std::multimap<KeyWithModifier, std::string>& keyBindings() const;
private:
std::multimap<KeyWithModifier, KeyInformation> _keyLua;
std::multimap<KeyWithModifier, std::string> _keyLua;
};
} // namespace openspace::interaction

View File

@@ -0,0 +1,51 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___KEYBOARDINPUTSTATE___H__
#define __OPENSPACE_CORE___KEYBOARDINPUTSTATE___H__
#include <openspace/util/keys.h>
#include <vector>
namespace openspace::interaction {
// This class represents the global input state of interaction devices
class KeyboardInputState {
public:
// Callback functions
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
// Accessors
const std::vector<std::pair<Key, KeyModifier>>& pressedKeys() const;
bool isKeyPressed(std::pair<Key, KeyModifier> keyModPair) const;
bool isKeyPressed(Key key) const;
private:
// Input from keyboard
std::vector<std::pair<Key, KeyModifier>> _keysDown;
};
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___KEYBOARDINPUTSTATE___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -29,11 +29,15 @@
namespace openspace::interaction {
class MouseInputState;
class KeyboardInputState;
class MouseCameraStates : public CameraInteractionStates {
public:
MouseCameraStates(double sensitivity, double velocityScaleFactor);
void updateStateFromInput(const InputState& inputState, double deltaTime) override;
void updateStateFromInput(const MouseInputState& mouseinputState,
const KeyboardInputState& keyboardinputState, double deltaTime);
void setInvertMouseButton(bool value);

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -22,58 +22,36 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___INPUTSTATE___H__
#define __OPENSPACE_CORE___INPUTSTATE___H__
#ifndef __OPENSPACE_CORE___MOUSEINPUTSTATE___H__
#define __OPENSPACE_CORE___MOUSEINPUTSTATE___H__
#include <openspace/interaction/websocketinputstate.h>
#include <openspace/util/keys.h>
#include <openspace/util/mouse.h>
#include <ghoul/glm.h>
#include <vector>
namespace openspace::interaction {
struct JoystickInputStates;
struct WebsocketInputStates;
// This class represents the global input state of interaction devices
class InputState {
class MouseInputState {
public:
// Callback functions
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
void mouseButtonCallback(MouseButton button, MouseAction action);
void mousePositionCallback(double mouseX, double mouseY);
void mouseScrollWheelCallback(double mouseScrollDelta);
// Accessors
const std::vector<std::pair<Key, KeyModifier>>& pressedKeys() const;
bool isKeyPressed(std::pair<Key, KeyModifier> keyModPair) const;
bool isKeyPressed(Key key) const;
const std::vector<MouseButton>& pressedMouseButtons() const;
glm::dvec2 mousePosition() const;
double mouseScrollDelta() const;
bool isMouseButtonPressed(MouseButton mouseButton) const;
float joystickAxis(int i) const;
bool joystickButton(int i) const;
WebsocketInputStates& websocketInputStates();
float websocketAxis(int i) const;
bool websocketButton(int i) const;
bool hasWebsocketStates() const;
void resetWebsockets();
private:
// Input from keyboard
std::vector<std::pair<Key, KeyModifier>> _keysDown;
// Input from mouse
std::vector<MouseButton> _mouseButtonsDown;
glm::dvec2 _mousePosition = glm::dvec2(0.0);
double _mouseScrollDelta;
double _mouseScrollDelta = 0.0;
};
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___INPUTSTATE___H__
#endif // __OPENSPACE_CORE___MOUSEINPUTSTATE___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -33,7 +33,7 @@ class ScriptCameraStates : public CameraInteractionStates {
public:
ScriptCameraStates();
void updateStateFromInput(const InputState& inputState, double deltaTime) override;
void updateStateFromInput(double deltaTime);
void addLocalRotation(const glm::dvec2& delta);
void addGlobalRotation(const glm::dvec2& delta);

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,11 +25,13 @@
#ifndef __OPENSPACE_CORE___SESSIONRECORDING___H__
#define __OPENSPACE_CORE___SESSIONRECORDING___H__
#include <openspace/interaction/externinteraction.h>
#include <openspace/interaction/keyframenavigator.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/navigation/keyframenavigator.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/scripting/lualibrary.h>
#include <vector>
#include <chrono>
namespace openspace::interaction {
@@ -60,7 +62,8 @@ public:
enum class SessionState {
Idle = 0,
Recording,
Playback
Playback,
PlaybackPaused
};
struct Timestamps {
@@ -69,6 +72,18 @@ public:
double timeSim;
};
/*
* Struct for storing a script substring that, if found in a saved script,
* will be replaced by its substringReplacement counterpart.
*/
struct ScriptSubstringReplace {
std::string substringFound;
std::string substringReplacement;
ScriptSubstringReplace(std::string found, std::string replace)
: substringFound(found)
, substringReplacement(replace) {}
};
static const size_t FileHeaderVersionLength = 5;
char FileHeaderVersion[FileHeaderVersionLength+1] = "01.00";
char TargetConvertVersion[FileHeaderVersionLength+1] = "01.00";
@@ -86,7 +101,7 @@ public:
SessionRecording();
SessionRecording(bool isGlobal);
~SessionRecording();
~SessionRecording() override;
/**
* Used to de-initialize the session recording feature. Any recording or playback
@@ -117,6 +132,33 @@ public:
*/
double fixedDeltaTimeDuringFrameOutput() const;
/**
* Returns the number of microseconds that have elapsed since playback started, if
* playback is set to be in the mode where a screenshot is captured with every
* rendered frame (enableTakeScreenShotDuringPlayback() is used to enable this mode).
* At the start of playback, this timer is set to the current steady_clock value.
* However, during playback it is incremented by the fixed framerate of the playback
* rather than the actual clock value (as in normal operation).
*
* \returns number of microseconds elapsed since playback started in terms of the
* number of rendered frames multiplied by the fixed time increment per
* frame
*/
std::chrono::steady_clock::time_point currentPlaybackInterpolationTime() const;
/**
* Returns the simulated application time. This simulated application time is only
* used when playback is set to be in the mode where a screenshot is captured with
* every rendered frame (enableTakeScreenShotDuringPlayback() is used to enable this
* mode). At the start of playback, this timer is set to the value of the current
* applicationTime function provided by the window delegate (used during normal
* mode or playback). However, during playback it is incremented by the fixed
* framerate of the playback rather than the actual clock value.
*
* \returns application time in seconds, for use in playback-with-frames mode
*/
double currentApplicationInterpolationTime() const;
/**
* Starts a recording session, which will save data to the provided filename
* according to the data format specified, and will continue until recording is
@@ -132,9 +174,7 @@ public:
* Starts a recording session, which will save data to the provided filename
* in ASCII data format until recording is stopped using stopRecording() method.
*
* \param filename file saved with recorded keyframes.
*
* \return \c true if recording to file starts without errors
* \param dataMode The format in which the session recording is stored
*/
void setRecordDataFormat(DataMode dataMode);
@@ -154,16 +194,20 @@ public:
/**
* Starts a playback session, which can run in one of three different time modes.
*
* \param filename file containing recorded keyframes to play back
* \param filename file containing recorded keyframes to play back. The file path
* is relative to the base recordings directory specified in the
* config file by the RECORDINGS variable
* \param timeMode which of the 3 time modes to use for time reference during
* \param forceSimTimeAtStart if true simulation time is forced to that of playback
* playback: recorded time, application time, or simulation time. See the
* LuaLibrary entry for SessionRecording for details on these time modes
* \param loop if true then the file will playback in loop mode, continuously
* looping back to the beginning until it is manually stopped
*
* \return \c true if recording to file starts without errors
* \return `true` if recording to file starts without errors
*/
bool startPlayback(std::string& filename, KeyframeTimeRef timeMode,
bool forceSimTimeAtStart);
bool forceSimTimeAtStart, bool loop);
/**
* Used to stop a playback in progress. If open, the playback file will be closed,
@@ -171,6 +215,22 @@ public:
*/
void stopPlayback();
/**
* Returns playback pause status.
*
* \return `true` if playback is paused
*/
bool isPlaybackPaused();
/**
* Pauses a playback session. This does both the normal pause functionality of
* setting simulation delta time to zero, and pausing the progression through the
* timeline.
*
* \param pause if true, then will set playback timeline progression to zero
*/
void setPlaybackPause(bool pause);
/**
* Enables that rendered frames should be saved during playback
* \param fps Number of frames per second.
@@ -205,13 +265,13 @@ public:
* whether it is following the rotation of a node, and timestamp). The data will be
* saved to the recording file only if a recording is currently in progress.
*/
void saveCameraKeyframe();
void saveCameraKeyframeToTimeline();
/**
* Used to trigger a save of the current timing states. The data will be saved to the
* recording file only if a recording is currently in progress.
*/
void saveTimeKeyframe();
void saveTimeKeyframeToTimeline();
/**
* Used to trigger a save of a script to the recording file, but only if a recording
@@ -219,7 +279,7 @@ public:
*
* \param scriptToSave String of the Lua command to be saved
*/
void saveScriptKeyframe(std::string scriptToSave);
void saveScriptKeyframeToTimeline(std::string scriptToSave);
/**
* \return The Lua library that contains all Lua functions available to affect the
@@ -241,7 +301,7 @@ public:
*
* \param callback function handle for the callback
*/
void removeStateChangeCallback(CallbackHandle handle);
void removeStateChangeCallback(CallbackHandle callback);
/**
* Provides list of available playback files.
@@ -405,6 +465,19 @@ public:
void saveScriptKeyframeAscii(Timestamps& times,
datamessagestructures::ScriptMessage& sm, std::ofstream& file);
/**
* Since session recordings only record changes, the initial conditions aren't
* preserved when a playback starts. This function is called whenever a property
* value is set and a recording is in progress. Before the set happens, this
* function will read the current value of the property and store it so that when
* the recording is finished, the initial state will be added as a set property
* command at the beginning of the recording file, to be applied when playback
* starts.
*
* \param prop The property being set
*/
void savePropertyBaseline(properties::Property& prop);
/**
* Reads header information from a session recording file
*
@@ -415,12 +488,13 @@ public:
static std::string readHeaderElement(std::ifstream& stream, size_t readLen_chars);
/**
* Reads header information from a session recording file
*
* \param stringstream reference to ifstream that contains the session recording file data
* \param readLen_chars number of characters to be read, which may be the expected
* length of the header line, or an arbitrary number of characters within it
*/
* Reads header information from a session recording file
*
* \param stream reference to ifstream that contains the session recording file
* data
* \param readLen_chars number of characters to be read, which may be the expected
* length of the header line, or an arbitrary number of characters within it
*/
static std::string readHeaderElement(std::stringstream& stream, size_t readLen_chars);
/**
@@ -474,6 +548,16 @@ public:
*/
std::string convertFile(std::string filename, int depth = 0);
/**
* Converts file format of a session recording file to the current format version
* (will determine the file format conversion to convert from based on the file's
* header version number). Accepts a relative path (currently from task runner dir)
* rather than a path assumed to be relative to ${RECORDINGS}.
*
* \param filenameRelative name of the file to convert
*/
void convertFileRelativePath(std::string filenameRelative);
/**
* Goes to legacy session recording inherited class, and calls its convertFile()
* method, and then returns the resulting conversion filename.
@@ -514,6 +598,7 @@ public:
protected:
properties::BoolProperty _renderPlaybackInformation;
properties::BoolProperty _ignoreRecordedScale;
enum class RecordedType {
Camera = 0,
@@ -521,42 +606,52 @@ protected:
Script,
Invalid
};
struct timelineEntry {
struct TimelineEntry {
RecordedType keyframeType;
unsigned int idxIntoKeyframeTypeArray;
double timestamp;
Timestamps t3stamps;
};
ExternInteraction _externInteract;
double _timestampRecordStarted = 0.0;
Timestamps _timestamps3RecordStarted{ 0.0, 0.0, 0.0 };
double _timestampPlaybackStarted_application = 0.0;
double _timestampPlaybackStarted_simulation = 0.0;
double _timestampApplicationStarted_simulation = 0.0;
bool hasCameraChangedFromPrev(datamessagestructures::CameraKeyframe kfNew);
double appropriateTimestamp(double timeOs, double timeRec, double timeSim);
double appropriateTimestamp(Timestamps t3stamps);
double equivalentSimulationTime(double timeOs, double timeRec, double timeSim);
double equivalentApplicationTime(double timeOs, double timeRec, double timeSim);
void recordCurrentTimePauseState();
void recordCurrentTimeRate();
bool handleRecordingFile(std::string filenameIn);
static bool isPath(std::string& filename);
void removeTrailingPathSlashes(std::string& filename);
void extractFilenameFromPath(std::string& filename);
bool playbackCamera();
bool playbackTimeChange();
bool playbackScript();
bool playbackAddEntriesToTimeline();
void signalPlaybackFinishedForComponent(RecordedType type);
void findFirstCameraKeyframeInTimeline();
void handlePlaybackEnd();
bool findFirstCameraKeyframeInTimeline();
Timestamps generateCurrentTimestamp3(double keyframeTime);
static void saveStringToFile(const std::string& s, unsigned char* kfBuffer,
size_t& idx, std::ofstream& file);
static void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size,
std::ofstream& file);
bool addKeyframe(double timestamp,
bool addKeyframe(Timestamps t3stamps,
interaction::KeyframeNavigator::CameraPose keyframe, int lineNum);
bool addKeyframe(double timestamp, datamessagestructures::TimeKeyframe keyframe,
int lineNum);
bool addKeyframe(double timestamp, std::string scriptToQueue, int lineNum);
bool addKeyframeToTimeline(RecordedType type, size_t indexIntoTypeKeyframes,
double timestamp, int lineNum);
bool addKeyframe(Timestamps t3stamps,
datamessagestructures::TimeKeyframe keyframe, int lineNum);
bool addKeyframe(Timestamps t3stamps,
std::string scriptToQueue, int lineNum);
bool addKeyframeToTimeline(std::vector<TimelineEntry>& timeline, RecordedType type,
size_t indexIntoTypeKeyframes, Timestamps t3stamps, int lineNum);
void initializePlayback_time(double now);
void initializePlayback_modeFlags();
bool initializePlayback_timeline();
void initializePlayback_triggerStart();
void moveAheadInTime();
void lookForNonCameraKeyframesThatHaveComeDue(double currTime);
void updateCameraWithOrWithoutNewKeyframes(double currTime);
@@ -580,15 +675,21 @@ protected:
const int lineNum);
void saveSingleKeyframeScript(datamessagestructures::ScriptMessage& kf,
Timestamps& times, DataMode mode, std::ofstream& file, unsigned char* buffer);
void saveScriptKeyframeToPropertiesBaseline(std::string script);
bool isPropertyAllowedForBaseline(const std::string& propString);
unsigned int findIndexOfLastCameraKeyframeInTimeline();
bool doesTimelineEntryContainCamera(unsigned int index) const;
std::vector<std::pair<CallbackHandle, StateChangeCallback>> _stateChangeCallbacks;
bool doesStartWithSubstring(const std::string& s, const std::string& matchSubstr);
void trimCommandsFromScriptIfFound(std::string& script);
void replaceCommandsFromScriptIfFound(std::string& script);
RecordedType getNextKeyframeType();
RecordedType getPrevKeyframeType();
double getNextTimestamp();
double getPrevTimestamp();
void cleanUpPlayback();
void cleanUpRecording();
void cleanUpTimelinesAndKeyframes();
bool convertEntries(std::string& inFilename, std::stringstream& inStream,
DataMode mode, int lineNum, std::ofstream& outFile);
virtual bool convertCamera(std::stringstream& inStream, DataMode mode, int lineNum,
@@ -600,6 +701,16 @@ protected:
DataMode readModeFromHeader(std::string filename);
void readPlaybackHeader_stream(std::stringstream& conversionInStream,
std::string& version, DataMode& mode);
void populateListofLoadedSceneGraphNodes();
void checkIfScriptUsesScenegraphNode(std::string s);
bool checkForScenegraphNodeAccessScene(std::string& s);
bool checkForScenegraphNodeAccessNav(std::string& navTerm);
std::string extractScenegraphNodeFromScene(std::string& s);
bool checkIfInitialFocusNodeIsLoaded(unsigned int firstCamIndex);
std::string isolateTermFromQuotes(std::string s);
void eraseSpacesFromString(std::string& s);
std::string getNameFromSurroundingQuotes(std::string& s);
static void writeToFileBuffer(unsigned char* buf, size_t& idx, double src);
static void writeToFileBuffer(unsigned char* buf, size_t& idx, std::vector<char>& cv);
@@ -616,26 +727,79 @@ protected:
std::string _playbackLineParsing;
std::ofstream _recordFile;
int _playbackLineNum = 1;
int _recordingEntryNum = 1;
KeyframeTimeRef _playbackTimeReferenceMode;
datamessagestructures::CameraKeyframe _prevRecordedCameraKeyframe;
bool _playbackActive_camera = false;
bool _playbackActive_time = false;
bool _playbackActive_script = false;
bool _hasHitEndOfCameraKeyframes = false;
bool _setSimulationTimeWithNextCameraKeyframe = false;
bool _playbackPausedWithinDeltaTimePause = false;
bool _playbackLoopMode = false;
bool _playbackForceSimTimeAtStart = false;
double _playbackPauseOffset = 0.0;
double _previousTime = 0.0;
bool _saveRenderingDuringPlayback = false;
double _saveRenderingDeltaTime = 1.0 / 30.0;
double _saveRenderingCurrentRecordedTime;
double _saveRenderingCurrentRecordedTime = 0.0;
std::chrono::steady_clock::duration _saveRenderingDeltaTime_interpolation_usec;
std::chrono::steady_clock::time_point _saveRenderingCurrentRecordedTime_interpolation;
double _saveRenderingCurrentApplicationTime_interpolation = 0.0;
long long _saveRenderingClockInterpolation_countsPerSec = 1;
bool _saveRendering_isFirstFrame = true;
unsigned char _keyframeBuffer[_saveBufferMaxSize_bytes];
bool _cleanupNeeded = false;
bool _cleanupNeededRecording = false;
bool _cleanupNeededPlayback = false;
const std::string scriptReturnPrefix = "return ";
std::vector<interaction::KeyframeNavigator::CameraPose> _keyframesCamera;
std::vector<datamessagestructures::TimeKeyframe> _keyframesTime;
std::vector<std::string> _keyframesScript;
std::vector<timelineEntry> _timeline;
std::vector<TimelineEntry> _timeline;
std::vector<std::string> _keyframesSavePropertiesBaseline_scripts;
std::vector<TimelineEntry> _keyframesSavePropertiesBaseline_timeline;
std::vector<std::string> _propertyBaselinesSaved;
const std::vector<std::string> _propertyBaselineRejects = {
"NavigationHandler.OrbitalNavigator.Anchor",
"NavigationHandler.OrbitalNavigator.Aim",
"NavigationHandler.OrbitalNavigator.RetargetAnchor",
"NavigationHandler.OrbitalNavigator.RetargetAim"
};
//A script that begins with an exact match of any of the strings contained in
// _scriptRejects will not be recorded
const std::vector<std::string> _scriptRejects = {
"openspace.sessionRecording.enableTakeScreenShotDuringPlayback",
"openspace.sessionRecording.startPlayback",
"openspace.sessionRecording.stopPlayback",
"openspace.sessionRecording.startRecording",
"openspace.sessionRecording.stopRecording",
"openspace.scriptScheduler.clear"
};
const std::vector<std::string> _navScriptsUsingNodes = {
"RetargetAnchor",
"Anchor",
"Aim"
};
//Any script snippet included in this vector will be trimmed from any script
// from the script manager, before it is recorded in the session recording file.
// The remainder of the script will be retained.
const std::vector<std::string> _scriptsToBeTrimmed = {
"openspace.sessionRecording.togglePlaybackPause"
};
//Any script snippet included in this vector will be trimmed from any script
// from the script manager, before it is recorded in the session recording file.
// The remainder of the script will be retained.
const std::vector<ScriptSubstringReplace> _scriptsToBeReplaced = {
{
"openspace.time.pauseToggleViaKeyboard",
"openspace.time.interpolateTogglePause"
}
};
std::vector<std::string> _loadedNodes;
unsigned int _idxTimeline_nonCamera = 0;
unsigned int _idxTime = 0;
@@ -648,6 +812,7 @@ protected:
double _cameraFirstInTimeline_timestamp = 0;
int _nextCallbackHandle = 0;
std::vector<std::pair<CallbackHandle, StateChangeCallback>> _stateChangeCallbacks;
DataMode _conversionDataMode = DataMode::Binary;
int _conversionLineNum = 1;
@@ -679,24 +844,24 @@ protected:
class SessionRecording_legacy_0085 : public SessionRecording {
public:
SessionRecording_legacy_0085() : SessionRecording() {}
~SessionRecording_legacy_0085() {}
~SessionRecording_legacy_0085() override {}
char FileHeaderVersion[FileHeaderVersionLength+1] = "00.85";
char TargetConvertVersion[FileHeaderVersionLength+1] = "01.00";
std::string fileFormatVersion() {
std::string fileFormatVersion() override {
return std::string(FileHeaderVersion);
}
std::string targetFileFormatVersion() {
std::string targetFileFormatVersion() override {
return std::string(TargetConvertVersion);
}
std::string getLegacyConversionResult(std::string filename, int depth);
std::string getLegacyConversionResult(std::string filename, int depth) override;
struct ScriptMessage_legacy_0085 : public datamessagestructures::ScriptMessage {
void read(std::istream* in) {
void read(std::istream* in) override {
size_t strLen;
//Read string length from file
in->read(reinterpret_cast<char*>(&strLen), sizeof(strLen));
if (strLen > saveBufferStringSize_max) {
throw ConversionError("Invalid script size for conversion read.");
throw ConversionError("Invalid script size for conversion read");
}
//Read back full string
std::vector<char> temp(strLen + 1);
@@ -705,12 +870,12 @@ public:
_script.erase();
_script = temp.data();
};
}
};
protected:
bool convertScript(std::stringstream& inStream, DataMode mode, int lineNum,
std::string& inputLine, std::ofstream& outFile, unsigned char* buffer);
std::string& inputLine, std::ofstream& outFile, unsigned char* buffer) override;
};
} // namespace openspace

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -37,7 +37,7 @@ namespace openspace::interaction {
class ConvertRecFileVersionTask : public Task {
public:
ConvertRecFileVersionTask(const ghoul::Dictionary& dictionary);
~ConvertRecFileVersionTask();
~ConvertRecFileVersionTask() override;
std::string description() override;
void perform(const Task::ProgressCallback& progressCallback) override;
static documentation::Documentation documentation();

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -41,7 +41,7 @@ public:
ToBinary
};
ConvertRecFormatTask(const ghoul::Dictionary& dictionary);
~ConvertRecFormatTask();
~ConvertRecFormatTask() override;
std::string description() override;
void perform(const Task::ProgressCallback& progressCallback) override;
static documentation::Documentation documentation();

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -65,7 +65,8 @@ public:
WebsocketCameraStates(double sensitivity, double velocityScaleFactor);
void updateStateFromInput(const InputState& inputState, double deltaTime) override;
void updateStateFromInput(
const WebsocketInputStates& websocketInputStates, double deltaTime);
void setAxisMapping(int axis, AxisType mapping,
AxisInvert shouldInvert = AxisInvert::No,

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -55,11 +55,11 @@ enum class WebsocketAction : uint8_t {
*/
struct WebsocketInputState {
/// The maximum number of supported axes
static constexpr const int MaxAxes = 10;
static constexpr int MaxAxes = 10;
/// The maximum number of supported buttons
static constexpr const int MaxButtons = 32;
static constexpr int MaxButtons = 32;
/// Marks whether this websocket is connected. If this value is \c false, all other
/// Marks whether this websocket is connected. If this value is `false`, all other
/// members of this struct are undefined
bool isConnected = false;
@@ -69,19 +69,19 @@ struct WebsocketInputState {
/// The number of axes that this websocket supports
int nAxes = 0;
/// The values for each axis. Each value is in the range [-1, 1]. Only the first
/// \c nAxes values are defined values, the rest are undefined
/// `nAxes` values are defined values, the rest are undefined
std::array<float, MaxAxes> axes;
/// The number of buttons that this websocket possesses
int nButtons = 0;
/// The status of each button. Only the first \c nButtons values are defined, the rest
/// The status of each button. Only the first `nButtons` values are defined, the rest
/// are undefined
std::array<WebsocketAction, MaxButtons> buttons;
};
/// The maximum number of websockets that are supported by this system. This number is
/// derived from the available GLFW constants
constexpr const int MaxWebsockets = 16;
constexpr int MaxWebsockets = 16;
//struct WebsocketInputStates : public std::array<WebsocketInputState, MaxWebsockets> {
struct WebsocketInputStates : public std::unordered_map<size_t, WebsocketInputState*> {
/**
@@ -104,7 +104,7 @@ struct WebsocketInputStates : public std::unordered_map<size_t, WebsocketInputSt
*
* \param button The button that is to be checked
* \param action The action which is checked for each button
* \return \c true if there is at least one websocket whose \param button is in the
* \return `true` if there is at least one websocket whose \p button is in the
* \p action state
*
* \pre \p button must be 0 or positive

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -104,7 +104,7 @@ public:
* \param time The time in which the subphases have to be active in order to be
* included
* \param maxDepth The maximum levels of subphases that will be considered. If this
* value is equal to <code>-1</code>, an infinite depth will be considered.
* value is equal to `-1`, an infinite depth will be considered.
* \return A list of MissionPhases that cover the provided \p time
*/
Trace phaseTrace(double time, int maxDepth = -1) const;

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -52,6 +52,7 @@ public:
* Reads a mission from file and maps the mission name to the Mission object. If
* this is the first mission to be loaded, the mission will also be set as the
* current active mission.
*
* \param filename The file that contains the mission that is to be loaded
* \return The name of the mission that was loaded
* \pre \p filename must not be empty
@@ -62,6 +63,7 @@ public:
/**
* Unloads a previously loaded mission identified by the provided \p missionName.
*
* \param missionName The name of the mission that should be unloded
* \pre \p filename must not be empty
* \pre \p missionName must be a valid mission that has previously been loaded
@@ -71,16 +73,18 @@ public:
/**
* Returns whether the provided \p missionName has previously been added to the
* MissionManager.
*
* \param missionName The name of the mission that is to be tested
* \return \c true if the \p missionName has been added before
* \return `true` if the \p missionName has been added before
*/
bool hasMission(const std::string& missionName);
/**
* Sets the mission with the name <missionName> as the current mission. The current
* mission is what is return by `currentMission()`.
* \pre missionName must not be empty
*/
* Sets the mission with the name \p missionName as the current mission. The current
* mission is what is return by `currentMission()`.
*
* \pre missionName must not be empty
*/
void setCurrentMission(const std::string& missionName);
/**

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,8 +25,8 @@
#ifndef __OPENSPACE_CORE___KEYFRAMENAVIGATOR___H__
#define __OPENSPACE_CORE___KEYFRAMENAVIGATOR___H__
#include <openspace/util/timeline.h>
#include <openspace/network/messagestructures.h>
#include <openspace/util/timeline.h>
#include <ghoul/glm.h>
#include <ghoul/misc/boolean.h>
#include <glm/gtx/quaternion.hpp>
@@ -76,7 +76,6 @@ public:
void removeKeyframesAfter(double timestamp, Inclusive inclusive = Inclusive::No);
void clearKeyframes();
size_t nKeyframes() const;
const std::vector<datamessagestructures::CameraKeyframe>& keyframes() const;
double currentTime() const;
void setTimeReferenceMode(KeyframeTimeRef refType, double referenceTimestamp);

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -26,14 +26,18 @@
#define __OPENSPACE_CORE___NAVIGATIONHANDLER___H__
#include <openspace/documentation/documentation.h>
#include <openspace/interaction/inputstate.h>
#include <openspace/interaction/joystickcamerastates.h>
#include <openspace/interaction/orbitalnavigator.h>
#include <openspace/interaction/keyframenavigator.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/interaction/keyboardinputstate.h>
#include <openspace/interaction/mouseinputstate.h>
#include <openspace/interaction/websocketcamerastates.h>
#include <openspace/navigation/keyframenavigator.h>
#include <openspace/navigation/navigationstate.h>
#include <openspace/navigation/orbitalnavigator.h>
#include <openspace/navigation/pathnavigator.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/scene/profile.h>
#include <openspace/util/mouse.h>
#include <openspace/util/keys.h>
#include <optional>
@@ -48,86 +52,83 @@ namespace openspace::scripting { struct LuaLibrary; }
namespace openspace::interaction {
struct JoystickInputStates;
struct NavigationState;
struct WebsocketInputStates;
class KeyframeNavigator;
class OrbitalNavigator;
class PathNavigator;
class NavigationHandler : public properties::PropertyOwner {
public:
struct NavigationState {
NavigationState() = default;
NavigationState(const ghoul::Dictionary& dictionary);
NavigationState(std::string anchor, std::string aim, std::string referenceFrame,
glm::dvec3 position, std::optional<glm::dvec3> up = std::nullopt,
double yaw = 0.0, double pitch = 0.0);
ghoul::Dictionary dictionary() const;
static documentation::Documentation Documentation();
std::string anchor;
std::string aim;
std::string referenceFrame;
glm::dvec3 position = glm::dvec3(0.0);
std::optional<glm::dvec3> up;
double yaw = 0.0;
double pitch = 0.0;
};
NavigationHandler();
~NavigationHandler();
virtual ~NavigationHandler() override;
void initialize();
void deinitialize();
// Mutators
void setFocusNode(SceneGraphNode* node);
void resetCameraDirection();
void setNavigationStateNextFame(NavigationState state);
void setCamera(Camera* camera);
void setInterpolationTime(float durationInSeconds);
void updateCamera(double deltaTime);
void setEnableKeyFrameInteraction();
void setDisableKeyFrameInteraction();
void triggerPlaybackStart();
void stopPlayback();
void resetNavigationUpdateVariables();
// Accessors
Camera* camera() const;
const SceneGraphNode* anchorNode() const;
const InputState& inputState() const;
const MouseInputState& mouseInputState() const;
const KeyboardInputState& keyboardInputState() const;
const OrbitalNavigator& orbitalNavigator() const;
OrbitalNavigator& orbitalNavigator();
KeyframeNavigator& keyframeNavigator();
PathNavigator& pathNavigator();
bool isKeyFrameInteractionEnabled() const;
float interpolationTime() const;
// Callback functions
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
bool disabledKeybindings() const;
bool disabledMouse() const;
bool disabledJoystick() const;
void mouseButtonCallback(MouseButton button, MouseAction action);
void mousePositionCallback(double x, double y);
void mouseScrollWheelCallback(double pos);
void setJoystickAxisMapping(int axis, JoystickCameraStates::AxisType mapping,
std::vector<std::string> listAllJoysticks() const;
void setJoystickAxisMapping(std::string joystickName,
int axis, JoystickCameraStates::AxisType mapping,
JoystickCameraStates::AxisInvert shouldInvert =
JoystickCameraStates::AxisInvert::No,
JoystickCameraStates::AxisNormalize shouldNormalize =
JoystickCameraStates::AxisNormalize::No
JoystickCameraStates::JoystickType joystickType =
JoystickCameraStates::JoystickType::JoystickLike,
bool isSticky = false, double sensitivity = 0.0
);
JoystickCameraStates::AxisInformation joystickAxisMapping(int axis) const;
void setJoystickAxisMappingProperty(std::string joystickName,
int axis, std::string propertyUri,
float min = 0.f, float max = 1.f,
JoystickCameraStates::AxisInvert shouldInvert =
JoystickCameraStates::AxisInvert::No, bool isRemote = true
);
void setJoystickAxisDeadzone(int axis, float deadzone);
float joystickAxisDeadzone(int axis) const;
JoystickCameraStates::AxisInformation joystickAxisMapping(
const std::string& joystickName, int axis) const;
void bindJoystickButtonCommand(int button, std::string command, JoystickAction action,
void setJoystickAxisDeadzone(const std::string& joystickName, int axis,
float deadzone);
float joystickAxisDeadzone(const std::string& joystickName, int axis) const;
void bindJoystickButtonCommand(const std::string& joystickName, int button,
std::string command, JoystickAction action,
JoystickCameraStates::ButtonCommandRemote remote, std::string documentation);
void clearJoystickButtonCommand(int button);
std::vector<std::string> joystickButtonCommand(int button) const;
void clearJoystickButtonCommand(const std::string& joystickName, int button);
std::vector<std::string> joystickButtonCommand(const std::string& joystickName,
int button) const;
// Websockets
void setWebsocketAxisMapping(int axis, WebsocketCameraStates::AxisType mapping,
@@ -139,7 +140,7 @@ public:
NavigationState navigationState() const;
NavigationState navigationState(const SceneGraphNode& referenceFrame) const;
void saveNavigationState(const std::string& filepath,
void saveNavigationState(const std::filesystem::path& filepath,
const std::string& referenceFrameIdentifier);
void loadNavigationState(const std::string& filepath);
@@ -153,19 +154,26 @@ public:
static scripting::LuaLibrary luaLibrary();
private:
void applyNavigationState(const NavigationHandler::NavigationState& ns);
void applyNavigationState(const NavigationState& ns);
void updateCameraTransitions();
void clearGlobalJoystickStates();
bool _playbackModeEnabled = false;
InputState _inputState;
MouseInputState _mouseInputState;
KeyboardInputState _keyboardInputState;
Camera* _camera = nullptr;
std::function<void()> _playbackEndCallback;
static constexpr double InteractionHystersis = 0.0125;
bool _inAnchorApproachSphere = false;
bool _inAnchorReachSphere = false;
OrbitalNavigator _orbitalNavigator;
KeyframeNavigator _keyframeNavigator;
PathNavigator _pathNavigator;
std::optional<NavigationState> _pendingNavigationState;
properties::BoolProperty _disableKeybindings;
properties::BoolProperty _disableMouseInputs;
properties::BoolProperty _disableJoystickInputs;
properties::BoolProperty _useKeyFrameInteraction;

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -22,54 +22,38 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___SYNCHRONIZATIONWATCHER___H__
#define __OPENSPACE_CORE___SYNCHRONIZATIONWATCHER___H__
#ifndef __OPENSPACE_CORE___NAVIGATIONSTATE___H__
#define __OPENSPACE_CORE___NAVIGATIONSTATE___H__
#include <openspace/util/resourcesynchronization.h>
#include <memory>
#include <mutex>
#include <vector>
#include <unordered_map>
#include <openspace/documentation/documentation.h>
#include <optional>
namespace openspace {
/**
* Delays callbacks of synchronization state changes to
* when notify is called.
*/
class SynchronizationWatcher {
public:
using WatchHandle = size_t;
struct WatchData {
std::weak_ptr<ResourceSynchronization> synchronization;
ResourceSynchronization::CallbackHandle callbackHandle;
};
struct NotificationData {
std::weak_ptr<ResourceSynchronization> synchronization;
ResourceSynchronization::State state;
WatchHandle handle;
ResourceSynchronization::StateChangeCallback callback;
};
WatchHandle watchSynchronization(
std::shared_ptr<ResourceSynchronization> synchronization,
ResourceSynchronization::StateChangeCallback callback
);
void unwatchSynchronization(WatchHandle watchHandle);
void notify();
private:
std::mutex _mutex;
std::unordered_map<WatchHandle, WatchData> _watchedSyncs;
std::vector<NotificationData> _pendingNotifications;
WatchHandle nextWatchHandle = 0;
};
struct CameraPose;
} // namespace openspace
#endif // __OPENSPACE_CORE___SYNCHRONIZATIONWATCHER___H__
namespace openspace::interaction {
struct NavigationState {
NavigationState() = default;
explicit NavigationState(const ghoul::Dictionary& dictionary);
NavigationState(std::string anchor, std::string aim, std::string referenceFrame,
glm::dvec3 position, std::optional<glm::dvec3> up = std::nullopt,
double yaw = 0.0, double pitch = 0.0);
CameraPose cameraPose() const;
ghoul::Dictionary dictionary() const;
static documentation::Documentation Documentation();
std::string anchor;
std::string aim;
std::string referenceFrame;
glm::dvec3 position = glm::dvec3(0.0);
std::optional<glm::dvec3> up;
double yaw = 0.0;
double pitch = 0.0;
};
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___NAVIGATIONSTATE___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -33,6 +33,7 @@
#include <openspace/interaction/mousecamerastates.h>
#include <openspace/interaction/scriptcamerastates.h>
#include <openspace/interaction/websocketcamerastates.h>
#include <openspace/properties/optionproperty.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
@@ -40,27 +41,61 @@
#include <openspace/properties/triggerproperty.h>
#include <ghoul/glm.h>
#include <glm/gtx/quaternion.hpp>
#include <optional>
namespace openspace {
class SceneGraphNode;
class Camera;
struct CameraPose;
struct SurfacePositionHandle;
} // namespace
namespace openspace::interaction {
class InputState;
class MouseInputState;
class KeyboardInputState;
class OrbitalNavigator : public properties::PropertyOwner {
public:
struct IdleBehavior : public properties::PropertyOwner {
enum class Behavior {
Orbit = 0,
OrbitAtConstantLat,
OrbitAroundUp
};
IdleBehavior();
properties::BoolProperty apply;
properties::BoolProperty shouldTriggerWhenIdle;
properties::FloatProperty idleWaitTime;
properties::BoolProperty abortOnCameraInteraction;
properties::BoolProperty invert;
properties::FloatProperty speedScaleFactor;
properties::FloatProperty dampenInterpolationTime;
properties::OptionProperty defaultBehavior;
std::optional<Behavior> chosenBehavior;
};
OrbitalNavigator();
void updateStatesFromInput(const InputState& inputState, double deltaTime);
void updateStatesFromInput(const MouseInputState& mouseInputState,
const KeyboardInputState& keyboardInputState, double deltaTime);
void updateCameraStateFromStates(double deltaTime);
void updateCameraScalingFromAnchor(double deltaTime);
void resetVelocities();
/*
* This function should be called on every camera interaction: for example when
* navigating using an input device, changing the focus node or starting a path or
* a session recording playback
*/
void updateOnCameraInteraction();
void tickIdleBehaviorTimer(double deltaTime);
void triggerIdleBehavior(std::string_view choice = "");
Camera* camera() const;
void setCamera(Camera* camera);
void clearPreviousState();
@@ -75,7 +110,7 @@ public:
void startRetargetAim();
float retargetInterpolationTime() const;
void setRetargetInterpolationTime(float durationInSeconds);
void resetNodeMovements();
void updatePreviousStateVariables();
JoystickCameraStates& joystickStates();
const JoystickCameraStates& joystickStates() const;
@@ -95,20 +130,24 @@ public:
bool hasZoomFriction() const;
bool hasRollFriction() const;
double minAllowedDistance() const;
glm::dvec3 anchorNodeToCameraVector() const;
glm::quat anchorNodeToCameraRotation() const;
/**
* Compute a camera position that pushed the camera position to
* a valid position over the anchor node, accounting for the
* minimal allowed distance
*/
glm::dvec3 pushToSurfaceOfAnchor(const glm::dvec3& cameraPosition) const;
private:
struct CameraRotationDecomposition {
glm::dquat localRotation = glm::dquat(1.0, 0.0, 0.0, 0.0);
glm::dquat globalRotation = glm::dquat(1.0, 0.0, 0.0, 0.0);
};
struct CameraPose {
glm::dvec3 position = glm::dvec3(0.0);
glm::dquat rotation = glm::dquat(1.0, 0.0, 0.0, 0.0);
};
using Displacement = std::pair<glm::dvec3, glm::dvec3>;
struct Friction : public properties::PropertyOwner {
@@ -125,16 +164,19 @@ private:
bool resetVelocitiesOnChange = true);
void setAimNode(const SceneGraphNode* aimNode);
void updatePreviousAnchorState();
void updatePreviousAimState();
Camera* _camera;
Friction _friction;
// Anchor: Node to follow and orbit.
// Anchor: Node to follow and orbit
properties::StringProperty _anchor;
// Aim: Node to look at (when camera direction is reset),
// Empty string means same as anchor.
// If these are the same node we call it the `focus` node.
// If these are the same node we call it the `focus` node
properties::StringProperty _aim;
// Reset camera direction to the anchor node.
@@ -142,13 +184,10 @@ private:
// Reset camera direction to the aim node.
properties::TriggerProperty _retargetAim;
properties::BoolProperty _followAnchorNodeRotation;
properties::FloatProperty _followAnchorNodeRotationDistance;
properties::FloatProperty _minimumAllowedDistance;
properties::FloatProperty _flightDestinationDistance;
properties::DoubleProperty _flightDestinationFactor;
properties::BoolProperty _applyLinearFlight;
properties::FloatProperty _velocitySensitivity;
properties::FloatProperty _mouseSensitivity;
properties::FloatProperty _joystickSensitivity;
properties::FloatProperty _websocketSensitivity;
@@ -157,6 +196,8 @@ private:
properties::FloatProperty _stereoscopicDepthOfFocusSurface;
properties::FloatProperty _staticViewScaleExponent;
properties::BoolProperty _constantVelocityFlight;
properties::FloatProperty _retargetInterpolationTime;
properties::FloatProperty _stereoInterpolationTime;
properties::FloatProperty _followRotationInterpolationTime;
@@ -182,6 +223,11 @@ private:
Interpolator<double> _retargetAnchorInterpolator;
Interpolator<double> _cameraToSurfaceDistanceInterpolator;
Interpolator<double> _followRotationInterpolator;
Interpolator<double> _idleBehaviorDampenInterpolator;
bool _invertIdleBehaviorInterpolation = false;
IdleBehavior _idleBehavior;
float _idleBehaviorTriggerTimer = 0.f;
/**
* Decomposes the camera's rotation in to a global and a local rotation defined by
@@ -189,7 +235,7 @@ private:
* camera points towards the reference node in the direction opposite to the direction
* out from the surface of the object. The local rotation defines the differential
* from the global to the current total rotation so that
* <code>cameraRotation = globalRotation * localRotation</code>.
* `cameraRotation = globalRotation * localRotation`.
*/
CameraRotationDecomposition decomposeCameraRotationSurface(const CameraPose pose,
const SceneGraphNode& reference);
@@ -197,9 +243,9 @@ private:
/**
* Decomposes the camera's rotation in to a global and a local rotation defined by
* CameraRotationDecomposition. The global rotation defines the rotation so that the
* camera points towards the reference node's origin.
* camera points towards the reference position.
* The local rotation defines the differential from the global to the current total
* rotation so that <code>cameraRotation = globalRotation * localRotation</code>.
* rotation so that `cameraRotation = globalRotation * localRotation`.
*/
CameraRotationDecomposition decomposeCameraRotation(const CameraPose pose,
glm::dvec3 reference);
@@ -256,20 +302,6 @@ private:
const glm::dvec3& objectPosition, const glm::dquat& globalCameraRotation,
const SurfacePositionHandle& positionHandle) const;
/**
* Moves the camera along a vector, camPosToCenterPosDiff, until it reaches the
* focusLimit. The velocity of the zooming depend on distFromCameraToFocus and the
* final frame where the camera stops moving depends on the distance set in the
* variable focusLimit. The bool determines whether to move/fly towards the focus node
* or away from it.
*
* \return a new position of the camera, closer to the focusLimit than the previous
* position
*/
glm::dvec3 moveCameraAlongVector(const glm::dvec3& camPos,
double distFromCameraToFocus, const glm::dvec3& camPosToCenterPosDiff,
double destination, double deltaTime) const;
/*
* Adds rotation to the camera position so that it follows the rotation of the anchor
* node defined by the differential anchorNodeRotationDiff.
@@ -308,17 +340,17 @@ private:
/**
* Push the camera out to the surface of the object.
*
* \return a position vector adjusted to be at least minHeightAboveGround meters
* \return a position vector adjusted to be at least _minimumAllowedDistance meters
* above the actual surface of the object
*/
glm::dvec3 pushToSurface(double minHeightAboveGround,
const glm::dvec3& cameraPosition, const glm::dvec3& objectPosition,
glm::dvec3 pushToSurface(const glm::dvec3& cameraPosition,
const glm::dvec3& objectPosition,
const SurfacePositionHandle& positionHandle) const;
/**
* Interpolates between rotationDiff and a 0 rotation.
*/
glm::dquat interpolateRotationDifferential(double deltaTime, double interpolationTime,
glm::dquat interpolateRotationDifferential(double deltaTime,
const glm::dvec3 cameraPosition, const glm::dquat& rotationDiff);
/**
@@ -331,7 +363,48 @@ private:
* Calculates a SurfacePositionHandle given a camera position in world space.
*/
SurfacePositionHandle calculateSurfacePositionHandle(const SceneGraphNode& node,
const glm::dvec3 cameraPositionWorldSpace);
const glm::dvec3& cameraPositionWorldSpace) const;
void resetIdleBehavior();
/**
* Apply the currently selected idle behavior to the position and rotations
*/
void applyIdleBehavior(double deltaTime, glm::dvec3& position,
glm::dquat& localRotation, glm::dquat& globalRotation);
/**
* Orbit the current anchor node, in a right-bound orbit, by updating the position
* and global rotation of the camera.
*
* Used for IdleBehavior::Behavior::Orbit
*
* \param deltaTime The time step to use for the motion. Controls the rotation angle
* \param position The position of the camera. Will be changed by the function
* \param globalRotation The camera's global rotation. Will be changed by the function
* \param speedScale A speed scale that controls the speed of the motion
*/
void orbitAnchor(double deltaTime, glm::dvec3& position,
glm::dquat& globalRotation, double speedScale);
/**
* Orbit the current anchor node, by adding a rotation around the given axis. For
* example, when the axis is the north vector, the camera will stay on the current
* latitude band. Note that this creates a rolling motion if the camera's forward
* vector coincides with the axis, and should be used with care.
*
* Used for:
* IdleBehavior::Behavior::OrbitAtConstantLat (axis = north = z-axis) and
* IdleBehavior::Behavior::OrbitAroundUp (axis = up = y-axis)
*
* \param axis The axis to arbit around, given in model coordinates of the anchor
* \param deltaTime The time step to use for the motion. Controls the rotation angle
* \param position The position of the camera. Will be changed by the function
* \param globalRotation The camera's global rotation. Will be changed by the function
* \param speedScale A speed scale that controls the speed of the motion
*/
void orbitAroundAxis(const glm::dvec3 axis, double deltaTime, glm::dvec3& position,
glm::dquat& globalRotation, double speedScale);
};
} // namespace openspace::interaction

View File

@@ -0,0 +1,193 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___PATH___H__
#define __OPENSPACE_CORE___PATH___H__
#include <openspace/navigation/pathcurve.h>
#include <openspace/navigation/waypoint.h>
#include <ghoul/misc/dictionary.h>
#include <optional>
#include <vector>
namespace openspace {
struct CameraPose;
} // namespace openspace
namespace openspace::interaction {
class Path {
public:
enum class Type {
AvoidCollision = 0,
ZoomOutOverview,
Linear,
AvoidCollisionWithLookAt // @TODO (2021-08-13, emmbr) This type right now leads
// to rapid rotations, but is useful in specific
// scenarios, e.g. close to surfaces. Later we want to
// remove it, and create a curve type that looks nicely
// at the targets when moving, avoids collisions and
// doesn't introduce sudden large changes in rotation
};
Path(Waypoint start, Waypoint end, Type type,
std::optional<double> duration = std::nullopt);
Waypoint startPoint() const;
Waypoint endPoint() const;
/**
* Return the total length of the the curve for the path, in meters
*/
double pathLength() const;
/**
* Return a vector of positions corresponding to the control points of the path's
* spline curve
*/
std::vector<glm::dvec3> controlPoints() const;
/**
* Take a step along the current path, corresponding to the delta time step \p dt, and
* return the resulting camera pose. The \p speedScale is a factor that will be
* multiplied with the traversal speed
*/
CameraPose traversePath(double dt, float speedScale = 1.f);
/**
* Function that can be used to permaturely quit a path, for example when skipping
* to the end
*/
void quitPath();
/**
* Return the identifer of the node that is the current appropriate anchor node, of
* the start and end waypoint's reference node. Dtermined based on how far along the
* path we have traveled
*/
std::string currentAnchor() const;
/**
* Return wether the path has reached its end point or not
*/
bool hasReachedEnd() const;
/**
* Compute the interpolated camera pose at a certain distance along a *linear*
* path. Note that the linear path is a special case, to avoid risks of precision
* problems for long paths
*/
CameraPose linearInterpolatedPose(double distance, double displacement);
/**
* Compute the interpolated camera pose at a certain distance along the path
*/
CameraPose interpolatedPose(double distance) const;
/**
* Reset variables used to play back path
*/
void resetPlaybackVariables();
private:
/**
* Interpolate between the paths start and end rotation using the approach that
* corresponds to the path's curve type. The interpolation parameter \p t is the
* same as for the position interpolation, i.e. the relative traveled distance
* along the path, in [0, 1]
*
* \param t The interpolation parameter, given as the relative traveled distance
along the path, in [0, 1]
*/
glm::dquat interpolateRotation(double t) const;
/**
* Compute the interpolated rotation quaternion using an eased SLERP approach
*
* \param t The interpolation variable for the rotatation interpolation.
* Should be the relative traveled distance, in [0, 1]
*/
glm::dquat easedSlerpRotation(double t) const;
/**
* Compute the interpolated rotation quaternion using a method that is customized
* for linear paths. The camera will first interpoalte to look at the targetted
* node, and keep doing so for most of the path. At the end, when within a certain
* distance from the target, the rotation is interpolated so that the camera ends up
* in the target pose at the end of the path.
*
* \param t The interpolation variable for the rotatation interpolation.
* Should be the relative traveled distance, in [0, 1]
*/
glm::dquat linearPathRotation(double t) const;
/**
* Compute the interpolated rotation quaternion using an approach that first
* interpolates to look at the start node, and then the end node, before
* interpolating to the end rotation
*
* \param t The interpolation variable for the rotatation interpolation.
* Should be the relative traveled distance, in [0, 1]
*/
glm::dquat lookAtTargetsRotation(double t) const;
/**
* Evaluate the current traversal speed along the path, based on the currently
* traveled distance. The final speed will be scaled to match the desired duration
* for the path (which might have been specified by the user)
*
* \param traveledDistance The current distance traveled along the path, in meters
*/
double speedAlongPath(double traveledDistance) const;
Waypoint _start;
Waypoint _end;
Type _type;
std::unique_ptr<PathCurve> _curve;
double _speedFactorFromDuration = 1.0;
// Playback variables
double _traveledDistance = 0.0; // Meters
double _progressedTime = 0.0; // Time since playback started (seconds)
bool _shouldQuit = false;
CameraPose _prevPose;
};
/**
* Create a path based on an instruction given as a dictionary. (See top of cpp file
* for documentation on keys and values for the dictionary.)
* If /p forceType is specified, that type will primarily be used as the type for the
* created path. Secondly, the type will be read from the dictionary, and lastly it will
* use the default from PathNavigator.
*
* \return the created path
*/
Path createPathFromDictionary(const ghoul::Dictionary& dictionary,
std::optional<Path::Type> forceType = std::nullopt);
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___PATH___H__

View File

@@ -0,0 +1,122 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___PATHCURVE___H__
#define __OPENSPACE_CORE___PATHCURVE___H__
#include <ghoul/glm.h>
#include <ghoul/misc/exception.h>
#include <vector>
namespace openspace::interaction {
class Waypoint;
class PathCurve {
public:
struct InsufficientPrecisionError : public ghoul::RuntimeError {
explicit InsufficientPrecisionError(std::string msg);
};
struct TooShortPathError : public ghoul::RuntimeError {
explicit TooShortPathError(std::string msg);
};
virtual ~PathCurve() = 0;
/**
* Return the length of the curve, in meters
*/
double length() const;
/**
* Compute and return the position along the path at the specified relative
* distance. The input parameter should be in range [0, 1], where 1 correspond to
* the full length of the path.
*
* Can be overridden by subclasses that want more control over the position
* interpolation
*/
virtual glm::dvec3 positionAt(double relativeDistance) const;
/**
* Get the intorlatied position along the spline, based on the given curve parameter
* u in range [0, 1]. A curve parameter of 0 returns the start position and 1 the end
* position. Note that u does not correspond to the relatively traveled distance.
*
* Can be overridden by subclasses that want more control over the position
* interpolation
*/
virtual glm::dvec3 interpolate(double u) const;
/**
* Return the positions defining the control points for the spline interpolation
*/
std::vector<glm::dvec3> points() const;
protected:
/**
* Precompute information related to the spline parameters that are
* needed for arc length reparameterization. Must be called after
* control point creation.
*/
void initializeParameterData();
/**
* Compute curve parameter u that matches the input arc length s.
* Input s is a length value in meters, in the range [0, _totalLength].
* The returned curve parameter u is in range [0, 1].
*/
double curveParameter(double s) const;
double approximatedDerivative(double u, double h = 0.0001) const;
double arcLength(double limit = 1.0) const;
double arcLength(double lowerLimit, double upperLimit) const;
std::vector<glm::dvec3> _points;
unsigned int _nSegments = 0;
std::vector<double> _curveParameterSteps; // per segment
std::vector<double> _lengthSums; // per segment
double _totalLength = 0.0; // meters
struct ParameterPair {
double u; // curve parameter
double s; // arc length parameter
};
std::vector<ParameterPair> _parameterSamples;
};
class LinearCurve : public PathCurve {
public:
LinearCurve(const Waypoint& start, const Waypoint& end);
glm::dvec3 positionAt(double relativeDistance) const override;
glm::dvec3 interpolate(double u) const override;
};
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___PATHCURVE___H__

View File

@@ -0,0 +1,48 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___AVOIDCOLLISIONCURVE___H__
#define __OPENSPACE_CORE___AVOIDCOLLISIONCURVE___H__
#include <openspace/navigation/pathcurve.h>
namespace openspace { class SceneGraphNode; }
namespace openspace::interaction {
class WayPoint;
class AvoidCollisionCurve : public PathCurve {
public:
AvoidCollisionCurve(const Waypoint& start, const Waypoint& end);
private:
void removeCollisions(int step = 0);
std::vector<SceneGraphNode*> _relevantNodes;
};
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___AVOIDCOLLISIONCURVE___H__

View File

@@ -0,0 +1,41 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___ZOOMOUTOVERVIEWCURVE___H__
#define __OPENSPACE_CORE___ZOOMOUTOVERVIEWCURVE___H__
#include <openspace/navigation/pathcurve.h>
namespace openspace::interaction {
class WayPoint;
class ZoomOutOverviewCurve : public PathCurve {
public:
ZoomOutOverviewCurve(const Waypoint& start, const Waypoint& end);
};
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___ZOOMOUTOVERVIEWCURVE___H__

View File

@@ -0,0 +1,127 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___PATHNAVIGATOR___H__
#define __OPENSPACE_CORE___PATHNAVIGATOR___H__
#include <openspace/properties/propertyowner.h>
#include <openspace/navigation/path.h>
#include <openspace/properties/list/stringlistproperty.h>
#include <openspace/properties/optionproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/doubleproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <ghoul/glm.h>
#include <memory>
namespace openspace {
class Camera;
struct CameraPose;
class SceneGraphNode;
} // namespace openspace
namespace openspace::scripting { struct LuaLibrary; }
namespace openspace::interaction {
class Path;
class PathNavigator : public properties::PropertyOwner {
public:
PathNavigator();
virtual ~PathNavigator() override;
// Accessors
Camera* camera() const;
const SceneGraphNode* anchor() const;
const Path* currentPath() const;
double speedScale() const;
double arrivalDistanceFactor() const;
float linearRotationSpeedFactor() const;
bool hasCurrentPath() const;
bool hasFinished() const;
bool isPlayingPath() const;
void updateCamera(double deltaTime);
void createPath(const ghoul::Dictionary& dictionary);
void clearPath();
void startPath();
void abortPath();
void pausePath();
void continuePath();
void skipToEnd();
Path::Type defaultPathType() const;
double minValidBoundingSphere() const;
double findValidBoundingSphere(const SceneGraphNode* node) const;
const std::vector<SceneGraphNode*>& relevantNodes();
/**
* Find a node close to the given node. Closeness is determined by a factor times
* the bounding sphere of the object
* \return pointer to the SGN if one was found, nullptr otherwise
*/
static SceneGraphNode* findNodeNearTarget(const SceneGraphNode* node);
/**
* \return The Lua library that contains all Lua functions available to affect the
* path navigation
*/
static scripting::LuaLibrary luaLibrary();
private:
void handlePathEnd();
/**
* Populate list of nodes that are relevant for collision checks, etc
*/
void findRelevantNodes();
void removeRollRotation(CameraPose& pose, double deltaTime);
std::unique_ptr<Path> _currentPath = nullptr;
bool _isPlaying = false;
bool _startSimulationTimeOnFinish = false;
bool _setCameraToEndNextFrame = false;
properties::OptionProperty _defaultPathType;
properties::BoolProperty _includeRoll;
properties::FloatProperty _speedScale;
properties::BoolProperty _applyIdleBehaviorOnFinish;
properties::DoubleProperty _arrivalDistanceFactor;
properties::FloatProperty _linearRotationSpeedFactor;
properties::DoubleProperty _minValidBoundingSphere;
properties::StringListProperty _relevantNodeTags;
std::vector<SceneGraphNode*> _relevantNodes;
bool _hasInitializedRelevantNodes = false;
};
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___PATHNAVIGATOR___H__

View File

@@ -0,0 +1,60 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___WAYPOINT___H__
#define __OPENSPACE_CORE___WAYPOINT___H__
#include <openspace/camera/camerapose.h>
#include <ghoul/glm.h>
#include <string>
namespace openspace { class SceneGraphNode; }
namespace openspace::interaction {
struct NavigationState;
class Waypoint {
public:
Waypoint() = default;
Waypoint(const glm::dvec3& pos, const glm::dquat& rot, const std::string& ref);
explicit Waypoint(const NavigationState& ns);
CameraPose pose() const;
glm::dvec3 position() const;
glm::dquat rotation() const;
SceneGraphNode* node() const;
std::string nodeIdentifier() const;
double validBoundingSphere() const;
private:
CameraPose _pose;
std::string _nodeIdentifier;
// to be able to handle nodes with faulty bounding spheres
double _validBoundingSphere = 0.0;
};
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___WAYPOINT___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -49,6 +49,14 @@ struct CameraKeyframe {
CameraKeyframe(const std::vector<char>& buffer) {
deserialize(buffer);
}
CameraKeyframe(glm::dvec3&& pos, glm::dquat&& rot, std::string&& focusNode,
bool&& followNodeRot, float&& scale)
: _position(pos)
, _rotation(rot)
, _followNodeRotation(followNodeRot)
, _focusNode(focusNode)
, _scale(scale)
{}
glm::dvec3 _position = glm::dvec3(0.0);
glm::dquat _rotation = glm::dquat(1.0, 0.0, 0.0, 0.0);
@@ -81,13 +89,13 @@ struct CameraKeyframe {
sizeof(_followNodeRotation)
);
int nodeNameLength = static_cast<int>(_focusNode.size());
uint32_t nodeNameLength = static_cast<uint32_t>(_focusNode.size());
// Add focus node
buffer.insert(
buffer.end(),
reinterpret_cast<const char*>(&nodeNameLength),
reinterpret_cast<const char*>(&nodeNameLength) + sizeof(nodeNameLength)
reinterpret_cast<const char*>(&nodeNameLength) + sizeof(uint32_t)
);
buffer.insert(
buffer.end(),
@@ -107,7 +115,7 @@ struct CameraKeyframe {
reinterpret_cast<const char*>(&_timestamp),
reinterpret_cast<const char*>(&_timestamp) + sizeof(_timestamp)
);
};
}
size_t deserialize(const std::vector<char>& buffer, size_t offset = 0) {
int size = 0;
@@ -147,7 +155,7 @@ struct CameraKeyframe {
offset += size;
return offset;
};
}
void write(std::ostream& out) const {
out.write(
@@ -176,7 +184,7 @@ struct CameraKeyframe {
// Write timestamp
out.write(reinterpret_cast<const char*>(&_timestamp), sizeof(_timestamp));
};
}
void write(std::stringstream& out) const {
// Add camera position
@@ -188,7 +196,9 @@ struct CameraKeyframe {
<< std::fixed << std::setprecision(7) << _rotation.y << ' '
<< std::fixed << std::setprecision(7) << _rotation.z << ' '
<< std::fixed << std::setprecision(7) << _rotation.w << ' ';
out << std::scientific << _scale << ' ';
out << std::fixed
<< std::setprecision(std::numeric_limits<double>::max_digits10)
<< _scale << ' ';
if (_followNodeRotation) {
out << "F ";
}
@@ -196,7 +206,7 @@ struct CameraKeyframe {
out << "- ";
}
out << _focusNode;
};
}
void read(std::istream* in) {
// Read position
@@ -224,7 +234,7 @@ struct CameraKeyframe {
// Read timestamp
in->read(reinterpret_cast<char*>(&_timestamp), sizeof(_timestamp));
};
}
void read(std::istringstream& iss) {
std::string rotationFollowing;
@@ -240,7 +250,7 @@ struct CameraKeyframe {
>> rotationFollowing
>> _focusNode;
_followNodeRotation = (rotationFollowing == "F");
};
}
};
struct TimeKeyframe {
@@ -261,17 +271,17 @@ struct TimeKeyframe {
reinterpret_cast<const char*>(this),
reinterpret_cast<const char*>(this) + sizeof(TimeKeyframe)
);
};
}
size_t deserialize(const std::vector<char>& buffer, size_t offset = 0) {
*this = *reinterpret_cast<const TimeKeyframe*>(buffer.data() + offset);
offset += sizeof(TimeKeyframe);
return offset;
};
}
void write(std::ostream* out) const {
out->write(reinterpret_cast<const char*>(this), sizeof(TimeKeyframe));
};
}
void write(std::stringstream& out) const {
out << ' ' << _dt;
@@ -287,11 +297,11 @@ struct TimeKeyframe {
else {
out << " -";
}
};
}
void read(std::istream* in) {
in->read(reinterpret_cast<char*>(this), sizeof(TimeKeyframe));
};
}
void read(std::istringstream& iss) {
std::string paused, jump;
@@ -301,7 +311,7 @@ struct TimeKeyframe {
>> jump;
_paused = (paused == "P");
_requiresTimeJump = (jump == "J");
};
}
};
struct TimeTimeline {
@@ -329,7 +339,7 @@ struct TimeTimeline {
for (const TimeKeyframe& k : _keyframes) {
k.serialize(buffer);
}
};
}
size_t deserialize(const std::vector<char>& buffer, size_t offset = 0) {
int size = 0;
@@ -348,7 +358,7 @@ struct TimeTimeline {
offset = k.deserialize(buffer, offset);
}
return offset;
};
}
void write(std::ostream* out) const {
out->write(reinterpret_cast<const char*>(&_clear), sizeof(bool));
@@ -358,7 +368,7 @@ struct TimeTimeline {
for (const TimeKeyframe& k : _keyframes) {
k.write(out);
}
};
}
void read(std::istream* in) {
in->read(reinterpret_cast<char*>(&_clear), sizeof(bool));
@@ -368,7 +378,7 @@ struct TimeTimeline {
for (TimeKeyframe& k : _keyframes) {
k.read(in);
}
};
}
};
struct ScriptMessage {
@@ -376,7 +386,7 @@ struct ScriptMessage {
ScriptMessage(const std::vector<char>& buffer) {
deserialize(buffer);
}
virtual ~ScriptMessage() {};
virtual ~ScriptMessage() {}
std::string _script;
double _timestamp = 0.0;
@@ -388,7 +398,7 @@ struct ScriptMessage {
buffer.insert(buffer.end(), p, p + sizeof(uint32_t));
buffer.insert(buffer.end(), _script.begin(), _script.end());
};
}
void deserialize(const std::vector<char>& buffer) {
const char* p = buffer.data();
@@ -407,11 +417,11 @@ struct ScriptMessage {
// We can skip over the first uint32_t that encoded the length
_script.assign(buffer.begin() + sizeof(uint32_t), buffer.end());
};
}
void write(std::ostream* out) const {
out->write(_script.c_str(), _script.size());
};
}
void write(unsigned char* buf, size_t& idx, std::ofstream& file) const {
size_t strLen = _script.size();
@@ -426,7 +436,7 @@ struct ScriptMessage {
file.write(reinterpret_cast<char*>(buf), idx);
//Write directly to file because some scripts can be very long
file.write(_script.c_str(), _script.size());
};
}
void write(std::stringstream& ss) const {
unsigned int numLinesInScript = static_cast<unsigned int>(
@@ -447,7 +457,7 @@ struct ScriptMessage {
_script.erase();
_script = temp.data();
};
}
void read(std::istringstream& iss) {
int numScriptLines;
@@ -466,7 +476,7 @@ struct ScriptMessage {
_script.append("\n");
}
}
};
}
};
} // namespace openspace::messagestructures

View File

@@ -0,0 +1,57 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___MESSAGESTRUCTURESHELPER___H__
#define __OPENSPACE_CORE___MESSAGESTRUCTURESHELPER___H__
#include <openspace/network/messagestructures.h>
namespace openspace::datamessagestructures {
/**
* Method that creates a CameraKeyframe object and populates
* it with the current properties of the camera from the navigation handler.
* \returns CameraKeyframe with current state from NavigationHandler
*/
CameraKeyframe generateCameraKeyframe();
/**
* Method that creates a TimeKeyframe object and populates
* it with the current time values from the application time manager.
* \returns TimeKeyframe The time keyframe
*/
TimeKeyframe generateTimeKeyframe();
/**
* Method that creates a ScriptMessage object from a given script
* string, and populates the ScriptMessage with the script and timestamp
* of the current application time.
* \param script The script to execute in std::string form
* \returns ScriptMessage The ScriptMessage data structure with script
*/
ScriptMessage generateScriptMessage(std::string script);
} // namespace openspace::datamessagestructures
#endif // __OPENSPACE_CORE___MESSAGESTRUCTURESHELPER___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -42,14 +42,13 @@ public:
Host
};
enum class MessageType : uint32_t {
enum class MessageType : uint8_t {
Authentication = 0,
Data,
ConnectionStatus,
HostshipRequest,
HostshipResignation,
NConnections,
Disconnection
NConnections
};
struct Message {
@@ -71,7 +70,9 @@ public:
class ConnectionLostError : public ghoul::RuntimeError {
public:
explicit ConnectionLostError();
explicit ConnectionLostError(bool shouldLogError = true);
bool shouldLogError;
};
ParallelConnection(std::unique_ptr<ghoul::io::TcpSocket> socket);
@@ -84,9 +85,12 @@ public:
ParallelConnection::Message receiveMessage();
static const unsigned int ProtocolVersion;
// Gonna do some UTF-like magic once we reach 255 to introduce a second byte or so
static constexpr uint8_t ProtocolVersion = 6;
private:
std::unique_ptr<ghoul::io::TcpSocket> _socket;
bool _shouldDisconnect = false;
};
} // namespace openspace

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,16 +25,13 @@
#ifndef __OPENSPACE_CORE___PARALLELPEER___H__
#define __OPENSPACE_CORE___PARALLELPEER___H__
#include <openspace/network/parallelconnection.h>
#include <openspace/interaction/externinteraction.h>
#include <openspace/network/messagestructures.h>
#include <openspace/util/timemanager.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/network/messagestructures.h>
#include <openspace/network/parallelconnection.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/util/timemanager.h>
#include <ghoul/designpattern/event.h>
#include <atomic>
#include <deque>
@@ -50,7 +47,7 @@ namespace scripting { struct LuaLibrary; }
class ParallelPeer : public properties::PropertyOwner {
public:
ParallelPeer();
~ParallelPeer();
~ParallelPeer() override;
void connect();
void setPort(std::string port);
@@ -128,13 +125,11 @@ private:
std::atomic<bool> _timeTimelineChanged;
std::mutex _latencyMutex;
std::deque<double> _latencyDiffs;
double _initialTimeDiff;
double _initialTimeDiff = 0.0;
std::unique_ptr<std::thread> _receiveThread = nullptr;
std::shared_ptr<ghoul::Event<>> _connectionEvent;
ExternInteraction _externInteract;
ParallelConnection _connection;
TimeManager::CallbackHandle _timeJumpCallback = -1;

View File

@@ -1,117 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___PARALLELSERVER___H__
#define __OPENSPACE_CORE___PARALLELSERVER___H__
#include <openspace/network/parallelconnection.h>
#include <openspace/util/concurrentqueue.h>
#include <ghoul/io/socket/tcpsocketserver.h>
#include <atomic>
#include <string>
#include <unordered_map>
namespace openspace {
class ParallelServer {
public:
void start(int port, const std::string& password,
const std::string& changeHostPassword);
void setDefaultHostAddress(std::string defaultHostAddress);
std::string defaultHostAddress() const;
void stop();
size_t nConnections() const;
private:
struct Peer {
size_t id;
std::string name;
ParallelConnection parallelConnection;
ParallelConnection::Status status;
std::thread thread;
};
struct PeerMessage {
size_t peerId;
ParallelConnection::Message message;
};
bool isConnected(const Peer& peer) const;
void sendMessage(Peer& peer, ParallelConnection::MessageType messageType,
const std::vector<char>& message);
void sendMessageToAll(ParallelConnection::MessageType messageType,
const std::vector<char>& message);
void sendMessageToClients(ParallelConnection::MessageType messageType,
const std::vector<char>& message);
void disconnect(Peer& peer);
void setName(Peer& peer, std::string name);
void assignHost(std::shared_ptr<Peer> newHost);
void setToClient(Peer& peer);
void setNConnections(size_t nConnections);
void sendConnectionStatus(Peer& peer);
void handleAuthentication(std::shared_ptr<Peer> peer, std::vector<char> message);
void handleData(const Peer& peer, std::vector<char> data);
void handleHostshipRequest(std::shared_ptr<Peer> peer, std::vector<char> message);
void handleHostshipResignation(Peer& peer);
void handleNewPeers();
void eventLoop();
std::shared_ptr<Peer> peer(size_t id);
void handlePeer(size_t id);
void handlePeerMessage(PeerMessage peerMessage);
std::unordered_map<size_t, std::shared_ptr<Peer>> _peers;
mutable std::mutex _peerListMutex;
std::thread _serverThread;
std::thread _eventLoopThread;
ghoul::io::TcpSocketServer _socketServer;
size_t _passwordHash;
size_t _changeHostPasswordHash;
size_t _nextConnectionId = 1;
std::atomic_bool _shouldStop = false;
std::atomic_size_t _nConnections = 0;
std::atomic_size_t _hostPeerId = 0;
mutable std::mutex _hostInfoMutex;
std::string _hostName;
std::string _defaultHostAddress;
ConcurrentQueue<PeerMessage> _incomingMessages;
};
} // namespace openspace
#endif // __OPENSPACE_CORE___PARALLELSERVER___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -34,15 +34,13 @@ public:
DoubleListProperty(Property::PropertyInfo info,
std::vector<double> values = std::vector<double>());
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<std::vector<double>>::operator std::vector<double>;
using TemplateProperty<std::vector<double>>::operator=;
protected:
std::vector<double> fromLuaConversion(lua_State* state, bool& success) const override;
void toLuaConversion(lua_State* state) const override;
std::string toStringConversion() const override;
};

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -34,15 +34,13 @@ public:
IntListProperty(Property::PropertyInfo info,
std::vector<int> values = std::vector<int>());
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<std::vector<int>>::operator std::vector<int>;
using TemplateProperty<std::vector<int>>::operator=;
protected:
std::vector<int> fromLuaConversion(lua_State* state, bool& success) const override;
void toLuaConversion(lua_State* state) const override;
std::string toStringConversion() const override;
};

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -35,16 +35,13 @@ public:
StringListProperty(Property::PropertyInfo info,
std::vector<std::string> values = std::vector<std::string>());
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<std::vector<std::string>>::operator std::vector<std::string>;
using TemplateProperty<std::vector<std::string>>::operator=;
protected:
std::vector<std::string> fromLuaConversion(lua_State* state,
bool& success) const override;
void toLuaConversion(lua_State* state) const override;
std::string toStringConversion() const override;
};

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -35,7 +35,11 @@ class ListProperty : public TemplateProperty<std::vector<T>> {
public:
ListProperty(Property::PropertyInfo info, std::vector<T> values);
virtual ~ListProperty() = 0;
virtual ~ListProperty() override = 0;
protected:
std::vector<T> fromLuaConversion(lua_State* state) const override;
void toLuaConversion(lua_State* state) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -32,5 +32,15 @@ ListProperty<T>::ListProperty(Property::PropertyInfo info, std::vector<T> values
template <typename T>
ListProperty<T>::~ListProperty() {}
template <typename T>
std::vector<T> ListProperty<T>::fromLuaConversion(lua_State* state) const {
return ghoul::lua::value<std::vector<T>>(state);
}
template <typename T>
void ListProperty<T>::toLuaConversion(lua_State* state) const {
ghoul::lua::push(state, TemplateProperty<std::vector<T>>::_value);
}
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -41,13 +41,10 @@ public:
ghoul::createFillMat2x2<double>(std::numeric_limits<double>::max()),
glm::dmat2x2 stepValue = ghoul::createFillMat2x2<double>(0.01));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::dmat2x2>::operator=;
protected:
glm::dmat2x2 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -41,13 +41,10 @@ public:
ghoul::createFillMat3x3<double>(std::numeric_limits<double>::max()),
glm::dmat3x3 stepValue = ghoul::createFillMat3x3<double>(0.01));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::dmat3x3>::operator=;
protected:
glm::dmat3x3 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -41,13 +41,10 @@ public:
ghoul::createFillMat4x4<double>(std::numeric_limits<double>::max()),
glm::dmat4x4 stepValue = ghoul::createFillMat4x4<double>(0.01));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::dmat4x4>::operator=;
protected:
glm::dmat4x4 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -41,13 +41,10 @@ public:
ghoul::createFillMat2x2<float>(std::numeric_limits<float>::max()),
glm::mat2x2 stepValue = ghoul::createFillMat2x2<float>(0.01f));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::mat2x2>::operator=;
protected:
glm::mat2x2 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -41,13 +41,10 @@ public:
ghoul::createFillMat3x3<float>(std::numeric_limits<float>::max()),
glm::mat3x3 stepValue = ghoul::createFillMat3x3<float>(0.01f));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::mat3x3>::operator=;
protected:
glm::mat3x3 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -41,13 +41,10 @@ public:
ghoul::createFillMat4x4<float>(std::numeric_limits<float>::max()),
glm::mat4x4 stepValue = ghoul::createFillMat4x4<float>(0.01f));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::mat4x4>::operator=;
protected:
glm::mat4x4 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -35,7 +35,7 @@ public:
NumericalProperty(Property::PropertyInfo info, T value, T minimumValue,
T maximumValue, T steppingValue, float exponent = 1.f);
virtual std::string className() const override = 0;
virtual std::string_view className() const override = 0;
virtual int typeLua() const override = 0;
T minValue() const;
@@ -66,7 +66,7 @@ protected:
static const std::string SteppingValueKey;
static const std::string ExponentValueKey;
virtual T fromLuaConversion(lua_State* state, bool& success) const override = 0;
T fromLuaConversion(lua_State* state) const override;
virtual void toLuaConversion(lua_State* state) const override;
virtual std::string toStringConversion() const override;

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -23,8 +23,11 @@
****************************************************************************************/
#include <openspace/util/json_helper.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/lua/ghoul_lua.h>
#include <glm/ext/matrix_common.hpp>
#include <cmath>
#include <type_traits>
namespace openspace::properties {
@@ -88,6 +91,36 @@ float NumericalProperty<T>::exponent() const {
template <typename T>
void NumericalProperty<T>::setExponent(float exponent) {
ghoul_assert(std::abs(exponent) > 0.f, "Exponent for property input cannot be zero");
auto isValidRange = [](const T& minValue, const T& maxValue) {
if constexpr (ghoul::isGlmVector<T>() || ghoul::isGlmMatrix<T>()) {
return glm::all(glm::greaterThanEqual(minValue, T(0))) &&
glm::all(glm::greaterThanEqual(maxValue, T(0)));
}
else {
return (minValue >= T(0) && maxValue >= T(0));
}
};
// While the exponential slider does not support ranges with negative values,
// prevent setting the exponent for such ranges
// @ TODO (2021-06-30, emmbr), remove this check when no longer needed
if (!std::is_unsigned<T>::value) {
if (!isValidRange(_minimumValue, _maximumValue)) {
LWARNINGC(
"NumericalProperty: setExponent",
fmt::format(
"Setting exponent for properties with negative values in "
"[min, max] range is not yet supported. Property: {}",
this->fullyQualifiedIdentifier()
)
);
_exponent = 1.f;
return;
}
}
_exponent = exponent;
}
@@ -133,12 +166,9 @@ void NumericalProperty<T>::setInterpolationTarget(std::any value) {
template <typename T>
void NumericalProperty<T>::setLuaInterpolationTarget(lua_State* state) {
bool success = false;
T targetValue = fromLuaConversion(state, success);
if (success) {
_interpolationStart = TemplateProperty<T>::_value;
_interpolationEnd = std::move(targetValue);
}
T targetValue = fromLuaConversion(state);
_interpolationStart = TemplateProperty<T>::_value;
_interpolationEnd = std::move(targetValue);
}
template <typename T>
@@ -158,6 +188,11 @@ void NumericalProperty<T>::toLuaConversion(lua_State* state) const {
ghoul::lua::push(state, TemplateProperty<T>::_value);
}
template <typename T>
T NumericalProperty<T>::fromLuaConversion(lua_State* state) const {
return ghoul::lua::value<T>(state);
}
template <typename T>
std::string NumericalProperty<T>::toStringConversion() const {
return formatJson(TemplateProperty<T>::_value);

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -33,16 +33,15 @@ namespace openspace::properties {
/**
* The OptionProperty is a property that provides a number of predefined (using the
* addOption method) options consisting of a <code>description</code> and a
* <code>value</code>. The available options can be queried using the options method.
* Only values representing valid options can be used to set this property, or an error
* will be logged
* addOption method) options consisting of a `description` and a `value`. The available
* options can be queried using the options method. Only values representing valid options
* can be used to set this property, or an error will be logged
*/
class OptionProperty : public IntProperty {
public:
/**
* The struct storing a single option consisting of an integer \c value and a
* \c string description.
* The struct storing a single option consisting of an integer `value` and a
* `string` description.
*/
struct Option {
int value;
@@ -55,7 +54,7 @@ public:
};
/**
* The constructor delegating the \c identifier and the \c guiName to its super class.
* The constructor delegating the `identifier` and the `guiName` to its super class.
*
* \param info The PropertyInfo structure that contains all the required static
* information for initializing this Property.
@@ -65,8 +64,7 @@ public:
OptionProperty(Property::PropertyInfo info);
/**
* The constructor delegating the <code>identifier</code> and the <code>guiName</code>
* to its super class.
* The constructor delegating the `identifier` and the `guiName` to its super class.
*
* \param info The PropertyInfo structure that contains all the required static
* information for initializing this Property.
@@ -82,7 +80,7 @@ public:
*
* \return The name of this class for reflection purposes
*/
std::string className() const override;
std::string_view className() const override;
using IntProperty::operator=;
/**
@@ -93,8 +91,8 @@ public:
DisplayType displayType() const;
/**
* Adds the passed option to the list of available options. The \c value of the
* \c option must not have been registered previously, or a warning will be logged.
* Adds the passed option to the list of available options. The `value` of the
* `option` must not have been registered previously, or a warning will be logged.
*
* \param value The option that will be added to the list of available options
* \param desc The description of the value that will be added
@@ -138,10 +136,10 @@ public:
void setValue(int value) override;
/**
* This method returns \c true if currently a valid option is selected. This might
* This method returns `true` if currently a valid option is selected. This might
* change as options are added or removed.
*
* \return \c true if a call to #option would return a valid Option
* \return `true` if a call to #option would return a valid Option
*/
bool hasOption() const;
@@ -153,7 +151,7 @@ public:
const Option& option() const;
/**
* Get the description of the option that matches \c value .
* Get the description of the option that matches `value`.
*
* \param value The value of the option
*/

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -30,6 +30,7 @@
#include <any>
#include <functional>
#include <string>
#include <string_view>
struct lua_State;
@@ -40,7 +41,7 @@ class PropertyOwner;
/**
* A property encapsulates a value which should be user-changeable. A property almost
* always belongs to a PropertyOwner who has taken ownership (setPropertyOwner) of the
* Property. Per PropertyOwner, the <code>identifier</code> needs to be unique and can be
* Property. Per PropertyOwner, the `identifier` needs to be unique and can be
* used as a URI. This class is an abstract base class and each subclass (most notable
* TemplateProperty) needs to implement the methods Property::className, Property::get,
* Property::set, Property::type(), Property::getLuaValue, Property::setLuaValue,
@@ -62,13 +63,15 @@ class Property {
public:
/**
* The visibility classes for Property%s. The classes are strictly ordered as
* All > Developer > User > Hidden
* Hidden > Developer > AdvancedUser > User > NoviceUser > Always
*/
enum class Visibility {
Hidden = 3, ///< Never visible
Developer = 2, ///< Visible in Developer mode
User = 1, ///< Visible in User mode
All = 0, ///< Visible for all types, no matter what
Hidden = 5, ///< Never visible
Developer = 4, ///< Visible in Developer mode
AdvancedUser = 3, ///< Visible in Advanced User mode
User = 2, ///< Visible in User mode
NoviceUser = 1, ///< Visible in Novice User mode
Always = 0, ///< Visible for all types, no matter what
};
/**
@@ -99,7 +102,7 @@ public:
/// The user facing description of this Property
const char* description;
/// Determines the visibility of this Property in the user interface
Visibility visibility = Visibility::All;
Visibility visibility = Visibility::Always;
};
/// An OnChangeHandle is returned by the onChange method to uniquely identify an
@@ -112,15 +115,16 @@ public:
/// This OnChangeHandle can be used to remove all onChange callbacks from this
/// Property
static OnChangeHandle OnChangeHandleAll;
constexpr static OnChangeHandle OnChangeHandleAll =
std::numeric_limits<OnChangeHandle>::max();
/**
* The constructor for the property. The \p info (see #PropertyInfo) contains
* necessary information for this Property. #PropertyInfo::identifier needs to be
* unique for each PropertyOwner. The #PropertyInfo::guiName will be stored in the
* metaData to be accessed by the GUI elements using the #PropertyInfo::guiName key.
* The default visibility settings is Visibility::All, whereas the default read-only
* state is \c false.
* The constructor for the property. The \p info (see PropertyInfo) contains
* necessary information for this Property. PropertyInfo::identifier needs to be
* unique for each PropertyOwner. The PropertyInfo::guiName will be stored in the
* metaData to be accessed by the GUI elements using the PropertyInfo::guiName key.
* The default visibility settings is Visibility::Always, whereas the default
* read-only state is `false`.
*
* \param info The PropertyInfo structure that contains all the required static
* information for initializing this Property.
@@ -143,7 +147,7 @@ public:
*
* \return The class name of the Property
*/
virtual std::string className() const = 0;
virtual std::string_view className() const = 0;
/**
* This method returns the encapsulated value of the Property to the caller. The type
@@ -168,7 +172,7 @@ public:
/**
* This method returns the type that is requested by this Property for the set method.
* The default implementation returns the type of \c void.
* The default implementation returns the type of `void`.
*
* \return The type that is requested by this Property's Property::set method
*/
@@ -182,7 +186,7 @@ public:
* no-op.
*
* \param state The Lua state to which the value will be encoded
* \return \c true if the encoding succeeded, \c false otherwise
* \return `true` if the encoding succeeded, `false` otherwise
*/
virtual bool getLuaValue(lua_State* state) const;
@@ -195,18 +199,16 @@ public:
* no-op.
*
* \param state The Lua state from which the value will be decoded
* \return \c true if the decoding and setting of the value succeeded, \c false
* otherwise
*/
virtual bool setLuaValue(lua_State* state);
virtual void setLuaValue(lua_State* state);
/**
* Returns the Lua type that will be put onto the stack in the Property::getLua method
* and which will be consumed by the Property::setLuaValue method. The returned value
* can belong to the set of Lua types: \c LUA_TNONE, \c LUA_TNIL, \c LUA_TBOOLEAN,
* \c LUA_TLIGHTUSERDATA, \c LUA_TNUMBER, \c LUA_TSTRING, \c LUA_TTABLE,
* \c LUA_TFUNCTION, \c LUA_TUSERDATA, or \c LUA_TTHREAD. The default implementation
* will return \c LUA_TNONE.
* can belong to the set of Lua types: `LUA_TNONE`, `LUA_TNIL`, `LUA_TBOOLEAN`,
* `LUA_TLIGHTUSERDATA`, `LUA_TNUMBER`, `LUA_TSTRING`, `LUA_TTABLE`,
* `LUA_TFUNCTION`, `LUA_TUSERDATA`, or `LUA_TTHREAD`. The default implementation
* will return `LUA_TNONE`.
*
* \return The Lua type that will be consumed or produced by the Property::getLuaValue
* and Property::setLuaValue methods.
@@ -214,24 +216,13 @@ public:
virtual int typeLua() const;
/**
* This method encodes the encapsulated \p value of this Property as a
* <code>std::string</code>. The specific details of this serialization is up to the
* property developer. The default implementation is a no-op.
* This method encodes the encapsulated \p value of this Property as a `std::string`.
* The specific details of this serialization is up to the property developer. The
* default implementation is a no-op.
*
* \param value The value to which the Property will be encoded
* \return \p true if the encoding succeeded, \p false otherwise
* \return The string representation of the stored property value
*/
virtual bool getStringValue(std::string& value) const;
/**
* This method encodes the encapsulated value of this Property as a
* <code>std::string</code>.
*
* \return the string value
*
* \throw ghoul::RuntimeError If value could not be fetched
*/
std::string getStringValue() const;
virtual std::string stringValue() const;
/**
* This method registers a \p callback function that will be called every time if
@@ -293,15 +284,14 @@ public:
/**
* Returns the fully qualified name for this Property that uniquely identifies this
* Property within OpenSpace. It consists of the identifier preceded by all levels of
* PropertyOwner%s separated with <code>.</code>; for example:
* <code>owner1.owner2.identifier</code>.
* PropertyOwner%s separated with `.`; for example: `owner1.owner2.identifier`.
*
* \return The fully qualified identifier for this Property
*/
std::string fullyQualifiedIdentifier() const;
/**
* Returns the PropertyOwner of this Property or \c nullptr, if it does not have an
* Returns the PropertyOwner of this Property or `nullptr`, if it does not have an
* owner.
*
* \return The Property of this Property
@@ -319,8 +309,7 @@ public:
/**
* Returns the human-readable GUI name for this Property that has been set in the
* constructor. This method returns the same value as accessing the metaData object
* and requesting the <code>std::string</code> stored for the <code>guiName</code>
* key.
* and requesting the `std::string` stored for the `guiName` key.
*
* \return The human-readable GUI name for this Property
*/
@@ -339,14 +328,14 @@ public:
* Sets the identifier of the group that this Property belongs to. Property groups can
* be used, for example, by GUI application to visually group different properties,
* but it has no impact on the Property itself. The default value for the \p groupID
* is <code>""</code>.
* is `""`.
*
* \param groupId The group id that this property should belong to
*/
void setGroupIdentifier(std::string groupId);
/**
* Returns the group idenfier that this Property belongs to, or <code>""</code> if it
* Returns the group idenfier that this Property belongs to, or `""` if it
* belongs to no group.
* \return The group identifier that this Property belongs to
*/
@@ -355,7 +344,7 @@ public:
/**
* Sets a hint about the visibility of the Property. Each application accessing the
* properties is free to ignore this hint. It is stored in the metaData Dictionary
* with the key: <code>Visibility</code>.
* with the key: `Visibility`.
*
* \param visibility The new visibility of the Property
*/
@@ -373,32 +362,33 @@ public:
* applications. This setting is only a hint and does not need to be followed by GUI
* applications and does not have any effect on the Property::set or
* Property::setLuaValue methods. The value is stored in the metaData Dictionary
* with the key: \c isReadOnly. The default value is \c false.
* with the key: `isReadOnly`. The default value is `false`.
*
* \param state \c true if the Property should be read only, \c false otherwise
* \param state `true` if the Property should be read only, `false` otherwise
*/
void setReadOnly(bool state);
/**
* Default view options that can be used in the Property::setViewOption method. The
* values are: Property::ViewOptions::Color = \c Color,
* Property::ViewOptions::Logarithmic = \c Logarithmic
*/
* Default view options that can be used in the Property::setViewOption method. The
* values are:
* - Property::ViewOptions::Color = `Color` (Intended for Vec3 and Vec4),
* - Property::ViewOptions::MinMaxRange = `MinMaxRange` (Intended for Vec2)
*/
struct ViewOptions {
static const char* Color;
static const char* Logarithmic;
static const char* MinMaxRange;
};
/**
* This method allows the developer to give hints to the GUI about different
* representations for the GUI. The same Property (for example Vec4Property) can be
* used in different ways, each requiring a different input method. These values are
* stored in the metaData object under <code>ViewOptions</code>.
* stored in the metaData object under `ViewOptions`.
* See Property::ViewOptions for a default list of possible options. As these are
* only hints, the GUI is free to ignore any suggestion by the developer.
* \param option The view option that should be modified
* \param value Determines if the view option should be active (<code>true</code>) or
* deactivated (<code>false</code>)
* \param value Determines if the view option should be active (`true`) or
* deactivated (`false`)
*/
void setViewOption(std::string option, bool value = true);
@@ -423,14 +413,6 @@ public:
*/
const ghoul::Dictionary& metaData() const;
/**
* Convert the Property into a string containing a JSON representation of the
* Property. Includes description of the object.
*
* \return The JSON string
*/
virtual std::string toJson() const;
/**
* Get a valid JSON formatted representation of the Property's value.
*
@@ -447,17 +429,17 @@ public:
/**
* Creates the information that is general to every Property and adds the
* \c Identifier, \c Name, \c Type, and \c MetaData keys and their values. The meta
* data is handles by the generateMetaDataDescription method, which has to be
* `Identifier`, `Name`, `Type`, and `MetaData` keys and their values. The meta
* data is handles by the generateMetaDataJsonDescription method, which has to be
* overloaded if a concrete base class wants to add meta data that is not curated by
* the Property class.
*
* \return The base description common to all Property classes
*/
std::string generateBaseJsonDescription() const;
std::string generateJsonDescription() const;
/**
* Creates the information for the \c MetaData key-part of the JSON description for
* Creates the information for the `MetaData` key-part of the JSON description for
* the Property. The result can be included as one key-value pair in the description
* text generated by subclasses. Only the metadata curated by the Property class is
* used in this method.
@@ -472,9 +454,15 @@ public:
* override this method and return the string containing all of the additional
* information. The base implementation of the #description method will return the Lua
* script:
* <code>return { generateBaseDescription(), generateMetaDataDescription(),</code>
* <code>generateAdditionalDescription()}</code>, which #generateMetaDataDescription
* and this method being the override points to customize the behavior.
* ```
* return {
* generateBaseDescription(),
* generateMetaDataJsonDescription(),
* generateAdditionalDescription()
* }
* ```
* #generateMetaDataJsonDescription and this method being the override points to
* customize the behavior.
*
* \return The information specific to each subclass of Property
*/
@@ -493,21 +481,13 @@ public:
void resetToUnchanged();
protected:
static const char* IdentifierKey;
static const char* NameKey;
static const char* TypeKey;
static const char* DescriptionKey;
static const char* JsonValueKey;
static const char* MetaDataKey;
static const char* AdditionalDataKey;
/**
* This method must be called by all subclasses whenever the encapsulated value has
* changed and potential listeners need to be informed.
*/
void notifyChangeListeners();
/// The PropetyOwner this Property belongs to, or <code>nullptr</code>
/// The PropetyOwner this Property belongs to, or `nullptr`
PropertyOwner* _owner = nullptr;
/// The identifier for this Property
@@ -544,9 +524,6 @@ private:
#endif
};
/// This function sanitizes an incoming string for JSON control characters
std::string sanitizeString(const std::string& str);
} // namespace openspace::properties
#endif // __OPENSPACE_CORE___PROPERTY___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -37,22 +37,21 @@ class Property;
/**
* A PropertyOwner can own Propertys or other PropertyOwner and provide access to both in
* a unified way. The <code>identifier</code>s and <code>name</code>s of Propertys and
* sub-owners must be unique to this PropertyOwner. A Property cannot have the same name
* as a PropertyOwner owned by this PropertyOwner.
* Propertys can be added using the Property::addProperty methods and be removed by the
* Property::removeProperty method. The same holds true for sub-owners
* a unified way. The `identifier`s and `name`s of Propertys and sub-owners must be unique
* to this PropertyOwner. A Property cannot have the same name as a PropertyOwner owned by
* this PropertyOwner. Propertys can be added using the Property::addProperty methods and
* be removed by the Property::removeProperty method. The same holds true for sub-owners
* (Property::addPropertySubOwner, Property::removePropertySubOwner). These methods will
* inform the passed object about the new ownership automatically.
* Stored properties can be accessed using the Property::properties method or the
* Property::property method, providing an URI for the location of the property. If the
* URI contains separators (<code>.</code>), the first name before the separator will be
* used as a subOwner's name and the search will proceed recursively.
* inform the passed object about the new ownership automatically. Stored properties can
* be accessed using the Property::properties method or the Property::property method,
* providing an URI for the location of the property. If the URI contains separators
* (`.`), the first name before the separator will be used as a subOwner's name and the
* search will proceed recursively.
*/
class PropertyOwner : public DocumentationGenerator {
public:
/// The separator that is used while accessing the properties and/or sub-owners
static const char URISeparator = '.';
static constexpr char URISeparator = '.';
struct PropertyOwnerInfo {
std::string identifier;
@@ -68,8 +67,7 @@ public:
* #PropertyOwnerInfo::description of this PropertyOwner.
*
* \pre The \p info 's #PropertyOwnerInfo::identifier must not contain any whitespaces
* \pre The \p info 's #PropertyOwnerInfo::identifier must not contain any
* <code>.</code>
* \pre The \p info 's #PropertyOwnerInfo::identifier must not contain any `.`
*/
PropertyOwner(PropertyOwnerInfo info);
@@ -77,7 +75,7 @@ public:
* The destructor will remove all Propertys and PropertyOwners it owns along with
* itself.
*/
virtual ~PropertyOwner();
virtual ~PropertyOwner() override;
/**
* Sets the identifier for this PropertyOwner. If the PropertyOwner does not have an
@@ -87,10 +85,10 @@ public:
* PropertyOwner::addProperty and PropertyOwner::addPropertySubOwner methods).
*
* \param identifier The identifier of this PropertyOwner. It must not contain any
* <code>.</code>s or whitespaces
* `.`s or whitespaces
*
* \pre \p identifier must not contain any whitespaces
* \pre \p identifier must not contain any <code>.</code>
* \pre \p identifier must not contain any `.`
*/
void setIdentifier(std::string identifier);
@@ -137,14 +135,14 @@ public:
/**
* Retrieves a Property identified by \p uri from this PropertyOwner. If \p uri does
* not contain a <code>.</code> the identifier must refer to a Property directly owned
* by this PropertyOwner. If the identifier contains one or more <code>.</code>, the
* not contain a `.` the identifier must refer to a Property directly owned
* by this PropertyOwner. If the identifier contains one or more `.`, the
* first part of the name will be recursively extracted and used as a name for a
* sub-owner and only the last part of the identifier is referring to a Property owned
* by PropertyOwner named by the second-but-last name.
*
* \param uri The identifier of the Property that should be extracted
* \return If the Property cannot be found, \c nullptr is returned, otherwise the
* \return If the Property cannot be found, `nullptr` is returned, otherwise the
* pointer to the Property is returned
*/
Property* property(const std::string& uri) const;
@@ -152,17 +150,17 @@ public:
/**
* This method checks if a Property with the provided \p uri exists in this
* PropertyOwner (or any sub-owner). If the identifier contains one or more
* <code>.</code>, the first part of the name will be recursively extracted and is
* `.`, the first part of the name will be recursively extracted and is
* used as a name for a sub-owner and only the last part of the identifier is
* referring to a Property owned by PropertyOwner named by the second-but-last name.
*
* \return \c true if the \p uri refers to a Property; \c false otherwise.
* \return `true` if the \p uri refers to a Property; `false` otherwise.
*/
bool hasProperty(const std::string& uri) const;
/**
* This method checks if a Property exists in this PropertyOwner.
* \return <code>true</code> if the Property existed, <code>false</code> otherwise.
* \return `true` if the Property existed, `false` otherwise.
*/
bool hasProperty(const Property* prop) const;
@@ -180,23 +178,22 @@ public:
/**
* This method returns the direct sub-owner of this PropertyOwner with the provided
* \p identifier. This means that <code>identifier</code> cannot contain any
* <code>.</code> as this character is not allowed in PropertyOwner names. If the
* \p name does not name a valid sub-owner of this PropertyOwner, a \c nullptr will be
* returned.
* \p identifier. This means that `identifier` cannot contain any `.` as this
* character is not allowed in PropertyOwner names. If the \p name does not name a
* valid sub-owner of this PropertyOwner, a `nullptr` will be returned.
*
* \param identifier The identifier of the sub-owner that should be returned
* \return The PropertyOwner with the given \p name, or \c nullptr
* \return The PropertyOwner with the given \p name, or `nullptr`
*/
PropertyOwner* propertySubOwner(const std::string& identifier) const;
/**
* Returns \c true if this PropertyOwner owns a sub-owner with the provided
* \p identifier; returns \c false otherwise.
* Returns `true` if this PropertyOwner owns a sub-owner with the provided
* \p identifier; returns `false` otherwise.
*
* \param identifier The identifier of the sub-owner that should be looked up
* \return \c true if this PropertyOwner owns a sub-owner with the provided
* \p identifier; returns \c false otherwise
* \return `true` if this PropertyOwner owns a sub-owner with the provided
* \p identifier; returns `false` otherwise
*/
bool hasPropertySubOwner(const std::string& identifier) const;
@@ -246,7 +243,7 @@ public:
/**
* Removes the Property from this PropertyOwner. Notifies the Property about this
* change by calling the Property::setPropertyOwner method with a \c nullptr as
* change by calling the Property::setPropertyOwner method with a `nullptr` as
* parameter.
*
* \param prop The Property that should be removed from this PropertyOwner

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,36 +25,25 @@
#ifndef __OPENSPACE_CORE___BOOLPROPERTY___H__
#define __OPENSPACE_CORE___BOOLPROPERTY___H__
/**
* \file boolproperty.h
*
* \addtogroup openspace
* @{
* \addtogroup properties
* @{
* \class BoolProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>bool</code>.
* @} @}
*/
#include <openspace/properties/templateproperty.h>
namespace openspace::properties {
/**
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type `bool`.
*/
class BoolProperty : public TemplateProperty<bool> {
public:
BoolProperty(Property::PropertyInfo info, bool value = false);
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<bool>::operator=;
protected:
bool fromLuaConversion(lua_State* state, bool& success) const override;
bool fromLuaConversion(lua_State* state) const override;
void toLuaConversion(lua_State* state) const override;
std::string toStringConversion() const override;
};

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,39 +25,25 @@
#ifndef __OPENSPACE_CORE___DOUBLEPROPERTY___H__
#define __OPENSPACE_CORE___DOUBLEPROPERTY___H__
/**
* \file doubleproperty.h
*
* \addtogroup openspace
* @{
* \addtogroup properties
* @{
* \class DoubleProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>double</code>.
* @} @}
*/
#include <openspace/properties/numericalproperty.h>
#include <limits>
namespace openspace::properties {
/**
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type `double`.
*/
class DoubleProperty : public NumericalProperty<double> {
public:
DoubleProperty(Property::PropertyInfo info, double value = 0.0,
double minValue = std::numeric_limits<double>::lowest(),
double maxValue = std::numeric_limits<double>::max(), double stepValue = 0.01);
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<double>::operator=;
protected:
double fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,39 +25,25 @@
#ifndef __OPENSPACE_CORE___FLOATPROPERTY___H__
#define __OPENSPACE_CORE___FLOATPROPERTY___H__
/**
* \file floatproperty.h
*
* \addtogroup openspace
* @{
* \addtogroup properties
* @{
* \class FloatProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>float</code>.
* @} @}
*/
#include <openspace/properties/numericalproperty.h>
#include <limits>
namespace openspace::properties {
/**
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type `float`.
*/
class FloatProperty : public NumericalProperty<float> {
public:
FloatProperty(Property::PropertyInfo info, float value = 0.f,
float minValue = std::numeric_limits<float>::lowest(),
float maxValue = std::numeric_limits<float>::max(), float stepValue = 0.01f);
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<float>::operator=;
protected:
float fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,39 +25,28 @@
#ifndef __OPENSPACE_CORE___INTPROPERTY___H__
#define __OPENSPACE_CORE___INTPROPERTY___H__
/**
* \file intproperty.h
*
* \addtogroup openspace
* @{
* \addtogroup properties
* @{
* \class IntProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>int</code>.
* @} @}
*/
#include <openspace/properties/numericalproperty.h>
#include <limits>
namespace openspace::properties {
/**
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type `int`.
*/
class IntProperty : public NumericalProperty<int> {
public:
IntProperty(Property::PropertyInfo info, int value = 0,
int minValue = std::numeric_limits<int>::lowest(),
int maxValue = std::numeric_limits<int>::max(), int stepValue = 1);
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<int>::operator=;
protected:
int fromLuaConversion(lua_State* state, bool& success) const override;
private:
int fromLuaConversion(lua_State* state) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,26 +25,15 @@
#ifndef __OPENSPACE_CORE___LONGPROPERTY___H__
#define __OPENSPACE_CORE___LONGPROPERTY___H__
/**
* \file longproperty.h
*
* \addtogroup openspace
* @{
* \addtogroup properties
* @{
* \class LongProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>long</code>.
* @} @}
*/
#include <openspace/properties/numericalproperty.h>
#include <limits>
namespace openspace::properties {
/**
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type `long`.
*/
class LongProperty : public NumericalProperty<long> {
public:
LongProperty(Property::PropertyInfo info, long value = long(0),
@@ -52,13 +41,10 @@ public:
long maxValue = std::numeric_limits<long>::max(),
long stepValue = long(1));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<long>::operator=;
protected:
long fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -34,8 +34,6 @@
* @{
* \class ShortProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>short</code>.
* @} @}
*/
@@ -45,6 +43,10 @@
namespace openspace::properties {
/**
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type `short`.
*/
class ShortProperty : public NumericalProperty<short> {
public:
ShortProperty(Property::PropertyInfo info, short value = short(0),
@@ -52,13 +54,10 @@ public:
short maxValue = std::numeric_limits<short>::max(),
short stepValue = short(1));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<short>::operator=;
protected:
short fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,26 +25,15 @@
#ifndef __OPENSPACE_CORE___UINTPROPERTY___H__
#define __OPENSPACE_CORE___UINTPROPERTY___H__
/**
* \file uintproperty.h
*
* \addtogroup openspace
* @{
* \addtogroup properties
* @{
* \class UIntProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>unsigned int</code>.
* @} @}
*/
#include <openspace/properties/numericalproperty.h>
#include <limits>
namespace openspace::properties {
/**
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type `unsigned int`.
*/
class UIntProperty : public NumericalProperty<unsigned int> {
public:
UIntProperty(Property::PropertyInfo info, unsigned int value = 0,
@@ -52,13 +41,10 @@ public:
unsigned int maxValue = std::numeric_limits<unsigned int>::max(),
unsigned int stepValue = 1);
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<unsigned int>::operator=;
protected:
unsigned int fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,26 +25,15 @@
#ifndef __OPENSPACE_CORE___ULONGPROPERTY___H__
#define __OPENSPACE_CORE___ULONGPROPERTY___H__
/**
* \file ulongproperty.h
*
* \addtogroup openspace
* @{
* \addtogroup properties
* @{
* \class ULongProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>unsigned long</code>.
* @} @}
*/
#include <openspace/properties/numericalproperty.h>
#include <limits>
namespace openspace::properties {
/**
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type `unsigned long`.
*/
class ULongProperty : public NumericalProperty<unsigned long> {
public:
ULongProperty(Property::PropertyInfo info, unsigned long value = 0ul,
@@ -52,13 +41,10 @@ public:
unsigned long maxValue = std::numeric_limits<unsigned long>::max(),
unsigned long stepValue = 1ul);
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<unsigned long>::operator=;
protected:
unsigned long fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -25,26 +25,15 @@
#ifndef __OPENSPACE_CORE___USHORTPROPERTY___H__
#define __OPENSPACE_CORE___USHORTPROPERTY___H__
/**
* \file ushortproperty.h
*
* \addtogroup openspace
* @{
* \addtogroup properties
* @{
* \class UShortProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>unsigned short</code>.
* @} @}
*/
#include <openspace/properties/numericalproperty.h>
#include <limits>
namespace openspace::properties {
/**
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type `unsigned short`.
*/
class UShortProperty : public NumericalProperty<unsigned short> {
public:
UShortProperty(Property::PropertyInfo info, unsigned short value = 0,
@@ -52,13 +41,10 @@ public:
unsigned short maxValue = std::numeric_limits<unsigned short>::max(),
unsigned short stepValue = 1);
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<unsigned short>::operator=;
protected:
unsigned short fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -37,11 +37,11 @@ class SelectionProperty : public TemplateProperty<std::set<std::string>> {
public:
SelectionProperty(Property::PropertyInfo info);
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
/**
* This method sets the stored value to the provided value <code>val</code>.
* This method sets the stored value to the provided value `val`.
* If the value is different, the listeners are notified. It also removes any
* invalid keys in the input set. A key is invalid if it does not correspond to
* an existing option in the SelectionProperty
@@ -51,18 +51,18 @@ public:
void setValue(std::set<std::string> val) override;
/**
* Checks if an option given by the provided <code>key</code> exists.
* Checks if an option given by the provided `key` exists.
*
* \param key The key that should be checked for existence
* \return \c if the option exists; \c false otherwise
* \return `true` if the option exists; `false` otherwise
*/
bool hasOption(const std::string& key) const;
/**
* Checks if an option given by the provided <code>key</code> is selected.
* Checks if an option given by the provided `key` is selected.
*
* \param key The key that should be checked
* \return \c true if the option is selected; \c false otherwise
* \return `true` if the option is selected; `false` otherwise
*/
bool isSelected(const std::string& key) const;
@@ -70,7 +70,7 @@ public:
* Checks if the SelectionProperty has any selected values, that is, if its
* value is empty.
*
* \return \c true if there are selected options; \c false otherwise
* \return `true` if there are selected options; `false` otherwise
*/
bool hasSelected() const;
@@ -114,7 +114,7 @@ public:
using TemplateProperty<std::set<std::string>>::operator=;
protected:
std::set<std::string> fromLuaConversion(lua_State* state, bool& success) const override;
std::set<std::string> fromLuaConversion(lua_State* state) const override;
void toLuaConversion(lua_State* state) const override;

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -33,13 +33,16 @@ class StringProperty : public TemplateProperty<std::string> {
public:
StringProperty(Property::PropertyInfo info, std::string value = "");
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<std::string>::operator=;
operator std::string_view();
operator std::string_view() const;
protected:
std::string fromLuaConversion(lua_State* state, bool& success) const override;
std::string fromLuaConversion(lua_State* state) const override;
void toLuaConversion(lua_State* state) const override;
std::string toStringConversion() const override;
};

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -31,16 +31,16 @@ namespace openspace::properties {
/**
* This subclass of Property handles a single parameter value that is of type
* <code>T</code>. It provides all the necessary methods to automatically access the
* `T`. It provides all the necessary methods to automatically access the
* value. One notable instantiation of this class is StringProperty, using
* <code>T = std::string</code> while NumericalProperty is a templated subclass dealing
* `T = std::string` while NumericalProperty is a templated subclass dealing
* with numerical parameter types.
* The accessor operator and assignment operators are overloaded, so that the
* TemplateProperty can be used just in the same way as a regular member variable. In the
* case that these cannot not be used inline, the Property::get method will work.
*
* Each instantiation of this class should provide a constructor that deals with the
* default value for that specific type <code>T</code>, so that a property can be
* default value for that specific type `T`, so that a property can be
* created from just a Property::PropertyInfo object.
*
* \tparam T The type of value that is stored in this TemplateProperty
@@ -71,7 +71,7 @@ public:
*
* \return The class name for the TemplateProperty
*/
virtual std::string className() const override = 0;
virtual std::string_view className() const override = 0;
/**
* Returns the stored value packed into a ghoul::any object.
@@ -82,19 +82,19 @@ public:
/**
* Sets the value from the provided ghoul::any object. If the types between
* <code>T</code> and <code>value</code> disagree, an error is logged and the stored
* `T` and `value` disagree, an error is logged and the stored
* value remains unchanged.
*
* \param value The value that is used to set this Property
*/
virtual void set(std::any value) override;
virtual void set(std::any value) final;
/**
* Returns the <code>std::type_info</code> describing the template parameter
* <code>T</code>. It can be used to test against a ghoul::any value before trying to
* Returns the `std::type_info` describing the template parameter
* `T`. It can be used to test against a ghoul::any value before trying to
* assign it.
*
* \return The type info object describing the template parameter <code>T</code>
* \return The type info object describing the template parameter `T`
*/
virtual const std::type_info& type() const override;
@@ -103,7 +103,7 @@ public:
* the stack.
*
* \param state The Lua state onto which the encoded object will be pushed
* \return \c true if the encoding succeeded; \c false otherwise
* \return `true` if the encoding succeeded; `false` otherwise
*/
virtual bool getLuaValue(lua_State* state) const override;
@@ -113,9 +113,9 @@ public:
* decoding is successful, the new value is set, otherwise it remains unchanged.
*
* \param state The Lua state from which the value will be decoded
* \return \c true if the decoding succeeded; \c false otherwise
* \return `true` if the decoding succeeded; `false` otherwise
*/
virtual bool setLuaValue(lua_State* state) override;
virtual void setLuaValue(lua_State* state) override;
/// \see Property::typeLua
virtual int typeLua() const override = 0;
@@ -124,10 +124,9 @@ public:
* This method encodes the stored value into a std::string object. The resulting
* encoding must also be a valid JSON representation fo the property.
*
* \param value The string object in which to store the resulting encoding
* \return \c true if the encoding succeeded; \c false otherwise
* \return The string representation of the stored property value
*/
virtual bool getStringValue(std::string& value) const override;
virtual std::string stringValue() const override;
/**
* Returns the description for this TemplateProperty as a Lua script that returns a
@@ -139,8 +138,8 @@ public:
/**
* This operator allows the TemplateProperty to be used almost transparently as if it
* was of the type <code>T</code>. It makes assignments such as
* <code>T v = property;</code> possible by allowing implicit casts (even though,
* was of the type `T`. It makes assignments such as
* `T v = property;` possible by allowing implicit casts (even though,
* internally, not casts are performed. This method is next to zero overhead).
*
* \return The internal representation of the Property
@@ -149,8 +148,8 @@ public:
/**
* This operator allows the TemplateProperty to be used almost transparently as if it
* was of the type <code>T</code>. It makes assignments such as
* <code>T v = property;</code> possible by allowing implicit casts (even though,
* was of the type `T`. It makes assignments such as
* `T v = property;` possible by allowing implicit casts (even though,
* internally, not casts are performed. This method is next to zero overhead).
*
* \return The internal representation of the Property
@@ -160,17 +159,17 @@ public:
/**
* The assignment operator allows the TemplateProperty's value to be set without using
* the TemplateProperty::set method. It will be done internally by this method and it
* allows assignments such as <code>prop = T(1)</code>.
* allows assignments such as `prop = T(1)`.
*
* \param val The value that should be set
*/
TemplateProperty<T>& operator=(T val);
/**
* This method sets the stored value to the provided value <code>val</code>,
* moving it into place. The move only happens if the provided value <code>val</code>
* This method sets the stored value to the provided value `val`,
* moving it into place. The move only happens if the provided value `val`
* is different from the stored value, which needs an operator== to exist for the type
* <code>T</code>. If the value is different, the listeners are notified.
* `T`. If the value is different, the listeners are notified.
*
* \param val The new value for this TemplateProperty
*/
@@ -185,14 +184,13 @@ public:
protected:
/**
* Decodes the object at the top of the stack to a value of the type <code>T</code>
* Decodes the object at the top of the stack to a value of the type `T`
* and returns it. This method has to be specialized for each new type.
*
* \param state The Lua state from which the value will be decoded
* \param success Set to true \c true if the decoding succeeded; \c false otherwise
* \return the decoded value
*/
virtual T fromLuaConversion(lua_State* state, bool& success) const = 0;
virtual T fromLuaConversion(lua_State* state) const = 0;
/**
* Encodes the stored value into a Lua object and pushes that object onto

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -22,6 +22,8 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <ghoul/lua/lua_helper.h>
namespace openspace::properties {
template <typename T>
@@ -60,12 +62,6 @@ void openspace::properties::TemplateProperty<T>::setValue(T val) {
}
}
template <typename T>
std::ostream& operator<<(std::ostream& os, const TemplateProperty<T>& obj) {
os << obj.value();
return os;
}
template <typename T>
std::any TemplateProperty<T>::get() const {
return std::any(_value);
@@ -89,19 +85,14 @@ bool TemplateProperty<T>::getLuaValue(lua_State* state) const {
}
template <typename T>
bool TemplateProperty<T>::setLuaValue(lua_State* state) {
bool success = false;
T thisValue = fromLuaConversion(state, success);
if (success) {
set(std::any(thisValue));
}
return success;
void TemplateProperty<T>::setLuaValue(lua_State* state) {
T thisValue = fromLuaConversion(state);
set(std::any(thisValue));
}
template <typename T>
bool TemplateProperty<T>::getStringValue(std::string& outValue) const {
outValue = toStringConversion();
return true;
std::string TemplateProperty<T>::stringValue() const {
return toStringConversion();
}
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -36,28 +36,28 @@ namespace openspace::properties {
class TriggerProperty : public Property {
public:
/**
* Initializes the TriggerProperty by delegating the <code>identifier</code> and
* <code>guiName</code> to the Property constructor.
* Initializes the TriggerProperty by delegating the `identifier` and
* `guiName` to the Property constructor.
* \param info The PropertyInfo structure that contains all the required static
* information for initializing this Property.
* information for initializing this Property.
* \pre \p info.identifier must not be empty
* \pre \p info.guiName must not be empty
*/
TriggerProperty(PropertyInfo info);
/**
* Returns the class name <code>TriggerProperty</code>.
* \return The class name <code>TriggerProperty</code>
* Returns the class name `TriggerProperty`.
* \return The class name `TriggerProperty`
*/
std::string className() const override;
std::string_view className() const override;
/**
* Accepts only the <code>LUA_TNIL</code> type and will notify all the listeners
* Accepts only the `LUA_TNIL` type and will notify all the listeners
* that the event has been triggered.
* \param state The unused Lua state
* \return Returns always <code>true</code>
* \return Returns always `true`
*/
bool setLuaValue(lua_State* state) override;
void setLuaValue(lua_State* state) override;
/**
* Silently ignores any value that is passed into this function and will trigger the
@@ -66,8 +66,6 @@ public:
*/
void set(std::any value) override;
std::string toJson() const override;
std::string jsonValue() const override;
};

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -39,13 +39,10 @@ public:
glm::dvec2 maxValue = glm::dvec2(std::numeric_limits<double>::max()),
glm::dvec2 stepValue = glm::dvec2(0.01));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::dvec2>::operator=;
protected:
glm::dvec2 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -39,13 +39,10 @@ public:
glm::dvec3 maxValue = glm::dvec3(std::numeric_limits<double>::max()),
glm::dvec3 stepValue = glm::dvec3(0.01));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::dvec3>::operator=;
protected:
glm::dvec3 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -39,13 +39,10 @@ public:
glm::dvec4 maxValue = glm::dvec4(std::numeric_limits<double>::max()),
glm::dvec4 stepValue = glm::dvec4(0.01));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::dvec4>::operator=;
protected:
glm::dvec4 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -39,13 +39,10 @@ public:
glm::ivec2 maxValue = glm::ivec2(std::numeric_limits<int>::max()),
glm::ivec2 stepValue = glm::ivec2(1));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::ivec2>::operator=;
protected:
glm::ivec2 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -39,13 +39,10 @@ public:
glm::ivec3 maxValue = glm::ivec3(std::numeric_limits<int>::max()),
glm::ivec3 stepValue = glm::ivec3(1));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::ivec3>::operator=;
protected:
glm::ivec3 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -39,13 +39,10 @@ public:
glm::ivec4 maxValue = glm::ivec4(std::numeric_limits<int>::max()),
glm::ivec4 stepValue = glm::ivec4(1));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::ivec4>::operator=;
protected:
glm::ivec4 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -39,13 +39,10 @@ public:
glm::uvec2 maxValue = glm::uvec2(std::numeric_limits<unsigned int>::max()),
glm::uvec2 stepValue = glm::uvec2(1));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::uvec2>::operator=;
protected:
glm::uvec2 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
@@ -39,13 +39,10 @@ public:
glm::uvec3 maxValue = glm::uvec3(std::numeric_limits<unsigned int>::max()),
glm::uvec3 stepValue = glm::uvec3(1));
std::string className() const override;
std::string_view className() const override;
int typeLua() const override;
using TemplateProperty<glm::uvec3>::operator=;
protected:
glm::uvec3 fromLuaConversion(lua_State* state, bool& success) const override;
};
} // namespace openspace::properties

Some files were not shown because too many files have changed in this diff Show More