Skip to content

Commit

Permalink
Merge pull request #84 from Klebert-Engineering/modelpool-to-json
Browse files Browse the repository at this point in the history
Support Model JSON Serialization
  • Loading branch information
johannes-wolf authored Jul 15, 2024
2 parents fdaef25 + b0f3456 commit e583bdb
Show file tree
Hide file tree
Showing 21 changed files with 376 additions and 259 deletions.
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ add_library(simfil ${LIBRARY_TYPE}
src/exception-handler.cpp
src/model/model.cpp
src/model/nodes.cpp
src/model/fields.cpp)
src/model/string-pool.cpp)

target_sources(simfil PUBLIC
FILE_SET public_headers
Expand All @@ -75,7 +75,7 @@ target_sources(simfil PUBLIC
include/simfil/exception-handler.h

include/simfil/model/arena.h
include/simfil/model/fields.h
include/simfil/model/string-pool.h
include/simfil/model/model.h
include/simfil/model/nodes.h
include/simfil/model/bitsery-traits.h)
Expand Down Expand Up @@ -122,7 +122,7 @@ if (SIMFIL_WITH_MODEL_JSON)
include/simfil/model/json.h)

target_link_libraries(simfil
PRIVATE
PUBLIC
nlohmann_json::nlohmann_json)
endif()

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,10 @@ target_link_libraries(<my-app> PUBLIC simfil)
```c++
#include "simfil/simfil.h"
#include "simfil/model/model.h"
#include "simfil/model/fields.h"
#include "simfil/model/string-pool.h"

// Shared string pool used for string interning
auto strings = std::make_shared<simfil::Fields>();
auto strings = std::make_shared<simfil::StringPool>();

// Declare a model with one object
auto model = std::make_shared<simfil::ModelPool>(strings);
Expand Down
4 changes: 2 additions & 2 deletions examples/minimal/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

#include "simfil/simfil.h"
#include "simfil/model/model.h"
#include "simfil/model/fields.h"
#include "simfil/model/string-pool.h"

int main()
{
// Shared string pool.
auto strings = std::make_shared<simfil::Fields>();
auto strings = std::make_shared<simfil::StringPool>();

// Data model pool
auto model = std::make_shared<simfil::ModelPool>(strings);
Expand Down
9 changes: 5 additions & 4 deletions include/simfil/environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ struct Environment
/**
* Construct a SIMFIL execution environment with a string cache,
* which is used to map field names to short integer IDs.
* @param fieldNames The string cache used by this environment.
* @param strings The string cache used by this environment.
* Must be the same cache that is also used by ModelPools which
* are queried using this environment.
*/
explicit Environment(std::shared_ptr<Fields> fieldNames);
explicit Environment(std::shared_ptr<StringPool> strings);

/**
* Constructor for instantiating an environment explicitly with
Expand Down Expand Up @@ -78,7 +78,8 @@ struct Environment
* Obtain a strong reference to this environment's string cache.
* Guaranteed not-null.
*/
auto fieldNames() const -> std::shared_ptr<Fields>;
[[nodiscard]]
auto strings() const -> std::shared_ptr<StringPool>;

public:
std::unique_ptr<std::mutex> warnMtx;
Expand All @@ -91,7 +92,7 @@ struct Environment
std::map<std::string, const Function*> functions;

Debug* debug = nullptr;
std::shared_ptr<Fields> fieldNames_;
std::shared_ptr<StringPool> stringPool;
};

/**
Expand Down
107 changes: 72 additions & 35 deletions include/simfil/model/model.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// Copyright (c) Navigation Data Standard e.V. - See "LICENSE" file.

#pragma once

#include "simfil/value.h"
#include "simfil/model/string-pool.h"
#if defined(SIMFIL_WITH_MODEL_JSON)
# include "nlohmann/json.hpp"
#endif

#include <memory>
#include <string_view>
#include <vector>
#include <istream>
#include <ostream>
Expand Down Expand Up @@ -44,17 +47,29 @@ class Model : public std::enable_shared_from_this<Model>
T fn_;
};

/// Virtual destructor to allow polymorphism
/** Virtual destructor to allow polymorphism */
virtual ~Model() = default;

/// Get a callback with the actual class of the given node.
/// This facilitates the Virtual Function Table role of the Model.
/**
* Get a callback with the actual class of the given node.
* This facilitates the Virtual Function Table role of the Model.
*/
virtual void resolve(ModelNode const& n, ResolveFn const& cb) const;

/// Add a small scalar value and get its model node view
/** Add a small scalar value and get its model node view */
ModelNode::Ptr newSmallValue(bool value);
ModelNode::Ptr newSmallValue(int16_t value);
ModelNode::Ptr newSmallValue(uint16_t value);

/**
* Lookup a field name for a field-id.
*
* This is in the base Model class to allow JSON
* serialization, without having to downcast to ModelPool;
* which contains the `strings()` function. The base
* implementation returns an unset optional.
*/
virtual std::optional<std::string_view> lookupStringId(StringId id) const;
};

/**
Expand All @@ -69,8 +84,8 @@ class ModelPool : public Model
public:
/**
* The pool consists of multiple ModelNode columns,
* each for a different data type. Each column
* is identified by a static column ID.
* each for a different data type. Each column
* is identified by a static column ID.
*/
enum ColumnId : uint8_t {
Objects = FirstNontrivialColumnId,
Expand All @@ -82,71 +97,93 @@ class ModelPool : public Model
FirstCustomColumnId = 128,
};

/// Default ctor with own string storage
/** Default ctor with own string storage */
ModelPool();
~ModelPool();

/// Ctor with shared string storage
explicit ModelPool(std::shared_ptr<Fields> stringStore);
/** Ctor with shared string storage */
explicit ModelPool(std::shared_ptr<StringPool> stringStore);

/// Validate that all internal string/node references are valid
/// Returns a list of found errors.
/**
* Validate that all internal string/node references are valid
* Returns a list of found errors.
*/
virtual std::vector<std::string> checkForErrors() const;

/// Get a callback with the actual class of the given node.
/// This facilitates the Virtual Function Table role of the ModelPool.
/**
* Get a callback with the actual class of the given node.
* This facilitates the Virtual Function Table role of the ModelPool.
*/
void resolve(ModelNode const& n, ResolveFn const& cb) const override;

/// Clear all columns and roots
/** Clear all columns and roots */
virtual void clear();

/// Check for errors, throw if there are any
/** Check for errors, throw if there are any */
void validate() const;

/// Get number of root nodes
/** Get number of root nodes */
[[nodiscard]] size_t numRoots() const;

/// Get specific root node
/** Get specific root node */
[[nodiscard]] ModelNode::Ptr root(size_t const& i) const;

/// Designate a model node index as a root
/** Designate a model node index as a root */
void addRoot(ModelNode::Ptr const& rootNode);

/// Adopt members from the given vector and obtain a new object
/// model index which has these members.
/**
* Adopt members from the given vector and obtain a new object
* model index which has these members.
*/
shared_model_ptr<Object> newObject(size_t initialFieldCapacity = 2);

/// Adopt members from the given vector and obtain a new array
/// model index which has these members.
/**
* Adopt members from the given vector and obtain a new array
* model index which has these members.
*/
shared_model_ptr<Array> newArray(size_t initialFieldCapacity = 2);

/// Add a scalar value and get its new model node index.
/** Add a scalar value and get its new model node index. */
ModelNode::Ptr newValue(int64_t const& value);
ModelNode::Ptr newValue(double const& value);
ModelNode::Ptr newValue(std::string_view const& value);

/// Node-type-specific resolve-functions
/** Node-type-specific resolve-functions */
[[nodiscard]]
shared_model_ptr<Object> resolveObject(ModelNode::Ptr const& n) const;
[[nodiscard]]
shared_model_ptr<Array> resolveArray(ModelNode::Ptr const& n) const;

/// Access the field name storage
std::shared_ptr<Fields> fieldNames() const;
/** Access the field name storage */
[[nodiscard]]
std::shared_ptr<StringPool> strings() const;

/**
* Change the string pool of this model to a different one.
* Note: This will potentially create new field entries in the newDict,
* for field names which were not there before.
*/
virtual void setStrings(std::shared_ptr<simfil::StringPool> const& strings);

/// Change the fields dict of this model to a different one.
/// Note: This will potentially create new field entries in the newDict,
/// for field names which were not there before.
virtual void setFieldNames(std::shared_ptr<simfil::Fields> const& newDict);
std::optional<std::string_view> lookupStringId(StringId id) const override;

/// Serialization
/** Serialization */
virtual void write(std::ostream& outputStream);
virtual void read(std::istream& inputStream);

#if defined(SIMFIL_WITH_MODEL_JSON)
/** JSON Serialization */
virtual nlohmann::json toJson() const;
#endif

protected:
struct Impl;
std::unique_ptr<Impl> impl_;

/// Protected object/array member storage access,
/// so derived ModelPools can create Object/Array-derived nodes.
/**
* Protected object/array member storage access,
* so derived ModelPools can create Object/Array-derived nodes.
*/
Object::Storage& objectMemberStorage();
Array::Storage& arrayMemberStorage();
};
Expand Down
Loading

0 comments on commit e583bdb

Please sign in to comment.