On Sun, Jun 26, 2011 at 11:15 PM, Stephan Beal <[email protected]>wrote:

> perform logic based on count, types, and potentially other app-related
> state (but i can't imagine that being all that useful except to maybe
> perform some one-time initialization of related code the first time it is
> called from JS. e.g. initializing lt_dlinit() or the ncurses screen state).
>

15 minutes ago that concept didn't sound all that useful, but i could have
used this when writing the curses bindings (to automatically ensure that the
screen state has been initialized). In principal this would be helpful for
any bindings where the bound functions rely on some app/lib-specific init
has been run (lt_dlinit() comes to mind).

So... here a generic InvocationCallback for it...

/**
    This class acts as a proxy for another InCa-compatible class,
    running client-defined intialization code the _first_ time
    its callback is called from JS. This could be used to run
    library-dependent intialization routines such as lt_dlinit().

    InCaT must conform to the InCa interface (i.e., have a static Call()
    function which implements the v8::InvocationCallback interface).

    InitFunctor must be default-constructable and have an operator()
    taking no args and returning any type which can be ignored (i.e.
    not dynamically-allocated resources).
*/
template <typename InCaT, typename InitFunctor>
struct OneTimeInitInCa
{
    /**
        The first time this function is called it runs
        InitFunctor()() to execute any client-dependent setup. If
        that throws a native exception it is propagated back to the
        caller and initialization is considered NOT to have
        occurred, meaning the next call to this function will also
        run InitFunctor()().

        If initialization, InCaT::Call(argv) is called and its value
        is returned.
    */
    static v8::Handle<v8::Value> Call( v8::Arguments const & argv )
    {
        static bool bob = false;
        if( ! bob )
        {
            InitFunctor()();
            /* Reminder: if it throws we do not set bob=true.
               This is part of the interface, not an accident.
            */
            bob = true;
        }
        return InCaT::Call( argv );
    }
};

It would be easy to rewrite to take an InvocationCallback as the template
arg instead of the InCaT type, but the latter just happens to fit better
with my library's model.

-- 
----- stephan beal
http://wanderinghorse.net/home/stephan/

-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users

Reply via email to