include/keima.h
changeset 195 c1ba166f3fc4
parent 170 5e4570966ece
child 232 2b8512340180
     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_