My Project
PERef.h
1 #pragma once
2 #include "PERefPtr.h"
3 #include <string>
4 
5 namespace ParaEngine
6 {
7  class IType;
8  struct ObjectEvent;
9 
10  /* base class for reference counted objects. */
11  class PE_CORE_DECL CRefCounted
12  {
13  public:
15  void addref()const
16  {
17  ++m_refcount;
18  }
19 
22  bool delref()const
23  {
24  return --m_refcount<=0;
25  }
27  int GetRefCount()const
28  {
29  return m_refcount;
30  }
31  //all overridden functions should call this function in order to use the "delete when
32  //reference is zero" scheme
33  virtual int Release();
34 
40  CRefCounted* AddToAutoReleasePool();
41 
42  protected:
43  CRefCounted();
44  virtual ~CRefCounted();
45  protected:
46  mutable int m_refcount;
47  };
48 
55  class CRefCountedOne : public CRefCounted
56  {
57  protected:
59  };
60 
65  template <typename T>
66  class PE_CORE_DECL weak_ref_object : public CRefCounted
67  {
68  public:
69  weak_ref_object() : m_watched_object(0){};
70  weak_ref_object(T* pWatchedObject) : m_watched_object(pWatchedObject){};
71 
72  virtual ~weak_ref_object(){};
73 
74  inline bool expired() const
75  {
76  return m_watched_object == nullptr;
77  }
78  inline bool IsValid() const
79  {
80  return m_watched_object != nullptr;
81  }
82 
84  inline T* get() const { return m_watched_object; }
85  inline operator T* () { return m_watched_object; }
88  inline void UnWatch(){
89  m_watched_object = nullptr;
90  }
91 
92  protected:
93  T* m_watched_object;
94  };
95 
104  template<class RealT, class DefaultPointerClass = RealT>
105  struct PE_CORE_DECL weak_ptr
106  {
107  public:
109 
110  weak_ptr() : px(0)
111  {
112  }
113 
114  ~weak_ptr()
115  {
116  if (px != 0)
117  px->Release();
118  }
119 
120  weak_ptr(WeakRefObject_type * p)
121  :px(p)
122  {
123  if (px != 0)
124  px->addref();
125  }
126 
128  template<class Y>
129  explicit weak_ptr(Y * p) :px(0)
130  {
131  static_assert(std::is_convertible<Y*, RealT*>::value, "Invalid Type for ParaEngine::weak_ptr!");
132  if (p)
133  px = p->GetWeakReference().get_weak_ref_object();
134 
135  if (px != 0)
136  px->addref();
137  }
138 
139  weak_ptr(const weak_ptr & r) : px(r.get_weak_ref_object()) // never throws
140  {
141  if (px != 0)
142  px->addref();
143  }
144 
145  weak_ptr & operator=(const weak_ptr & r) // never throws
146  {
147  if (px != r.get_weak_ref_object())
148  {
149  if (px != 0)
150  px->Release();
151  px = r.get_weak_ref_object();
152  if (px != 0)
153  px->addref();
154  }
155  return *this;
156  }
157 
158  weak_ptr& operator=(WeakRefObject_type * r)
159  {
160  if(px != r)
161  {
162  if (px != 0)
163  px->Release();
164  px = r;
165  if (px != 0)
166  px->addref();
167  }
168  return *this;
169  }
170 
172  template<class Y>
173  weak_ptr& operator=(Y* r) // never throws
174  {
175  static_assert(std::is_convertible<Y*, RealT*>::value, "Invalid Type for ParaEngine::weak_ptr!");
176 
177  if (get() != r)
178  {
179  if (px != 0)
180  px->Release();
181 
182  px = r ? r->GetWeakReference().get_weak_ref_object() : 0;
183 
184  if (px != 0)
185  px->addref();
186  }
187  return *this;
188  }
189 
193  template<class Y>
194  operator Y* () const // never throws
195  {
196  static_assert(std::is_convertible<Y*, RealT*>::value, "Invalid Type for ParaEngine::weak_ptr!");
197  return (Y*)get();
198  }
199 
200  DefaultPointerClass& operator* () const // never throws
201  {
202  PE_ASSERT(px != 0 && (*px).get()!=0);
203  return *((*px).get());
204  }
205 
206  DefaultPointerClass * operator-> () const // never throws
207  {
208  PE_ASSERT(px != 0);
209  return (DefaultPointerClass*) ((*px).get());
210  }
211 
212  DefaultPointerClass * get() const // never throws
213  {
214  return (DefaultPointerClass*) ((px != 0) ? (*px).get() : nullptr);
215  }
216 
217  inline WeakRefObject_type * get_weak_ref_object() const // never throws
218  {
219  return px;
220  }
221 
222  operator bool() const
223  {
224  return px != 0 && (*px).get()!=nullptr;
225  }
226 
227  bool operator! () const // never throws
228  {
229  return px == 0 || (*px).get() == nullptr;
230  }
231 
232  int use_count() const // never throws
233  {
234  return (px != 0 && (*px).get()) ? ((*px).get())->GetRefCount() : 0;
235  }
236 
237  bool unique() const // nothrow
238  {
239  return use_count() == 1;
240  }
241 
242  void reset()
243  {
244  if (px != 0)
245  {
246  px->Release();
247  px = 0;
248  }
249  }
250 
251  inline bool operator==(weak_ptr const & b) const
252  {
253  return this->px == b.get_weak_ref_object();
254  }
255 
256  inline bool operator!=(weak_ptr const & b) const
257  {
258  return this->px != b.get_weak_ref_object();
259  }
260 
261  /* this conflicts with implicit cast operator
262 
263  template<class Y>
264  inline bool operator==(Y const * b) const
265  {
266  return this->get() == b;
267  }
268 
269  template<class Y>
270  inline bool operator!=(Y const * b) const
271  {
272  return this->get() != b;
273  }*/
274 
275  inline void UnWatch(){
276  if (px)
277  px->UnWatch();
278  }
279  private:
280  // contained pointer
281  WeakRefObject_type * px;
282  };
283 
287  class PE_CORE_DECL IObject :public CRefCounted
288  {
289  public:
291 
302  virtual void Clone(IObject* obj)const;
309  virtual IObject* Clone()const;
314  virtual bool Equals(const IObject *obj)const;
315  virtual const IType* GetType()const { return nullptr; };
316  virtual std::string ToString()const;
317 
319  WeakPtr_type& GetWeakReference();
320 
322  virtual int ProcessObjectEvent(const ObjectEvent& event) { return 0; };
323  protected:
324  //One should not delete the object, use Release() instead
325  //all overridden destructor should follow this rule
326  virtual ~IObject();
327 
328  WeakPtr_type m_weak_reference;
329  };
330 
332 }
IType is for type information and validating It contains type information of an object.
Definition: Type.h:75
weak_ptr & operator=(Y *r)
Y must be derived class of RealT.
Definition: PERef.h:173
event that can be passed to scene object
Definition: ObjectEvent.h:6
Base class for a reference counted asset.
Definition: PERef.h:55
different physics engine has different winding order.
Definition: EventBinding.h:32
bool delref() const
decrease reference count of the object.
Definition: PERef.h:22
virtual int ProcessObjectEvent(const ObjectEvent &event)
this function is only used to backward compatibility of ParaObject:AddEvent() function.
Definition: PERef.h:322
DONOT use this class directly, use weak_ptr instead.
Definition: PERef.h:66
base class for object, such as CBaseObject, IAttributeObject, GUI object.
Definition: PERef.h:287
Definition: PERef.h:11
weak reference ptr use in a class like this: weak_ptr<CRefCounted> p; e.g.
Definition: PERef.h:105
weak_ptr(Y *p)
Y must be derived class of RealT.
Definition: PERef.h:129
void addref() const
add reference count of the object.
Definition: PERef.h:15
void UnWatch()
this is usually called in the destructor of type T, so that we know that the pointer is invalid...
Definition: PERef.h:88
int GetRefCount() const
get the reference count
Definition: PERef.h:27