Пример #1
0
Файл: qml.go Проект: hahaya/qml
func registerType(spec *TypeSpec, singleton bool) error {
	// Copy and hold a reference to the spec data.
	localSpec := *spec

	// TODO Validate localSpec fields.

	var err error
	gui(func() {
		sample := spec.New()
		if sample == nil {
			err = fmt.Errorf("TypeSpec.New for type %q returned nil", spec.Name)
			return
		}

		cloc := C.CString(localSpec.Location)
		cname := C.CString(localSpec.Name)
		if singleton {
			C.registerSingleton(cloc, C.int(localSpec.Major), C.int(localSpec.Minor), cname, typeInfo(sample), unsafe.Pointer(&localSpec))
		} else {
			C.registerType(cloc, C.int(localSpec.Major), C.int(localSpec.Minor), cname, typeInfo(sample), unsafe.Pointer(&localSpec))
		}
		// TODO Check if qmlRegisterType keeps a reference to those.
		//C.free(unsafe.Pointer(cloc))
		//C.free(unsafe.Pointer(cname))
		types = append(types, &localSpec)
	})

	// TODO Are there really no errors possible from qmlRegisterType?
	return err
}
Пример #2
0
func registerType(spec *TypeSpec, singleton bool) error {
	// Copy and hold a reference to the spec data.
	localSpec := *spec

	// TODO Validate localSpec fields.

	var err error
	gui(func() {
		sample := spec.New()
		if sample == nil {
			err = fmt.Errorf("TypeSpec.New for type %q returned nil", spec.Name)
			return
		}

		cloc := C.CString(localSpec.Location)
		cname := C.CString(localSpec.Name)
		cres := C.int(0)
		if singleton {
			cres = C.registerSingleton(cloc, C.int(localSpec.Major), C.int(localSpec.Minor), cname, typeInfo(sample), unsafe.Pointer(&localSpec))
		} else {
			cres = C.registerType(cloc, C.int(localSpec.Major), C.int(localSpec.Minor), cname, typeInfo(sample), unsafe.Pointer(&localSpec))
		}
		// It doesn't look like it keeps references to these, but it's undocumented and unclear.
		C.free(unsafe.Pointer(cloc))
		C.free(unsafe.Pointer(cname))
		if cres == -1 {
			err = fmt.Errorf("QML engine failed to register type; invalid type location or name?")
		} else {
			types = append(types, &localSpec)
		}
	})

	return err
}
Пример #3
0
func registerType(location string, major, minor int, spec *TypeSpec) error {
	// Copy and hold a reference to the spec data.
	localSpec := *spec

	f := reflect.ValueOf(localSpec.Init)
	ft := f.Type()
	if ft.Kind() != reflect.Func {
		return fmt.Errorf("TypeSpec.Init must be a function, got %#v", localSpec.Init)
	}
	if ft.NumIn() != 1 {
		return fmt.Errorf("TypeSpec.Init's function must accept single argument: %s", ft)
	}
	// firstArg := ft.In(0)
	// if firstArg.Kind() != reflect.Ptr || firstArg.Elem().Kind() == reflect.Ptr {
	//  return fmt.Errorf("TypeSpec.Init's function must take a pointer type as the first argument: %s", ft)
	// }
	if ft.In(0) != typeObject {
		return fmt.Errorf("TypeSpec.Init's function must take qml.Object as the second argument: %s", ft)
	}

	if ft.NumOut() != 1 {
		return fmt.Errorf("TypeSpec.Init's function must return instance pointer: %s", ft)
	}

	returnValue := ft.Out(0)
	if returnValue.Kind() != reflect.Ptr {
		return fmt.Errorf("TypeSpec.Init's function must return a pointer type: %s", ft)
	}

	customType := typeInfo(reflect.New(returnValue.Elem()).Interface())
	if localSpec.Name == "" {
		localSpec.Name = returnValue.Elem().Name()
		if localSpec.Name == "" {
			panic("cannot determine registered type name; please provide one explicitly")
		}
	}

	var err error
	RunMain(func() {
		cloc := C.CString(location)
		cname := C.CString(localSpec.Name)
		cres := C.int(0)
		if localSpec.Singleton {
			cres = C.registerSingleton(cloc, C.int(major), C.int(minor), cname, customType, unsafe.Pointer(&localSpec))
		} else {
			cres = C.registerType(cloc, C.int(major), C.int(minor), cname, customType, unsafe.Pointer(&localSpec))
		}
		// It doesn't look like it keeps references to these, but it's undocumented and unclear.
		C.free(unsafe.Pointer(cloc))
		C.free(unsafe.Pointer(cname))
		if cres == -1 {
			err = fmt.Errorf("QML engine failed to register type; invalid type location or name?")
		} else {
			types = append(types, &localSpec)
		}
	})

	return err
}