Skip to content

Commit

Permalink
Merge branch 'v1.3.0_dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
SSBMTonberry committed Feb 1, 2021
2 parents 1c255a0 + 9deb2de commit 39673a1
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 28 deletions.
44 changes: 26 additions & 18 deletions README.md
Expand Up @@ -15,16 +15,21 @@ Be sure to take a look at the release notes to see what's new!

There is a `Doxygen` generated documentation of Tileson that can be found [HERE](https://ssbmtonberry.github.io/tileson/html)

### IMPORTANT: Tileson requires that everything it needs in a map is embedded into it, to be able to resolve their related objects. Maps having external references to tilesets etc. will not work.


# Tileson is header-only!
This means that all you need is one file, `single_include/tileson.hpp` to have Tileson going
in your project! The single-file is generated, and is quite large, as it uses the nlohmann/json as a built-in dependency,
and might thus be a bit heavy to load (26 000 lines of code).

There is also an option to use a `tileson_min.hpp` file which only contains the `Tileson` related code (~5000 lines of code), but this requires you to include your own version of [nlohmann/json](https://github.com/nlohmann/json) before including `tileson_min.hpp`
in your project! The single-file is generated using only ~7000 lines of code with everything included. There is also a `tileson_min.hpp` where no Json parser is bundled. See the `extras` folder for supported Json backends.

You may alternatively copy the `include` directory and all its contents if you
want to have every component in their own file. This will probably be way less heavy for your IDE, but you will still only need to include the `tileson.h` file in the top level.
want to have every component in their own file. This will probably be less heavy on your IDE, but you will still only need to include the `tileson.h` file in the top level.

# What's new in v1.3.0 alpha?
- Tileson now uses a `tson::IJson` abstraction layer, which means the user is no longer restricted to use one Json parser. In fact, there are now three parsers with default implementations: `Json11`, `Nlohmann` and `Picojson`. You may even create your own!
- The code base of Tileson is reduced from ~26000 to ~7000 lines of code. In addition Tileson is slightly faster due to switching default/main backend from `Nlohmann` to `Json11`.
- Tileson now has support for reading `LZMA` compressed maps using [PocketLzma](https://github.com/SSBMTonberry/pocketlzma). Example: The `ultimate_test.json` map gets reduced from `68,6 KiB` to `2,4 KiB` when LZMA compressed.
- See release notes for more details!

# What is Tiled?
Tiled is a general purpose map editor developed by `Thorbjørn Lindeijer`.
Expand All @@ -46,8 +51,8 @@ Parsing a Tiled json

//Tileson uses an alias fs for std::filesystem.
int main()
tson::Tileson parser;
std::unique_ptr<tson::Map> map = parser.parse(fs::path("./path/to/map.json"));
tson::Tileson t;
std::unique_ptr<tson::Map> map = t.parse(tson_files::_ULTIMATE_TEST_JSON, tson_files::_ULTIMATE_TEST_JSON_SIZE);

if(map->getStatus() == tson::ParseStatus::OK)
{
Expand Down Expand Up @@ -148,11 +153,9 @@ int main()
bool myBool = layer->get<bool>("my_bool");
std::string myString = layer->get<std::string>("my_string");
tson::Colori myColor = layer->get<tson::Colori>("my_color");
#ifndef DISABLE_CPP17_FILESYSTEM

fs::path file = layer->get<fs::path>("my_file");
#else
std::string file = layer->get<std::string>("my_file");
#endif

tson::Property *prop = layer->getProp("my_property");
}
else //Error occured
Expand Down Expand Up @@ -274,7 +277,7 @@ if(map->getStatus() == tson::ParseStatus::OK)

### Parsing worlds

- Tileson now supports `Tiled worlds`. These contains a collection of several maps that can be tied together, but the files themselves must be parsed separately using `Tileson`. **NB! This functionality requires `std::filesystem` to be enabled (DISABLE_CPP17_FILESYSTEM not defined (default))**. (See `examples` to get a full idea how worlds works):
- Tileson now supports `Tiled worlds`. These contains a collection of several maps that can be tied together, but the files themselves must be parsed separately using `Tileson`. (See `examples` to get a full idea how worlds works):

```c++
tson::Tileson t;
Expand All @@ -293,7 +296,7 @@ for(const auto &data : world.getMapData())

### Parsing Tiled-projects

- Tileson now supports `Tiled projects`. These contains all `map` and `world` data, but the files themselves must be parsed separately using `Tileson`. **NB! This functionality requires `std::filesystem` to be enabled (DISABLE_CPP17_FILESYSTEM not defined (default))**. (See `examples` to get a full idea how projects works).
- Tileson now supports `Tiled projects`. These contains all `map` and `world` data, but the files themselves must be parsed separately using `Tileson`. (See `examples` to get a full idea how projects works).

```c++
tson::Tileson t;
Expand All @@ -313,9 +316,7 @@ for(const auto &folder : m_project.getFolders())
```

# Compiling
The program is cross-platform. However, it does not compile on all compilers.
`std::filesystem` is used as a default for Linux and Windows systems, as it has been
supported for a while. Unfortunately, the default compiler, `Apple Clang`, shipped with todays Apple OSX (as of `24.08.2019`) does not support `std::filesystem` at all. For this reason, `std::filesystem` is disabled as default for `Apple` systems. As of v1.1.0 filesystem is in use unless `DISABLE_CPP17_FILESYSTEM` is defined (`#define`). This can also be controlled as a CMake parameter. Also, the library itself is header-only, and will only need the headers to work (see top of README for details).
The program is cross-platform. It utilizes the features of modern C++ (C++17), which requires the user to have a pretty up to date compiler. Tileson specifically supports the compilers `MSVC` (Windows), `GCC` (Linux) and `Clang` (Mac/OSX), but other compilers supporting all C++17 features should be fine.

As a default, compiling examples are disabled due to CI, but it can easily be enabled through the CMakeLists.txt file on the root level of the project. Also keep in mind that the examples are using content from the `tileson/content` folder and are using relative paths. This is where the executable usually is located when compiling, and must have the same relative path to find the files:

Expand Down Expand Up @@ -367,8 +368,15 @@ Simply call it like this: `sh amalgamate_script.sh`. There is also a .bat-versio
# Libraries used by Tileson

- [Catch2](https://github.com/catchorg/Catch2/) - For Unit Tests
- [JSON for Modern C++](https://github.com/nlohmann/json) - For JSON read/write
- [Amalgamate](https://github.com/SSBMTonberry/Amalgamate) - Fork of [vinniefalco/Amalgamate](https://github.com/vinniefalco/Amalgamate) - For generating single-header include of `tileson.hpp`
- [json11](https://github.com/dropbox/json11) - For JSON read/write
- [PocketLzma](https://github.com/SSBMTonberry/pocketlzma) - For LZMA compression.
- [Amalgamate](https://github.com/SSBMTonberry/Amalgamate) - Fork of [vinniefalco/Amalgamate](https://github.com/vinniefalco/Amalgamate) - For generating single-header include of `tileson.hpp` and `tileson_min.hpp`

## Optional Json parsers supported by Tileson
- [JSON for Modern C++](https://github.com/nlohmann/json) - At least version 3.9.1
- [Picojson](https://github.com/kazuho/picojson).

The json libraries supported can all be found in a single-header format inside the `extras` folder.

# Libraries used for examples/demo

Expand Down
2 changes: 2 additions & 0 deletions extras/json11.hpp
Expand Up @@ -31,6 +31,8 @@
#include <memory>
#include <initializer_list>

#define JSON11_IS_DEFINED

#ifdef _MSC_VER
#if _MSC_VER <= 1800 // VS 2013
#ifndef noexcept
Expand Down
2 changes: 2 additions & 0 deletions include/external/json11.hpp
Expand Up @@ -31,6 +31,8 @@
#include <memory>
#include <initializer_list>

#define JSON11_IS_DEFINED

#ifdef _MSC_VER
#if _MSC_VER <= 1800 // VS 2013
#ifndef noexcept
Expand Down
8 changes: 8 additions & 0 deletions include/tiled/Project.hpp
Expand Up @@ -17,11 +17,19 @@ namespace tson
class Project
{
public:
#ifdef JSON11_IS_DEFINED
inline explicit Project(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>()) : m_json {std::move(jsonParser)}
{

}
inline explicit Project(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>());
#else
inline explicit Project(std::unique_ptr<tson::IJson> jsonParser) : m_json {std::move(jsonParser)}
{

}
inline explicit Project(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser);
#endif
inline bool parse(const fs::path &path);

[[nodiscard]] inline const ProjectData &getData() const;
Expand Down
8 changes: 8 additions & 0 deletions include/tiled/World.hpp
Expand Up @@ -13,11 +13,19 @@ namespace tson
class World
{
public:
#ifdef JSON11_IS_DEFINED
inline explicit World(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>()) : m_json {std::move(jsonParser)}
{
}

inline explicit World(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>());
#else
inline explicit World(std::unique_ptr<tson::IJson> jsonParser) : m_json {std::move(jsonParser)}
{
}

inline explicit World(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser);
#endif
inline bool parse(const fs::path &path);
inline int loadMaps(tson::Tileson *parser); //tileson_forward.hpp
inline bool contains(std::string_view filename);
Expand Down
4 changes: 4 additions & 0 deletions include/tileson_parser.hpp
Expand Up @@ -53,7 +53,11 @@ namespace tson
class Tileson
{
public:
#ifdef JSON11_IS_DEFINED
inline explicit Tileson(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>(), bool includeBase64Decoder = true);
#else
inline explicit Tileson(std::unique_ptr<tson::IJson> jsonParser, bool includeBase64Decoder = true);
#endif

inline std::unique_ptr<tson::Map> parse(const fs::path &path, std::unique_ptr<IDecompressor<std::vector<uint8_t>, std::vector<uint8_t>>> decompressor = nullptr);
inline std::unique_ptr<tson::Map> parse(const void * data, size_t size, std::unique_ptr<IDecompressor<std::vector<uint8_t>, std::vector<uint8_t>>> decompressor = nullptr);
Expand Down
22 changes: 22 additions & 0 deletions single_include/tileson.hpp
Expand Up @@ -64,6 +64,8 @@
#include <memory>
#include <initializer_list>

#define JSON11_IS_DEFINED

#ifdef _MSC_VER
#if _MSC_VER <= 1800 // VS 2013
#ifndef noexcept
Expand Down Expand Up @@ -6714,11 +6716,19 @@ namespace tson
class World
{
public:
#ifdef JSON11_IS_DEFINED
inline explicit World(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>()) : m_json {std::move(jsonParser)}
{
}

inline explicit World(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>());
#else
inline explicit World(std::unique_ptr<tson::IJson> jsonParser) : m_json {std::move(jsonParser)}
{
}

inline explicit World(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser);
#endif
inline bool parse(const fs::path &path);
inline int loadMaps(tson::Tileson *parser); //tileson_forward.hpp
inline bool contains(std::string_view filename);
Expand Down Expand Up @@ -6979,11 +6989,19 @@ namespace tson
class Project
{
public:
#ifdef JSON11_IS_DEFINED
inline explicit Project(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>()) : m_json {std::move(jsonParser)}
{

}
inline explicit Project(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>());
#else
inline explicit Project(std::unique_ptr<tson::IJson> jsonParser) : m_json {std::move(jsonParser)}
{

}
inline explicit Project(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser);
#endif
inline bool parse(const fs::path &path);

[[nodiscard]] inline const ProjectData &getData() const;
Expand Down Expand Up @@ -7082,7 +7100,11 @@ namespace tson
class Tileson
{
public:
#ifdef JSON11_IS_DEFINED
inline explicit Tileson(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>(), bool includeBase64Decoder = true);
#else
inline explicit Tileson(std::unique_ptr<tson::IJson> jsonParser, bool includeBase64Decoder = true);
#endif

inline std::unique_ptr<tson::Map> parse(const fs::path &path, std::unique_ptr<IDecompressor<std::vector<uint8_t>, std::vector<uint8_t>>> decompressor = nullptr);
inline std::unique_ptr<tson::Map> parse(const void * data, size_t size, std::unique_ptr<IDecompressor<std::vector<uint8_t>, std::vector<uint8_t>>> decompressor = nullptr);
Expand Down
20 changes: 20 additions & 0 deletions single_include/tileson_min.hpp
Expand Up @@ -5732,11 +5732,19 @@ namespace tson
class World
{
public:
#ifdef JSON11_IS_DEFINED
inline explicit World(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>()) : m_json {std::move(jsonParser)}
{
}

inline explicit World(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>());
#else
inline explicit World(std::unique_ptr<tson::IJson> jsonParser) : m_json {std::move(jsonParser)}
{
}

inline explicit World(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser);
#endif
inline bool parse(const fs::path &path);
inline int loadMaps(tson::Tileson *parser); //tileson_forward.hpp
inline bool contains(std::string_view filename);
Expand Down Expand Up @@ -5997,11 +6005,19 @@ namespace tson
class Project
{
public:
#ifdef JSON11_IS_DEFINED
inline explicit Project(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>()) : m_json {std::move(jsonParser)}
{

}
inline explicit Project(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>());
#else
inline explicit Project(std::unique_ptr<tson::IJson> jsonParser) : m_json {std::move(jsonParser)}
{

}
inline explicit Project(const fs::path &path, std::unique_ptr<tson::IJson> jsonParser);
#endif
inline bool parse(const fs::path &path);

[[nodiscard]] inline const ProjectData &getData() const;
Expand Down Expand Up @@ -6100,7 +6116,11 @@ namespace tson
class Tileson
{
public:
#ifdef JSON11_IS_DEFINED
inline explicit Tileson(std::unique_ptr<tson::IJson> jsonParser = std::make_unique<tson::Json11>(), bool includeBase64Decoder = true);
#else
inline explicit Tileson(std::unique_ptr<tson::IJson> jsonParser, bool includeBase64Decoder = true);
#endif

inline std::unique_ptr<tson::Map> parse(const fs::path &path, std::unique_ptr<IDecompressor<std::vector<uint8_t>, std::vector<uint8_t>>> decompressor = nullptr);
inline std::unique_ptr<tson::Map> parse(const void * data, size_t size, std::unique_ptr<IDecompressor<std::vector<uint8_t>, std::vector<uint8_t>>> decompressor = nullptr);
Expand Down
10 changes: 2 additions & 8 deletions tests/CMakeLists.txt
Expand Up @@ -17,14 +17,8 @@ if(LINUX)
#target_link_libraries(tileson_tests tileson stdc++fs)
elseif(APPLE)
message("OSX!")
if(${USE_CPP17_FILESYSTEM})
message("Using filesystem for tests!")
target_link_libraries(tileson_tests /usr/local/opt/llvm/lib/libc++experimental.a /usr/local/opt/llvm/lib/libc++fs.a)
#target_link_libraries(tileson_tests tileson /usr/local/opt/llvm/lib/libc++experimental.a /usr/local/opt/llvm/lib/libc++fs.a)
else()
message("Filesystem disabled. Using std::string for paths!")
#target_link_libraries(tileson_tests tileson)
endif()
message("Using filesystem for tests!")
target_link_libraries(tileson_tests /usr/local/opt/llvm/lib/libc++experimental.a /usr/local/opt/llvm/lib/libc++fs.a)
elseif(WINDOWS)
message("WINDOWS!")
#target_link_libraries(tileson_tests tileson)
Expand Down
1 change: 0 additions & 1 deletion tools/amalgamate_min_script.bat

This file was deleted.

1 change: 0 additions & 1 deletion tools/amalgamate_min_script.sh

This file was deleted.

0 comments on commit 39673a1

Please sign in to comment.