Skip to content

Commit

Permalink
Showing 9 changed files with 121 additions and 226 deletions.
165 changes: 109 additions & 56 deletions src/xrCore/intrusive_ptr.h
Original file line number Diff line number Diff line change
@@ -1,89 +1,142 @@
////////////////////////////////////////////////////////////////////////////
// Module : intrusive_ptr.h
// Created : 30.07.2004
// Modified : 30.07.2004
// Author : Dmitriy Iassenev
// Description : Intrusive pointer template
// Module : intrusive_ptr.h
// Created : 30.07.2004
// Modified : 8.11.2016 by Im-Dex
// Author : Dmitriy Iassenev
// Description : Intrusive pointer template
////////////////////////////////////////////////////////////////////////////

#pragma once

#include "Common/object_type_traits.h"

#pragma pack(push, 4)

struct intrusive_base
{
u32 m_ref_count;
intrusive_base() XR_NOEXCEPT : m_ref_count(0) {}

IC intrusive_base() : m_ref_count(0) {}
template <typename T>
IC void _release(T* object)
void release(T* object) XR_NOEXCEPT
{
try
{
xr_delete(object);
}
catch (...)
{
}
catch (...) { }
}

void acquire() XR_NOEXCEPT { ++m_ref_count; }

bool release() XR_NOEXCEPT { return --m_ref_count == 0; }

bool released() const XR_NOEXCEPT { return m_ref_count == 0; }

private:
size_t m_ref_count;
};

template <typename object_type, typename base_type = intrusive_base>
template <typename ObjectType, typename BaseType = intrusive_base>
class intrusive_ptr
{
private:
typedef intrusive_ptr<object_type, base_type> self_type;
typedef const object_type* (intrusive_ptr::*unspecified_bool_type)() const;
using object_type = ObjectType;
using base_type = BaseType;
using self_type = intrusive_ptr<object_type, base_type>;

private:
enum
{
result = object_type_traits::is_base_and_derived<base_type, object_type>::value ||
object_type_traits::is_same<base_type, object_type>::value
};
static_assert(std::is_base_of_v<BaseType, ObjectType>,
"ObjectType must be derived from the BaseType");

private:
object_type* m_object;

protected:
IC void dec();
void dec() XR_NOEXCEPT
{
if (!m_object)
return;

if (m_object->release())
m_object->release(m_object);
}

public:
IC intrusive_ptr();
IC intrusive_ptr(object_type* rhs);
IC intrusive_ptr(self_type const& rhs);
IC ~intrusive_ptr();
IC self_type& operator=(object_type* rhs);
IC self_type& operator=(self_type const& rhs);
IC object_type& operator*() const;
IC object_type* operator->() const;
IC bool operator!() const;
IC operator unspecified_bool_type() const { return (!m_object ? 0 : &intrusive_ptr::get); }
IC u32 size();
IC void swap(self_type& rhs);
IC bool equal(const self_type& rhs) const;
IC void set(object_type* rhs);
IC void set(self_type const& rhs);
IC const object_type* get() const;
};
intrusive_ptr() XR_NOEXCEPT : m_object(nullptr) {}

template <typename object_type, typename base_type>
IC bool operator==(intrusive_ptr<object_type, base_type> const& a, intrusive_ptr<object_type, base_type> const& b);
intrusive_ptr(object_type* rhs) XR_NOEXCEPT : m_object(rhs)
{
if (m_object != nullptr)
m_object->acquire();
}

template <typename object_type, typename base_type>
IC bool operator!=(intrusive_ptr<object_type, base_type> const& a, intrusive_ptr<object_type, base_type> const& b);
intrusive_ptr(const self_type& rhs) XR_NOEXCEPT : m_object(rhs.m_object)
{
if (m_object != nullptr)
m_object->acquire();
}

template <typename object_type, typename base_type>
IC bool operator<(intrusive_ptr<object_type, base_type> const& a, intrusive_ptr<object_type, base_type> const& b);
intrusive_ptr(self_type&& rhs) XR_NOEXCEPT : m_object(rhs.m_object) { rhs.m_object = nullptr; }

template <typename object_type, typename base_type>
IC bool operator>(intrusive_ptr<object_type, base_type> const& a, intrusive_ptr<object_type, base_type> const& b);
~intrusive_ptr() XR_NOEXCEPT { dec(); }

template <typename object_type, typename base_type>
IC void swap(intrusive_ptr<object_type, base_type>& lhs, intrusive_ptr<object_type, base_type>& rhs);
self_type& operator=(object_type* rhs) XR_NOEXCEPT
{
dec();
m_object = rhs;
if (m_object != nullptr)
m_object->acquire();

#include "intrusive_ptr_inline.h"
return *this;
}

self_type& operator=(const self_type& rhs) XR_NOEXCEPT
{
dec();
m_object = rhs.m_object;
if (m_object != nullptr)
m_object->acquire();

return *this;
}

self_type& operator=(self_type&& rhs) XR_NOEXCEPT
{
dec();
m_object = rhs.m_object;
if (m_object != nullptr)
rhs.m_object = nullptr;
return *this;
}

object_type& operator*() const XR_NOEXCEPT
{
VERIFY(m_object);
return *m_object;
}

object_type* operator->() const XR_NOEXCEPT
{
VERIFY(m_object);
return m_object;
}

explicit operator bool() const XR_NOEXCEPT { return m_object != nullptr; }

bool operator==(const self_type& rhs) const XR_NOEXCEPT { return m_object == rhs.m_object; }

bool operator!=(const self_type& rhs) const XR_NOEXCEPT { return m_object != rhs.m_object; }

#pragma pack(pop)
bool operator<(const self_type& rhs) const XR_NOEXCEPT { return m_object < rhs.m_object; }

bool operator>(const self_type& rhs) const XR_NOEXCEPT { return m_object > rhs.m_object; }

void swap(self_type& rhs) XR_NOEXCEPT
{
object_type* tmp = m_object;
m_object = rhs.m_object;
rhs.m_object = tmp;
}

const object_type* get() const XR_NOEXCEPT { return m_object; }
};

template <typename object_type, typename base_type>
void swap(intrusive_ptr<object_type, base_type>& lhs,
intrusive_ptr<object_type, base_type>& rhs) XR_NOEXCEPT
{
lhs.swap(rhs);
}
157 changes: 0 additions & 157 deletions src/xrCore/intrusive_ptr_inline.h

This file was deleted.

1 change: 0 additions & 1 deletion src/xrCore/xrCore.vcxproj
Original file line number Diff line number Diff line change
@@ -327,7 +327,6 @@
<ClInclude Include="FS_internal.h" />
<ClInclude Include="FTimer.h" />
<ClInclude Include="intrusive_ptr.h" />
<ClInclude Include="intrusive_ptr_inline.h" />
<ClInclude Include="LocatorAPI.h" />
<ClInclude Include="LocatorAPI_defs.h" />
<ClInclude Include="log.h" />
3 changes: 0 additions & 3 deletions src/xrCore/xrCore.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -563,9 +563,6 @@
<ClInclude Include="intrusive_ptr.h">
<Filter>intrusive_ptr</Filter>
</ClInclude>
<ClInclude Include="intrusive_ptr_inline.h">
<Filter>intrusive_ptr</Filter>
</ClInclude>
<ClInclude Include="memory_monitor.h">
<Filter>memory_monitor</Filter>
</ClInclude>
2 changes: 1 addition & 1 deletion src/xrGame/LevelGraphDebugRender.cpp
Original file line number Diff line number Diff line change
@@ -701,7 +701,7 @@ void LevelGraphDebugRender::DrawRestrictions()
const float yOffset = 0.1;
for (auto& pair : spaceRestrictionMgr.restrictions())
{
if (!pair.second->m_ref_count)
if (pair.second->released())
continue;
if (!pair.second->initialized())
continue;
6 changes: 3 additions & 3 deletions src/xrGame/smart_cover_storage.cpp
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ storage::~storage()
Descriptions::const_iterator I = m_descriptions.begin();
Descriptions::const_iterator E = m_descriptions.end();
for (; I != E; ++I)
VERIFY(!(*I)->m_ref_count);
VERIFY((*I)->released());
#endif // DEBUG
delete_data(m_descriptions);
}
@@ -56,9 +56,9 @@ void storage::collect_garbage()
{
struct garbage
{
static IC bool predicate(::description* const& object)
static bool predicate(::description* const& object)
{
if (object->m_ref_count)
if (!object->released())
return (false);

if (Device.dwTimeGlobal < object->m_last_time_dec + time_to_delete)
2 changes: 1 addition & 1 deletion src/xrGame/space_restriction_holder.cpp
Original file line number Diff line number Diff line change
@@ -205,7 +205,7 @@ IC void CSpaceRestrictionHolder::collect_garbage()
RESTRICTIONS::iterator E = m_restrictions.end();
for (; I != E;)
{
if (!(*I).second->shape() && !(*I).second->m_ref_count &&
if (!(*I).second->shape() && (*I).second->released() &&
(Device.dwTimeGlobal >= (*I).second->m_last_time_dec + time_to_delete))
{
J = I;
2 changes: 1 addition & 1 deletion src/xrGame/space_restriction_manager.cpp
Original file line number Diff line number Diff line change
@@ -103,7 +103,7 @@ void CSpaceRestrictionManager::collect_garbage()
SPACE_RESTRICTIONS::iterator E = m_space_restrictions.end();
for (; I != E;)
{
if (!(*I).second->m_ref_count && (Device.dwTimeGlobal >= (*I).second->m_last_time_dec + time_to_delete))
if ((*I).second->released() && (Device.dwTimeGlobal >= (*I).second->m_last_time_dec + time_to_delete))
{
J = I;
++I;
9 changes: 6 additions & 3 deletions src/xrServerEntities/restriction_space.h
Original file line number Diff line number Diff line change
@@ -14,12 +14,15 @@ struct CTimeIntrusiveBase : public intrusive_base
{
u32 m_last_time_dec;

IC CTimeIntrusiveBase() : m_last_time_dec(0) {}
CTimeIntrusiveBase() XR_NOEXCEPT : m_last_time_dec(0) {}

template <typename T>
IC void _release(T* object)
void release(T*) XR_NOEXCEPT
{
m_last_time_dec = Device.dwTimeGlobal;
}

using intrusive_base::release;
};

enum ERestrictorTypes
@@ -31,4 +34,4 @@ enum ERestrictorTypes
eRestrictorTypeIn = u8(4),
eRestrictorTypeOut = u8(5),
};
};
}; // namespace RestrictionSpace

0 comments on commit fb907f2

Please sign in to comment.