forked from cutelyst/cutelyst
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontroller.h
180 lines (163 loc) · 5.95 KB
/
controller.h
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
* Copyright (C) 2013-2017 Daniel Nicoletti <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef CUTELYST_CONTROLLER_H
#define CUTELYST_CONTROLLER_H
#include <QObject>
#include <Cutelyst/cutelyst_global.h>
#include <Cutelyst/action.h>
#include <Cutelyst/context.h>
#include <Cutelyst/request.h>
#include <Cutelyst/response.h>
#define STR(X) #X
#define C_PATH(X, Y) Q_CLASSINFO(STR(X ## _Path), STR(Y))
#define C_NAMESPACE(value) Q_CLASSINFO("Namespace", value)
#define C_ATTR(X, Y) Q_CLASSINFO(STR(X), STR(Y)) Q_INVOKABLE
# define CActionFor(str) \
([this]() -> Cutelyst::Action * { \
static thread_local Cutelyst::Action *action = \
Cutelyst::Controller::actionFor(str); \
return action; \
}()) \
/**/
namespace Cutelyst {
class ControllerPrivate;
/*! \class Controller controller.h Cutelyst/Controller
* @brief %Cutelyst %Controller base class
*
* Controllers are where the actions in the Cutelyst framework reside.
* Each action is represented by a function with an attribute to identify
* what kind of action it is. See the Cutelyst::Dispatcher for more info
* about how Cutelyst dispatches to actions.
*
* Use C_ATTR to give hints about methods
* build like methodName_option
* Where option is one of the following:
*
* \b :Path - An ending path relative to the class info Namespace
* for example:
* \n :Path("") - /namespace/controlername (used for the index)
* \n :Path("foo") - /namespace/controlername/foo
* \n :Path("/bar") - /namespace/bar
*
* \b :Chained - Sets the name of this part of the chain. If it
* is specified without arguments, it takes the name of
* the action as default.
*
* \b :PathPart - The part of the chained path
*
* \b :Args - In the case of more than 9 parameters, to build
* the path set the needed number here, where an empty string
* means unlimited arguments.
*
* \b :CaptureArgs - In the case of more than 9 parameters, to
* be captured the path set the needed number here, where -1
* means unlimited arguments.
*
* \b :Global - Alias to Path="/methodname" which sets the
* method relative to your root.
*
* \b :Local - Alias to Path="methodname".
*
* \b :Args - When used with "Path" it indicates the number of
* arguments in the path.
* \n The number is computed by counting the arguments the method expects.
* \n However if no Args value is set, assumed to 'slurp' all
* remaining path parts under this namespace.
*
* There are also three special methods that can be implemented
* that will be automatically dispatched, they are Begin(),
* Auto() and End().
*
* Begin(Context*) and End(Context*) are both called on the closest
* namespace match. If the Controller implements Begin it's that action
* that will be called otherwise it will try to match looking at the
* namespace.
*
* Auto(Context*) is called in namespace order, so if
* you have a Foo and a FooBar controller with 'foo' and 'foo/bar'
* namespaces respectively and both implement Auto(), you get
* Foo->Auto() and FooBar->Auto() called.
*/
class CUTELYST_LIBRARY Controller : public QObject
{
Q_OBJECT
public:
/**
* Constructs a Controller object with the given \p parent.
*/
explicit Controller(QObject *parent = nullptr);
virtual ~Controller();
/**
* This specifies the internal namespace the controller should
* be bound to.
* By default the controller is bound to the URI version of the
* controller name. For instance a controller named
* 'MyFooBar' will be bound to 'my/foo/bar'.
* The default Root controller is an example of setting
* namespace to '' (the null string).
*/
QString ns() const;
/**
* Returns the Cutelyst::Action object (if any) for a given method name in
* this class namespace.
*
* You can also use the macro CActionFor to keep the resolved action around.
*/
Action *actionFor(const QString &name) const;
/**
* Returns the Cutelyst::ActionList containing all actions which belongs to
* this controller.
*/
ActionList actions() const;
/**
* Return TRUE if className is equal to this Controller's name
*/
bool operator==(const char *className);
protected:
/**
* This method is called right after Controller has been setup
* and before application forks and \sa postFork() is called.
*
* Reimplement this method if you need to configure
* internal variable and you need to know for
* example which configuration options are enabled.
*/
virtual bool preFork(Application *app);
/**
* This method is called after the application
* has registered all controllers.
*
* Reimplement this method if you need to configure
* internal variable and you need to know for
* example which configuration options are enabled.
*/
virtual bool postFork(Application *app);
/**
* This is called by the dispatch engine to do the contextual action dispatching.
* Transversing each namespace's Begin(), nearest Auto(), the Action method of
* this controller and nearest End().
*/
bool _DISPATCH(Context *c);
ControllerPrivate *d_ptr;
private:
Q_DECLARE_PRIVATE(Controller)
friend class Application;
friend class Dispatcher;
};
}
#endif // CUTELYST_CONTROLLER_H