mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Re-enabled intrusive_ptr
This commit is contained in:
@@ -252,7 +252,7 @@ void CurveDragAction::move(const Vector2D& delta, double t) {
|
||||
|
||||
ControlPointAddAction::ControlPointAddAction(const SymbolShapeP& shape, UInt insert_after, double t)
|
||||
: shape(shape)
|
||||
, new_point(make_shared<ControlPoint>())
|
||||
, new_point(make_intrusive<ControlPoint>())
|
||||
, insert_after(insert_after)
|
||||
, point1(shape->getPoint(insert_after))
|
||||
, point2(shape->getPoint(insert_after + 1))
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ DECLARE_POINTER_TYPE(StyleSheet);
|
||||
// ----------------------------------------------------------------------------- : Card
|
||||
|
||||
/// A card from a card Set
|
||||
class Card : public IntrusivePtrVirtualBase {
|
||||
class Card : public IntrusivePtrVirtualBase, public IntrusiveFromThis<Card> {
|
||||
public:
|
||||
/// Default constructor, uses game_for_new_cards to make the game
|
||||
Card();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <gui/util.hpp>
|
||||
#include <util/window_id.hpp>
|
||||
#include <data/stylesheet.hpp>
|
||||
#include <data/card.hpp>
|
||||
#include <wx/splitter.h>
|
||||
#include <wx/dcbuffer.h>
|
||||
#include <wx/clipbrd.h>
|
||||
|
||||
@@ -134,20 +134,8 @@ void SetScriptManager::initDependencies(Context& ctx, StyleSheet& stylesheet) {
|
||||
void SetScriptManager::onAction(const Action& action, bool undone) {
|
||||
TYPE_CASE(action, ValueAction) {
|
||||
if (action.card) {
|
||||
#ifdef USE_INTRUSIVE_PTR
|
||||
// we can just turn the Card* into a CardP
|
||||
updateValue(*action.valueP, CardP(const_cast<Card*>(action.card)));
|
||||
return;
|
||||
#else
|
||||
// find the affected card
|
||||
FOR_EACH(card, set.cards) {
|
||||
if (card->data.contains(action.valueP)) {
|
||||
updateValue(*action.valueP, card);
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(false);
|
||||
#endif
|
||||
updateValue(*action.valueP, const_cast<Card*>(action.card)->intrusive_from_this());
|
||||
return;
|
||||
} else {
|
||||
// is it a keyword's fake value?
|
||||
KeywordTextValue* value = dynamic_cast<KeywordTextValue*>(action.valueP.get());
|
||||
|
||||
@@ -210,8 +210,8 @@ ScriptValueP rangeIterator(int start, int end) {
|
||||
|
||||
// ----------------------------------------------------------------------------- : Integers
|
||||
|
||||
#ifdef USE_INTRUSIVE_PTR
|
||||
#define USE_POOL_ALLOCATOR
|
||||
#if defined(USE_INTRUSIVE_PTR) && !defined(USE_POOL_ALLOCATOR)
|
||||
#define USE_POOL_ALLOCATOR 0 // disabled by default
|
||||
#endif
|
||||
|
||||
// Integer values
|
||||
@@ -224,8 +224,8 @@ public:
|
||||
double toDouble() const override { return value; }
|
||||
int toInt() const override { return value; }
|
||||
protected:
|
||||
#ifdef USE_POOL_ALLOCATOR
|
||||
virtual void destroy() {
|
||||
#if USE_POOL_ALLOCATOR
|
||||
void destroy() const override {
|
||||
boost::singleton_pool<ScriptValue, sizeof(ScriptInt)>::free(this);
|
||||
}
|
||||
#endif
|
||||
@@ -233,7 +233,7 @@ private:
|
||||
int value;
|
||||
};
|
||||
|
||||
#if defined(USE_POOL_ALLOCATOR) && !defined(USE_INTRUSIVE_PTR)
|
||||
#if USE_POOL_ALLOCATOR && !USE_INTRUSIVE_PTR
|
||||
// deallocation function for pool allocated integers
|
||||
void destroy_value(ScriptInt* v) {
|
||||
boost::singleton_pool<ScriptValue, sizeof(ScriptInt)>::free(v);
|
||||
@@ -241,8 +241,8 @@ private:
|
||||
#endif
|
||||
|
||||
ScriptValueP to_script(int v) {
|
||||
#ifdef USE_POOL_ALLOCATOR
|
||||
#ifdef USE_INTRUSIVE_PTR
|
||||
#if USE_POOL_ALLOCATOR
|
||||
#if USE_INTRUSIVE_PTR
|
||||
return ScriptValueP(
|
||||
new(boost::singleton_pool<ScriptValue, sizeof(ScriptInt)>::malloc())
|
||||
ScriptInt(v));
|
||||
|
||||
@@ -183,7 +183,7 @@ class Package : public IntrusivePtrVirtualBase {
|
||||
|
||||
protected:
|
||||
// TODO: I dislike putting this here very much. There ought to be a better way.
|
||||
virtual VCSP getVCS() { return make_shared<VCS>(); }
|
||||
virtual VCSP getVCS() { return make_intrusive<VCS>(); }
|
||||
|
||||
/// true if this is a zip file, false if a directory
|
||||
bool isZipfile() const { return !wxDirExists(filename); }
|
||||
|
||||
+86
-25
@@ -8,7 +8,7 @@
|
||||
|
||||
/** @file util/smart_ptr.hpp
|
||||
*
|
||||
* @brief Utilities related to boost smart pointers
|
||||
* @brief Smart pointers and related utility functions
|
||||
*/
|
||||
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
@@ -22,21 +22,96 @@ using std::dynamic_pointer_cast;
|
||||
using std::make_shared;
|
||||
using std::make_unique;
|
||||
|
||||
#ifndef USE_INTRUSIVE_PTR
|
||||
#define USE_INTRUSIVE_PTR 1
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------- : Intrusive pointers
|
||||
|
||||
#if USE_INTRUSIVE_PTR
|
||||
|
||||
#include <atomic>
|
||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||
using boost::intrusive_ptr;
|
||||
|
||||
/// Base class for types that can be pointed to
|
||||
template <typename T> class IntrusivePtrBase {
|
||||
public:
|
||||
IntrusivePtrBase() {}
|
||||
// don't copy or assign ref count
|
||||
IntrusivePtrBase(IntrusivePtrBase const&) {}
|
||||
void operator = (IntrusivePtrBase const&) {}
|
||||
protected:
|
||||
inline void destroy() const {
|
||||
delete static_cast<const T*>(this);
|
||||
}
|
||||
private:
|
||||
mutable std::atomic<unsigned int> ref_count = 0;
|
||||
template <typename T> friend void intrusive_ptr_add_ref(const IntrusivePtrBase<T>* ptr);
|
||||
template <typename T> friend void intrusive_ptr_release(const IntrusivePtrBase<T>* ptr);
|
||||
};
|
||||
|
||||
template <typename T> void intrusive_ptr_add_ref(const IntrusivePtrBase<T>* ptr) {
|
||||
++(ptr->ref_count);
|
||||
}
|
||||
|
||||
template <typename T> void intrusive_ptr_release(const IntrusivePtrBase<T>* ptr) {
|
||||
if (--(ptr->ref_count) == 0) {
|
||||
static_cast<const T*>(ptr)->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class IntrusiveFromThis {
|
||||
public:
|
||||
inline intrusive_ptr<T> intrusive_from_this() noexcept {
|
||||
return intrusive_ptr<T>(static_cast<T*>(this));
|
||||
}
|
||||
};
|
||||
|
||||
/// Allocate an object of type T and store it in a new intrusive_ptr, similar to std::make_shared
|
||||
template <typename T, class... Args>
|
||||
inline intrusive_ptr<T> make_intrusive(Args&&... args) {
|
||||
return intrusive_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Shared pointers
|
||||
#else
|
||||
|
||||
template <typename T> using intrusive_ptr = shared_ptr<T>;
|
||||
|
||||
/// Base class for types that can be pointed to
|
||||
template <typename T> class IntrusivePtrBase {};
|
||||
|
||||
template <typename T>
|
||||
class IntrusiveFromThis : public std::enable_shared_from_this<T> {
|
||||
public:
|
||||
inline intrusive_ptr<T> intrusive_from_this() {
|
||||
return shared_from_this();
|
||||
}
|
||||
};
|
||||
|
||||
/// Allocate an object of type T and store it in a new intrusive_ptr, similar to std::make_shared
|
||||
template <typename T, class... Args>
|
||||
inline intrusive_ptr<T> make_intrusive(Args&&... args) {
|
||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------- : Declaring
|
||||
|
||||
/// Declares the type TypeP as a intrusive_ptr<Type>
|
||||
#define DECLARE_POINTER_TYPE(Type) \
|
||||
class Type; \
|
||||
typedef intrusive_ptr<Type> Type##P;
|
||||
|
||||
/// Declares the type TypeP as a shared_ptr<Type>
|
||||
#define DECLARE_SHARED_POINTER_TYPE(Type) \
|
||||
class Type; \
|
||||
typedef shared_ptr<Type> Type##P;
|
||||
|
||||
// ----------------------------------------------------------------------------- : Shared pointers
|
||||
|
||||
#define DECLARE_POINTER_TYPE DECLARE_SHARED_POINTER_TYPE
|
||||
|
||||
template <typename T> using intrusive_ptr = shared_ptr<T>;
|
||||
|
||||
/// Base class for types that can be pointed to
|
||||
template <typename T> class IntrusivePtrBase {};
|
||||
// ----------------------------------------------------------------------------- : Utility
|
||||
|
||||
/// IntrusivePtrBase with a virtual destructor
|
||||
class IntrusivePtrVirtualBase : public IntrusivePtrBase<IntrusivePtrVirtualBase> {
|
||||
@@ -49,27 +124,13 @@ public:
|
||||
virtual ~IntrusivePtrBaseWithDelete() {}
|
||||
protected:
|
||||
/// Delete this object
|
||||
virtual void destroy() {
|
||||
virtual void destroy() const {
|
||||
delete this;
|
||||
}
|
||||
template <typename T> friend void intrusive_ptr_release(const IntrusivePtrBase<T>* ptr);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class IntrusiveFromThis : public std::enable_shared_from_this<T> {
|
||||
protected:
|
||||
inline intrusive_ptr<T> intrusive_from_this() {
|
||||
return shared_from_this();
|
||||
}
|
||||
};
|
||||
|
||||
/// Allocate an object of type T and store it in a new intrusive_ptr, similar to std::make_shared
|
||||
template <typename T, class... Args>
|
||||
inline intrusive_ptr<T> make_intrusive(Args&&... args) {
|
||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/// Pointer to 'anything'
|
||||
typedef intrusive_ptr<IntrusivePtrVirtualBase> VoidP;
|
||||
|
||||
// ----------------------------------------------------------------------------- : Intrusive pointers
|
||||
|
||||
|
||||
Reference in New Issue
Block a user