1.1 --- a/include/keima.h Mon Sep 17 00:10:01 2012 -0700
1.2 +++ b/include/keima.h Sat Nov 17 18:41:01 2012 -0800
1.3 @@ -43,6 +43,7 @@
1.4 template <typename T>
1.5 class Handle
1.6 {
1.7 + template <typename S> friend class Root;
1.8 protected:
1.9 template <typename S> void typeCheck() {
1.10 while (false) {
1.11 @@ -111,46 +112,45 @@
1.12 };
1.13
1.14 /*
1.15 - * A non-local variable that outlives HandleScopes. A Root is reference-
1.16 - * counted. When its reference count reaches 0, the Root is removed.
1.17 + * A non-local variable that outlives HandleScopes. Unlike Local, a Root
1.18 + * actually represents a rooted location. Roots must be allocated and
1.19 + * disposed, and assignment to a root changes its contained object, not
1.20 + * the location of the object.
1.21 */
1.22 template <typename T>
1.23 -class Root : public Handle<T>
1.24 +class Root
1.25 {
1.26 public:
1.27 - Root<T>()
1.28 - : Handle<T>()
1.29 + Root()
1.30 + : root_(NULL)
1.31 {
1.32 }
1.33
1.34 - Root<T>(const Root<T> &other)
1.35 - : Handle<T>(reinterpret_cast<T *>(*other))
1.36 + Root(Handle<T> other)
1.37 + : root_(NULL)
1.38 {
1.39 - incref();
1.40 + set(other);
1.41 }
1.42
1.43 - explicit Root(ke::HeapRoot *obj)
1.44 - : Handle<T>(reinterpret_cast<T *>(obj))
1.45 - {
1.46 -incref();
1.47 + inline ~Root();
1.48 +
1.49 + operator const Handle<T>() const {
1.50 + return obj_;
1.51 }
1.52
1.53 - static inline Root<T> New(Handle<T> other);
1.54 -
1.55 - ~Root() {
1.56 - decref();
1.57 + bool operator ==(Handle<T> other) {
1.58 + return Handle<T>(*this) == other;
1.59 }
1.60 -
1.61 - Root<T> &operator =(const Root<T> &other) {
1.62 - decref();
1.63 - this->obj_ = other.obj_;
1.64 - incref();
1.65 + Root<T> &operator =(Handle<T> other) {
1.66 + set(other);
1.67 return *this;
1.68 }
1.69
1.70 private:
1.71 - void incref();
1.72 - void decref();
1.73 + void set(Handle<T> other);
1.74 +
1.75 + ke::HeapRoot *root_;
1.76 + Handle<T> obj_;
1.77 };
1.78
1.79 /*
1.80 @@ -211,7 +211,8 @@
1.81 class IStackFrameIterator
1.82 {
1.83 public:
1.84 - virtual ~IStackFrameIterator() { }
1.85 + virtual ~IStackFrameIterator() {
1.86 + }
1.87
1.88 // Returns true if there are more frames, false otherwise.
1.89 virtual bool done() = 0;
1.90 @@ -232,6 +233,20 @@
1.91 virtual void prev() = 0;
1.92 };
1.93
1.94 +// Listener interface for when public functions are registered or unregisted.
1.95 +class IPublicFunctionListener
1.96 +{
1.97 + public:
1.98 + virtual ~IPublicFunctionListener() {
1.99 + }
1.100 +
1.101 + // Called when a public function becomes available to the runtime.
1.102 + virtual void registerPublic(Handle<Function> fun) = 0;
1.103 +
1.104 + // Called when a public is no longer available to the runtime.
1.105 + virtual void unregisterPublic(Handle<Function> fun) = 0;
1.106 +};
1.107 +
1.108 // A string is an immutable UTF8 buffer.
1.109 class KE_EXPORT String
1.110 {
1.111 @@ -253,21 +268,6 @@
1.112 Local<String> name();
1.113 };
1.114
1.115 -// A native is an ISourcePawnEngine-compatible function provided by C++.
1.116 -class KE_EXPORT Native
1.117 -{
1.118 - public:
1.119 - // Returns the name of a native, which is never NULL. The string is
1.120 - // guaranteed to be interned.
1.121 - Local<String> name();
1.122 -
1.123 - // Returns the function pointer of the native.
1.124 - void *function();
1.125 -
1.126 - // Sets the function pointer of the native.
1.127 - void bind(void *function);
1.128 -};
1.129 -
1.130 // A pubvar is an ISourcePawnEngine-compatible structure that holds information
1.131 // about public variables.
1.132 class KE_EXPORT Pubvar
1.133 @@ -283,21 +283,9 @@
1.134 class KE_EXPORT Module
1.135 {
1.136 public:
1.137 - // Returns publics that are based on forwards.
1.138 - unsigned numPublics();
1.139 - Local<Function> getPublic(unsigned index);
1.140 -
1.141 - // Returns natives.
1.142 - unsigned numNatives();
1.143 - Local<Native> getNative(unsigned index);
1.144 -
1.145 // Sets the native identity pointer, which is passed as the first argument
1.146 // to natives.
1.147 void setNativeIdentity(void *ptr);
1.148 -
1.149 - // Returns the number of public variables.
1.150 - unsigned numPubvars();
1.151 - Local<Pubvar> getPubvar(unsigned index);
1.152 };
1.153
1.154 class Keima
1.155 @@ -346,7 +334,23 @@
1.156 */
1.157 static void InstallMessageReporter(IMessageReporter *reporter);
1.158
1.159 + /* Returns a new stack frame iterator object. */
1.160 static IStackFrameIterator *NewStackFrameIterator();
1.161 +
1.162 + /*
1.163 + * Binds a native, by name, to an address. Natives are an ISPE1 concept
1.164 + * (originally from Pawn/Small's AMX API). In SourceMod 1, natives were
1.165 + * registered globally, but bound to plugins individually. We roughly
1.166 + * preserve that functionality here, by allowing host applications to
1.167 + * give us the name -> address mappings.
1.168 + *
1.169 + * Natives can be rebound or unbound any number of times. This function
1.170 + * fails if there is not enough memory.
1.171 + */
1.172 + static bool BindNative(const char *name, void *address);
1.173 +
1.174 + /* Sets the object that will listen for public functions. */
1.175 + static void SetPublicFunctionListener(IPublicFunctionListener *listener);
1.176 };
1.177
1.178 /*
1.179 @@ -470,38 +474,38 @@
1.180 template <typename T> friend class Root;
1.181
1.182 private:
1.183 - static ke::HeapRoot *NewHeapRoot(ke::Object **objp);
1.184 - static void IncRef(ke::HeapRoot *root);
1.185 - static void DecRef(ke::HeapRoot *root);
1.186 + static ke::HeapRoot *NewHeapRoot();
1.187 + static void Destroy(ke::HeapRoot *root);
1.188 };
1.189
1.190 -template <typename T> Root<T>
1.191 -Root<T>::New(Handle<T> other)
1.192 -{
1.193 - if (!other)
1.194 - return Root<T>();
1.195 - ke::Object **ptr = reinterpret_cast<ke::Object **>(*other);
1.196 - return Root<T>(Internals::NewHeapRoot(ptr));
1.197 -}
1.198 -
1.199 template <typename T> void
1.200 -Root<T>::incref()
1.201 +Root<T>::set(Handle<T> other)
1.202 {
1.203 - if (!*this)
1.204 + if (!other) {
1.205 + obj_ = other;
1.206 return;
1.207 - ke::HeapRoot *ptr = reinterpret_cast<ke::HeapRoot *>(**this);
1.208 - Internals::IncRef(ptr);
1.209 + }
1.210 +
1.211 + ke::Object **ptr = reinterpret_cast<ke::Object **>(*other);
1.212 + if (!root_) {
1.213 + root_ = Internals::NewHeapRoot();
1.214 + if (!root_)
1.215 + return;
1.216 + }
1.217 +
1.218 + *reinterpret_cast<ke::Object **>(root_) = *ptr;
1.219 + obj_.obj_ = reinterpret_cast<T *>(root_);
1.220 }
1.221
1.222 -template <typename T> void
1.223 -Root<T>::decref()
1.224 +template <typename T>
1.225 +Root<T>::~Root()
1.226 {
1.227 - if (!*this)
1.228 + if (!root_)
1.229 return;
1.230 - ke::HeapRoot *ptr = reinterpret_cast<ke::HeapRoot *>(**this);
1.231 - Internals::DecRef(ptr);
1.232 + Internals::Destroy(root_);
1.233 }
1.234
1.235 +
1.236 }
1.237
1.238 #endif // _include_sourcepawn2_api_h_