@@ -24,7 +24,7 @@ type Controller struct {
24
24
Type * ControllerType // A description of the controller type.
25
25
MethodName string // The method name, e.g. "Index"
26
26
MethodType * MethodType // A description of the invoked action type.
27
- AppController interface {} // The controller that was instantiated.
27
+ AppController interface {} // The controller that was instantiated. extends from revel.Controller
28
28
Action string // The fully qualified action name, e.g. "App.Index"
29
29
ClientIP string // holds IP address of request came from
30
30
@@ -39,8 +39,14 @@ type Controller struct {
39
39
ViewArgs map [string ]interface {} // Variables passed to the template.
40
40
Validation * Validation // Data validation helpers
41
41
}
42
+ type BaseController struct {
43
+ SetAppController (interface {})
44
+ }
42
45
43
46
// NewController returns new controller instance for Request and Response
47
+ func NewControllerEmpty () * Controller {
48
+ return & Controller {}
49
+ }
44
50
func NewController (req * Request , resp * Response ) * Controller {
45
51
return & Controller {
46
52
Request : req ,
@@ -53,6 +59,52 @@ func NewController(req *Request, resp *Response) *Controller {
53
59
},
54
60
}
55
61
}
62
+ func (c * Controller ) SetController (req * Request , resp * Response ) {
63
+
64
+ c .Request = req
65
+ c .Response = resp
66
+ c .Params = new (Params )
67
+ c .Args = map [string ]interface {}{}
68
+ c .ViewArgs = map [string ]interface {}{
69
+ "RunMode" : RunMode ,
70
+ "DevMode" : DevMode ,
71
+ }
72
+
73
+ }
74
+ func (c * Controller ) Destroy () {
75
+ // When the instantiated controller gets injected
76
+ // It inherits this method, so we need to
77
+ // check to see if the controller is nil before performing
78
+ // any actions
79
+ if c == nil {
80
+ return
81
+ }
82
+ if c .AppController != nil {
83
+ c .resetAppControllerFields ()
84
+ // Return this instance to the pool
85
+ appController := c .AppController
86
+ c .AppController = nil
87
+ cachedControllerMap [c .Name ].Push (appController )
88
+ c .AppController = nil
89
+ }
90
+ c .Request = nil
91
+ c .Response = nil
92
+ c .Params = nil
93
+ c .Args = nil
94
+ c .ViewArgs = nil
95
+ c .Name = ""
96
+ c .Type = nil
97
+ c .MethodName = ""
98
+ c .MethodType = nil
99
+ c .Action = ""
100
+ c .ClientIP = ""
101
+ c .Result = nil
102
+ c .Flash = Flash {}
103
+ c .Session = Session {}
104
+ c .Params = nil
105
+ c .Validation = nil
106
+
107
+ }
56
108
57
109
// FlashParams serializes the contents of Controller.Params to the Flash
58
110
// cookie.
@@ -63,7 +115,8 @@ func (c *Controller) FlashParams() {
63
115
}
64
116
65
117
func (c * Controller ) SetCookie (cookie * http.Cookie ) {
66
- http .SetCookie (c .Response .Out , cookie )
118
+ c .Response .Out .Header ().SetCookie (cookie .String ())
119
+
67
120
}
68
121
69
122
func (c * Controller ) RenderError (err error ) Result {
@@ -130,7 +183,7 @@ func (c *Controller) RenderTemplate(templatePath string) Result {
130
183
}
131
184
132
185
return & RenderTemplateResult {
133
- Template : template ,
186
+ Template : template ,
134
187
ViewArgs : c .ViewArgs ,
135
188
}
136
189
}
@@ -263,11 +316,23 @@ func (c *Controller) Redirect(val interface{}, args ...interface{}) Result {
263
316
return & RedirectToActionResult {val }
264
317
}
265
318
319
+ // This stats returns some interesting stats based on what is cached in memory
320
+ // and what is available directly
321
+ func (c * Controller ) Stats () map [string ]interface {} {
322
+ result := CurrentEngine .Stats ()
323
+ result ["revel-controllers" ] = controllerStack .String ()
324
+ result ["revel-requests" ] = requestStack .String ()
325
+ result ["revel-response" ] = responseStack .String ()
326
+ for key ,appStack := range cachedControllerMap {
327
+ result ["app-" + key ] = appStack .String ()
328
+ }
329
+ return result
330
+ }
266
331
// Message performs a lookup for the given message name using the given
267
332
// arguments using the current language defined for this controller.
268
333
//
269
334
// The current language is set by the i18n plugin.
270
- func (c * Controller ) Message (message string , args ... interface {}) ( value string ) {
335
+ func (c * Controller ) Message (message string , args ... interface {}) string {
271
336
return MessageFunc (c .Request .Locale , message , args ... )
272
337
}
273
338
@@ -286,27 +351,51 @@ func (c *Controller) SetAction(controllerName, methodName string) error {
286
351
287
352
c .Name , c .MethodName = c .Type .Type .Name (), c .MethodType .Name
288
353
c .Action = c .Name + "." + c .MethodName
289
-
354
+ if _ , ok := cachedControllerMap [c .Name ]; ! ok {
355
+ // Create a new stack for this controller
356
+ localType := c .Type .Type
357
+ cachedControllerMap [c .Name ] = NewStackLock (cachedControllerStackSize , func () interface {} {
358
+ return reflect .New (localType ).Interface ()
359
+ })
360
+ }
290
361
// Instantiate the controller.
291
- c .AppController = initNewAppController (c .Type , c ).Interface ()
362
+ c .AppController = cachedControllerMap [c .Name ].Pop ()
363
+ c .setAppControllerFields ()
364
+
365
+ // TODO Old method, remove c.AppController = initNewAppController(c.Type, c).Interface()
292
366
293
367
return nil
294
368
}
369
+ func (c * Controller ) setAppControllerFields () {
370
+ appController := reflect .ValueOf (c .AppController ).Elem () //.(reflect.Value).Elem()
371
+ cValue := reflect .ValueOf (c )
372
+ for _ , index := range c .Type .ControllerIndexes {
373
+ appController .FieldByIndex (index ).Set (cValue )
374
+ }
375
+ }
376
+ func (c * Controller ) resetAppControllerFields () {
377
+ appController := reflect .ValueOf (c .AppController ).Elem ()
378
+ // Zero out controller
379
+ for _ , index := range c .Type .ControllerIndexes {
380
+ appController .FieldByIndex (index ).Set (reflect .Zero (reflect .TypeOf (c .AppController ).Elem ().FieldByIndex (index ).Type ))
381
+ }
382
+ }
295
383
296
384
// This is a helper that initializes (zeros) a new app controller value.
297
385
// Specifically, it sets all *revel.Controller embedded types to the provided controller.
298
386
// Returns a value representing a pointer to the new app controller.
299
- func initNewAppController (appControllerType * ControllerType , c * Controller ) reflect.Value {
300
- var (
301
- appControllerPtr = reflect .New (appControllerType .Type )
302
- appController = appControllerPtr .Elem ()
303
- cValue = reflect .ValueOf (c )
304
- )
305
- for _ , index := range appControllerType .ControllerIndexes {
306
- appController .FieldByIndex (index ).Set (cValue )
307
- }
308
- return appControllerPtr
309
- }
387
+ // TODO Unneeded method
388
+ //func initNewAppController(appControllerType *ControllerType, c *Controller) reflect.Value {
389
+ // var (
390
+ // appControllerPtr = reflect.New(appControllerType.Type)
391
+ // appController = appControllerPtr.Elem()
392
+ // cValue = reflect.ValueOf(c)
393
+ // )
394
+ // for _, index := range appControllerType.ControllerIndexes {
395
+ // appController.FieldByIndex(index).Set(cValue)
396
+ // }
397
+ // return appControllerPtr
398
+ //}
310
399
311
400
func findControllers (appControllerType reflect.Type ) (indexes [][]int ) {
312
401
// It might be a multi-level embedding. To find the controllers, we follow
0 commit comments