Skip to content

Commit

Permalink
Introduced removal of mutation rules
Browse files Browse the repository at this point in the history
  • Loading branch information
iboB committed Oct 15, 2017
1 parent f967ca6 commit 947e968
Show file tree
Hide file tree
Showing 16 changed files with 197 additions and 43 deletions.
13 changes: 13 additions & 0 deletions doc/08_revision_history.dox
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
/*! \page revisions Revision History

DynaMix 1.2.1
=============

Released: 2017 Oct 15

- Improved mutation rules: They can now be added, removed and persisted via
shared pointers
- Added `object::has` and `object::get` with `const char*` to query mixins by
name
- `add_new_mutation_rule` is now deprecated
- Fixed library version header


DynaMix 1.2.0
=============

Expand Down
2 changes: 1 addition & 1 deletion doc/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "DynaMix"
PROJECT_NUMBER = 1.2.0
PROJECT_NUMBER = 1.2.1
PROJECT_BRIEF = "A new take on polymorphism in C++"

# TODO: (max size 200x55)
Expand Down
4 changes: 2 additions & 2 deletions example/basic/object_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// DynaMix
// Copyright (c) 2013-2016 Borislav Stanimirov, Zahary Karadjov
// Copyright (c) 2013-2017 Borislav Stanimirov, Zahary Karadjov
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
Expand Down Expand Up @@ -31,7 +31,7 @@ void object_manager::create_objects()
rendering_mixins->add<d3d_renderer>();
rendering_mixins->add<gl_renderer>();

add_new_mutation_rule(rendering_mixins);
add_mutation_rule(rendering_mixins);

object_type_template type;
type
Expand Down
14 changes: 10 additions & 4 deletions include/dynamix/domain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
#include <dynamix/message.hpp>

#include <unordered_map>
#include <memory>
#include <type_traits> // alignment of

#if DYNAMIX_THREAD_SAFE_MUTATIONS
#include <mutex>
#endif


/**
* \file
* Domain related classes and functions.
Expand Down Expand Up @@ -52,7 +52,9 @@ class DYNAMIX_API domain : public noncopyable
// no static variables, not safe to call globally
static const domain& instance();

void add_new_mutation_rule(mutation_rule* rule);
mutation_rule_id add_mutation_rule(std::shared_ptr<mutation_rule> rule);
mutation_rule_id add_mutation_rule(mutation_rule* rule);
std::shared_ptr<mutation_rule> remove_mutation_rule(mutation_rule_id id);
void apply_mutation_rules(object_type_mutation& mutation);

size_t num_registered_mixins() const { return _num_registered_mixins; }
Expand Down Expand Up @@ -144,9 +146,13 @@ class DYNAMIX_API domain : public noncopyable
typedef std::unordered_map<available_mixins_bitset, object_type_info*> object_type_info_map;

object_type_info_map _object_type_infos;
std::mutex _object_type_infos_mutex;

std::vector<mutation_rule*> _mutation_rules;
std::vector<std::shared_ptr<mutation_rule>> _mutation_rules;

#if DYNAMIX_THREAD_SAFE_MUTATIONS
std::mutex _object_type_infos_mutex;
std::mutex _mutation_rules_mutex;
#endif

// feature registration functions for the supported kinds of features
void internal_register_feature(message_t& m);
Expand Down
1 change: 1 addition & 0 deletions include/dynamix/global.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ namespace dynamix
{
typedef size_t mixin_id;
typedef size_t feature_id;
typedef size_t mutation_rule_id;

namespace internal
{
Expand Down
29 changes: 27 additions & 2 deletions include/dynamix/mutation_rule.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// DynaMix
// Copyright (c) 2013-2016 Borislav Stanimirov, Zahary Karadjov
// Copyright (c) 2013-2017 Borislav Stanimirov, Zahary Karadjov
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
Expand All @@ -15,6 +15,8 @@
#include "global.hpp"
#include "mixin_collection.hpp"

#include <memory>

namespace dynamix
{

Expand All @@ -30,10 +32,33 @@ class DYNAMIX_API mutation_rule
virtual void apply_to(object_type_mutation& mutation) = 0;
};

/// DEPRECATED:
/// Adds a mutation rule to the domain.
/// Takes ownership of the pointer and assumes it's created with `new`.
/// Returns the mutation rule id by whitch it can be removed.
///
/// Does *not* perform a topological sort of the rules.
/// It is the user's responsibility to add the mutation rules in the appropriate order.
mutation_rule_id DYNAMIX_API add_new_mutation_rule(mutation_rule* rule);

/// Adds a mutation rule to the domain.
/// Takes ownership of the pointer and assumes it's created with `new`.
/// Returns the mutation rule id by whitch it can be removed.
///
/// Does *not* perform a topological sort of the rules.
/// It is the user's responsibility to add the mutation rules in the appropriate order.
void DYNAMIX_API add_new_mutation_rule(mutation_rule* rule);
mutation_rule_id DYNAMIX_API add_mutation_rule(mutation_rule* rule);

/// Adds a mutation rule to the domain via a shared pointer.
/// Returns the mutation rule id by whitch it can be removed.
///
/// Does *not* perform a topological sort of the rules.
/// It is the user's responsibility to add the mutation rules in the appropriate order.
mutation_rule_id DYNAMIX_API add_mutation_rule(std::shared_ptr<mutation_rule> rule);

/// Removes a mutation rule from the domain by id.
/// Returns a shared pointer to the rule which the user might use to persist it, or null
/// if no such mutation rule exists
std::shared_ptr<mutation_rule> DYNAMIX_API remove_mutation_rule(mutation_rule_id id);

} // namespace dynamix
4 changes: 2 additions & 2 deletions include/dynamix/version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
*/

#define DYNAMIX_VERSION_MAJOR 1
#define DYNAMIX_VERSION_MINOR 1
#define DYNAMIX_VERSION_SUB_MINOR 0
#define DYNAMIX_VERSION_MINOR 2
#define DYNAMIX_VERSION_SUB_MINOR 1

/// The library's version.
///
Expand Down
68 changes: 60 additions & 8 deletions src/domain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,60 @@ domain::~domain()
{
delete i.second;
}
}

mutation_rule_id domain::add_mutation_rule(mutation_rule* rule)
{
std::shared_ptr<mutation_rule> ptr(rule);
return add_mutation_rule(ptr);
}

mutation_rule_id domain::add_mutation_rule(std::shared_ptr<mutation_rule> rule)
{
#if DYNAMIX_THREAD_SAFE_MUTATIONS
std::lock_guard<std::mutex> lock(_mutation_rules_mutex);
#endif

for (const mutation_rule* rule : _mutation_rules)
// find free slot
for (mutation_rule_id i = 0; i < _mutation_rules.size(); ++i)
{
delete rule;
auto& r = _mutation_rules[i];
if (!r)
{
r = rule;
return i;
}
}

_mutation_rules.emplace_back(std::move(rule));
return _mutation_rules.size() - 1;
}

void domain::add_new_mutation_rule(mutation_rule* rule)
std::shared_ptr<mutation_rule> domain::remove_mutation_rule(mutation_rule_id id)
{
_mutation_rules.push_back(rule);
#if DYNAMIX_THREAD_SAFE_MUTATIONS
std::lock_guard<std::mutex> lock(_mutation_rules_mutex);
#endif

if (id >= _mutation_rules.size()) return std::shared_ptr<mutation_rule>();

auto ret = _mutation_rules[id];
_mutation_rules[id].reset();
return ret;
}

void domain::apply_mutation_rules(object_type_mutation& mutation)
{
for (mutation_rule* rule : _mutation_rules)
#if DYNAMIX_THREAD_SAFE_MUTATIONS
std::lock_guard<std::mutex> lock(_mutation_rules_mutex);
#endif

for (auto& rule : _mutation_rules)
{
rule->apply_to(mutation);
if (rule)
{
rule->apply_to(mutation);
}
}
}

Expand Down Expand Up @@ -309,9 +346,24 @@ mixin_id domain::get_mixin_id_by_name(const char* mixin_name) const

} // namespace internal

void add_new_mutation_rule(mutation_rule* rule)
mutation_rule_id add_new_mutation_rule(mutation_rule* rule)
{
return internal::domain::safe_instance().add_mutation_rule(rule);
}

mutation_rule_id add_mutation_rule(mutation_rule* rule)
{
return internal::domain::safe_instance().add_mutation_rule(rule);
}

mutation_rule_id add_mutation_rule(std::shared_ptr<mutation_rule> rule)
{
return internal::domain::safe_instance().add_mutation_rule(rule);
}

std::shared_ptr<mutation_rule> remove_mutation_rule(mutation_rule_id id)
{
internal::domain::safe_instance().add_new_mutation_rule(rule);
return internal::domain::safe_instance().remove_mutation_rule(id);
}

// set allocator to all domains
Expand Down
2 changes: 1 addition & 1 deletion test/mutation_rules/bundled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ TEST_CASE("bundled")
auto bundle = new bundled_mixins;
bundle->add<a>();
bundle->add<b>();
add_new_mutation_rule(bundle);
add_mutation_rule(bundle);

object o;

Expand Down
47 changes: 45 additions & 2 deletions test/mutation_rules/custom.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// DynaMix
// Copyright (c) 2013-2016 Borislav Stanimirov, Zahary Karadjov
// Copyright (c) 2013-2017 Borislav Stanimirov, Zahary Karadjov
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
Expand Down Expand Up @@ -35,7 +35,9 @@ TEST_SUITE("mutation rules");

TEST_CASE("mutation rules")
{
add_new_mutation_rule(new custom_rule());
auto id = add_mutation_rule(new custom_rule());

CHECK(id == 0);

object o;

Expand All @@ -53,4 +55,45 @@ TEST_CASE("mutation rules")
CHECK(!o.has<a>());
CHECK(!o.has<b>());
CHECK(o.has<c>());

auto rule = remove_mutation_rule(id);

mutate(o)
.add<a>();

CHECK(o.has<a>());
CHECK(!o.has<b>());
CHECK(o.has<c>());

mutate(o)
.add<b>();

CHECK(o.has<a>());
CHECK(o.has<b>());
CHECK(o.has<c>());

id = add_mutation_rule(rule);
CHECK(id == 0);

auto depr = std::make_shared<deprecated_mixin<c>>();
id = add_mutation_rule(depr);
CHECK(id == 1);

mutate(o)
.remove<a>();

CHECK(o.empty());

CHECK(rule == remove_mutation_rule(0));

mutate(o)
.add<a>()
.add<c>();

CHECK(o.has<a>());
CHECK(!o.has<b>());
CHECK(!o.has<c>());

rule.reset();
CHECK(rule == remove_mutation_rule(123));
}
4 changes: 2 additions & 2 deletions test/mutation_rules/dependent.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// DynaMix
// Copyright (c) 2013-2016 Borislav Stanimirov, Zahary Karadjov
// Copyright (c) 2013-2017 Borislav Stanimirov, Zahary Karadjov
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
Expand All @@ -21,7 +21,7 @@ TEST_CASE("dependent")
auto rule = new dependent_mixins;
rule->set_master<a>();
rule->add<b>();
add_new_mutation_rule(rule);
add_mutation_rule(rule);

object o;

Expand Down
4 changes: 2 additions & 2 deletions test/mutation_rules/deprecated.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// DynaMix
// Copyright (c) 2013-2016 Borislav Stanimirov, Zahary Karadjov
// Copyright (c) 2013-2017 Borislav Stanimirov, Zahary Karadjov
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
Expand All @@ -18,7 +18,7 @@ TEST_SUITE("mutation rules");

TEST_CASE("deprecated")
{
add_new_mutation_rule(new deprecated_mixin<a>());
add_mutation_rule(new deprecated_mixin<a>());

object o;

Expand Down
4 changes: 2 additions & 2 deletions test/mutation_rules/mandatory.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// DynaMix
// Copyright (c) 2013-2016 Borislav Stanimirov, Zahary Karadjov
// Copyright (c) 2013-2017 Borislav Stanimirov, Zahary Karadjov
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
Expand All @@ -18,7 +18,7 @@ TEST_SUITE("mutation rules");

TEST_CASE("mandatory")
{
add_new_mutation_rule(new mandatory_mixin<c>());
add_mutation_rule(new mandatory_mixin<c>());

object o;

Expand Down
4 changes: 2 additions & 2 deletions test/mutation_rules/mutually_exclusive.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// DynaMix
// Copyright (c) 2013-2016 Borislav Stanimirov, Zahary Karadjov
// Copyright (c) 2013-2017 Borislav Stanimirov, Zahary Karadjov
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
Expand All @@ -23,7 +23,7 @@ TEST_CASE("mutually exclusive")
rule->add<a>();
rule->add<b>();

add_new_mutation_rule(rule);
add_mutation_rule(rule);

object o;

Expand Down
Loading

0 comments on commit 947e968

Please sign in to comment.