@@ -2,6 +2,7 @@ package neffos
2
2
3
3
import (
4
4
"reflect"
5
+ "strings"
5
6
)
6
7
7
8
func indirectType (typ reflect.Type ) reflect.Type {
@@ -109,8 +110,8 @@ func resolveStructNamespace(v reflect.Value) (string, bool) {
109
110
if ok {
110
111
if getNamespace , ok := v .Method (method .Index ).Interface ().(func () string ); ok {
111
112
namespace := getNamespace ()
112
- debugf ("set namespace [%s ] from method [%s.%s]" , func () dargs {
113
- return dargs {namespace , indirectType (typ ). Name ( ), method .Name }
113
+ debugf ("Set namespace [\" %s \" ] from method [%s.%s]" , func () dargs {
114
+ return dargs {namespace , nameOf (typ ), method .Name }
114
115
})
115
116
116
117
return namespace , true
@@ -123,8 +124,8 @@ func resolveStructNamespace(v reflect.Value) (string, bool) {
123
124
if f , ok := typ .FieldByNameFunc (func (s string ) bool { return s == "Namespace" }); ok {
124
125
if f .Type .Kind () == reflect .String {
125
126
namespace := v .Field (f .Index [0 ]).String ()
126
- debugf ("set namespace [%s ] from field [%s.%s]" , func () dargs {
127
- return dargs {namespace , typ . Name ( ), f .Name }
127
+ debugf ("Set namespace [\" %s \" ] from field [%s.%s]" , func () dargs {
128
+ return dargs {namespace , nameOf ( typ ), f .Name }
128
129
})
129
130
return namespace , true
130
131
}
@@ -204,15 +205,27 @@ func makeEventFromMethod(v reflect.Value, method reflect.Method, eventMatcher Ev
204
205
// the NSConn exists on the "controller" itself which is set dynamically.
205
206
cb = func (c * NSConn , msg Message ) error {
206
207
// load an existing instance which contains the same "c".
207
- cachePtr := c .Value .Load ().(reflect.Value )
208
- return cachePtr .Method (method .Index ).Interface ().(func (Message ) error )(msg )
208
+ return c .value .Method (method .Index ).Interface ().(func (Message ) error )(msg )
209
209
}
210
210
}
211
211
212
212
return
213
213
}
214
214
215
- func makeEventsFromStruct (v reflect.Value , eventMatcher EventMatcherFunc ) Events {
215
+ // StructInjector is a type which injects a dynamic struct value.
216
+ // See `Struct.SetInjector` for more.
217
+ type StructInjector func (structType reflect.Type , nsConn * NSConn ) (structValue reflect.Value )
218
+
219
+ func nameOf (structType reflect.Type ) string {
220
+ structType = indirectType (structType )
221
+
222
+ typName := structType .Name ()
223
+ pkgPath := structType .PkgPath ()
224
+ fullname := pkgPath [strings .LastIndexByte (pkgPath , '/' )+ 1 :] + "." + typName
225
+ return fullname
226
+ }
227
+
228
+ func makeEventsFromStruct (v reflect.Value , eventMatcher EventMatcherFunc , injector StructInjector ) Events {
216
229
events := make (Events , 0 )
217
230
218
231
typ := v .Type ()
@@ -233,60 +246,59 @@ func makeEventsFromStruct(v reflect.Value, eventMatcher EventMatcherFunc) Events
233
246
continue
234
247
}
235
248
236
- debugf ("event [%s ] is handled by [%s.%s]" , func () dargs {
237
- return dargs {eventName , indirectType (typ ). Name ( ), method .Name }
249
+ debugf ("Event [ \" %s \" ] is handled by [%s.%s] method " , func () dargs {
250
+ return dargs {eventName , nameOf (typ ), method .Name }
238
251
})
239
252
240
253
events [eventName ] = cb
241
254
}
242
255
243
256
if nsConnFieldIndex != - 1 {
244
- // if it's a dynamic.
245
257
typ = indirectType (typ )
246
258
247
- cb , hasNamespaceConnect := events [OnNamespaceConnect ]
248
- staticFields := getNonZeroFields (v )
249
-
250
- // debugf("field [%s.%s] will be automatically re-filled with [%T(%s)]", func(fidx int, f reflect.Value) dargs {
251
- // fval := f.Interface()
252
- // return dargs{typ.Name(), typ.Field(fidx).Name, fval, fval}
253
- // }).forEach(staticFields)
254
-
255
- debugEach (staticFields , func (idx int , f reflect.Value ) {
256
- fval := f .Interface ()
257
- fname := typ .Field (idx ).Name
258
- if fname == "Namespace" {
259
- return // let's no log this as user field because
260
- // it's optionally used to provide a namespace on NewStruct.getNamespaces().
261
- }
259
+ var staticFields map [int ]reflect.Value
262
260
263
- debugf ("field [%s.%s] marked as static on value [%v]" , typ .Name (), fname , fval )
264
- })
261
+ if injector == nil {
262
+ // maybe this should be added no matter what, I have to check
263
+ // some things in our company's production server first.
264
+ staticFields = getNonZeroFields (v )
265
+
266
+ debugEach (staticFields , func (idx int , f reflect.Value ) {
267
+ fval := f .Interface ()
268
+ fname := typ .Field (idx ).Name
269
+ if fname == "Namespace" {
270
+ // let's no log this as user field because
271
+ // it's optionally used to provide a namespace on NewStruct.GetNamespaces().
272
+ return
273
+ }
274
+
275
+ debugf ("Field [%s.%s] marked as static on value [%v]" , nameOf (typ ), fname , fval )
276
+ })
277
+
278
+ injector = func (typ reflect.Type , nsConn * NSConn ) reflect.Value {
279
+ return reflect .New (typ )
280
+ }
281
+ }
265
282
266
- // if debugEnabled() {
267
- // for fidx, f := range staticFields {
268
- // fval := f.Interface()
269
- // debugf(, typ.Name(), typ.Field(fidx).Name, fval, fval)
270
- // }
271
- // }
283
+ cb , hasNamespaceConnect := events [OnNamespaceConnect ]
272
284
273
285
events [OnNamespaceConnect ] = func (c * NSConn , msg Message ) error {
274
- // create a new elem instance.
275
- cachePtr := reflect .New (typ )
286
+ cachePtr := injector (typ , c )
276
287
cacheElem := cachePtr .Elem ()
277
288
278
289
// set the NSConn dynamic field.
279
290
cacheElem .Field (nsConnFieldIndex ).Set (reflect .ValueOf (c ))
291
+
280
292
if staticFields != nil {
281
- // set any static fields.
293
+ // set any static fields if default injector (see above) .
282
294
for findex , fvalue := range staticFields {
283
295
cacheElem .Field (findex ).Set (fvalue )
284
296
}
285
297
}
286
298
287
299
// Store it for the rest of the events inside
288
300
// this namespace of that specific connection.
289
- c .Value . Store ( cachePtr )
301
+ c .value = cachePtr
290
302
291
303
if hasNamespaceConnect {
292
304
return cb (c , msg )
0 commit comments