luaobject.go
func (lo *LuaObject) Call(results interface{}, args ...interface{}) error {
	L := lo.l
	// Push the callable value.
	lo.Push()
	if !L.IsFunction(-1) {
		if !L.GetMetaField(-1, "__call") {
			L.Pop(1)
			return ErrLuaObjectCallable
		}
		// We leave the __call metamethod on stack.
		L.Remove(-2)
	}

	// Push the args.
	for _, arg := range args {
		GoToLuaProxy(L, arg)
	}

	// Special case: discard the results.
	if results == nil {
		err := L.Call(len(args), 0)
		if err != nil {
			L.Pop(1)
			return err
		}
		return nil
	}

	resptr := reflect.ValueOf(results)
	if resptr.Kind() != reflect.Ptr {
		return ErrLuaObjectCallResults
	}
	res := resptr.Elem()

	switch res.Kind() {
	case reflect.Ptr:
		err := L.Call(len(args), 1)
		defer L.Pop(1)
		if err != nil {
			return err
		}
		return LuaToGo(L, -1, res.Interface())

	case reflect.Slice:
		residx := L.GetTop() - len(args)
		err := L.Call(len(args), lua.LUA_MULTRET)
		if err != nil {
			L.Pop(1)
			return err
		}

		nresults := L.GetTop() - residx + 1
		defer L.Pop(nresults)
		t := res.Type()

		// Adjust the length of the slice.
		if res.IsNil() || nresults > res.Len() {
			v := reflect.MakeSlice(t, nresults, nresults)
			res.Set(v)
		} else if nresults < res.Len() {
			res.SetLen(nresults)
		}

		for i := 0; i < nresults; i++ {
			err = LuaToGo(L, residx+i, res.Index(i).Addr().Interface())
			if err != nil {
				return err
			}
		}

	case reflect.Struct:
		exportedFields := []reflect.Value{}
		for i := 0; i < res.NumField(); i++ {
			if res.Field(i).CanInterface() {
				exportedFields = append(exportedFields, res.Field(i).Addr())
			}
		}
		nresults := len(exportedFields)
		err := L.Call(len(args), nresults)
		if err != nil {
			L.Pop(1)
			return err
		}
		defer L.Pop(nresults)
		residx := L.GetTop() - nresults + 1

		for i := 0; i < nresults; i++ {
			err = LuaToGo(L, residx+i, exportedFields[i].Interface())
			if err != nil {
				return err
			}
		}

	default:
		return ErrLuaObjectCallResults
	}

	return nil
}
func (lo *LuaObject) Call(results interface{}, args ...interface{}) error {
	L := lo.l
	// Push the callable value.
	lo.Push()
	if !L.IsFunction(-1) {
		if !L.GetMetaField(-1, "__call") {
			L.Pop(1)
			return ErrLuaObjectCallable
		}
		// We leave the __call metamethod on stack.
		L.Remove(-2)
	}

	// Push the args.
	for _, arg := range args {
		GoToLuaProxy(L, arg)
	}

	// Special case: discard the results.
	if results == nil {
		err := L.Call(len(args), 0)
		if err != nil {
			L.Pop(1)
			return err
		}
		return nil
	}

	resptr := reflect.ValueOf(results)
	if resptr.Kind() != reflect.Ptr {
		return ErrLuaObjectCallResults
	}
	res := resptr.Elem()

	switch res.Kind() {
	case reflect.Ptr:
		err := L.Call(len(args), 1)
		defer L.Pop(1)
		if err != nil {
			return err
		}
		return LuaToGo(L, -1, res.Interface())

	case reflect.Slice:
		residx := L.GetTop() - len(args)
		err := L.Call(len(args), lua.LUA_MULTRET)
		if err != nil {
			L.Pop(1)
			return err
		}

		nresults := L.GetTop() - residx + 1
		defer L.Pop(nresults)
		t := res.Type()

		// Adjust the length of the slice.
		if res.IsNil() || nresults > res.Len() {
			v := reflect.MakeSlice(t, nresults, nresults)
			res.Set(v)
		} else if nresults < res.Len() {
			res.SetLen(nresults)
		}

		for i := 0; i < nresults; i++ {
			err = LuaToGo(L, residx+i, res.Index(i).Addr().Interface())
			if err != nil {
				return err
			}
		}

	case reflect.Struct:
		exportedFields := []reflect.Value{}
		for i := 0; i < res.NumField(); i++ {
			if res.Field(i).CanInterface() {
				exportedFields = append(exportedFields, res.Field(i).Addr())
			}
		}
		nresults := len(exportedFields)
		err := L.Call(len(args), nresults)
		if err != nil {
			L.Pop(1)
			return err
		}
		defer L.Pop(nresults)
		residx := L.GetTop() - nresults + 1

		for i := 0; i < nresults; i++ {
			err = LuaToGo(L, residx+i, exportedFields[i].Interface())
			if err != nil {
				return err
			}
		}

	default:
		return ErrLuaObjectCallResults
	}

	return nil
}
func ( lo * LuaObject ) Call ( results interface { } , args ... interface { } ) error { L := lo . l // Push the callable value. lo . Push ( ) if ! L . IsFunction ( - 1 ) { if ! L . GetMetaField ( - 1 , " " ) { L . Pop ( 1 ) return ErrLuaObjectCallable } // We leave the __call metamethod on stack. L . Remove ( - 2 ) } // Push the args. for _ , arg := range args { GoToLuaProxy ( L , arg ) } // Special case: discard the results. if results == nil { err := L . Call ( len ( args ) , 0 ) if err != nil { L . Pop ( 1 ) return err } return nil } resptr := reflect . ValueOf ( results ) if resptr . Kind ( ) != reflect . Ptr { return ErrLuaObjectCallResults } res := resptr . Elem ( ) switch res . Kind ( ) { case reflect . Ptr : err := L . Call ( len ( args ) , 1 ) defer L . Pop ( 1 ) if err != nil { return err } return LuaToGo ( L , - 1 , res . Interface ( ) ) case reflect . Slice : residx := L . GetTop ( ) - len ( args ) err := L . Call ( len ( args ) , lua . LUA_MULTRET ) if err != nil { L . Pop ( 1 ) return err } nresults := L . GetTop ( ) - residx + 1 defer L . Pop ( nresults ) t := res . Type ( ) // Adjust the length of the slice. if res . IsNil ( ) || nresults > res . Len ( ) { v := reflect . MakeSlice ( t , nresults , nresults ) res . Set ( v ) } else if nresults < res . Len ( ) { res . SetLen ( nresults ) } for i := 0 ; i < nresults ; i ++ { err = LuaToGo ( L , residx + i , res . Index ( i ) . Addr ( ) . Interface ( ) ) if err != nil { return err } } case reflect . Struct : exportedFields := [ ] reflect . Value { } for i := 0 ; i < res . NumField ( ) ; i ++ { if res . Field ( i ) . CanInterface ( ) { exportedFields = append ( exportedFields , res . Field ( i ) . Addr ( ) ) } } nresults := len ( exportedFields ) err := L . Call ( len ( args ) , nresults ) if err != nil { L . Pop ( 1 ) return err } defer L . Pop ( nresults ) residx := L . GetTop ( ) - nresults + 1 for i := 0 ; i < nresults ; i ++ { err = LuaToGo ( L , residx + i , exportedFields [ i ] . Interface ( ) ) if err != nil { return err } } default : return ErrLuaObjectCallResults } return nil }
// Call calls a Lua function, given the desired results and the arguments.
// 'results' must be a pointer to a pointer/struct/slice.
//
// - If a pointer, then only the first result is stored to that pointer.
//
// - If a struct with 'n' exported fields, then the first 'n' results are stored in the first 'n' exported fields.
//
// - If a slice, then all the results are stored in the slice. The slice is re-allocated if necessary.
//
// If the function returns more values than can be stored in the 'results'
// argument, they will be ignored.
//
// If 'results' is nil, results will be discarded.
Call calls a Lua function given the desired results and the arguments . results must be a pointer to a pointer / struct / slice . - If a pointer then only the first result is stored to that pointer . - If a struct with n exported fields then the first n results are stored in the first n exported fields . - If a slice then all the results are stored in the slice . The slice is re - allocated if necessary . If the function returns more values than can be stored in the results argument they will be ignored . If results is nil results will be discarded .