summaryrefslogtreecommitdiff
path: root/include/method.h
blob: 9398fd75f3f01c92ebc7eb1ad42129fb34952777 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/**
 *  Method.h
 */
 
/**
 *  Namespace
 */
namespace Php {

/**
 *  A very generic function pointer
 */
typedef void (*function_ptr)();

/**
 *  Base class of the method
 */
class _Method
{
public:
    /**
     *  Copy constructor
     *  @param  method
     */
    _Method(const _Method &method) : _type(method._type), _callback(method._callback) {}

    /**
     *  Destructor
     *  @param  type
     *  @param  callback
     */
    virtual ~_Method() {}

    /**
     *  Invoke the method
     *  @param  environment
     *  @param  parameters
     *  @return Value
     */
    Value invoke(Environment &environment, Parameters &parameters)
    {
        // the object to call a method on
        Base *base = parameters.object();
        
        // find out which method to call, and call it
        switch (_type) {
        case 0:     (base->*_callback.m0)(); return Value();
        case 1:     (base->*_callback.m1)(parameters); return Value();
        case 2:     (base->*_callback.m2)(environment); return Value();
        case 3:     (base->*_callback.m3)(environment, parameters); return Value();
        case 4:     return (base->*_callback.m4)();
        case 5:     return (base->*_callback.m5)(parameters);
        case 6:     return (base->*_callback.m6)(environment);
        case 7:     return (base->*_callback.m7)(environment, parameters);
        default:    return Value();
        }
    }

protected:
    /**
     *  Protected constructor to prevent that anyone instantiates this object
     */
    _Method(method_callback_0 callback) : _type(0) { _callback.m0 = callback; }
    _Method(method_callback_1 callback) : _type(1) { _callback.m1 = callback; }
    _Method(method_callback_2 callback) : _type(2) { _callback.m2 = callback; }
    _Method(method_callback_3 callback) : _type(3) { _callback.m3 = callback; }
    _Method(method_callback_4 callback) : _type(4) { _callback.m4 = callback; }
    _Method(method_callback_5 callback) : _type(5) { _callback.m5 = callback; }
    _Method(method_callback_6 callback) : _type(6) { _callback.m6 = callback; }
    _Method(method_callback_7 callback) : _type(7) { _callback.m7 = callback; }
    
private:
    /**
     *  Callback type
     *  @var int
     */
    int _type;
    
    /**
     *  The actual callback
     *  @var void*
     */
    union {
         method_callback_0 m0;
         method_callback_1 m1;
         method_callback_2 m2;
         method_callback_3 m3;
         method_callback_4 m4;
         method_callback_5 m5;
         method_callback_6 m6;
         method_callback_7 m7;
    } _callback;
};

/**
 *  Actual template class of the method
 */
template <typename T>
class Method : public _Method
{
public:
    /**
     *  Constructor
     *  @param  callback
     */
    Method(void(T::*callback)())                            : _Method(static_cast<method_callback_0>(callback)) {}
    Method(void(T::*callback)(Parameters&))                 : _Method(static_cast<method_callback_1>(callback)) {}
    Method(void(T::*callback)(Environment&))                : _Method(static_cast<method_callback_2>(callback)) {}
    Method(void(T::*callback)(Environment&,Parameters&))    : _Method(static_cast<method_callback_3>(callback)) {}
    Method(Value(T::*callback)())                           : _Method(static_cast<method_callback_4>(callback)) {}
    Method(Value(T::*callback)(Parameters&))                : _Method(static_cast<method_callback_5>(callback)) {}
    Method(Value(T::*callback)(Environment&))               : _Method(static_cast<method_callback_6>(callback)) {}
    Method(Value(T::*callback)(Environment&,Parameters&))   : _Method(static_cast<method_callback_7>(callback)) {}
    
    /**
     *  Destructor
     */
    virtual ~Method() {}

};
    
/**
 *  End of namespace
 */
}