Merge branch 'develop' of github.com:OpenSpace/OpenSpace into feature/parallelconnection

Conflicts:
	include/openspace/engine/openspaceengine.h
	src/engine/openspaceengine.cpp
	src/interaction/interactionhandler.cpp
	src/network/parallelconnection.cpp
	src/scripting/scriptengine.cpp
This commit is contained in:
Emil Axelsson
2016-09-22 19:33:05 +02:00
311 changed files with 12363 additions and 4144 deletions

View File

@@ -0,0 +1,38 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __CORE_REGISTRATION_H__
#define __CORE_REGISTRATION_H__
namespace openspace {
namespace documentation {
class DocumentationEngine;
void registerCoreClasses(documentation::DocumentationEngine& engine);
} // namespace documentation
} // namespace openspace
#endif // __CORE_REGISTRATION_H__

View File

@@ -0,0 +1,297 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __DOCUMENTATION_H__
#define __DOCUMENTATION_H__
#include <ghoul/misc/boolean.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/exception.h>
#include <memory>
#include <string>
#include <vector>
namespace openspace {
namespace documentation {
using Optional = ghoul::Boolean;
using Exhaustive = ghoul::Boolean;
/**
* The TestResult structure returns the information from the #testSpecification method. It
* contains the information whether test specification test was successful
* (TestResult::success) and a list of TestResult::Offense%s (TestResult::offenses). If
* TestResult::success is true, TestResult::offenses is guaranteed to be empty.
*/
struct TestResult {
/**
* An Offense is a violation against a specific verifier. The Offense::offender is the
* key that caused the offense (in the case of nested tables, it will be fully
* qualified identifier) and the Offense::Reason is the reason that caused the
* offense.
*/
struct Offense {
/**
* The Reason for the offense
*/
enum class Reason {
MissingKey, ///< The offending key that was requested was not found
ExtraKey, ///< The exhaustive documentation contained an extra key
WrongType, ///< The key's value was not of the expected type
Verification, ///< The value did not pass a necessary non-type verifier
UnknownIdentifier ///< If the identifier for a ReferencingVerifier did not exist
};
/// The offending key that caused the Offense. In the case of a nested table,
/// this value will be the fully qualified name of the key
std::string offender;
/// The Reason that caused this offense
Reason reason;
};
/// Is \c true if the TestResult is positive, \c false otherwise
bool success;
/// Contains a list of offenses that were found in the test. Is empty if
/// TestResult::Success is \c true
std::vector<Offense> offenses;
};
/**
* This exception is thrown by the #testSpecificationAndThrow method if the test detected
* a specification violation. This class contains the TestResult that would have otherwise
* be returned in a call to #testSpecification.
*/
struct SpecificationError : public ghoul::RuntimeError {
/**
* Creates the SpecificationError exception instance.
* \param result The offending TestResult that is passed on
* \param component The component that initiated the specification test
* \pre \p result%'s TestResult::success must be \c false
*/
SpecificationError(TestResult result, std::string component);
/// The TestResult that caused the SpecificationError to be thrown
TestResult result;
};
struct Verifier;
/**
* A DocumentationEntry provides the specification for a single key, which is tested using
* the provided Verifier. Each DocumentationEntry can contain a textual documentation that
* describes the entry and is printed when the documentation for a Documentation is
* requested. Lastly, each DocumentationEntry can be Optional. If the provided key is the
* DocumentationEntry::Wildcard, any key in the containing Documentation will be tested
* against the provided verifier. The most convenient way of creating DocumentationEntry%s
* is by using an inline initializer list such as:
*\verbatim
DocumentationEntry e = { "key", new IntVerifier, "Documentation text", Optional::Yes };
\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
* memory as the DocumentationEntry takes ownership of them in the constructor.
*/
struct DocumentationEntry {
/// The wildcard character that will match against every key in a Documentation
static const std::string Wildcard;
/**
* The constructor for a DocumentationEntry describing a \p key in a Documentation.
* The value for the key (or each value in the case of the
* DocumentationEntry::Wildcard) is tested using the \p verifier, that specifies the
* conditions that the \p key%'s value has to fulfill. The textual documentation
* \p doc shall describe the usage of the key-value pair and will be printed for human
* consumption for example in the DocumentationEngine. Each DocumentationEntry can
* further be \p optional.
* \param key The key for which this DocumentationEntry is valid. If this valid is
* equal to DocumentationEntry::Wildcard, each entry in the Documentation that
* contains this DocumentationEntry will be matched
* \param verifier The Verifier that is used to test the \p key%'s value to determine
* if it is a valid value
* \param doc The textual documentation that describes the DocumentationEntry in a
* human readable format
* \param optional Determines whether the Documentation containing this
* DocumentationEntry must have a key \p key, or whether it is optional
* \pre \p key must not be empty
* \pre \p verifier must not be nullptr
*/
DocumentationEntry(std::string key, std::shared_ptr<Verifier> verifier,
std::string doc = "", Optional optional = Optional::No);
/**
* The constructor for a DocumentationEntry describing a \p key in a Documentation.
* The value for the key (or each value in the case of the
* DocumentationEntry::Wildcard) is tested using the \p verifier, that specifies the
* conditions that the \p key%'s value has to fulfill. The textual documentation
* \p doc shall describe the usage of the key-value pair and will be printed for human
* consumption for example in the DocumentationEngine. Each DocumentationEntry can
* further be \p optional.
* \param key The key for which this DocumentationEntry is valid. If this valid is
* equal to DocumentationEntry::Wildcard, each entry in the Documentation that
* contains this DocumentationEntry will be matched
* \param verifier The Verifier that is used to test the \p key%'s value to determine
* if it is a valid value. The DocumentationEntry will take ownership of the passed
* object
* \param doc The textual documentation that describes the DocumentationEntry in a
* human readable format
* \param optional Determines whether the Documentation containing this
* DocumentationEntry must have a key \p key, or whether it is optional
* \pre \p key must not be empty
* \pre \p verifier must not be nullptr
*/
DocumentationEntry(std::string key, Verifier* verifier, std::string doc = "",
Optional optional = Optional::No);
/// The key that is described by this DocumentationEntry
std::string key;
/// The Verifier that is used to test the key's value
std::shared_ptr<Verifier> verifier;
/// Determines whether the described DocumentationEntry is optional or not
Optional optional;
/// The textual description of this DocumentationEntry
std::string documentation;
};
/**
* This struct contains the documentation and specification for a ghoul::Dictionary. It is
* 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, a list of DocumentationEntry%s that each describe a single key value, and a
* flag whether these entries are Exhaustive or not. If a Documentation is Exhaustive, a
* ghoul::Dictionary that contains additional keys will fail the specification, whereas a
* non-exhaustive Documentation allow for other (potentially non used) keys. The most
* convenient way of creating a Documentation is by using nested initializer lists:
*\verbatim
Documentation doc = {
"Documentation for an arbitrary dictionary",
{ // A list of DocumentationEntry%s; also specified using initializer lists
{ "key1", new IntVerifier, "Documentation key1", Optional::Yes },
{ "key2", new FloatVerifier, "Documentation key2" },
{ "key3", new StringVerifier }
},
Exhaustive::Yes
+;
\endverbatim
*
* If multiple DocumentationEntries cover the same key, they are all evaluated for that
* specific key. The same holds true if there is a DocumentationEntry with a
* DocumentationEntry::Wildcard and a more specialized DocumentationEntry. In this case,
* both the wildcard and the specialized entry will be evaluated.
*/
struct Documentation {
using DocumentationEntries = std::vector<documentation::DocumentationEntry>;
/**
* Creates a Documentation with a human-readable \p name and a list of \p entries.
* \param name The human-readable name of this Documentation
* \param id A unique identifier which can be used by applications (or other
* Documentation%s to reference this entry
* \param entries A list of DocumentationEntry%s that describe the individual keys for
* this entrie Documentation
* \param exhaustive Determines whether the \p entries are an exhaustive specification
* of the object or whether additional, potentially unused, keys are allowed
*/
Documentation(std::string name, std::string id, DocumentationEntries entries = {},
Exhaustive exhaustive = Exhaustive::No);
/**
* Creates a Documentation with a human-readable \p name.
* \param name The human-readable name of this Documentation
* \param entries A list of DocumentationEntry%s that describe the individual keys for
* this entrie Documentation
* \param exhaustive Determines whether the \p entries are an exhaustive specification
* of the object or whether additional, potentially unused, keys are allowed
*/
Documentation(std::string name, DocumentationEntries entries = {},
Exhaustive exhaustive = Exhaustive::No);
/**
* Creates a Documentation.
* \param entries A list of DocumentationEntry%s that describe the individual keys for
* this entrie Documentation
* \param exhaustive Determines whether the \p entries are an exhaustive specification
* of the object or whether additional, potentially unused, keys are allowed
*/
Documentation(DocumentationEntries entries = {}, Exhaustive exhaustive = Exhaustive::No);
/// The human-readable name of the Documentation
std::string name;
/// A unique identifier which can be used to reference this Documentation
std::string id;
/// A list of specifications that are describing this Documentation
DocumentationEntries entries;
/// A flag to say wheter the DocumentationEntries are an exhaustive description
Exhaustive exhaustive;
};
/**
* This method tests whether a provided ghoul::Dictionary \p dictionary adheres to the
* specification \p documentation and returns its result as a TestResult. The TestResult
* will contain whether the \p dictionary adheres to the \p documentation and, in
* addition, the list of all offending keys together with the reason why they are
* offending.
* \param documentation The Documentation that the \p dictionary is tested against
* \param dictionary The ghoul::Dictionary that is to be tested against the
* \p documentation
* \return A TestResult that contains the results of the specification testing
*/
TestResult testSpecification(const Documentation& documentation,
const ghoul::Dictionary& dictionary);
/**
* This method tests whether a provided ghoul::Dictionary \p dictionary adheres to the
* specification \p documentation. If the \p dictionary does not adhere to the
* specification a SpecificationError is thrown, and the exception contains the TestResult
* that contains more information about the offending keys. If the \p dictionary adheres to
* the \p documentation, the method returns normally.
* \param documentation The Documentation that the \p dictionary is tested against
* \param dictionary The ghoul::Dictionary that is to be tested against the
* \p documentation
* \param component The component that is using this method; this argument is passed to the
* SpecificationError that is thrown in case of not adhering to the \p documentation
* \throw SpecificationError If the \p dictionary does not adhere to the \p documentation
*/
void testSpecificationAndThrow(const Documentation& documentation,
const ghoul::Dictionary& dictionary, std::string component);
} // namespace documentation
// We want to make it easier for people to use it, so we pull the Documentation class into
// the openspace namespace
using documentation::Documentation;
} // namespace openspace
// Make the overload for std::to_string available for the Offense::Reason for easier
// error logging
namespace std {
std::string to_string(openspace::documentation::TestResult::Offense::Reason reason);
} // namespace
#endif // __DOCUMENTATION_H__

View File

@@ -0,0 +1,102 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __DOCUMENTATIONENGINE_H__
#define __DOCUMENTATIONENGINE_H__
#include <openspace/documentation/documentation.h>
#include <ghoul/designpattern/singleton.h>
#include <ghoul/misc/exception.h>
namespace openspace {
namespace documentation {
/**
* The DocumentationEngine has the ability to collect all Documentation%s that are
* produced in the application an write them out as a documentation file for human
* consumption.
*/
class DocumentationEngine : public ghoul::Singleton<DocumentationEngine> {
public:
/**
* This exception is thrown by the addDocumentation method if a provided Documentation
* has an identifier, but the identifier was registered previously.
*/
struct DuplicateDocumentationException : public ghoul::RuntimeError {
/**
* Constructor of a DuplicateDocumentationException storing the offending
* Documentation for later use.
* \param documentation The Documentation whose identifier was previously
* registered
*/
DuplicateDocumentationException(Documentation documentation);
/// The offending Documentation whose identifier was previously registered
Documentation documentation;
};
/**
* Write the collected Documentation%s to disk at the \p filename in the specified
* \p type. A new file is created and silently overwritten in the location that
* \p filename is pointed to.
* \param filename The file that is to be created containing all the Documentation
* information.
* \param type The type of documentation that is written. Currently allowed values are
* \c text and \c html
*/
void writeDocumentation(const std::string& filename, const std::string& type);
/**
* Adds the \p documentation to the list of Documentation%s that are written to a
* documentation file with the writeDocumentation method.
* \param documentation The Documentation object that is to be stored for later use
* \throws DuplicateDocumentationException If the \p documentation has a non-empty
* identifier and it was not unique
*/
void addDocumentation(Documentation documentation);
/**
* Returns a list of all registered Documentation%s
* \return A list of all registered Documentation%s
*/
std::vector<Documentation> documentations() const;
/**
* Returns a static reference to the main singleton DocumentationEngine
* \return A static reference to the main singleton DocumentationEngine
*/
static DocumentationEngine& ref();
private:
/// The list of all Documentation%s that are stored by the DocumentationEngine
std::vector<Documentation> _documentations;
};
} // namespace documentation
} // namespace openspace
#define DocEng (openspace::documentation::DocumentationEngine::ref())
#endif // __DOCUMENTATIONENGINE_H__

View File

@@ -0,0 +1,943 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __VERIFIER_H__
#define __VERIFIER_H__
#include <openspace/documentation/documentation.h>
#include <functional>
#include <type_traits>
namespace openspace {
namespace documentation {
/**
* The base class of all Verifier%s. Each object must have an Verifier::operator()
* overload, that performs the actual testing of the key inside the passed
* ghoul::Dictionary and return a TestResult. The Verifier::type method returns a
* human-readable representation of the type that is expected by the concret subclass of
* Verifier. Furthermore, the Verifier::documentation method returns a human-readable
* description of the Verifier subclass and what it tests for.
*/
struct Verifier {
/**
* This method tests whether the \p key contained in the \p dictionary adheres to
* whatever the concrete Verifer needs to test. The actual testing depends on the
* concrete subclass and can range from type testing (for example IntVerifier or
* StringVerifier) to more complex testing (for example DoubleInRangeVerifier or
* TableVerifier).
* \param dictionary The dictionary that contains the \p key which is to be tested by
* this Verifier
* \param key The key inside the \p dictionary that is to be tested
* \return A TestResult struct that contains information about whether the key adheres
* to the demands of the specific Verifier. If it does not, 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
* TestResult::offenders is empty
*/
virtual TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const = 0;
/**
* This method returns a human-readable string describing the type of object that is
* handled by the Verifier subclass. This is only used for generating a human-readable
* documentation and description of a Documenation object.
* \return A human-readable string describing the type of object for the Verifier
* \post The return value is not empty
*/
virtual std::string type() const = 0;
/**
* This method returns a human-readable string describing the tests that the concrete
* Verifier subclass implements. This is only used for generating a human-readable
* documentation and description of a Documentation object.
* \return A human-readable string describing the tests that are performed by the
* Verifier
* \post The return value is not empty
*/
virtual std::string documentation() const = 0;
};
//----------------------------------------------------------------------------------------
// General verifiers
//----------------------------------------------------------------------------------------
/**
* 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.
* \tparam T The type against which the key's value is tested
*/
template <typename T>
struct TemplateVerifier : public Verifier {
using Type = T;
/**
* Tests whether the \p key contained in the ghoul::Dictionary \p dictionary exists
* and has the same type as \c 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.
* \post The return values' TestResult::success is either \c true and
* TestResult::offenders is empty, or it is \c false and TestResult::offenders
* contains \p key
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
std::string documentation() const override;
};
/**
* 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.
*/
struct BoolVerifier : public TemplateVerifier<bool> {
std::string type() const override;
};
/**
* 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.
*/
struct DoubleVerifier : public TemplateVerifier<double> {
std::string type() const override;
};
/**
* 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>).
*/
struct IntVerifier : public TemplateVerifier<int> {
TestResult operator()(const ghoul::Dictionary& dict,
const std::string& key) const override;
std::string type() const override;
};
/**
* 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.
*/
struct StringVerifier : public TemplateVerifier<std::string> {
std::string type() const override;
};
/**
* A Verifier that checks whether a given key inside a ghoul::Dictionary is another
* ghoul::Dictionary. The constructor takes a list of DocumentationEntry%s, which are used
* 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.
*/
struct TableVerifier : public TemplateVerifier<ghoul::Dictionary> {
/**
* This constructor takes a list of DocumentationEntry%s that are used recursively to
* check the table (= ghoul::Dictionary) contained in the key's value. Similar to the
* Documentation, these DocumentationEntry%s can be Exhaustive or not.
* \param documentationEntries The DocumentationEntry%s that are used to recursively
* test the ghoul::Dictionary that is contained inside. If this list is empty, only a
* type check is performed
* \param exhaustive Whether the DocumentationEntry%s contained in
* \p documentationEntries completely describe the contained table or whether
* additional keys are allowed
*/
TableVerifier(std::vector<DocumentationEntry> documentationEntries = {},
Exhaustive exhaustive = Exhaustive::No);
/**
* Checks whether the \p key%'s value is a table (= ghoul::Dictionary) and (if
* provided) recursively checks whether the table adheres to the DocumentationEntry%s
* provided in the constructor. 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.
* \param dictionary The ghoul::Dictionary that is to be tested for the \p key
* \param key The key for which the \p dictionary is tested
* \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.
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
std::string type() const override;
/// The documentations passed in the constructor
std::vector<DocumentationEntry> documentations;
/// Flag that specifies whether the TableVerifier::documentation exhaustively
/// describes the table or whether additional keys are allowed
Exhaustive exhaustive;
};
//----------------------------------------------------------------------------------------
// Vector verifiers
//----------------------------------------------------------------------------------------
/**
* This struct is the base class for all Verifier%s that check for \c 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>.
*/
struct VectorVerifier {};
/**
* This Verifier checks whether the value is of type <code>glm::tvec2<T></code>
*/
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>
*/
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>
*/
template <typename T>
struct Vector4Verifier : public TemplateVerifier<glm::tvec4<T>>, public VectorVerifier {
std::string type() const override;
};
//----------------------------------------------------------------------------------------
// Operator verifiers
//----------------------------------------------------------------------------------------
/**
* 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.
*
* 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.
* 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
* reason TestResult::Offense::Verification is returned instead.
*/
template <typename T, typename Operator>
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
*/
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,
* the \p key%'s value is checked against the stored OperatorVerifier::value using the
* \c 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 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
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
* as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
*/
template <typename T>
struct LessVerifier : public OperatorVerifier<T, std::less<typename T::Type>> {
static_assert(
!std::is_base_of<BoolVerifier, T>::value,
"T cannot be BoolVerifier"
);
static_assert(
!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;
std::string documentation() const;
using OperatorVerifier<T, std::less<typename T::Type>>::value;
};
/**
* 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
* as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
*/
template <typename T>
struct LessEqualVerifier : public OperatorVerifier<T, std::less_equal<typename T::Type>> {
static_assert(
!std::is_base_of<BoolVerifier, T>::value,
"T cannot be BoolVerifier"
);
static_assert(
!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_equal<typename T::Type>>::OperatorVerifier;
std::string documentation() const override;
using OperatorVerifier<T, std::less_equal<typename T::Type>>::value;
};
/**
* 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
* as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
*/
template <typename T>
struct GreaterVerifier : public OperatorVerifier<T, std::greater<typename T::Type>> {
static_assert(
!std::is_base_of<BoolVerifier, T>::value,
"T cannot be BoolVerifier"
);
static_assert(
!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::greater<typename T::Type>>::OperatorVerifier;
std::string documentation() const override;
using OperatorVerifier<T, std::greater<typename T::Type>>::value;
};
/**
* 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
* as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
*/
template <typename T>
struct GreaterEqualVerifier : public OperatorVerifier<T, std::greater_equal<typename T::Type>> {
static_assert(
!std::is_base_of<BoolVerifier, T>::value,
"T cannot be BoolVerifier"
);
static_assert(
!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::greater_equal<typename T::Type>>::OperatorVerifier;
std::string documentation() const override;
using OperatorVerifier<T, std::greater_equal<typename T::Type>>::value;
};
/**
* 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) TableVerifier.
*/
template <typename T>
struct EqualVerifier : public OperatorVerifier<T, std::equal_to<typename T::Type>> {
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
using OperatorVerifier<T, std::equal_to<typename T::Type>>::OperatorVerifier;
std::string documentation() const override;
using OperatorVerifier<T, std::equal_to<typename T::Type>>::value;
};
/**
* 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)
* TableVerifier.
*/
template <typename T>
struct UnequalVerifier : public OperatorVerifier<T, std::not_equal_to<typename T::Type>> {
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
using OperatorVerifier<T, std::not_equal_to<typename T::Type>>::OperatorVerifier;
std::string documentation() const override;
using OperatorVerifier<T, std::not_equal_to<typename T::Type>>::value;
};
//----------------------------------------------------------------------------------------
// List verifiers
//----------------------------------------------------------------------------------------
/**
* 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
* be a subclass of (or the same as) TableVerifier.
*/
template <typename T>
struct InListVerifier : public T {
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
/**
* Constructs an InListVerifier that checks whether the incoming value is of the
* correct type and whether the value is part of the list passed as \p values.
* \param values The list of values against which the incoming value is tested
*/
InListVerifier(std::vector<typename T::Type> values);
/**
* 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
* is part of the list passed to the constructor.
* \param dictionary The ghoul::Dictionary that contains the \p key
* \param key The key that is contained in the \p dictionary and whose value is 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 value is not
* in the list, it will be added with the reason TestResult::Offense::Verification
* instead.
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
std::string documentation() const override;
/// The list of values against which the incoming value is tested
std::vector<typename T::Type> values;
};
/**
* 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
* be a subclass of (or the same as) TableVerifier.
*/
template <typename T>
struct NotInListVerifier : public T {
static_assert(!std::is_base_of<TableVerifier, T>::value, "T cannot be TableVerifier");
/**
* Constructs a NotInListVerifier that checks whether the incoming value is of the
* correct type and whether the value is not part of the list passed as \p values.
* \param values The list of values against which the incoming value is tested
*/
NotInListVerifier(std::vector<typename T::Type> values);
/**
* 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
* is not part of the list passed to the constructor.
* \param dictionary The ghoul::Dictionary that contains the \p key
* \param key The key that is contained in the \p dictionary and whose value is 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 value is in the
* list, it will be added with the reason TestResult::Offense::Verification instead.
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
std::string documentation() const override;
std::vector<typename T::Type> values;
};
//----------------------------------------------------------------------------------------
// Range verifiers
//----------------------------------------------------------------------------------------
/**
* 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
* 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,
* TableVerifier, or VectorVerifier. Both the lower and the higher limit are inclusive).
*/
template <typename T>
struct InRangeVerifier : public T {
static_assert(
!std::is_base_of<BoolVerifier, T>::value,
"T cannot be BoolVerifier"
);
static_assert(
!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"
);
/**
* 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.
* \param lower The (inclusive) lower limit of the range
* \param upper The (inclusive) upper limit of the range
* \pre \p lower must be smaller or equal to \p upper
*/
InRangeVerifier(typename T::Type lower, typename T::Type upper);
/**
* 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
* is between the lower and upper limits (both inclusive) that were passed to the
* constructor.
* \param dictionary The ghoul::Dictionary that contains the \p key
* \param key The key that is contained in the \p dictionary and whose value is 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 value is outside
* the range defined by the lower and upper limits passed to the constructor, it will
* be added with the reason TestResult::Offense::Verification instead.
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
std::string documentation() const override;
typename T::Type lower;
typename T::Type upper;
};
/**
* 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
* (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,
* TableVerifier, or VectorVerifier. Both the lower and the higher limit are exclusive).
*/
template <typename T>
struct NotInRangeVerifier : public T {
static_assert(
!std::is_base_of<BoolVerifier, T>::value,
"T cannot be BoolVerifier"
);
static_assert(
!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"
);
/**
* Constructs a InRangeVerifier that checks whether the incoming value is of the
* correct type and whether the value is less then \p lower and greater than \upper.
* \param lower The (exclusive) lower limit of the range
* \param upper The (exclusive) upper limit of the range
* \pre \p lower must be smaller or equal to \p upper
*/
NotInRangeVerifier(typename T::Type lower, typename T::Type upper);
/**
* 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
* is outside the lower and upper limits (both exclusive) that were passed to the
* constructor.
* \param dictionary The ghoul::Dictionary that contains the \p key
* \param key The key that is contained in the \p dictionary and whose value is 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 value is greater
* or equal to the lower limit and less or equal to the upper limit, it will be added
* with the reason TestResult::Offense::Verification instead.
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
std::string documentation() const override;
typename T::Type lower;
typename T::Type upper;
};
//----------------------------------------------------------------------------------------
// Misc verifiers
//----------------------------------------------------------------------------------------
/**
* This Verifier only checks for the correct type of the incoming value. If the
* documentation is requested, it will return an additional string that is the annotation.
* This can be used to specify further conditions that are hard (or impossible) to codify,
* but the user should be notified about. This, for example, can be that used to notify
* the user that the parameter should be a file of a specific type.
*/
template <typename T>
struct AnnotationVerifier : public T {
/**
* Constructs an AnnotationVerifier that contains the passed \p annotation which is
* passed to the user when a documentation is requested.
* \param annotation The annotation that is stored and returned to the user when it
* is requested.
* \pre annotation must not be empty
*/
AnnotationVerifier(std::string annotation);
std::string documentation() const override;
/// The annotation that is returned to the user in the documentation
std::string annotation;
};
/**
* This Verifier can reference and apply other Documentation%s that have been registered
* with a DocumentationEngine. The dependency is only resolved when the operator() is
* called, at which the referencing Documentation must have been registered, or the
* TestResult will contain an offense of TestResult::Offense::Reason::UnknownIdentifier.
* If the referenced Documentation exists, the stored Table will be checked against that
* Documentation.
*/
struct ReferencingVerifier : public TableVerifier {
/**
* Creates a ReferencingVerifier that references a documentation with the provided
* \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 identifier);
/**
* Checks whether the \p key in the \p dictionary exists and is of type Table (similar
* to the TableVerifier). If it exists and is a Table, the Documentation referenced by
* the identifier provided in the constructor is used to validate the Table. If the
* identifier does not name a registered Documentation, the TestResult::offenses
* will contain the \p key and TestResult::Offense::Reason::UnknownIdentifier will be
* signaled. If the identifier exists and the \p key%'s value does not comply with the
* Documentation, the offending keys will be returned in the TestResult with their
* fully qualified names.
* \param dictionary The ghoul::Dictionary whose \p key should be tested
* \param key The key contained in the \p dictionary that should be tested
* \return A TestResult struct that contains the results of the testing
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
std::string documentation() const override;
/// The identifier that references another Documentation registered with the
/// DocumentationEngine
std::string identifier;
};
//----------------------------------------------------------------------------------------
// Misc verifiers
//----------------------------------------------------------------------------------------
/**
* This Verifier takes two Verifiers and performs a boolean \c 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>
* operator, the AndVerifier does not perform any short-circut evaluation.
*/
struct AndVerifier : public Verifier {
/**
* Constructs an AndVerifier with two Verifiers which must be cleared by incoming
* values in order to pass this Verifier.
* \param lhs The first Verifier that is to be tested
* \param rhs The second Verifier that is to be tested
* \pre lhs must not be nullptr
* \pre rhs must not be nullptr
*/
AndVerifier(Verifier* lhs, Verifier* rhs);
/**
* Checks whether the \p dictionary contains the \p key and whether this key passes
* both Verifier%'s that were passed in the constructor. If the value fails either
* of the two Verifiers, it is only added once to the TestResult::offenses list with
* a reason of TestResult::Offense::Reason::Verification.
* \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
* either of the two Verifiers, TestResult::success is \c 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
* TestResult::offenses is empty.
*/
TestResult operator()(const ghoul::Dictionary& dictionary,
const std::string& key) const override;
std::string type() const override;
std::string documentation() const override;
/// The first Verifier that incoming values are tested against
std::shared_ptr<Verifier> lhs;
/// The second Verifier that incoming values are tested against
std::shared_ptr<Verifier> rhs;
};
/**
* This Verifier takes two Verifiers and performs a boolean \c 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.
*/
struct OrVerifier : public Verifier {
/**
* Constructs an OrVerifier with two Verifiers, either of which must be cleared by
* incoming values in order to pass this Verifier.
* \param lhs The first Verifier that is to be tested
* \param rhs The second Verifier that is to be tested
* \pre lhs must not be nullptr
* \pre rhs must not be nullptr
*/
OrVerifier(Verifier* lhs, Verifier* rhs);
/**
* Checks whether the \p dictionary contains the \p key and whether this key passes
* either of the two Verifier%'s that were passed in the constructor. If the value
* fails both Verifiers, it is added to the TestResult::offenses list with a reason of
* TestResult::Offense::Reason::Verification.
* \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
* both Verifiers, TestResult::success is \c 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 TestResult::offenses is empty.
*/
TestResult operator()(const ghoul::Dictionary& dict,
const std::string& key) const override;
std::string type() const override;
std::string documentation() const override;
/// The first Verifier that incoming values are tested against
std::shared_ptr<Verifier> lhs;
/// The second Verifier that incoming values are tested against
std::shared_ptr<Verifier> rhs;
};
/// A short-hand definition for a Verifier checking for <code>glm::bvec2</code>
using BoolVector2Verifier = Vector2Verifier<bool>;
/// A short-hand definition for a Verifier checking for <code>glm::ivec2</code>
using IntVector2Verifier = Vector2Verifier<int>;
/// A short-hand definition for a Verifier checking for <code>glm::dvec2</code>
using DoubleVector2Verifier = Vector2Verifier<double>;
/// A short-hand definition for a Verifier checking for <code>glm::bvec3</code>
using BoolVector3Verifier = Vector3Verifier<bool>;
/// A short-hand definition for a Verifier checking for <code>glm::ivec3</code>
using IntVector3Verifier = Vector3Verifier<int>;
/// A short-hand definition for a Verifier checking for <code>glm::dvec3</code>
using DoubleVector3Verifier = Vector3Verifier<double>;
/// A short-hand definition for a Verifier checking for <code>glm::bvec4</code>
using BoolVector4Verifier = Vector4Verifier<bool>;
/// A short-hand definition for a Verifier checking for <code>glm::ivec4</code>
using IntVector4Verifier = Vector4Verifier<int>;
/// A short-hand definition for a Verifier checking for <code>glm::dvec4</code>
using DoubleVector4Verifier = Vector4Verifier<double>;
/// A short-hand definition for a LessVerifier with a type check for \c int
using IntLessVerifier = LessVerifier<IntVerifier>;
/// A short-hand definition for a LessVerifier with a type check for \c double
using DoubleLessVerifier = LessVerifier<DoubleVerifier>;
/// A short-hand definition for a LessEqualVerifier with a type check for \c int
using IntLessEqualVerifier = LessEqualVerifier<IntVerifier>;
/// A short-hand definition for a LessEqualVerifier with a type check for \c double
using DoubleLessEqualVerifier = LessEqualVerifier<DoubleVerifier>;
/// A short-hand definition for a GreaterVerifier with a type check for \c int
using IntGreaterVerifier = GreaterVerifier<IntVerifier>;
/// A short-hand definition for a GreaterVerifier with a type check for \c double
using DoubleGreaterVerifier = GreaterVerifier<DoubleVerifier>;
/// A short-hand definition for a GreaterEqualVerifier with a type check for \c int
using IntGreaterEqualVerifier = GreaterEqualVerifier<IntVerifier>;
/// A short-hand definition for a GreaterEqualVerifier with a type check for \c double
using DoubleGreaterEqualVerifier = GreaterEqualVerifier<DoubleVerifier>;
/// A short-hand definition for a EqualVerifier with a type check for \c bool
using BoolEqualVerifier = EqualVerifier<BoolVerifier>;
/// A short-hand definition for a EqualVerifier with a type check for \c int
using IntEqualVerifier = EqualVerifier<IntVerifier>;
/// A short-hand definition for a EqualVerifier with a type check for \c double
using DoubleEqualVerifier = EqualVerifier<DoubleVerifier>;
/// A short-hand definition for a EqualVerifier with a type check for \c string
using StringEqualVerifier = EqualVerifier<StringVerifier>;
/// A short-hand definition for a UnequalVerifier with a type check for \c bool
using BoolUnequalVerifier = UnequalVerifier<BoolVerifier>;
/// A short-hand definition for a UnequalVerifier with a type check for \c int
using IntUnequalVerifier = UnequalVerifier<IntVerifier>;
/// A short-hand definition for a UnequalVerifier with a type check for \c double
using DoubleUnequalVerifier = UnequalVerifier<DoubleVerifier>;
/// A short-hand definition for a UnequalVerifier with a type check for \c string
using StringUnequalVerifier = UnequalVerifier<StringVerifier>;
/// A short-hand definition for a InListVerifier with a type check for \c bool
using BoolInListVerifier = InListVerifier<BoolVerifier>;
/// A short-hand definition for a InListVerifier with a type check for \c int
using IntInListVerifier = InListVerifier<IntVerifier>;
/// A short-hand definition for a InListVerifier with a type check for \c double
using DoubleInListVerifier = InListVerifier<DoubleVerifier>;
/// A short-hand definition for a InListVerifier with a type check for \c string
using StringInListVerifier = InListVerifier<StringVerifier>;
/// A short-hand definition for a NotInListVerifier with a type check for \c bool
using BoolNotInListVerifier = NotInListVerifier<BoolVerifier>;
/// A short-hand definition for a NotInListVerifier with a type check for \c int
using IntNotInListVerifier = NotInListVerifier<IntVerifier>;
/// A short-hand definition for a NotInListVerifier with a type check for \c double
using DoubleNotInListVerifier = NotInListVerifier<DoubleVerifier>;
/// A short-hand definition for a NotInListVerifier with a type check for \c string
using StringNotInListVerifier = NotInListVerifier<StringVerifier>;
/// A short-hand definition for a InRangeVerifier with a type check for \c int
using IntInRangeVerifier = InRangeVerifier<IntVerifier>;
/// A short-hand definition for a InRangeVerifier with a type check for \c double
using DoubleInRangeVerifier = InRangeVerifier<DoubleVerifier>;
/// A short-hand definition for a NotInRangeVerifier with a type check for \c int
using IntNotInRangeVerifier = NotInRangeVerifier<IntVerifier>;
/// A short-hand definition for a NotInRangeVerifier with a type check for \c double
using DoubleNotInRangeVerifier = NotInRangeVerifier<DoubleVerifier>;
/// A short-hand definition for a AnnotationVerifier with a type check for \c bool
using BoolAnnotationVerifier = AnnotationVerifier<BoolVerifier>;
/// A short-hand definition for a AnnotationVerifier with a type check for \c int
using IntAnnotationVerifier = AnnotationVerifier<IntVerifier>;
/// A short-hand definition for a AnnotationVerifier with a type check for \c double
using DoubleAnnotationVerifier = AnnotationVerifier<DoubleVerifier>;
/// A short-hand definition for a AnnotationVerifier with a type check for \c string
using StringAnnotationVerifier = AnnotationVerifier<StringVerifier>;
/// A short-hand definition for a AnnotationVerifier with a type check for
/// <code>ghoul::Dictionary</code>
using TableAnnotationVerifier = AnnotationVerifier<TableVerifier>;
// Definitions of external templates that are instantiated in the cpp file
// This cuts down the compilation times as almost all of the possible template types do
// not need to be instantiated multiple times
extern template struct Vector2Verifier<bool>;
extern template struct Vector2Verifier<int>;
extern template struct Vector2Verifier<double>;
extern template struct Vector3Verifier<bool>;
extern template struct Vector3Verifier<int>;
extern template struct Vector3Verifier<double>;
extern template struct Vector4Verifier<bool>;
extern template struct Vector4Verifier<int>;
extern template struct Vector4Verifier<double>;
extern template struct LessVerifier<IntVerifier>;
extern template struct LessVerifier<DoubleVerifier>;
extern template struct LessEqualVerifier<IntVerifier>;
extern template struct LessEqualVerifier<DoubleVerifier>;
extern template struct GreaterVerifier<IntVerifier>;
extern template struct GreaterVerifier<DoubleVerifier>;
extern template struct GreaterEqualVerifier<IntVerifier>;
extern template struct GreaterEqualVerifier<DoubleVerifier>;
extern template struct EqualVerifier<BoolVerifier>;
extern template struct EqualVerifier<IntVerifier>;
extern template struct EqualVerifier<DoubleVerifier>;
extern template struct EqualVerifier<StringVerifier>;
extern template struct UnequalVerifier<BoolVerifier>;
extern template struct UnequalVerifier<IntVerifier>;
extern template struct UnequalVerifier<DoubleVerifier>;
extern template struct UnequalVerifier<StringVerifier>;
extern template struct InListVerifier<BoolVerifier>;
extern template struct InListVerifier<IntVerifier>;
extern template struct InListVerifier<DoubleVerifier>;
extern template struct InListVerifier<StringVerifier>;
extern template struct NotInListVerifier<BoolVerifier>;
extern template struct NotInListVerifier<IntVerifier>;
extern template struct NotInListVerifier<DoubleVerifier>;
extern template struct NotInListVerifier<StringVerifier>;
extern template struct InRangeVerifier<IntVerifier>;
extern template struct InRangeVerifier<DoubleVerifier>;
extern template struct NotInRangeVerifier<IntVerifier>;
extern template struct NotInRangeVerifier<DoubleVerifier>;
extern template struct AnnotationVerifier<BoolVerifier>;
extern template struct AnnotationVerifier<IntVerifier>;
extern template struct AnnotationVerifier<DoubleVerifier>;
extern template struct AnnotationVerifier<StringVerifier>;
extern template struct AnnotationVerifier<TableVerifier>;
} // namespace documentation
} // namespace openspace
#include "verifier.inl"
#endif // __VERIFIER_H__

View File

@@ -0,0 +1,303 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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. *
****************************************************************************************/
#include <iterator>
namespace std {
std::string to_string(std::string value);
}
namespace openspace {
namespace documentation {
template <typename T>
TestResult TemplateVerifier<T>::operator()(const ghoul::Dictionary& dict,
const std::string& key) const
{
if (dict.hasKeyAndValue<Type>(key)) {
return { true, {} };
}
else {
if (dict.hasKey(key)) {
return { false, { { key, TestResult::Offense::Reason::WrongType } } };
}
else {
return { false, { { key, TestResult::Offense::Reason::MissingKey } } };
}
}
}
template <typename T>
std::string TemplateVerifier<T>::documentation() const {
return "Type testing of '" + type() + "'";
}
template <typename T>
std::string Vector2Verifier<T>::type() const {
using namespace std::string_literals;
return "Vector2<"s + typeid(T).name() + ">";
}
template <typename T>
std::string Vector3Verifier<T>::type() const {
using namespace std::string_literals;
return "Vector3<"s + typeid(T).name() + ">";
}
template <typename T>
std::string Vector4Verifier<T>::type() const {
using namespace std::string_literals;
return "Vector4<"s + typeid(T).name() + ">";
}
template <typename T, typename Operator>
OperatorVerifier<T, Operator>::OperatorVerifier(typename T::Type value)
: value(std::move(value))
{}
template <typename T, typename Operator>
TestResult OperatorVerifier<T, Operator>::operator()(const ghoul::Dictionary& dict,
const std::string& key) const
{
TestResult res = T::operator()(dict, key);
if (res.success) {
if (Operator()(dict.value<typename T::Type>(key), value)) {
return { true, {} };
}
else {
return { false, { { key, TestResult::Offense::Reason::Verification }}};
}
}
else {
return res;
}
}
template <typename T>
std::string LessVerifier<T>::documentation() const {
return "Less than: " + std::to_string(value);
}
template <typename T>
std::string LessEqualVerifier<T>::documentation() const {
return "Less or equal to: " + std::to_string(value);
}
template <typename T>
std::string GreaterVerifier<T>::documentation() const {
return "Greater than: " + std::to_string(value);
}
template <typename T>
std::string GreaterEqualVerifier<T>::documentation() const {
return "Greater or equal to: " + std::to_string(value);
}
template <typename T>
std::string EqualVerifier<T>::documentation() const {
return "Equal to: " + std::to_string(value);
}
template <typename T>
std::string UnequalVerifier<T>::documentation() const {
return "Unequal to: " + std::to_string(value);
}
template <typename T>
InListVerifier<T>::InListVerifier(std::vector<typename T::Type> values)
: values(std::move(values))
{}
template <typename T>
TestResult InListVerifier<T>::operator()(const ghoul::Dictionary& dict,
const std::string& key) const
{
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);
if (it != values.end()) {
return { true, {} };
}
else {
return { false, { { key, TestResult::Offense::Reason::Verification } } };
}
}
else {
return res;
}
}
template <typename T>
std::string InListVerifier<T>::documentation() const {
std::string result = "In list { ";
std::stringstream s;
std::copy(
values.begin(),
values.end(),
std::ostream_iterator<typename T::Type>(s, ",")
);
std::string joined = s.str();
// We need to remove a trailing ',' at the end of the string
result += joined.substr(0, joined.size() - 1);
result += " }";
return result;
}
template <typename T>
NotInListVerifier<T>::NotInListVerifier(std::vector<typename T::Type> values)
: values(std::move(values))
{}
template <typename T>
TestResult NotInListVerifier<T>::operator()(const ghoul::Dictionary& dict,
const std::string& key) const
{
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);
if (it == values.end()) {
return { true, {} };
}
else {
return { false, { { key, TestResult::Offense::Reason::Verification } } };
}
}
else {
return res;
}
}
template <typename T>
std::string NotInListVerifier<T>::documentation() const {
std::string result = "Not in list { ";
std::stringstream s;
std::copy(
values.begin(),
values.end(),
std::ostream_iterator<typename T::Type>(s, ",")
);
std::string joined = s.str();
// We need to remove a trailing ',' at the end of the string
result += joined.substr(0, joined.size() - 1);
result += " }";
return result;
}
template <typename T>
InRangeVerifier<T>::InRangeVerifier(typename T::Type lower, typename T::Type upper)
: lower(std::move(lower))
, upper(std::move(upper))
{
ghoul_assert(lower <= upper, "lower must be smaller or equal to upper");
}
template <typename T>
TestResult InRangeVerifier<T>::operator()(const ghoul::Dictionary& dict,
const std::string& key) const
{
TestResult res = T::operator()(dict, key);
if (res.success) {
typename T::Type val = dict.value<typename T::Type>(key);
if (val >= lower && val <= upper) {
return { true, {} };
}
else {
return { false, { { key, TestResult::Offense::Reason::Verification } } };
}
}
else {
return res;
}
}
template <typename T>
std::string InRangeVerifier<T>::documentation() const {
return "In range: ( " + std::to_string(lower) + "," +
std::to_string(upper) + " )";
}
template <typename T>
NotInRangeVerifier<T>::NotInRangeVerifier(typename T::Type lower, typename T::Type upper)
: lower(std::move(lower))
, upper(std::move(upper))
{
ghoul_assert(lower <= upper, "lower must be smaller or equal to upper");
}
template <typename T>
TestResult NotInRangeVerifier<T>::operator()(const ghoul::Dictionary& dict,
const std::string& key) const {
TestResult res = T::operator()(dict, key);
if (res.success) {
typename T::Type val = dict.value<typename T::Type>(key);
if (val >= lower && val <= upper) {
return { false, { { key, TestResult::Offense::Reason::Verification } } };
}
else {
return { true, {} };
}
}
else {
return res;
}
}
template <typename T>
std::string NotInRangeVerifier<T>::documentation() const {
return "Not in range: ( " + std::to_string(lower) + "," +
std::to_string(upper) + " )";
}
template <typename T>
AnnotationVerifier<T>::AnnotationVerifier(std::string annotation)
: annotation(std::move(annotation))
{
ghoul_assert(!this->annotation.empty(), "Annotation must not be empty");
}
template <typename T>
std::string AnnotationVerifier<T>::documentation() const {
return annotation;
}
} // namespace documentation
} // namespace openspace

View File

@@ -25,6 +25,8 @@
#ifndef __CONFIGURATIONMANAGER_H__
#define __CONFIGURATIONMANAGER_H__
#include <openspace/documentation/documentation.h>
#include <ghoul/misc/dictionary.h>
namespace openspace {
@@ -49,22 +51,22 @@ public:
/// The key that stores the location of the SGCT configuration file that is used on
/// application launch
static const std::string KeyConfigSgct;
/// The key that stores the type of Lua documentation that should be stored
static const std::string KeyLuaDocumentationType;
/// The key that stores the save location of the Lua documentation
static const std::string KeyLuaDocumentationFile;
/// The key that stores the type of scripting log that should be stored
static const std::string KeyScriptLogType;
/// The key that stores the save location of the scripting log
static const std::string KeyScriptLogFile;
/// The key that stores the type of Property documentation that should be stored
static const std::string KeyPropertyDocumentationType;
/// The key that stores the save location of the Property documentation
static const std::string KeyPropertyDocumentationFile;
/// The key that stores the type of keyboard bindings that should be stored
static const std::string KeyKeyboardShortcutsType;
/// The key that stores the save location of the keyboard bindings file
static const std::string KeyKeyboardShortcutsFile;
/// The part of the key that defines the type
static const std::string PartType;
/// The part of the key that defines the file
static const std::string PartFile;
/// The key that stores the Lua documentation
static const std::string KeyLuaDocumentation;
/// The key that stores the scripting log
static const std::string KeyScriptLog;
/// The key that stores the Property documentation
static const std::string KeyPropertyDocumentation;
/// The key that stores the keyboard bindings that should be stored
static const std::string KeyKeyboardShortcuts;
/// The key that stores the main documentation
static const std::string KeyDocumentation;
/// The key that stores the factory documentation values
static const std::string KeyFactoryDocumentation;
/// The key that stores the location of the scene file that is initially loaded
static const std::string KeyConfigScene;
/// The key that stores the subdirectory containing a list of all startup scripts to
@@ -73,18 +75,24 @@ public:
/// The key that stores the subdirectory containing a list of all settings scripts to
/// be executed on application start and after the scene file is loaded
static const std::string KeySettingsScript;
/// The key that stores the settings for determining log-related settings
static const std::string KeyLogging;
/// The key that stores the desired LogLevel for the whole application
/// \sa ghoul::logging::LogManager
static const std::string KeyLogLevel;
static const std::string PartLogLevel;
/// The key that stores whether the log should be immediately flushed after a n
/// \sa ghoul::logging::LogManager
static const std::string KeyLogImmediateFlush;
static const std::string PartImmediateFlush;
/// The key that stores a subdirectory with a description for additional
/// ghoul::logging::Log%s to be created
/// \sa LogFactory
static const std::string KeyLogs;
static const std::string PartLogs;
/// The key that stores whether a log should be appended to or should be overwritten
static const std::string PartAppend;
/// The key that stores the verbosity (None, Minimal, Default, Full) of the system
/// capabilities components
static const std::string PartCapabilitiesVerbosity;
/// The full key that stores the verbosity of the system capabilities component
static const std::string KeyCapabilitiesVerbosity;
/// The key that stores the time (in seconds) that the application will wait before
/// shutting down after the shutdown call is made
@@ -95,6 +103,9 @@ public:
/// The key that sets the request URL that is used to request additional data to be
/// downloaded
static const std::string KeyDownloadRequestURL;
/// The key that stores the switch for enabling/disabling the rendering on a master
/// computer
static const std::string KeyRenderingMethod;
/**
* Iteratively walks the directory structure starting with \p filename to find the
@@ -123,6 +134,8 @@ public:
*/
void loadFromFile(const std::string& filename);
static openspace::Documentation Documentation();
private:
/**
* Checks whether the loaded configuration file is complete, that is specifying the

View File

@@ -29,6 +29,7 @@
#include <openspace/util/mouse.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/scripting/scriptscheduler.h>
#include <ghoul/glm.h>
#include <ghoul/misc/dictionary.h>
@@ -50,11 +51,11 @@ class LuaConsole;
class NetworkEngine;
class GUI;
class RenderEngine;
class SyncBuffer;
class ModuleEngine;
class WindowWrapper;
class SettingsEngine;
class TimeManager;
class SyncEngine;
namespace interaction { class InteractionHandler; }
namespace gui { class GUI; }
@@ -81,6 +82,7 @@ public:
interaction::InteractionHandler& interactionHandler();
RenderEngine& renderEngine();
scripting::ScriptEngine& scriptEngine();
scripting::ScriptScheduler& scriptScheduler();
NetworkEngine& networkEngine();
LuaConsole& console();
ModuleEngine& moduleEngine();
@@ -115,6 +117,9 @@ public:
void disableBarrier();
void toggleShutdownMode();
bool useBusyWaitForDecode();
bool logSGCTOutOfOrderErrors();
void runPostInitializationScripts(const std::string& sceneDescription);
@@ -140,7 +145,9 @@ private:
std::unique_ptr<interaction::InteractionHandler> _interactionHandler;
std::unique_ptr<RenderEngine> _renderEngine;
std::unique_ptr<scripting::ScriptEngine> _scriptEngine;
std::unique_ptr<scripting::ScriptScheduler> _scriptScheduler;
std::unique_ptr<NetworkEngine> _networkEngine;
std::unique_ptr<SyncEngine> _syncEngine;
std::unique_ptr<ghoul::cmdparser::CommandlineParser> _commandlineParser;
std::unique_ptr<LuaConsole> _console;
std::unique_ptr<ModuleEngine> _moduleEngine;
@@ -156,7 +163,6 @@ private:
// Others
std::unique_ptr<properties::PropertyOwner> _globalPropertyNamespace;
std::unique_ptr<SyncBuffer> _syncBuffer;
bool _isMaster;
double _runTime;

View File

@@ -43,12 +43,25 @@ public:
void setModules(std::vector<OpenSpaceModule*> modules);
bool busyWaitForDecode();
bool logSGCTOutOfOrderErrors();
bool useDoubleBuffering();
private:
void initEyeSeparation();
void initSceneFiles();
void initShowFrameNumber();
void initBusyWaitForDecode();
void initLogSGCTOutOfOrderErrors();
void initUseDoubleBuffering();
properties::FloatProperty _eyeSeparation;
properties::OptionProperty _scenes;
properties::BoolProperty _showFrameNumber;
properties::BoolProperty _busyWaitForDecode;
properties::BoolProperty _logSGCTOutOfOrderErrors;
properties::BoolProperty _useDoubleBuffering;
};
} // namespace openspace

View File

@@ -0,0 +1,106 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __SYNCENGINE_H__
#define __SYNCENGINE_H__
#include <vector>
#include <memory>
namespace openspace {
class Syncable;
class SyncBuffer;
/**
* Manages a collection of <code>Syncable</code>s and ensures they are synchronized
* over SGCT nodes. Encoding/Decoding order is handles internally.
*/
class SyncEngine {
public:
/**
* Dependency injection: a SyncEngine relies on a SyncBuffer to encode the sync data.
*/
SyncEngine(SyncBuffer* syncBuffer);
/**
* Encodes all added Syncables in the injected <code>SyncBuffer</code>.
* This method is only called on the SGCT master node
*/
void encodeSyncables();
/**
* Decodes the <code>SyncBuffer</code> into the added Syncables.
* This method is only called on the SGCT slave nodes
*/
void decodeSyncables();
/**
* Invokes the presync method of all added Syncables
*/
void presync(bool isMaster);
/**
* Invokes the postsync method of all added Syncables
*/
void postsync(bool isMaster);
/**
* Add a Syncable to be synchronized over the SGCT cluster
*/
void addSyncable(Syncable* syncable);
/**
* Add multiple Syncables to be synchronized over the SGCT cluster
*/
void addSyncables(const std::vector<Syncable*>& syncables);
/**
* Remove a Syncable from being synchronized over the SGCT cluster
*/
void removeSyncable(Syncable* syncable);
private:
/**
* Vector of Syncables. The vectors ensures consistent encode/decode order
*/
std::vector<Syncable*> _syncables;
/**
* Databuffer used in encoding/decoding
*/
std::unique_ptr<SyncBuffer> _syncBuffer;
};
} // namespace openspace
#endif //#ifndef __SYNCENGINE_H__

View File

@@ -53,6 +53,8 @@ public:
bool isRegularRendering() const override;
bool hasGuiWindow() const override;
bool isGuiWindow() const override;
bool isUsingSwapGroups() const override;
bool isSwapGroupMaster() const override;
glm::mat4 viewProjectionMatrix() const override;
glm::mat4 modelMatrix() const override;
@@ -66,7 +68,7 @@ public:
bool isSimpleRendering() const override;
void takeScreenshot() const override;
void takeScreenshot(bool applyWarping = false) const override;
};
} // namespace openspace

View File

@@ -153,6 +153,16 @@ public:
*/
virtual bool isGuiWindow() const;
/**
* Returns <code>true</code> if the current rendering window is using swap groups.
*/
virtual bool isUsingSwapGroups() const;
/**
* Returns <code>true</code> if the current rendering window is master of the swap its group.
*/
virtual bool isSwapGroupMaster() const;
/**
* Returns the currently employed view-projection matrix. On default, this method will
* return the identity matrix.
@@ -216,7 +226,7 @@ public:
/**
* Advises the windowing system to take a screenshot. This method defaults to a no-op.
*/
virtual void takeScreenshot() const;
virtual void takeScreenshot(bool applyWarping = false) const;
struct WindowWrapperException : public ghoul::RuntimeError {
explicit WindowWrapperException(const std::string& msg);

View File

@@ -76,12 +76,8 @@ public:
void unlockControls();
//void update(double deltaTime);
void preSynchronization(double deltaTime);
void postSynchronizationPreDraw();
void serialize(SyncBuffer* syncBuffer);
void deserialize(SyncBuffer* syncBuffer);
void updateCamera();
void updateInputStates(double timeSinceLastUpdate);
// Accessors
ghoul::Dictionary getCameraStateDictionary();

View File

@@ -97,9 +97,6 @@ public:
virtual void updateMouseStatesFromInput(const InputState& inputState, double deltaTime) = 0;
virtual void updateCameraStateFromMouseStates(Camera& camera) = 0;
virtual void serialize(SyncBuffer* syncBuffer) = 0;
virtual void deserialize(SyncBuffer* syncBuffer) = 0;
protected:
/**
Inner class that acts as a smoothing filter to a variable. The filter has a step
@@ -170,10 +167,6 @@ public:
virtual void updateMouseStatesFromInput(const InputState& inputState, double deltaTime);
virtual void updateCameraStateFromMouseStates(Camera& camera);
// Need implementation
virtual void serialize(SyncBuffer* syncBuffer) {};
virtual void deserialize(SyncBuffer* syncBuffer) {};
private:
std::vector<network::datamessagestructures::CameraKeyframe> _keyframes;
double _currentKeyframeTime;
@@ -187,9 +180,9 @@ public:
class MouseStates
{
public:
/*!
/**
\param sensitivity
\param velocityScalefactor can be set to 60 to remove the inertia of the
\param velocityScaleFactor can be set to 60 to remove the inertia of the
interaction. Lower value will make it harder to move the camera.
*/
MouseStates(double sensitivity, double velocityScaleFactor);
@@ -206,11 +199,6 @@ public:
glm::dvec2 synchedLocalRollMouseVelocity();
glm::dvec2 synchedGlobalRollMouseVelocity();
void preSynchronization();
void postSynchronizationPreDraw();
void serialize(SyncBuffer* syncBuffer);
void deserialize(SyncBuffer* syncBuffer);
private:
double _sensitivity;
@@ -219,19 +207,6 @@ public:
MouseState _truckMovementMouseState;
MouseState _localRollMouseState;
MouseState _globalRollMouseState;
// MouseStates have synched variables
glm::dvec2 _sharedGlobalRotationMouseVelocity;
glm::dvec2 _sharedLocalRotationMouseVelocity;
glm::dvec2 _sharedTruckMovementMouseVelocity;
glm::dvec2 _sharedLocalRollMouseVelocity;
glm::dvec2 _sharedGlobalRollMouseVelocity;
glm::dvec2 _synchedGlobalRotationMouseVelocity;
glm::dvec2 _synchedLocalRotationMouseVelocity;
glm::dvec2 _synchedTruckMovementMouseVelocity;
glm::dvec2 _synchedLocalRollMouseVelocity;
glm::dvec2 _synchedGlobalRollMouseVelocity;
};
OrbitalInteractionMode(std::shared_ptr<MouseStates> mouseStates);
@@ -242,9 +217,6 @@ public:
virtual void updateMouseStatesFromInput(const InputState& inputState, double deltaTime);
virtual void updateCameraStateFromMouseStates(Camera& camera);
virtual void serialize(SyncBuffer* syncBuffer);
virtual void deserialize(SyncBuffer* syncBuffer);
protected:
//void updateCameraStateFromMouseStates(Camera& camera);
std::shared_ptr<MouseStates> _mouseStates;

View File

@@ -32,10 +32,10 @@ namespace openspace {
std::string licenseText();
const int OPENSPACE_VERSION_MAJOR = 0;
const int OPENSPACE_VERSION_MINOR = 4;
const int OPENSPACE_VERSION_MINOR = 5;
const int OPENSPACE_VERSION_PATCH = 0;
const std::string OPENSPACE_VERSION_STRING = "prerelease-9 (IPS)";
const std::string OPENSPACE_VERSION_STRING = "prerelease-10 (Kulturnatten)";
} // namespace openspace

View File

@@ -48,7 +48,10 @@ public:
bool setStringValue(std::string value) override;
T minValue() const;
void setMinValue(T value);
T maxValue() const;
void setMaxValue(T value);
virtual std::string className() const override;

View File

@@ -329,11 +329,21 @@ T NumericalProperty<T>::minValue() const {
return _minimumValue;
}
template <typename T>
void NumericalProperty<T>::setMinValue(T value) {
_minimumValue = std::move(value);
}
template <typename T>
T NumericalProperty<T>::maxValue() const {
return _maximumValue;
}
template <typename T>
void NumericalProperty<T>::setMaxValue(T value) {
_maximumValue = std::move(value);
}
template <typename T>
std::string NumericalProperty<T>::generateAdditionalDescription() const {
std::string result;

View File

@@ -60,9 +60,16 @@ public:
* to its super class.
* \param identifier A unique identifier for this property
* \param guiName The GUI name that should be used to represent this property
* \param displayType Optional DisplayType for GUI (default RADIO)
*/
OptionProperty(std::string identifier, std::string guiName);
/**
* The constructor delegating the <code>identifier</code> and the <code>guiName</code>
* to its super class.
* \param identifier A unique identifier for this property
* \param guiName The GUI name that should be used to represent this property
* \param displayType Optional DisplayType for GUI (default RADIO)
*/
OptionProperty(std::string identifier, std::string guiName, DisplayType displayType);
/**

View File

@@ -71,6 +71,8 @@ public:
* \param identifier A unique identifier for this property. It has to be unique to the
* PropertyOwner and cannot contain any <code>.</code>s
* \param guiName The human-readable GUI name for this Property
* \pre \p identifier must not be empty
* \pre \p guiName must not be empty
*/
Property(std::string identifier, std::string guiName);

View File

@@ -25,6 +25,77 @@
#ifndef __SCALARPROPERTY_H__
#define __SCALARPROPERTY_H__
/**
* \file scalarproperty.h
*
* \addtogroup openspace
* @{
* \addtogroup properties
* @{
* \class BoolProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>bool</code>.
* \class CharProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>char</code>.
* \class SignedCharProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>signed char</code>.
* \class UCharProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>unsigned char</code>.
* \class ShortProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>short</code>.
* \class UShortProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>unsigned short</code>.
* \class IntProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>int</code>.
* \class UIntProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>unsigned int</code>.
* \class LongProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>long</code>.
* \class ULongProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>unsigned long</code>.
* \class LongLongProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>long long</code>.
* \class ULongLongProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>unsigned long long</code>.
* \class FloatProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>float</code>.
* \class DoubleProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>double</code>.
* \class LongDoubleProperty
* This class is a concrete implementation of openspace::properties::TemplateProperty with
* the type <code>long double</code>.
* @} @}
*/
#include "openspace/properties/numericalproperty.h"
namespace openspace {

View File

@@ -38,7 +38,7 @@ namespace properties {
// C++ class name for which a typedef will be created
// TYPE = The template parameter T for which the TemplateProperty is specialized
#define REGISTER_TEMPLATEPROPERTY_HEADER(CLASS_NAME, TYPE) \
typedef TemplateProperty<TYPE> CLASS_NAME; \
using CLASS_NAME = TemplateProperty<TYPE>; \
\
template <> \
std::string PropertyDelegate<TemplateProperty<TYPE>>::className(); \

View File

@@ -105,7 +105,7 @@ private:
/**
* When a volume is attached or detached from the scene graph,
* the resolve program needs to be recompiled.
* The #_volumes map keeps track of which volumes that can
* The _volumes map keeps track of which volumes that can
* be rendered using the current resolve program, along with their raycast data
* (id, namespace, etc)
*/

View File

@@ -1,4 +1,3 @@
/*****************************************************************************************
* *
* OpenSpace *
@@ -33,6 +32,8 @@
#include <ghoul/opengl/programobject.h>
#include <openspace/documentation/documentation.h>
// Forward declare to minimize dependencies
namespace ghoul {
@@ -51,6 +52,13 @@ class PowerScaledCoordinate;
class Renderable : public properties::PropertyOwner {
public:
enum class RenderBin : int {
Background = 1,
Opaque = 2,
Transparent = 4,
Overlay = 8
};
static Renderable* createFromDictionary(const ghoul::Dictionary& dictionary);
// constructors & destructor
@@ -64,14 +72,18 @@ public:
virtual bool isReady() const = 0;
bool isEnabled() const;
void setBoundingSphere(const PowerScaledScalar& boundingSphere);
const PowerScaledScalar& getBoundingSphere();
void setBoundingSphere(PowerScaledScalar boundingSphere);
PowerScaledScalar getBoundingSphere();
virtual void render(const RenderData& data);
virtual void render(const RenderData& data, RendererTasks& rendererTask);
virtual void postRender(const RenderData& data);
virtual void update(const UpdateData& data);
RenderBin renderBin() const;
void setRenderBin(RenderBin bin);
bool matchesRenderBinMask(int binMask);
bool isVisible() const;
bool hasTimeInterval();
@@ -81,10 +93,13 @@ public:
static void setPscUniforms(ghoul::opengl::ProgramObject& program, const Camera& camera, const PowerScaledCoordinate& position);
static openspace::Documentation Documentation();
protected:
properties::BoolProperty _enabled;
private:
RenderBin _renderBin;
PowerScaledScalar boundingSphere_;
std::string _startTime;
std::string _endTime;

View File

@@ -31,6 +31,9 @@
#include <openspace/properties/stringproperty.h>
#include <openspace/rendering/screenspacerenderable.h>
#include <openspace/util/syncdata.h>
#include <openspace/performance/performancemanager.h>
namespace ghoul {
@@ -49,6 +52,7 @@ namespace openspace {
// Forward declare to minimize dependencies
class Camera;
class SyncBuffer;
class Scene;
class Renderer;
class RaycasterManager;
@@ -94,15 +98,19 @@ public:
// sgct wrapped functions
bool initializeGL();
void postSynchronizationPreDraw();
void preSynchronization();
void updateSceneGraph();
void updateShaderPrograms();
void updateFade();
void updateRenderer();
void updateScreenSpaceRenderables();
void render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix);
void renderScreenLog();
void renderShutdownInformation(float timer, float fullTime);
void postDraw();
void takeScreenshot();
void takeScreenshot(bool applyWarping = false);
void toggleInfoText(bool b);
void toggleFrametimeType(int t);
@@ -111,13 +119,10 @@ public:
bool doesPerformanceMeasurements() const;
performance::PerformanceManager* performanceManager();
void serialize(SyncBuffer* syncBuffer);
void deserialize(SyncBuffer* syncBuffer);
float globalBlackOutFactor();
void setGlobalBlackOutFactor(float factor);
void setNAaSamples(int nAaSamples);
void setShowFrameNumber(bool enabled);
void setDisableRenderingOnMaster(bool enabled);
@@ -184,12 +189,17 @@ public:
void startFading(int direction, float fadeDuration);
void sortScreenspaceRenderables();
// This is temporary until a proper screenspace solution is found ---abock
struct {
struct OnScreenInformation{
glm::vec2 _position;
unsigned int _size;
int _node;
} _onScreenInformation;
};
SyncData<OnScreenInformation> _onScreenInformation;
std::vector<Syncable*> getSyncables();
private:
void setRenderer(std::unique_ptr<Renderer> renderer);
@@ -214,16 +224,20 @@ private:
bool _showInfo;
bool _showLog;
bool _takeScreenshot;
bool _applyWarping;
bool _showFrameNumber;
float _globalBlackOutFactor;
float _fadeDuration;
float _currentFadeTime;
int _fadeDirection;
int _nAaSamples;
unsigned int _frameNumber;
std::vector<ghoul::opengl::ProgramObject*> _programs;
std::vector<std::shared_ptr<ScreenSpaceRenderable>> _screenSpaceRenderables;
std::shared_ptr<ghoul::fontrendering::Font> _fontBig = nullptr;
std::shared_ptr<ghoul::fontrendering::Font> _fontInfo = nullptr;
std::shared_ptr<ghoul::fontrendering::Font> _fontDate = nullptr;
std::shared_ptr<ghoul::fontrendering::Font> _fontLog = nullptr;

View File

@@ -35,6 +35,8 @@
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
#include <openspace/documentation/documentation.h>
namespace openspace {
/**
@@ -63,6 +65,8 @@ public:
glm::vec3 sphericalPosition() const;
float depth() const;
static openspace::Documentation Documentation();
protected:
void createPlane();
void useEuclideanCoordinates(bool b);

View File

@@ -25,24 +25,25 @@
#ifndef __EPHEMERIS_H__
#define __EPHEMERIS_H__
#include <openspace/util/powerscaledcoordinate.h>
#include <ghoul/misc/dictionary.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/documentation/documentation.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/misc/dictionary.h>
namespace openspace {
class Ephemeris {
class Ephemeris : public properties::PropertyOwner {
public:
static Ephemeris* createFromDictionary(const ghoul::Dictionary& dictionary);
Ephemeris(const ghoul::Dictionary& dictionary);
virtual ~Ephemeris();
virtual bool initialize();
virtual const glm::dvec3& position() const = 0;
virtual glm::dvec3 position() const = 0;
virtual void update(const UpdateData& data);
protected:
Ephemeris();
static openspace::Documentation Documentation();
};
} // namespace openspace

View File

@@ -28,6 +28,8 @@
#include <ghoul/misc/dictionary.h>
#include <openspace/util/updatestructures.h>
#include <openspace/documentation/documentation.h>
namespace openspace {
class Rotation {
@@ -40,6 +42,8 @@ public:
virtual const glm::dmat3& matrix() const = 0;
virtual void update(const UpdateData& data);
static openspace::Documentation Documentation();
protected:
Rotation();
};

View File

@@ -25,23 +25,25 @@
#ifndef __SCALE_H__
#define __SCALE_H__
#include <ghoul/misc/dictionary.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/documentation/documentation.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/misc/dictionary.h>
namespace openspace {
class Scale {
class Scale : public properties::PropertyOwner {
public:
static Scale* createFromDictionary(const ghoul::Dictionary& dictionary);
Scale(const ghoul::Dictionary& dictionary);
virtual ~Scale();
virtual bool initialize();
virtual double scaleValue() const = 0;
virtual void update(const UpdateData& data);
protected:
Scale();
static openspace::Documentation Documentation();
};
} // namespace openspace

View File

@@ -31,6 +31,8 @@
#include <set>
#include <mutex>
#include <openspace/documentation/documentation.h>
#include <openspace/util/camera.h>
#include <openspace/util/updatestructures.h>
#include <openspace/scripting/scriptengine.h>
@@ -117,6 +119,8 @@ public:
*/
static scripting::LuaLibrary luaLibrary();
static documentation::Documentation Documentation();
private:
bool loadSceneInternal(const std::string& sceneDescriptionFilePath);

View File

@@ -26,6 +26,8 @@
#define __SCENEGRAPHNODE_H__
// open space includes
#include <openspace/documentation/documentation.h>
#include <openspace/rendering/renderable.h>
#include <openspace/scene/ephemeris.h>
#include <openspace/scene/rotation.h>
@@ -106,6 +108,8 @@ public:
_ephemeris = eph;
}
static documentation::Documentation Documentation();
private:
bool sphereInsideFrustum(const psc& s_pos, const PowerScaledScalar& s_rad, const Camera* camera);

View File

@@ -26,6 +26,7 @@
#define __SCRIPTENGINE_H__
#include <openspace/scripting/lualibrary.h>
#include <openspace/util/syncdata.h>
#include <ghoul/lua/ghoul_lua.h>
@@ -47,7 +48,7 @@ namespace scripting {
* <code>openspace</code> namespac prefix in Lua. The same functions can be exposed to
* other Lua states by passing them to the #initializeLuaState method.
*/
class ScriptEngine {
class ScriptEngine : public Syncable {
public:
using RemoteScripting = ghoul::Boolean;
/**
@@ -70,17 +71,14 @@ public:
bool runScript(const std::string& script);
bool runScriptFile(const std::string& filename);
bool writeDocumentation(const std::string& filename, const std::string& type) const;
void writeDocumentation(const std::string& filename, const std::string& type) const;
bool writeLog(const std::string& script);
void serialize(SyncBuffer* syncBuffer);
void deserialize(SyncBuffer* syncBuffer);
void postSynchronizationPreDraw();
void preSynchronization();
virtual void presync(bool isMaster);
virtual void encode(SyncBuffer* syncBuffer);
virtual void decode(SyncBuffer* syncBuffer);
virtual void postsync(bool isMaster);
void queueScript(const std::string &script, RemoteScripting remoteScripting);

View File

@@ -0,0 +1,136 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __SCRIPTSCHEDULER_H__
#define __SCRIPTSCHEDULER_H__
#include <ghoul/misc/dictionary.h>
#include <openspace/scripting/lualibrary.h>
#include <queue>
#include <vector>
namespace openspace {
namespace scripting {
struct ReversibleLuaScript {
std::string forwardScript;
std::string backwardScript;
};
struct ScheduledScript {
ScheduledScript() : time(-DBL_MAX) { }
ScheduledScript(const ghoul::Dictionary& dict);
double time;
ReversibleLuaScript script;
static bool CompareByTime(const ScheduledScript& s1, const ScheduledScript& s2);
};
/**
* Maintains an ordered list of <code>ScheduledScript</code>s and provides a simple
* interface for retrieveing scheduled scripts
*/
class ScriptScheduler {
public:
/**
* Load a schedule from a Lua-file
* \param filename Lua file to load
* \param L an optional lua_State defining variables that may be used
* in the Lua-file.
*/
void loadScripts(const std::string& filename, lua_State* L = nullptr);
/**
* Load a schedule from a <code>ghoul::Dictionary</code>
* \param dict Dictionary to read
*/
void loadScripts(const ghoul::Dictionary& dict);
/**
* Rewinds the script scheduler to the first scheduled script.
*/
void rewind();
/**
* Removes all scripts for the schedule.
*/
void clearSchedule();
/**
* Progresses the script schedulers time and returns all scripts that has been
* scheduled to run between \param newTime and the time provided in the last invocation
* of this method.
*
* \param newTime A j2000 time value specifying the new time stamp that
* the script scheduler should progress to.
*
* \returns the ordered queue of scripts .
*/
std::queue<std::string> progressTo(double newTime);
/**
* See <code>progressTo(double newTime)</code>.
*
* \param timeStr A string specifying the a new time stamp that the
* scripts scheduler should progress to.
*/
std::queue<std::string> progressTo(const std::string& timeStr);
/**
* Returns the the j2000 time value that the script scheduler is currently at
*/
double currentTime() const;
/**
* \returns a vector of all scripts that has been loaded
*/
const std::vector<ScheduledScript>& allScripts() const;
static LuaLibrary luaLibrary();
private:
std::vector<ScheduledScript> _scheduledScripts;
size_t _currentIndex = 0;
double _currentTime;
};
} // namespace scripting
} // namespace openspace
#endif // __SCRIPTSCHEDULER_H__

View File

@@ -29,9 +29,10 @@
// open space includes
#include <openspace/util/powerscaledcoordinate.h>
#include <openspace/util/syncbuffer.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/syncdata.h>
// glm includes
#include <ghoul/glm.h>
#include <glm/gtc/matrix_transform.hpp>
@@ -118,12 +119,8 @@ namespace openspace {
// of the old calls to the function wrong..
const Mat4& combinedViewMatrix() const;
// Synchronization
void postSynchronizationPreDraw();
void preSynchronization();
void serialize(SyncBuffer* syncBuffer);
void deserialize(SyncBuffer* syncBuffer);
void invalidateCache();
void serialize(std::ostream& os) const;
void deserialize(std::istream& is);
@@ -177,32 +174,17 @@ namespace openspace {
[[deprecated("Replaced by Camera::SgctInternal::viewProjectionMatrix()")]]
const glm::mat4& viewProjectionMatrix() const;
std::vector<Syncable*> getSyncables();
private:
/**
Class encapsulating data that needs to be synched between SGCT nodes.
Are all three variables (i.e. local, shared, synced) really neccessary? /EB
*/
template <typename T>
struct SyncData {
SyncData() {}
SyncData(const SyncData& d)
: local(d.local), shared(d.shared), synced(d.synced) {}
void serialize(SyncBuffer* syncBuffer) { syncBuffer->encode(shared); }
void deserialize(SyncBuffer* syncBuffer) { syncBuffer->decode(shared); }
void postSynchronizationPreDraw() { synced = shared; }
void preSynchronization() { shared = local; }
T local;
T shared;
T synced;
};
// State of the camera
SyncData<Vec3> _position;
SyncData<Quat> _rotation;
SyncData<glm::vec2> _scaling;
// _focusPosition to be removed
Vec3 _focusPosition;
float _maxFov;

View File

@@ -86,9 +86,11 @@ public:
/**
* Adds the passed \p factory to the FactoryManager. Factories may only be added once.
* \param factory The ghoul::TemplateFactory to add to this FactoryManager
* \param name A user-readable name for the registered factory.
* \pre \p factory must not be nullptr
*/
void addFactory(std::unique_ptr<ghoul::TemplateFactoryBase> factory);
void addFactory(std::unique_ptr<ghoul::TemplateFactoryBase> factory,
std::string name = "");
/**
* This method provides access to all registered ghoul::TemplateFactory%s through
@@ -102,11 +104,25 @@ public:
template <class T>
ghoul::TemplateFactory<T>* factory() const;
/**
* Writes a documentation for the FactoryMananger that contains all of the registered
* factories and for each factory all registered class names.
* \param file The file to which the documentation will be written
* \param type The type of documentation that will be written
* \pre \p file must not be empty
* \pre \p type must not be empty
*/
void writeDocumentation(const std::string& file, const std::string& type);
private:
/// Singleton member for the Factory Manager
static FactoryManager* _manager;
std::vector<std::unique_ptr<ghoul::TemplateFactoryBase>> _factories;
struct FactoryInfo {
std::unique_ptr<ghoul::TemplateFactoryBase> factory;
std::string name;
};
std::vector<FactoryInfo> _factories;
};
} // namespace openspace

View File

@@ -27,8 +27,8 @@ namespace openspace {
template <class T>
ghoul::TemplateFactory<T>* FactoryManager::factory() const {
for (auto& factory : _factories) {
if (factory->baseClassType() == typeid(T))
return dynamic_cast<ghoul::TemplateFactory<T>*>(factory.get());
if (factory.factory->baseClassType() == typeid(T))
return dynamic_cast<ghoul::TemplateFactory<T>*>(factory.factory.get());
}
throw FactoryNotFoundError(typeid(T).name());

View File

@@ -27,6 +27,8 @@
#include <openspace/properties/propertyowner.h>
#include <openspace/documentation/documentation.h>
#include <string>
#include <vector>
@@ -64,6 +66,8 @@ public:
*/
void deinitialize();
virtual std::vector<Documentation> documentations() const;
protected:
/**
* Customization point for each derived class. The internalInitialize method is called

View File

@@ -0,0 +1,134 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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 __SYNC_DATA_H__
#define __SYNC_DATA_H__
#include <memory>
#include <mutex>
#include <ghoul/misc/assert.h>
#include <openspace/util/syncbuffer.h>
namespace openspace {
/**
* Interface for synchronizable data
*
* Used by <code>SyncEngine</code>
*/
class Syncable {
public:
virtual ~Syncable() {};
protected:
// Allowing SyncEngine synchronization methods and at the same time hiding them
// from the used of implementations of the interface
friend class SyncEngine;
virtual void presync(bool isMaster) {};
virtual void encode(SyncBuffer* syncBuffer) = 0;
virtual void decode(SyncBuffer* syncBuffer) = 0;
virtual void postsync(bool isMaster) {};
};
/**
* A double buffered implementation of the Syncable interface.
* Users are encouraged to used this class as a default way to synchronize different
* C++ data types using the <code>SyncEngine</code>
*
* This class aims to handle the synchronization parts and yet act like a regular
* instance of T. Implicit casts are supported, however, when accessing member functions or
* or variables, user may have to do explicit casts.
*
* ((T&) t).method();
*
*/
template<class T>
class SyncData : public Syncable {
public:
SyncData() {};
SyncData(const T& val) : data(val) {};
SyncData(const SyncData<T>& o) : data(o.data) {
// Should not have to be copied!
};
/**
* Allowing assignment of data as if
*/
SyncData& operator=(const T& rhs) {
data = rhs;
return *this;
}
/**
* Allow implicit cast to referenced T
*/
operator T&() {
return data;
}
/**
* Allow implicit cast to const referenced T
*/
operator const T&() const {
return data;
}
protected:
virtual void encode(SyncBuffer* syncBuffer) {
_mutex.lock();
syncBuffer->encode(data);
_mutex.unlock();
}
virtual void decode(SyncBuffer* syncBuffer) {
_mutex.lock();
syncBuffer->decode(doubleBufferedData);
_mutex.unlock();
}
virtual void postsync(bool isMaster) {
// apply synced update
if (!isMaster) {
_mutex.lock();
data = doubleBufferedData;
_mutex.unlock();
}
};
T data;
T doubleBufferedData;
std::mutex _mutex;
};
} // namespace openspace
#endif //#ifndef __SYNC_DATA_H__

View File

@@ -26,6 +26,7 @@
#define __TIME_H__
#include <openspace/scripting/scriptengine.h>
#include <openspace/util/syncdata.h>
#include <mutex>
#include <string>
@@ -40,7 +41,7 @@ namespace openspace {
* a valid date string in accordance to the Spice library
* (http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html). The time can
* be retrieved as the number of seconds since the J2000 epoch with currentTime() or as a
* UTC string following ISO 8601 with the method currentTimeUTC().
* UTC string following ISO 8601 with the method UTC().
*
* In addition to the time itself, it also stores a delta time value. This value denotes
* the number of seconds that pass for each real-time second. This value is set with
@@ -102,7 +103,7 @@ public:
* time-jump; defaults to true as most calls to set time will require recomputation of
* planetary paths etc.
*/
void setTime(double value, bool requireJump = true);
void setTime(double j2000Seconds, bool requireJump = true);
/**
* Sets the current time to the specified value given as a Spice compliant string as
@@ -120,16 +121,14 @@ public:
* current time is a date before that epoch, the returned value will be negative.
* \return The current time as the number of seconds past the J2000 epoch
*/
double currentTime() const;
double unsyncedJ2000Seconds() const;
double j2000Seconds() const;
/**
* Returns the current time as a formatted date string compliant with ISO 8601 and
* thus also compliant with the Spice library.
* \return The current time as a formatted date string
*/
std::string currentTimeUTC() const;
std::string UTC() const;
/**
* Returns the current time as a ISO 8601 formatted, i.e YYYY-MM-DDThh:mm:ssZ
@@ -182,14 +181,6 @@ public:
*/
double advanceTime(double tickTime);
void serialize(SyncBuffer* syncBuffer);
void deserialize(SyncBuffer* syncBuffer);
void postSynchronizationPreDraw();
void preSynchronization();
bool timeJumped() const;
void setTimeJumped(bool jumped);
@@ -209,28 +200,16 @@ public:
*/
static scripting::LuaLibrary luaLibrary();
std::vector<Syncable*> getSyncables();
private:
static Time* _instance; ///< The singleton instance
//local copies
/// The time stored as the number of seconds past the J2000 epoch
double _time = -1.0;
double _dt = 1.0;
bool _timeJumped = false;
bool _timePaused = false;
bool _jockeHasToFixThisLater;
//shared copies
double _sharedTime = -1.0;
double _sharedDt = 1.0;
bool _sharedTimeJumped = false;
SyncData<double> _time;
SyncData<double> _dt;
SyncData<bool> _timeJumped;
//synced copies
double _syncedTime = -1.0;
double _syncedDt = 1.0;
bool _syncedTimeJumped = false;
std::mutex _syncMutex;
bool _timePaused = false;
};
} // namespace openspace

View File

@@ -50,12 +50,14 @@ struct UpdateData {
bool doPerformanceMeasurement;
};
struct RenderData {
const Camera& camera;
// psc position to be removed in favor of the double precision position defined in
// the translation in transform.
psc position;
bool doPerformanceMeasurement;
int renderBinMask;
TransformData modelTransform;
};