Simulant  21.12-194
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
managed.h
1 /* * Copyright (c) 2011-2017 Luke Benstead https://simulant-engine.appspot.com
2  *
3  * This file is part of Simulant.
4  *
5  * Simulant is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Simulant is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with Simulant. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #include <stdexcept>
22 #include <memory>
23 #include <string>
24 #include <functional>
25 
26 namespace smlt {
27 
29  public std::runtime_error {
30 
31 public:
33  std::runtime_error("Couldn't initialize the instance") {}
34 
35  InstanceInitializationError(const std::string& type):
36  std::runtime_error(type + " could not be initialized") {
37 
38  }
39 };
40 
41 template<typename T>
42 void deleter(T* obj) {
43  obj->clean_up();
44  delete obj;
45 }
46 
48 public:
49  virtual ~TwoPhaseConstructed() {}
50 
51  virtual bool init() { return true; }
52  virtual void clean_up() {
53 #if DEBUG
54  assert(!cleaned_up);
55  cleaned_up = true;
56 #endif
57  }
58 
59 #ifdef DEBUG
60  bool cleaned_up = false;
61 #endif
62 };
63 
64 template<typename T>
65 class RefCounted : public virtual TwoPhaseConstructed, public virtual std::enable_shared_from_this<T> {
66 public:
67  typedef std::shared_ptr<T> ptr;
68  typedef std::weak_ptr<T> wptr;
69 
70  template<typename... Args>
71  static typename RefCounted<T>::ptr create(Args&&... args) {
72  typename RefCounted<T>::ptr instance = typename RefCounted<T>::ptr(
73  new T(std::forward<Args>(args)...),
74  std::bind(&deleter<T>, std::placeholders::_1)
75  );
76 
77  if(!instance->init()) {
78  throw InstanceInitializationError(typeid(T).name());
79  }
80  return instance;
81  }
82 
83  static typename RefCounted<T>::ptr create() {
84  typename RefCounted<T>::ptr instance = typename RefCounted<T>::ptr(
85  new T(),
86  std::bind(&deleter<T>, std::placeholders::_1)
87  );
88 
89  if(!instance->init()) {
90  throw InstanceInitializationError(typeid(T).name());
91  }
92  return instance;
93  }
94 
95 protected:
96  RefCounted() = default;
97  virtual ~RefCounted() {}
98 
99  template<typename...Args>
100  RefCounted(Args&&...) {}
101 };
102 
103 }
104 
smlt::RefCounted
Definition: managed.h:65
smlt
Definition: animation.cpp:25
smlt::InstanceInitializationError
Definition: managed.h:29
smlt::TwoPhaseConstructed
Definition: managed.h:47