1
0
mirror of https://github.com/kataras/iris.git synced 2025-12-20 03:17:04 +00:00

performance close to handlers if no bindings but even if bindings except service (new feature is that we can bind functions as well) is x1.1 faster than the previous mvc implementation - make BaseController (so and C) optionally but not break the existing APIs that using iris.C or mvc.C

Former-commit-id: a26a8f836894c061e0f435df8ac1c2c534f0ee48
This commit is contained in:
Gerasimos (Makis) Maropoulos
2017-12-13 06:17:28 +02:00
parent 257f1318c9
commit 8dcbdc0741
11 changed files with 238 additions and 74 deletions

99
mvc2/bind_values.go Normal file
View File

@@ -0,0 +1,99 @@
package mvc2
import (
"reflect"
)
/// TODO:
// create another package because these bindings things are useful
// for other libraries I'm working on, so something like github.com/kataras/di
// will be great, combine these with the bind.go and controller's inside handler
// but generic things.
type ValueStore []reflect.Value
// Bind binds values to this controller, if you want to share
// binding values between controllers use the Engine's `Bind` function instead.
func (bv *ValueStore) Bind(values ...interface{}) {
for _, val := range values {
bv.bind(reflect.ValueOf(val))
}
}
func (bv *ValueStore) bind(v reflect.Value) {
if !goodVal(v) {
return
}
*bv = append(*bv, v)
}
// Unbind unbinds a binding value based on the type,
// it returns true if at least one field is not binded anymore.
//
// The "n" indicates the number of elements to remove, if <=0 then it's 1,
// this is useful because you may have bind more than one value to two or more fields
// with the same type.
func (bv *ValueStore) Unbind(value interface{}, n int) bool {
return bv.unbind(reflect.TypeOf(value), n)
}
func (bv *ValueStore) unbind(typ reflect.Type, n int) (ok bool) {
input := *bv
for i, in := range input {
if equalTypes(in.Type(), typ) {
ok = true
input = input[:i+copy(input[i:], input[i+1:])]
if n > 1 {
continue
}
break
}
}
*bv = input
return
}
// BindExists returns true if a binder responsible to
// bind and return a type of "typ" is already registered to this controller.
func (bv *ValueStore) BindExists(value interface{}) bool {
return bv.bindTypeExists(reflect.TypeOf(value))
}
func (bv *ValueStore) bindTypeExists(typ reflect.Type) bool {
input := *bv
for _, in := range input {
if equalTypes(in.Type(), typ) {
return true
}
}
return false
}
// BindIfNotExists bind a value to the controller's field with the same type,
// if it's not binded already.
//
// Returns false if binded already or the value is not the proper one for binding,
// otherwise true.
func (bv *ValueStore) BindIfNotExists(value interface{}) bool {
return bv.bindIfNotExists(reflect.ValueOf(value))
}
func (bv *ValueStore) bindIfNotExists(v reflect.Value) bool {
var (
typ = v.Type() // no element, raw things here.
)
if !goodVal(v) {
return false
}
if bv.bindTypeExists(typ) {
return false
}
bv.bind(v)
return true
}