Browse Source

Trade: reworked AbstractImporter plugin interface.

Implementation is moved into private virtual `do*()` functions and the
public interface does additional checks aroung them to simplify plugin
development. Opening files is by default done by the base
implementation, which then calls function for opening raw data with file
contents.

Added test for file opening, bumped plugin interface version to 0.3.
Y# Please enter the commit message for your changes. Lines starting
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
80fc4611de
  1. 461
      src/Trade/AbstractImporter.cpp
  2. 324
      src/Trade/AbstractImporter.h
  3. 69
      src/Trade/Test/AbstractImporterTest.cpp
  4. 6
      src/Trade/Test/CMakeLists.txt
  5. 1
      src/Trade/Test/file.bin
  6. 25
      src/Trade/Test/testConfigure.h.cmake

461
src/Trade/AbstractImporter.cpp

@ -24,6 +24,8 @@
#include "AbstractImporter.h"
#include <fstream>
#include <Containers/Array.h>
#include <Utility/Assert.h>
namespace Magnum { namespace Trade {
@ -32,55 +34,416 @@ AbstractImporter::AbstractImporter() = default;
AbstractImporter::AbstractImporter(PluginManager::AbstractManager* manager, std::string plugin): AbstractPlugin(manager, std::move(plugin)) {}
bool AbstractImporter::openData(const void* const, const std::size_t) {
bool AbstractImporter::openData(Containers::ArrayReference<const unsigned char> data) {
CORRADE_ASSERT(features() & Feature::OpenData,
"Trade::AbstractImporter::openData(): feature advertised but not implemented", nullptr);
CORRADE_ASSERT(false, "Trade::AbstractImporter::openData(): feature not implemented", nullptr);
}
bool AbstractImporter::openFile(const std::string&) {
CORRADE_ASSERT(features() & Feature::OpenFile,
"Trade::AbstractImporter::openFile(): feature advertised but not implemented", nullptr);
CORRADE_ASSERT(false, "Trade::AbstractImporter::openFile(): feature not implemented", nullptr);
}
Int AbstractImporter::sceneForName(const std::string&) { return -1; }
std::string AbstractImporter::sceneName(UnsignedInt) { return {}; }
SceneData* AbstractImporter::scene(UnsignedInt) { return nullptr; }
Int AbstractImporter::lightForName(const std::string&) { return -1; }
std::string AbstractImporter::lightName(UnsignedInt) { return {}; }
LightData* AbstractImporter::light(UnsignedInt) { return nullptr; }
Int AbstractImporter::cameraForName(const std::string&) { return -1; }
std::string AbstractImporter::cameraName(UnsignedInt) { return {}; }
CameraData* AbstractImporter::camera(UnsignedInt) { return nullptr; }
Int AbstractImporter::object2DForName(const std::string&) { return -1; }
std::string AbstractImporter::object2DName(UnsignedInt) { return {}; }
ObjectData2D* AbstractImporter::object2D(UnsignedInt) { return nullptr; }
Int AbstractImporter::object3DForName(const std::string&) { return -1; }
std::string AbstractImporter::object3DName(UnsignedInt) { return {}; }
ObjectData3D* AbstractImporter::object3D(UnsignedInt) { return nullptr; }
Int AbstractImporter::mesh2DForName(const std::string&) { return -1; }
std::string AbstractImporter::mesh2DName(UnsignedInt) { return {}; }
MeshData2D* AbstractImporter::mesh2D(UnsignedInt) { return nullptr; }
Int AbstractImporter::mesh3DForName(const std::string&) { return -1; }
std::string AbstractImporter::mesh3DName(UnsignedInt) { return {}; }
MeshData3D* AbstractImporter::mesh3D(UnsignedInt) { return nullptr; }
Int AbstractImporter::materialForName(const std::string&) { return -1; }
std::string AbstractImporter::materialName(UnsignedInt) { return {}; }
AbstractMaterialData* AbstractImporter::material(UnsignedInt) { return nullptr; }
Int AbstractImporter::textureForName(const std::string&) { return -1; }
std::string AbstractImporter::textureName(UnsignedInt) { return {}; }
TextureData* AbstractImporter::texture(UnsignedInt) { return nullptr; }
Int AbstractImporter::image1DForName(const std::string&) { return -1; }
std::string AbstractImporter::image1DName(UnsignedInt) { return {}; }
ImageData1D* AbstractImporter::image1D(UnsignedInt) { return nullptr; }
Int AbstractImporter::image2DForName(const std::string&) { return -1; }
std::string AbstractImporter::image2DName(UnsignedInt) { return {}; }
ImageData2D* AbstractImporter::image2D(UnsignedInt) { return nullptr; }
Int AbstractImporter::image3DForName(const std::string&) { return -1; }
std::string AbstractImporter::image3DName(UnsignedInt) { return {}; }
ImageData3D* AbstractImporter::image3D(UnsignedInt) { return nullptr; }
"Trade::AbstractImporter::openData(): feature not supported", nullptr);
close();
doOpenData(data);
return isOpened();
}
void AbstractImporter::doOpenData(Containers::ArrayReference<const unsigned char>) {
CORRADE_ASSERT(false, "Trade::AbstractImporter::openData(): feature advertised but not implemented", );
}
bool AbstractImporter::openFile(const std::string& filename) {
close();
doOpenFile(filename);
return isOpened();
}
void AbstractImporter::doOpenFile(const std::string& filename) {
CORRADE_ASSERT(features() & Feature::OpenData, "Trade::AbstractImporter::openFile(): not implemented", );
/* Open file */
std::ifstream in(filename.data(), std::ios::binary);
if(!in.good()) {
Error() << "Trade::AbstractImporter::openFile(): cannot open file" << filename;
return;
}
/* Create array to hold file contents */
in.seekg(0, std::ios::end);
Containers::Array<unsigned char> data(in.tellg());
/* Read data, close */
in.seekg(0, std::ios::beg);
in.read(reinterpret_cast<char*>(data.begin()), data.size());
in.close();
doOpenData(data);
}
void AbstractImporter::close() {
if(isOpened()) doClose();
}
Int AbstractImporter::defaultScene() {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::defaultScene(): no file opened", -1);
return doDefaultScene();
}
Int AbstractImporter::doDefaultScene() { return -1; }
UnsignedInt AbstractImporter::sceneCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::sceneCount(): no file opened", 0);
return doSceneCount();
}
UnsignedInt AbstractImporter::doSceneCount() const { return 0; }
Int AbstractImporter::sceneForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::sceneForName(): no file opened", -1);
return doSceneForName(name);
}
Int AbstractImporter::doSceneForName(const std::string&) { return -1; }
std::string AbstractImporter::sceneName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::sceneName(): no file opened", {});
CORRADE_ASSERT(id < doSceneCount(), "Trade::AbstractImporter::sceneName(): index out of range", {});
return doSceneName(id);
}
std::string AbstractImporter::doSceneName(UnsignedInt) { return {}; }
SceneData* AbstractImporter::scene(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::scene(): no file opened", {});
CORRADE_ASSERT(id < doSceneCount(), "Trade::AbstractImporter::scene(): index out of range", {});
return doScene(id);
}
SceneData* AbstractImporter::doScene(UnsignedInt) { return nullptr; }
UnsignedInt AbstractImporter::lightCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::lightCount(): no file opened", {});
return doLightCount();
}
UnsignedInt AbstractImporter::doLightCount() const { return 0; }
Int AbstractImporter::lightForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::lightForName(): no file opened", {});
return doLightForName(name);
}
Int AbstractImporter::doLightForName(const std::string&) { return -1; }
std::string AbstractImporter::lightName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::lightName(): no file opened", {});
CORRADE_ASSERT(id < doLightCount(), "Trade::AbstractImporter::lightName(): index out of range", {});
return doLightName(id);
}
std::string AbstractImporter::doLightName(UnsignedInt) { return {}; }
LightData* AbstractImporter::light(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::light(): no file opened", {});
CORRADE_ASSERT(id < doLightCount(), "Trade::AbstractImporter::light(): index out of range", {});
return doLight(id);
}
LightData* AbstractImporter::doLight(UnsignedInt) { return nullptr; }
UnsignedInt AbstractImporter::cameraCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::cameraCount(): no file opened", {});
return doCameraCount();
}
UnsignedInt AbstractImporter::doCameraCount() const { return 0; }
Int AbstractImporter::cameraForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::cameraForName(): no file opened", {});
return doCameraForName(name);
}
Int AbstractImporter::doCameraForName(const std::string&) { return -1; }
std::string AbstractImporter::cameraName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::cameraName(): no file opened", {});
CORRADE_ASSERT(id < doCameraCount(), "Trade::AbstractImporter::cameraName(): index out of range", {});
return doCameraName(id);
}
std::string AbstractImporter::doCameraName(UnsignedInt) { return {}; }
CameraData* AbstractImporter::camera(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::camera(): no file opened", {});
CORRADE_ASSERT(id < doCameraCount(), "Trade::AbstractImporter::camera(): index out of range", {});
return doCamera(id);
}
CameraData* AbstractImporter::doCamera(UnsignedInt) { return nullptr; }
UnsignedInt AbstractImporter::object2DCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::object2DCount(): no file opened", {});
return doObject2DCount();
}
UnsignedInt AbstractImporter::doObject2DCount() const { return 0; }
Int AbstractImporter::object2DForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::object2DForName(): no file opened", {});
return doObject2DForName(name);
}
Int AbstractImporter::doObject2DForName(const std::string&) { return -1; }
std::string AbstractImporter::object2DName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::object2DName(): no file opened", {});
CORRADE_ASSERT(id < doObject2DCount(), "Trade::AbstractImporter::object2DName(): index out of range", {});
return doObject2DName(id);
}
std::string AbstractImporter::doObject2DName(UnsignedInt) { return {}; }
ObjectData2D* AbstractImporter::object2D(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::object2D(): no file opened", {});
CORRADE_ASSERT(id < doObject2DCount(), "Trade::AbstractImporter::object2D(): index out of range", {});
return doObject2D(id);
}
ObjectData2D* AbstractImporter::doObject2D(UnsignedInt) { return nullptr; }
UnsignedInt AbstractImporter::object3DCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::object3DCount(): no file opened", {});
return doObject3DCount();
}
UnsignedInt AbstractImporter::doObject3DCount() const { return 0; }
Int AbstractImporter::object3DForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::object3DForName(): no file opened", {});
return doObject3DForName(name);
}
Int AbstractImporter::doObject3DForName(const std::string&) { return -1; }
std::string AbstractImporter::object3DName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::object3DName(): no file opened", {});
CORRADE_ASSERT(id < doObject3DCount(), "Trade::AbstractImporter::object3DName(): index out of range", {});
return doObject3DName(id);
}
std::string AbstractImporter::doObject3DName(UnsignedInt) { return {}; }
ObjectData3D* AbstractImporter::object3D(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::object3D(): no file opened", {});
CORRADE_ASSERT(id < doObject3DCount(), "Trade::AbstractImporter::object3D(): index out of range", {});
return doObject3D(id);
}
ObjectData3D* AbstractImporter::doObject3D(UnsignedInt) { return nullptr; }
UnsignedInt AbstractImporter::mesh2DCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::mesh2DCount(): no file opened", {});
return doMesh2DCount();
}
UnsignedInt AbstractImporter::doMesh2DCount() const { return 0; }
Int AbstractImporter::mesh2DForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::mesh2DForName(): no file opened", {});
return doMesh2DForName(name);
}
Int AbstractImporter::doMesh2DForName(const std::string&) { return -1; }
std::string AbstractImporter::mesh2DName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::mesh2DName(): no file opened", {});
CORRADE_ASSERT(id < doMesh2DCount(), "Trade::AbstractImporter::object2DName(): index out of range", {});
return doMesh2DName(id);
}
std::string AbstractImporter::doMesh2DName(UnsignedInt) { return {}; }
MeshData2D* AbstractImporter::mesh2D(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::mesh2D(): no file opened", {});
CORRADE_ASSERT(id < doMesh2DCount(), "Trade::AbstractImporter::object2D(): index out of range", {});
return doMesh2D(id);
}
MeshData2D* AbstractImporter::doMesh2D(UnsignedInt) { return nullptr; }
UnsignedInt AbstractImporter::mesh3DCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::mesh3DCount(): no file opened", {});
return doMesh3DCount();
}
UnsignedInt AbstractImporter::doMesh3DCount() const { return 0; }
Int AbstractImporter::mesh3DForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::mesh3DForName(): no file opened", {});
return doMesh3DForName(name);
}
Int AbstractImporter::doMesh3DForName(const std::string&) { return -1; }
std::string AbstractImporter::mesh3DName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::mesh3DName(): no file opened", {});
CORRADE_ASSERT(id < doMesh3DCount(), "Trade::AbstractImporter::object3DName(): index out of range", {});
return doMesh3DName(id);
}
std::string AbstractImporter::doMesh3DName(UnsignedInt) { return {}; }
MeshData3D* AbstractImporter::mesh3D(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::mesh3D(): no file opened", {});
CORRADE_ASSERT(id < doMesh3DCount(), "Trade::AbstractImporter::mesh3D(): index out of range", {});
return doMesh3D(id);
}
MeshData3D* AbstractImporter::doMesh3D(UnsignedInt) { return nullptr; }
UnsignedInt AbstractImporter::materialCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::materialCount(): no file opened", {});
return doMaterialCount();
}
UnsignedInt AbstractImporter::doMaterialCount() const { return 0; }
Int AbstractImporter::materialForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::materialForName(): no file opened", {});
return doMaterialForName(name);
}
Int AbstractImporter::doMaterialForName(const std::string&) { return -1; }
std::string AbstractImporter::materialName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::materialName(): no file opened", {});
CORRADE_ASSERT(id < doMaterialCount(), "Trade::AbstractImporter::materialName(): index out of range", {});
return doMaterialName(id);
}
std::string AbstractImporter::doMaterialName(UnsignedInt) { return {}; }
AbstractMaterialData* AbstractImporter::material(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::material(): no file opened", {});
CORRADE_ASSERT(id < doMaterialCount(), "Trade::AbstractImporter::material(): index out of range", {});
return doMaterial(id);
}
AbstractMaterialData* AbstractImporter::doMaterial(UnsignedInt) { return nullptr; }
UnsignedInt AbstractImporter::textureCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::textureCount(): no file opened", {});
return doTextureCount();
}
UnsignedInt AbstractImporter::doTextureCount() const { return 0; }
Int AbstractImporter::textureForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::textureForName(): no file opened", {});
return doTextureForName(name);
}
Int AbstractImporter::doTextureForName(const std::string&) { return -1; }
std::string AbstractImporter::textureName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::textureName(): no file opened", {});
CORRADE_ASSERT(id < doTextureCount(), "Trade::AbstractImporter::textureName(): index out of range", {});
return doTextureName(id);
}
std::string AbstractImporter::doTextureName(UnsignedInt) { return {}; }
TextureData* AbstractImporter::texture(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::texture(): no file opened", {});
CORRADE_ASSERT(id < doTextureCount(), "Trade::AbstractImporter::texture(): index out of range", {});
return doTexture(id);
}
TextureData* AbstractImporter::doTexture(UnsignedInt) { return nullptr; }
UnsignedInt AbstractImporter::image1DCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image1DCount(): no file opened", {});
return doImage1DCount();
}
UnsignedInt AbstractImporter::doImage1DCount() const { return 0; }
Int AbstractImporter::image1DForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image1DForName(): no file opened", {});
return doImage1DForName(name);
}
Int AbstractImporter::doImage1DForName(const std::string&) { return -1; }
std::string AbstractImporter::image1DName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image1DName(): no file opened", {});
CORRADE_ASSERT(id < doImage1DCount(), "Trade::AbstractImporter::image1DName(): index out of range", {});
return doImage1DName(id);
}
std::string AbstractImporter::doImage1DName(UnsignedInt) { return {}; }
ImageData1D* AbstractImporter::image1D(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image1D(): no file opened", {});
CORRADE_ASSERT(id < doImage1DCount(), "Trade::AbstractImporter::image1D(): index out of range", {});
return doImage1D(id);
}
ImageData1D* AbstractImporter::doImage1D(UnsignedInt) { return nullptr; }
UnsignedInt AbstractImporter::image2DCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image2DCount(): no file opened", {});
return doImage2DCount();
}
UnsignedInt AbstractImporter::doImage2DCount() const { return 0; }
Int AbstractImporter::image2DForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image1DForName(): no file opened", {});
return doImage2DForName(name);
}
Int AbstractImporter::doImage2DForName(const std::string&) { return -1; }
std::string AbstractImporter::image2DName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image2DName(): no file opened", {});
CORRADE_ASSERT(id < doImage2DCount(), "Trade::AbstractImporter::image2DName(): index out of range", {});
return doImage2DName(id);
}
std::string AbstractImporter::doImage2DName(UnsignedInt) { return {}; }
ImageData2D* AbstractImporter::image2D(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image2D(): no file opened", {});
CORRADE_ASSERT(id < doImage2DCount(), "Trade::AbstractImporter::image2D(): index out of range", {});
return doImage2D(id);
}
ImageData2D* AbstractImporter::doImage2D(UnsignedInt) { return nullptr; }
UnsignedInt AbstractImporter::image3DCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image3DCount(): no file opened", {});
return doImage3DCount();
}
UnsignedInt AbstractImporter::doImage3DCount() const { return 0; }
Int AbstractImporter::image3DForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image3DForName(): no file opened", {});
return doImage3DForName(name);
}
Int AbstractImporter::doImage3DForName(const std::string&) { return -1; }
std::string AbstractImporter::image3DName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image3DName(): no file opened", {});
CORRADE_ASSERT(id < image3DCount(), "Trade::AbstractImporter::image3DName(): index out of range", {});
return doImage3DName(id);
}
std::string AbstractImporter::doImage3DName(UnsignedInt) { return {}; }
ImageData3D* AbstractImporter::image3D(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image3D(): no file opened", {});
CORRADE_ASSERT(id < doImage3DCount(), "Trade::AbstractImporter::image3D(): index out of range", {});
return doImage3D(id);
}
ImageData3D* AbstractImporter::doImage3D(UnsignedInt) { return nullptr; }
}}

324
src/Trade/AbstractImporter.h

@ -44,17 +44,31 @@ Importer is used for importing data like scenes, lights, objects, images,
textures etc.
@section AbstractImporter-subclassing Subclassing
Plugin implements function features(), one or more open() functions,
function close() and one or more pairs of data access functions, based on
which features are supported in given format.
Plugin implements function doFeatures(), doIsOpened(), one of or both
doOpenData() and doOpenFile() functions, function doClose() and one or more
tuples of data access functions, based on which features are supported in given
format.
For multi-data formats file opening shouldn't take long, all parsing should
be done in data parsing functions, because the user might want to import only
some data. This is obviously not the case for single-data formats like images,
as the file contains all data user wants to import.
You don't need to do most of the redundant sanity checks, these things are
checked by the implementation:
- Functions doOpenData() and doOpenFile() are called after the previous file
was closed, function doClose() is called only if there is any file opened.
- Function doOpenData() is called only if @ref Feature "Feature::OpenData"
is supported.
- All `do*()` implementations working on opened file are called only if
there is any file opened.
- All `do*()` implementations taking data ID as parameter are called only if
the ID is from valid range.
*/
class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
CORRADE_PLUGIN_INTERFACE("cz.mosra.magnum.Trade.AbstractImporter/0.2.1")
CORRADE_PLUGIN_INTERFACE("cz.mosra.magnum.Trade.AbstractImporter/0.3")
public:
/**
@ -63,8 +77,8 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* @see Features, features()
*/
enum class Feature: UnsignedByte {
OpenData = 1 << 0, /**< Opening files from raw data */
OpenFile = 1 << 1 /**< Opening files specified by filename */
/** Opening files from raw data using openData() */
OpenData = 1 << 0
};
/** @brief Set of features supported by this importer */
@ -77,7 +91,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
explicit AbstractImporter(PluginManager::AbstractManager* manager, std::string plugin);
/** @brief Features supported by this importer */
virtual Features features() const = 0;
Features features() const { return doFeatures(); }
/** @brief Whether any file is opened */
bool isOpened() const { return doIsOpened(); }
/**
* @brief Open raw data
@ -89,35 +106,23 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* supported. Returns `true` on success, `false` otherwise.
* @see features(), openFile()
*/
virtual bool openData(const void* const data, const std::size_t size);
/**
* @brief Open raw data
* @param data Data
*
* Convenience alternative to above function useful when array size is
* known at compile-time.
*/
template<std::size_t size, class T> bool openData(const T(&data)[size]) {
return openData(data, size*sizeof(T));
}
bool openData(Containers::ArrayReference<const unsigned char> data);
/**
* @brief Open file
* @param filename Filename
*
* Closes previous file, if it was opened, and tries to open given
* file. Available only if @ref Feature "Feature::OpenFile" is
* supported. Returns `true` on success, `false` otherwise.
* file. Returns `true` on success, `false` otherwise.
* @see features(), openData()
*/
virtual bool openFile(const std::string& filename);
bool openFile(const std::string& filename);
/** @brief Close file */
virtual void close() = 0;
void close();
/** @{ @name Data accessors
* Each function pair provides access to the data.
* Each function tuple provides access to given data.
*/
/**
@ -129,10 +134,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* @note The function is not const, because the value will probably
* be lazy-populated.
*/
virtual Int defaultScene() { return -1; }
Int defaultScene();
/** @brief %Scene count */
virtual UnsignedInt sceneCount() const { return 0; }
UnsignedInt sceneCount() const;
/**
* @brief %Scene ID for given name
@ -140,7 +145,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no scene for given name exists, returns `-1`.
* @see sceneName()
*/
virtual Int sceneForName(const std::string& name);
Int sceneForName(const std::string& name);
/**
* @brief %Scene name
@ -148,7 +153,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see sceneForName()
*/
virtual std::string sceneName(UnsignedInt id);
std::string sceneName(UnsignedInt id);
/**
* @brief %Scene
@ -157,10 +162,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given scene or `nullptr` if import failed. Deleting the data
* is user responsibility.
*/
virtual SceneData* scene(UnsignedInt id);
SceneData* scene(UnsignedInt id);
/** @brief %Light count */
virtual UnsignedInt lightCount() const { return 0; }
UnsignedInt lightCount() const;
/**
* @brief %Light ID for given name
@ -168,7 +173,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no light for given name exists, returns `-1`.
* @see lightName()
*/
virtual Int lightForName(const std::string& name);
Int lightForName(const std::string& name);
/**
* @brief %Light name
@ -176,7 +181,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see lightForName()
*/
virtual std::string lightName(UnsignedInt id);
std::string lightName(UnsignedInt id);
/**
* @brief %Light
@ -185,10 +190,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given light or `nullptr` if importing failed. Deleting the
* data is user responsibility.
*/
virtual LightData* light(UnsignedInt id);
LightData* light(UnsignedInt id);
/** @brief Camera count */
virtual UnsignedInt cameraCount() const { return 0; }
UnsignedInt cameraCount() const;
/**
* @brief Camera ID for given name
@ -196,7 +201,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no camera for given name exists, returns `-1`.
* @see cameraName()
*/
virtual Int cameraForName(const std::string& name);
Int cameraForName(const std::string& name);
/**
* @brief Camera name
@ -204,7 +209,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see cameraForName()
*/
virtual std::string cameraName(UnsignedInt id);
std::string cameraName(UnsignedInt id);
/**
* @brief Camera
@ -213,10 +218,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given camera or `nullptr` if importing failed. Deleting the
* data is user responsibility.
*/
virtual CameraData* camera(UnsignedInt id);
CameraData* camera(UnsignedInt id);
/** @brief Two-dimensional object count */
virtual UnsignedInt object2DCount() const { return 0; }
UnsignedInt object2DCount() const;
/**
* @brief Two-dimensional object ID for given name
@ -224,7 +229,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no scene for given name exists, returns `-1`.
* @see object2DName()
*/
virtual Int object2DForName(const std::string& name);
Int object2DForName(const std::string& name);
/**
* @brief Two-dimensional object name
@ -232,7 +237,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see object2DForName()
*/
virtual std::string object2DName(UnsignedInt id);
std::string object2DName(UnsignedInt id);
/**
* @brief Two-dimensional object
@ -241,10 +246,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given object or `nullptr` if importing failed. Deleting the
* data is user responsibility.
*/
virtual ObjectData2D* object2D(UnsignedInt id);
ObjectData2D* object2D(UnsignedInt id);
/** @brief Three-dimensional object count */
virtual UnsignedInt object3DCount() const { return 0; }
UnsignedInt object3DCount() const;
/**
* @brief Three-dimensional object ID for given name
@ -252,7 +257,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no scene for given name exists, returns `-1`.
* @see object3DName()
*/
virtual Int object3DForName(const std::string& name);
Int object3DForName(const std::string& name);
/**
* @brief Three-dimensional object name
@ -260,7 +265,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see object3DForName()
*/
virtual std::string object3DName(UnsignedInt id);
std::string object3DName(UnsignedInt id);
/**
* @brief Three-dimensional object
@ -269,10 +274,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given object or `nullptr` if importing failed. Deleting the
* data is user responsibility.
*/
virtual ObjectData3D* object3D(UnsignedInt id);
ObjectData3D* object3D(UnsignedInt id);
/** @brief Two-dimensional mesh count */
virtual UnsignedInt mesh2DCount() const { return 0; }
UnsignedInt mesh2DCount() const;
/**
* @brief Two-dimensional mesh ID for given name
@ -280,7 +285,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no mesh for given name exists, returns `-1`.
* @see mesh2DName()
*/
virtual Int mesh2DForName(const std::string& name);
Int mesh2DForName(const std::string& name);
/**
* @brief Two-dimensional mesh name
@ -288,7 +293,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see mesh2DForName()
*/
virtual std::string mesh2DName(UnsignedInt id);
std::string mesh2DName(UnsignedInt id);
/**
* @brief Two-dimensional mesh
@ -297,10 +302,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given mesh or `nullptr` if importing failed. Deleting the
* data is user responsibility.
*/
virtual MeshData2D* mesh2D(UnsignedInt id);
MeshData2D* mesh2D(UnsignedInt id);
/** @brief Three-dimensional mesh count */
virtual UnsignedInt mesh3DCount() const { return 0; }
UnsignedInt mesh3DCount() const;
/**
* @brief Three-dimensional mesh ID for given name
@ -308,7 +313,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no mesh for given name exists, returns `-1`.
* @see mesh3DName()
*/
virtual Int mesh3DForName(const std::string& name);
Int mesh3DForName(const std::string& name);
/**
* @brief Three-dimensional mesh name
@ -316,7 +321,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see mesh3DForName()
*/
virtual std::string mesh3DName(UnsignedInt id);
std::string mesh3DName(UnsignedInt id);
/**
* @brief Three-dimensional mesh
@ -325,10 +330,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given mesh or `nullptr` if importing failed. Deleting the
* data is user responsibility.
*/
virtual MeshData3D* mesh3D(UnsignedInt id);
MeshData3D* mesh3D(UnsignedInt id);
/** @brief Material count */
virtual UnsignedInt materialCount() const { return 0; }
UnsignedInt materialCount() const;
/**
* @brief Material ID for given name
@ -336,7 +341,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no material for given name exists, returns `-1`.
* @see materialName()
*/
virtual Int materialForName(const std::string& name);
Int materialForName(const std::string& name);
/**
* @brief Material name
@ -344,7 +349,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see materialForName()
*/
virtual std::string materialName(UnsignedInt id);
std::string materialName(UnsignedInt id);
/**
* @brief Material
@ -353,10 +358,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given material or `nullptr` if importing failed. Deleting
* the data is user responsibility.
*/
virtual AbstractMaterialData* material(UnsignedInt id);
AbstractMaterialData* material(UnsignedInt id);
/** @brief %Texture count */
virtual UnsignedInt textureCount() const { return 0; }
UnsignedInt textureCount() const;
/**
* @brief %Texture ID for given name
@ -364,7 +369,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no texture for given name exists, returns `-1`.
* @see textureName()
*/
virtual Int textureForName(const std::string& name);
Int textureForName(const std::string& name);
/**
* @brief %Texture name
@ -372,7 +377,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see textureForName()
*/
virtual std::string textureName(UnsignedInt id);
std::string textureName(UnsignedInt id);
/**
* @brief %Texture
@ -381,10 +386,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given texture or `nullptr` if importing failed. Deleting the
* data is user responsibility.
*/
virtual TextureData* texture(UnsignedInt id);
TextureData* texture(UnsignedInt id);
/** @brief One-dimensional image count */
virtual UnsignedInt image1DCount() const { return 0; }
UnsignedInt image1DCount() const;
/**
* @brief One-dimensional image ID for given name
@ -392,7 +397,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no image for given name exists, returns `-1`.
* @see image1Dname()
*/
virtual Int image1DForName(const std::string& name);
Int image1DForName(const std::string& name);
/**
* @brief One-dimensional image name
@ -400,7 +405,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see image1DForName()
*/
virtual std::string image1DName(UnsignedInt id);
std::string image1DName(UnsignedInt id);
/**
* @brief One-dimensional image
@ -409,10 +414,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given image or `nullptr` if importing failed. Deleting the
* data is user responsibility.
*/
virtual ImageData1D* image1D(UnsignedInt id);
ImageData1D* image1D(UnsignedInt id);
/** @brief Two-dimensional image count */
virtual UnsignedInt image2DCount() const { return 0; }
UnsignedInt image2DCount() const;
/**
* @brief Two-dimensional image ID for given name
@ -420,7 +425,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no image for given name exists, returns `-1`.
* @see image2DName()
*/
virtual Int image2DForName(const std::string& name);
Int image2DForName(const std::string& name);
/**
* @brief Two-dimensional image name
@ -428,7 +433,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see image2DForName()
*/
virtual std::string image2DName(UnsignedInt id);
std::string image2DName(UnsignedInt id);
/**
* @brief Two-dimensional image
@ -437,10 +442,10 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given image or `nullptr` if importing failed. Deleting the
* data is user responsibility.
*/
virtual ImageData2D* image2D(UnsignedInt id);
ImageData2D* image2D(UnsignedInt id);
/** @brief Three-dimensional image count */
virtual UnsignedInt image3DCount() const { return 0; }
UnsignedInt image3DCount() const;
/**
* @brief Three-dimensional image ID for given name
@ -448,7 +453,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* If no image for given name exists, returns `-1`.
* @see image3DName()
*/
virtual Int image3DForName(const std::string& name);
Int image3DForName(const std::string& name);
/**
* @brief Three-dimensional image name
@ -456,7 +461,7 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
*
* @see image3DForName()
*/
virtual std::string image3DName(UnsignedInt id);
std::string image3DName(UnsignedInt id);
/**
* @brief Three-dimensional image
@ -465,9 +470,182 @@ class MAGNUM_EXPORT AbstractImporter: public PluginManager::AbstractPlugin {
* Returns given image or `nullptr` if importing failed. Deleting the
* data is user responsibility.
*/
virtual ImageData3D* image3D(UnsignedInt id);
ImageData3D* image3D(UnsignedInt id);
/*@}*/
#ifndef DOXYGEN_GENERATING_OUTPUT
private:
#else
protected:
#endif
/** @brief Implementation for features() */
virtual Features doFeatures() const = 0;
/** @brief Implementation for isOpened() */
virtual bool doIsOpened() const = 0;
/** @brief Implementation for openData() */
virtual void doOpenData(Containers::ArrayReference<const unsigned char> data);
/**
* @brief Implementation for openFile()
*
* If @ref Feature "Feature::OpenData" is supported, default
* implementation opens the file and calls doOpenData() with its
* contents.
*/
virtual void doOpenFile(const std::string& filename);
/** @brief Implementation for close() */
virtual void doClose() = 0;
/** @brief Implementation for defaultScene() */
virtual Int doDefaultScene();
/** @brief Implementation for sceneCount() */
virtual UnsignedInt doSceneCount() const;
/** @brief Implementation for sceneForName() */
virtual Int doSceneForName(const std::string& name);
/** @brief Implementation for sceneName() */
virtual std::string doSceneName(UnsignedInt id);
/** @brief Implementation for scene() */
virtual SceneData* doScene(UnsignedInt id);
/** @brief Implementation for lightCount() */
virtual UnsignedInt doLightCount() const;
/** @brief Implementation for lightForName() */
virtual Int doLightForName(const std::string& name);
/** @brief Implementation for lightName() */
virtual std::string doLightName(UnsignedInt id);
/** @brief Implementation for light() */
virtual LightData* doLight(UnsignedInt id);
/** @brief Implementation for cameraCount() */
virtual UnsignedInt doCameraCount() const;
/** @brief Implementation for cameraForName() */
virtual Int doCameraForName(const std::string& name);
/** @brief Implementation for cameraName() */
virtual std::string doCameraName(UnsignedInt id);
/** @brief Implementation for camera() */
virtual CameraData* doCamera(UnsignedInt id);
/** @brief Implementation for object2DCount() */
virtual UnsignedInt doObject2DCount() const;
/** @brief Implementation for object2DForName() */
virtual Int doObject2DForName(const std::string& name);
/** @brief Implementation for object2DName() */
virtual std::string doObject2DName(UnsignedInt id);
/** @brief Implementation for object2D() */
virtual ObjectData2D* doObject2D(UnsignedInt id);
/** @brief Implementation for object3DCount() */
virtual UnsignedInt doObject3DCount() const;
/** @brief Implementation for object3DForName() */
virtual Int doObject3DForName(const std::string& name);
/** @brief Implementation for object3DName() */
virtual std::string doObject3DName(UnsignedInt id);
/** @brief Implementation for object3D() */
virtual ObjectData3D* doObject3D(UnsignedInt id);
/** @brief Implementation for mesh2DCount() */
virtual UnsignedInt doMesh2DCount() const;
/** @brief Implementation for mesh2DForName() */
virtual Int doMesh2DForName(const std::string& name);
/** @brief Implementation for mesh2DName() */
virtual std::string doMesh2DName(UnsignedInt id);
/** @brief Implementation for mesh2D() */
virtual MeshData2D* doMesh2D(UnsignedInt id);
/** @brief Implementation for mesh3DCount() */
virtual UnsignedInt doMesh3DCount() const;
/** @brief Implementation for mesh3DForName() */
virtual Int doMesh3DForName(const std::string& name);
/** @brief Implementation for mesh3DName() */
virtual std::string doMesh3DName(UnsignedInt id);
/** @brief Implementation for mesh3D() */
virtual MeshData3D* doMesh3D(UnsignedInt id);
/** @brief Implementation for materialCount() */
virtual UnsignedInt doMaterialCount() const;
/** @brief Implementation for materialForName() */
virtual Int doMaterialForName(const std::string& name);
/** @brief Implementation for materialName() */
virtual std::string doMaterialName(UnsignedInt id);
/** @brief Implementation for material() */
virtual AbstractMaterialData* doMaterial(UnsignedInt id);
/** @brief Implementation for textureCount() */
virtual UnsignedInt doTextureCount() const;
/** @brief Implementation for textureForName() */
virtual Int doTextureForName(const std::string& name);
/** @brief Implementation for textureName() */
virtual std::string doTextureName(UnsignedInt id);
/** @brief Implementation for texture() */
virtual TextureData* doTexture(UnsignedInt id);
/** @brief Implementation for image1DCount() */
virtual UnsignedInt doImage1DCount() const;
/** @brief Implementation for image1DForName() */
virtual Int doImage1DForName(const std::string& name);
/** @brief Implementation for image1DName() */
virtual std::string doImage1DName(UnsignedInt id);
/** @brief Implementation for image1D() */
virtual ImageData1D* doImage1D(UnsignedInt id);
/** @brief Implementation for image2DCount() */
virtual UnsignedInt doImage2DCount() const;
/** @brief Implementation for image2DForName() */
virtual Int doImage2DForName(const std::string& name);
/** @brief Implementation for image2DName() */
virtual std::string doImage2DName(UnsignedInt id);
/** @brief Implementation for image2D() */
virtual ImageData2D* doImage2D(UnsignedInt id);
/** @brief Implementation for image3DCount() */
virtual UnsignedInt doImage3DCount() const;
/** @brief Implementation for image3DForName() */
virtual Int doImage3DForName(const std::string& name);
/** @brief Implementation for image3DName() */
virtual std::string doImage3DName(UnsignedInt id);
/** @brief Implementation for image3D() */
virtual ImageData3D* doImage3D(UnsignedInt id);
};
CORRADE_ENUMSET_OPERATORS(AbstractImporter::Features)

69
src/Trade/Test/AbstractImporterTest.cpp

@ -0,0 +1,69 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
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 <Containers/Array.h>
#include <TestSuite/Tester.h>
#include <Utility/Directory.h>
#include "Trade/AbstractImporter.h"
#include "testConfigure.h"
namespace Magnum { namespace Trade { namespace Test {
class AbstractImporterTest: public TestSuite::Tester {
public:
explicit AbstractImporterTest();
void openFile();
};
AbstractImporterTest::AbstractImporterTest() {
addTests({&AbstractImporterTest::openFile});
}
void AbstractImporterTest::openFile() {
class DataImporter: public Trade::AbstractImporter {
private:
Features doFeatures() const override { return Feature::OpenData; }
bool doIsOpened() const override { return opened; }
void doClose() override {}
void doOpenData(Containers::ArrayReference<const unsigned char> data) override {
opened = (data.size() == 1 && data[0] == 0xa5);
}
bool opened;
};
/* doOpenFile() should call doOpenData() */
DataImporter importer;
CORRADE_VERIFY(!importer.isOpened());
importer.openFile(Utility::Directory::join(TRADE_TEST_DIR, "file.bin"));
CORRADE_VERIFY(importer.isOpened());
}
}}}
CORRADE_TEST_MAIN(Magnum::Trade::Test::AbstractImporterTest)

6
src/Trade/Test/CMakeLists.txt

@ -22,5 +22,11 @@
# DEALINGS IN THE SOFTWARE.
#
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/testConfigure.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/testConfigure.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
corrade_add_test(TradeAbstractImporterTest AbstractImporterTest.cpp LIBRARIES Magnum)
corrade_add_test(TradeObjectData2DTest ObjectData2DTest.cpp LIBRARIES Magnum)
corrade_add_test(TradeObjectData3DTest ObjectData3DTest.cpp LIBRARIES Magnum)

1
src/Trade/Test/file.bin

@ -0,0 +1 @@
<EFBFBD>

25
src/Trade/Test/testConfigure.h.cmake

@ -0,0 +1,25 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
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.
*/
#define TRADE_TEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
Loading…
Cancel
Save