nativescript.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. // Copyright © 2019 - 2020 Oscar Campos <oscar.campos@thepimpam.com>
  2. // Copyright © 2017 - William Edwards
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License
  15. // Package gdnative provides a wrapper around Godot's nativescript
  16. // extension. It exists to provide a way to use Go as an alternative scripting
  17. // language from GDScript.
  18. package gdnative
  19. /*
  20. #include <nativescript/godot_nativescript.h>
  21. #include "nativescript.gen.h"
  22. #include "nativescript.h"
  23. #include "variant.h"
  24. */
  25. import "C"
  26. import (
  27. "log"
  28. "unsafe"
  29. )
  30. // PropertyUsageFlags is a Godot C godot_property_usage_flags wrapper
  31. type PropertyUsageFlags int
  32. func (p PropertyUsageFlags) getBase() C.godot_property_usage_flags {
  33. return C.godot_property_usage_flags(p)
  34. }
  35. // Property usage flags for bit masks
  36. const (
  37. PropertyUsageStorage PropertyUsageFlags = 1
  38. PropertyUsageEditor PropertyUsageFlags = 2
  39. PropertyUsageNetwork PropertyUsageFlags = 4
  40. PropertyUsageEditorHelper PropertyUsageFlags = 8
  41. PropertyUsageCheckable PropertyUsageFlags = 16 //used for editing global variables
  42. PropertyUsageChecked PropertyUsageFlags = 32 //used for editing global variables
  43. PropertyUsageInternationalized PropertyUsageFlags = 64 //hint for internationalized strings
  44. PropertyUsageGroup PropertyUsageFlags = 128 //used for grouping props in the editor
  45. PropertyUsageCategory PropertyUsageFlags = 256
  46. PropertyUsageStoreIfNonZero PropertyUsageFlags = 512 //only store if nonzero
  47. PropertyUsageStoreIfNonOne PropertyUsageFlags = 1024 //only store if false
  48. PropertyUsageNoInstanceState PropertyUsageFlags = 2048
  49. PropertyUsageRestartIfChanged PropertyUsageFlags = 4096
  50. PropertyUsageScriptVariable PropertyUsageFlags = 8192
  51. PropertyUsageStoreIfNull PropertyUsageFlags = 16384
  52. PropertyUsageAnimateAsTrigger PropertyUsageFlags = 32768
  53. PropertyUsageUpdateAllIfModified PropertyUsageFlags = 65536
  54. PropertyUsageDefault PropertyUsageFlags = PropertyUsageStorage | PropertyUsageEditor | PropertyUsageNetwork
  55. PropertyUsageDefaultIntl PropertyUsageFlags = PropertyUsageStorage | PropertyUsageEditor | PropertyUsageNetwork | PropertyUsageInternationalized
  56. PropertyUsageNoEditor PropertyUsageFlags = PropertyUsageStorage | PropertyUsageNetwork
  57. )
  58. // PropertyUsageFlagsLookupMap is a string-based lookup table of constants for PropertyUsageFlags.
  59. var PropertyUsageFlagsLookupMap = map[string]PropertyUsageFlags{
  60. "PropertyUsageStorage": PropertyUsageStorage,
  61. "PropertyUsageEditor": PropertyUsageEditor,
  62. "PropertyUsageNetwork": PropertyUsageNetwork,
  63. "PropertyUsageEditorHelper": PropertyUsageEditorHelper,
  64. "PropertyUsageCheckable": PropertyUsageCheckable,
  65. "PropertyUsageChecked": PropertyUsageChecked,
  66. "PropertyUsageInternationalized": PropertyUsageInternationalized,
  67. "PropertyUsageGroup": PropertyUsageGroup,
  68. "PropertyUsageCategory": PropertyUsageCategory,
  69. "PropertyUsageStoreIfNonZero": PropertyUsageStoreIfNonZero,
  70. "PropertyUsageStoreIfNonOne": PropertyUsageStoreIfNonOne,
  71. "PropertyUsageNoInstanceState": PropertyUsageNoInstanceState,
  72. "PropertyUsageRestartIfChanged": PropertyUsageRestartIfChanged,
  73. "PropertyUsageScriptVariable": PropertyUsageScriptVariable,
  74. "PropertyUsageStoreIfNull": PropertyUsageStoreIfNull,
  75. "PropertyUsageAnimateAsTrigger": PropertyUsageAnimateAsTrigger,
  76. "PropertyUsageUpdateAllIfModified": PropertyUsageUpdateAllIfModified,
  77. "PropertyUsageDefault": PropertyUsageDefault,
  78. "PropertyUsageDefaultIntl": PropertyUsageDefaultIntl,
  79. "PropertyUsageNoEditor": PropertyUsageNoEditor,
  80. }
  81. // CreateFunc will be called when we need to create a new instance of a class.
  82. // When it is called, the Godot object will passed as an argument, as well as the
  83. // methodData string, which is usually the name of the class to be created.
  84. type CreateFunc func(Object, string) string
  85. // CreateFuncRegistry is a mapping of instance creation functions. This map is
  86. // used whenever a CreateFunc is registered. It is also used to look up a
  87. // Creation function when Godot asks Go to create a new class instance.
  88. var CreateFuncRegistry = map[string]CreateFunc{}
  89. // DestroyFunc will be called when the object is destroyed. Takes the instance
  90. // object, method data, user data. The method data is generally the class name,
  91. // and the user data is generally the class instance id to destroy.
  92. type DestroyFunc func(Object, string, string)
  93. // DestroyFuncRegistry is a mapping of instance destroy functions. This map is
  94. // used whenever a DestroyFunc is registered. It is also used to look up a
  95. // Destroy function when Godot asks Go to destroy a class instance.
  96. var DestroyFuncRegistry = map[string]DestroyFunc{}
  97. // FreeFunc will be called when we should free the instance from memory. Takes
  98. // in method data. The method data is generally the class name to be freed.
  99. type FreeFunc func(string)
  100. // SetPropertyFunc will be called when Godot requests to set a property on a given
  101. // class. When it is called, the Godot object instance will be passed as an argument,
  102. // as well as the methodData (which is usually the name of the class), the
  103. // userData (which is generally the instance ID of the object), and the value
  104. // to set.
  105. type SetPropertyFunc func(Object, string, string, Variant)
  106. // SetPropertyFuncRegistry is a mapping of instance property setters. This map is
  107. // used whenever a SetPropertyFunc is registered. It is also used to look up
  108. // a property setter function when Godot asks Go to set a property on an object.
  109. var SetPropertyFuncRegistry = map[string]SetPropertyFunc{}
  110. // GetPropertyFunc will be called when Godot requests a property on a given class
  111. // instance. When it is called, Godot will pass the Godot object instance as an
  112. // argument, as well as the methodData (which is usually the name of the class),
  113. // and the userData (which is generally the instance ID of the object. You should
  114. // return the property as a Variant.
  115. type GetPropertyFunc func(Object, string, string) Variant
  116. // GetPropertyFuncRegistry is a mapping of instance property getters. This map is
  117. // used whenever a GetPropertyFunc is registered. It is also used to look up a
  118. // property getter function when Godot asks Go to get a property on an object.
  119. var GetPropertyFuncRegistry = map[string]GetPropertyFunc{}
  120. // FreeFuncRegistry is a mapping of instance free functions. This map is used
  121. // whenever a FreeFunc is registered. It is also used to look up a Free
  122. // function when Godot asks Go to free a class instance.
  123. var FreeFuncRegistry = map[string]FreeFunc{}
  124. // MethodFunc will be called when a method attached to an instance is called.
  125. // When it is called, it will be passed the Godot object the method is attached to,
  126. // the methodData string (which is usually the class and method name that is being called),
  127. // the userData string (which is usually the class instance ID), the number of
  128. // arguments being passed to the function, and a list of Variant arguments to pass
  129. // to the function.
  130. type MethodFunc func(Object, string, string, int, []Variant) Variant
  131. // MethodFuncRegistry is a mapping of instance method functions. This map is
  132. // used whenever a MethodFunc is registered. It is also used to look up a Method
  133. // function when Godot asks Go to call a class method.
  134. var MethodFuncRegistry = map[string]MethodFunc{}
  135. // InstanceCreateFunc is a structure that contains the instance creation function
  136. // that will be called when Godot asks Go to create a new instance of a class.
  137. type InstanceCreateFunc struct {
  138. base C.godot_instance_create_func
  139. CreateFunc CreateFunc
  140. MethodData string
  141. FreeFunc FreeFunc
  142. }
  143. func (i *InstanceCreateFunc) getBase() C.godot_instance_create_func {
  144. return i.base
  145. }
  146. // InstanceDestroyFunc is a structure that contains the instance destruction function
  147. // that will be called when Godot asks Go to destroy a class instance.
  148. type InstanceDestroyFunc struct {
  149. base C.godot_instance_destroy_func
  150. DestroyFunc DestroyFunc
  151. MethodData string
  152. FreeFunc FreeFunc
  153. }
  154. func (i *InstanceDestroyFunc) getBase() C.godot_instance_destroy_func {
  155. return i.base
  156. }
  157. // InstanceMethod is a structure that contains an instance method function that
  158. // will be called when Godot asks Go to call a method on a class.
  159. type InstanceMethod struct {
  160. base C.godot_instance_method
  161. Method MethodFunc
  162. MethodData string
  163. FreeFunc FreeFunc
  164. }
  165. func (i *InstanceMethod) getBase() C.godot_instance_method {
  166. return i.base
  167. }
  168. // MethodAttributes is a Godot C godot_method_attributes wrapper
  169. type MethodAttributes struct {
  170. base C.godot_method_attributes
  171. RPCType MethodRpcMode
  172. }
  173. func (m *MethodAttributes) getBase() C.godot_method_attributes {
  174. return m.base
  175. }
  176. // InstancePropertySet is a structure that contains an instance property setter
  177. // function that will be called when Godot asks Go to set a property on a class.
  178. type InstancePropertySet struct {
  179. base C.godot_property_set_func
  180. SetFunc SetPropertyFunc
  181. MethodData string
  182. FreeFunc FreeFunc
  183. }
  184. func (i *InstancePropertySet) getBase() C.godot_property_set_func {
  185. return i.base
  186. }
  187. // InstancePropertyGet is a structure that contains an instance property getter
  188. // function that will be called when Godot asks Go to get a property from a class
  189. // instance.
  190. type InstancePropertyGet struct {
  191. base C.godot_property_get_func
  192. GetFunc GetPropertyFunc
  193. MethodData string
  194. FreeFunc FreeFunc
  195. }
  196. func (i *InstancePropertyGet) getBase() C.godot_property_get_func {
  197. return i.base
  198. }
  199. // NativeScript is a wrapper for the NativeScriptAPI.
  200. var NativeScript = new(nativeScript)
  201. // nativeScript is a structure that wraps the NativeScriptAPI methods.
  202. type nativeScript struct {
  203. api *C.godot_gdnative_ext_nativescript_api_struct
  204. // Handle is a pointer to the gdnative handler. It must be passed to any
  205. // Godot nativescript functions. This will be populated when 'godot_nativescript_init'
  206. // is called by Godot upon script initialization.
  207. handle unsafe.Pointer
  208. }
  209. // RegisterClass will register the given class with Godot. This will make it
  210. // available to be attached to a Node in Godot. The name of the class that you
  211. // provide here will be the name that you specify when you attach a NativeScript
  212. // script to a Node. The base parameter that you specify will be what the class
  213. // should be inheriting from (e.g. Node2D, Node, etc.).
  214. //
  215. // The create and destroy function parameters are C structs that contain
  216. // function pointers to C methods that will be called when the object is created
  217. // or destroyed. Because of the pointer passing rules, Go code can not pass a
  218. // function value directly to C, so a gateway function should be used. More
  219. // information on using a gateway function can be found here:
  220. // https://github.com/golang/go/wiki/cgo#function-variables
  221. func (n *nativeScript) RegisterClass(name, base string, createFunc *InstanceCreateFunc, destroyFunc *InstanceDestroyFunc) {
  222. // Construct the C struct based on the Go struct wrappers
  223. createFunc.base.create_func = (C.create_func)(unsafe.Pointer(C.cgo_gateway_create_func))
  224. createFunc.base.method_data = unsafe.Pointer(C.CString(createFunc.MethodData))
  225. createFunc.base.free_func = (C.free_func)(unsafe.Pointer(C.cgo_gateway_free_func))
  226. destroyFunc.base.destroy_func = (C.destroy_func)(unsafe.Pointer(C.cgo_gateway_destroy_func))
  227. destroyFunc.base.method_data = unsafe.Pointer(C.CString(destroyFunc.MethodData))
  228. destroyFunc.base.free_func = (C.free_func)(unsafe.Pointer(C.cgo_gateway_free_func))
  229. // Register our Create and Destroy functions in a Go map, so the correct
  230. // function can be called when cgo_gateway_<type>_func is called.
  231. CreateFuncRegistry[createFunc.MethodData] = createFunc.CreateFunc
  232. FreeFuncRegistry[createFunc.MethodData] = createFunc.FreeFunc
  233. DestroyFuncRegistry[destroyFunc.MethodData] = destroyFunc.DestroyFunc
  234. FreeFuncRegistry[destroyFunc.MethodData] = destroyFunc.FreeFunc
  235. // Register the class with Godot.
  236. C.go_godot_nativescript_register_class(
  237. n.api,
  238. n.handle,
  239. C.CString(name),
  240. C.CString(base),
  241. createFunc.getBase(),
  242. destroyFunc.getBase(),
  243. )
  244. }
  245. // RegisterToolClass will register the given class with Godot as a tool. Refer to
  246. // the 'RegisterClass' method for more information on how to use this.
  247. func (n *nativeScript) RegisterToolClass(name, base string, createFunc *InstanceCreateFunc, destroyFunc *InstanceDestroyFunc) {
  248. // Construct the C struct based on the Go struct wrappers
  249. createFunc.base.create_func = (C.create_func)(unsafe.Pointer(C.cgo_gateway_create_func))
  250. createFunc.base.method_data = unsafe.Pointer(C.CString(createFunc.MethodData))
  251. createFunc.base.free_func = (C.free_func)(unsafe.Pointer(C.cgo_gateway_free_func))
  252. destroyFunc.base.destroy_func = (C.destroy_func)(unsafe.Pointer(C.cgo_gateway_destroy_func))
  253. destroyFunc.base.method_data = unsafe.Pointer(C.CString(destroyFunc.MethodData))
  254. destroyFunc.base.free_func = (C.free_func)(unsafe.Pointer(C.cgo_gateway_free_func))
  255. // Register our Create and Destroy functions in a Go map, so the correct
  256. // function can be called when cgo_gateway_<type>_func is called.
  257. CreateFuncRegistry[createFunc.MethodData] = createFunc.CreateFunc
  258. FreeFuncRegistry[createFunc.MethodData] = createFunc.FreeFunc
  259. DestroyFuncRegistry[destroyFunc.MethodData] = destroyFunc.DestroyFunc
  260. FreeFuncRegistry[destroyFunc.MethodData] = destroyFunc.FreeFunc
  261. // Register the class with Godot.
  262. C.go_godot_nativescript_register_tool_class(
  263. n.api,
  264. n.handle,
  265. C.CString(name),
  266. C.CString(base),
  267. createFunc.getBase(),
  268. destroyFunc.getBase(),
  269. )
  270. }
  271. // RegisterMethod will register the given method with Godot and associate it with
  272. // the given class name. The name parameter is the name of the class you wish to
  273. // attach this method to. The funcName parameter is the name of the function you
  274. // want to register. The attributes and method are what will actually be called
  275. // when Godot calls the method on the object.
  276. func (n *nativeScript) RegisterMethod(name, funcName string, attributes *MethodAttributes, method *InstanceMethod) {
  277. // Construct the C struct based on the Go struct wrappers
  278. attributes.base.rpc_type = attributes.RPCType.getBase()
  279. method.base.method = (C.method)(unsafe.Pointer(C.cgo_gateway_method_func))
  280. method.base.method_data = unsafe.Pointer(C.CString(method.MethodData))
  281. method.base.free_func = (C.free_func)(unsafe.Pointer(C.cgo_gateway_free_func))
  282. // Register the Method function in a Go map, so the correct function can
  283. // be called when cgo_gateway_<type>_func is called.
  284. MethodFuncRegistry[method.MethodData] = method.Method
  285. FreeFuncRegistry[method.MethodData] = method.FreeFunc
  286. // Register the method with Godot.
  287. C.go_godot_nativescript_register_method(
  288. n.api,
  289. n.handle,
  290. C.CString(name),
  291. C.CString(funcName),
  292. attributes.getBase(),
  293. method.getBase(),
  294. )
  295. }
  296. // RegisterProperty will register the given property with Godot and associate it
  297. // with the given class name. The name parameter is the name of the class you wish
  298. // to attach this property to. The path is the name of the property itself. The
  299. // attributes and setter/getter methods are what will be called when Godot gets
  300. // or sets this property.
  301. //func (n *nativeScript) RegisterProperty(name, path string, attributes *C.godot_property_attributes, setFunc C.godot_property_set_func, getFunc C.godot_property_get_func) {
  302. func (n *nativeScript) RegisterProperty(name, path string, attributes *PropertyAttributes, setFunc *InstancePropertySet, getFunc *InstancePropertyGet) {
  303. // Construct the C struct based on the attributes Go wrapper
  304. var attr C.godot_property_attributes
  305. attributes.base = &attr
  306. attributes.base.rset_type = attributes.RsetType.getBase()
  307. attributes.base._type = attributes.Type.getBase()
  308. attributes.base.hint = attributes.Hint.getBase()
  309. attributes.base.hint_string = *(attributes.HintString.getBase())
  310. attributes.base.usage = attributes.Usage.getBase()
  311. attributes.base.default_value = *(attributes.DefaultValue.getBase())
  312. // Construct the C struct based on the setFunc Go wrapper
  313. setFunc.base.set_func = (C.set_property_func)(unsafe.Pointer(C.cgo_gateway_property_set_func))
  314. setFunc.base.method_data = unsafe.Pointer(C.CString(setFunc.MethodData))
  315. setFunc.base.free_func = (C.free_func)(unsafe.Pointer(C.cgo_gateway_free_func))
  316. // Construct the C struct based on the getFunc Go wrapper
  317. getFunc.base.get_func = (C.get_property_func)(unsafe.Pointer(C.cgo_gateway_property_get_func))
  318. getFunc.base.method_data = unsafe.Pointer(C.CString(getFunc.MethodData))
  319. getFunc.base.free_func = (C.free_func)(unsafe.Pointer(C.cgo_gateway_free_func))
  320. // Register the set/get property functions in a Go map, so the correct function can
  321. // be called when cgo_gateway_<type>_func is called.
  322. SetPropertyFuncRegistry[setFunc.MethodData] = setFunc.SetFunc
  323. GetPropertyFuncRegistry[getFunc.MethodData] = getFunc.GetFunc
  324. FreeFuncRegistry[setFunc.MethodData] = setFunc.FreeFunc
  325. FreeFuncRegistry[getFunc.MethodData] = getFunc.FreeFunc
  326. // Register the property with Godot.
  327. C.go_godot_nativescript_register_property(
  328. n.api,
  329. n.handle,
  330. C.CString(name),
  331. C.CString(path),
  332. attributes.getBase(),
  333. setFunc.getBase(),
  334. getFunc.getBase(),
  335. )
  336. }
  337. // RegisterSignal will register the given signal with Godot.
  338. func (n *nativeScript) RegisterSignal(name string, signal *Signal) {
  339. // Construct the C struct based on the signal Go wrapper
  340. var base C.godot_signal
  341. signal.base = (*C.godot_signal)(unsafe.Pointer(&base))
  342. signal.base.name = *(signal.Name.getBase())
  343. signal.base.num_args = signal.NumArgs.getBase()
  344. signal.base.num_default_args = signal.NumDefaultArgs.getBase()
  345. // Build the arguments
  346. // argsArray := C.go_godot_signal_argument_build_array(C.int(signal.NumArgs))
  347. argsArray := make([]*C.godot_signal_argument, int(signal.NumArgs))
  348. for i, arg := range signal.Args {
  349. cArg := C.go_godot_new_signal_argument()
  350. (*cArg).name = *(arg.Name.getBase())
  351. (*cArg)._type = arg.Type.getBase()
  352. (*cArg).default_value = *(arg.DefaultValue.getBase())
  353. (*cArg).hint = arg.Hint.getBase()
  354. (*cArg).hint_string = *(arg.HintString.getBase())
  355. (*cArg).usage = arg.Usage.getBase()
  356. argsArray[i] = cArg
  357. }
  358. signal.base.args = argsArray[0]
  359. // Build the default arguments
  360. variantArray := C.go_godot_variant_build_array(C.int(signal.NumDefaultArgs))
  361. for i, variant := range signal.DefaultArgs {
  362. C.go_godot_variant_add_element(variantArray, variant.getBase(), C.int(i))
  363. }
  364. signal.base.default_args = *(**C.godot_variant)(unsafe.Pointer(&variantArray))
  365. // Register the signal with Godot.
  366. C.go_godot_nativescript_register_signal(
  367. n.api,
  368. n.handle,
  369. C.CString(name),
  370. signal.getBase(),
  371. )
  372. }
  373. // nativeScriptInit will be called when `godot_nativescript_init` is called by
  374. // Godot. You can use `SetNativeScriptInit` to set the function that will be called
  375. // when NativeScript initializes.
  376. var nativeScriptInit = []func(){}
  377. // SetNativeScriptInit will configure the given function to be called when
  378. // `godot_nativescript_init` is called by Godot upon NativeScript initialization.
  379. // This is used so you can define a function that will run to register all of the
  380. // classes that you want exposed to Godot.
  381. func SetNativeScriptInit(initFunc ...func()) {
  382. nativeScriptInit = append(nativeScriptInit, initFunc...)
  383. }
  384. /*------------------------------------------------------------------------------
  385. // Exported C Functions
  386. //
  387. // The methods below are special C exported functions. They can be called by
  388. // Godot directly or by one of the C gateway functions defined in
  389. // nativescript.c.
  390. //
  391. //----------------------------------------------------------------------------*/
  392. /** Script entry (Registering all the classes and stuff) **/
  393. // godot_nativescript_init is the script's entrypoint. It is called by Godot
  394. // when a script is loaded. It is responsible for registering all the classes,
  395. // etc. The `unsafe.Pointer` type is used to represent a void C pointer.
  396. //export godot_nativescript_init
  397. func godot_nativescript_init(hdl unsafe.Pointer) {
  398. if debug {
  399. log.Println("Initializing NativeScript")
  400. }
  401. NativeScript.handle = hdl
  402. // Call the user-defined nativeScriptInit function
  403. if nativeScriptInit == nil {
  404. err := "NativeScript initialization function was not set! Use `gdnative.SetNativeScriptInit` to define the function that will run to register classes."
  405. log.Println(err)
  406. Log.Error(err)
  407. return
  408. }
  409. // Loop through any defined nativeScriptInit methods and execute them.
  410. for _, init := range nativeScriptInit {
  411. init()
  412. }
  413. }
  414. // This is a native Go function that is callable from C. It is called by the
  415. // gateway functions defined in nativescript.c. It will be ultimately called by
  416. // Godot, where it will pass us the Godot object and the MethodData defined in
  417. // CreateFunc. We will need to return UserData, which can be used to track the
  418. // actual instance that was created.
  419. //export go_create_func
  420. func go_create_func(godotObject *C.godot_object, methodData unsafe.Pointer) unsafe.Pointer {
  421. // Convert the method data into a Go string.
  422. methodDataString := unsafeToGoString(methodData)
  423. if debug {
  424. log.Println("Create function called for:", methodDataString)
  425. }
  426. // Look up the creation function in our CreateFuncRegistry for the function
  427. // to call.
  428. constructor := CreateFuncRegistry[methodDataString]
  429. // Call the constructor and return the user data string. The user data
  430. // returned by the create func will be passed to the method function as
  431. // userData.
  432. userData := constructor(Object{base: godotObject}, methodDataString)
  433. return unsafe.Pointer(C.CString(userData))
  434. }
  435. // This is a native Go function that is callable from C. It is called by the
  436. // gateway functions defined in nativescript.c. It will use the userData passed to it,
  437. // which is a CString of the instance id, which we can use to delete the instance
  438. // from the instance registry. This will make the instance available to be garbage
  439. // collected.
  440. //export go_destroy_func
  441. func go_destroy_func(godotObject *C.godot_object, methodData unsafe.Pointer, userData unsafe.Pointer) {
  442. // Convert the method data and user data into a Go string
  443. methodDataString := unsafeToGoString(methodData)
  444. userDataString := unsafeToGoString(userData)
  445. if debug {
  446. log.Println("Destroy function called for:", methodDataString)
  447. }
  448. // Look up the destroy function in our DestroyFuncRegistry for the function
  449. // to call.
  450. destructor := DestroyFuncRegistry[methodDataString]
  451. // Call the destructor function. We pass the methodData and userData to
  452. // the destructor so it knows which class and instance to destroy.
  453. destructor(Object{base: godotObject}, methodDataString, userDataString)
  454. }
  455. //export go_free_func
  456. func go_free_func(methodData unsafe.Pointer) {
  457. // Convert the method data and user data into a Go string
  458. methodDataString := unsafeToGoString(methodData)
  459. if debug {
  460. log.Println("Free function called for:", methodDataString)
  461. }
  462. // Look up the free function in our FreeFuncRegistry for the function
  463. // to call.
  464. freer := FreeFuncRegistry[methodDataString]
  465. // Call the free function. We pass the methodData to the free
  466. // function so it knows which class to free.
  467. freer(methodDataString)
  468. }
  469. // This is a native Go function that is callable from C. It is called by the
  470. // gateway functions defined in nativescript.c.
  471. //export go_method_func
  472. func go_method_func(godotObject *C.godot_object, methodData unsafe.Pointer, userData unsafe.Pointer, numArgs C.int, args **C.godot_variant) C.godot_variant {
  473. // Convert the method data and user data into a Go string
  474. methodDataString := unsafeToGoString(methodData)
  475. userDataString := unsafeToGoString(userData)
  476. // Create a slice of Variants for the arguments
  477. variantArgs := []Variant{}
  478. // Get the size of each godot_variant object pointer.
  479. if debug {
  480. log.Println(" Getting size of argument pointer")
  481. }
  482. size := unsafe.Sizeof(*args)
  483. // Panic if something's wrong.
  484. if int(numArgs) > 50 {
  485. panic("Too many arguments. Invalid method.")
  486. }
  487. // If we have arguments, append the first argument.
  488. if int(numArgs) > 0 {
  489. arg := args
  490. // Loop through all our arguments.
  491. for i := 0; i < int(numArgs); i++ {
  492. // Convert the variant into a Go Variant
  493. variant := Variant{base: *arg}
  494. // Append the variant to our list of variants
  495. variantArgs = append(variantArgs, variant)
  496. // Convert the pointer into a uintptr so we can perform arithmetic on it.
  497. arrayPtr := uintptr(unsafe.Pointer(arg))
  498. // Add the size of the godot_variant pointer to our array pointer to get the position
  499. // of the next argument.
  500. arg = (**C.godot_variant)(unsafe.Pointer(arrayPtr + size))
  501. }
  502. }
  503. // Look up the method function in our MethodFuncRegistry for the function
  504. // to call.
  505. method := MethodFuncRegistry[methodDataString]
  506. // Call the method
  507. ret := method(Object{base: godotObject}, methodDataString, userDataString, int(numArgs), variantArgs)
  508. return *ret.getBase()
  509. }
  510. // This is a native Go function that is callable from C. It is called by the
  511. // gateway functions defined in nativescript.c.
  512. //export go_set_property_func
  513. func go_set_property_func(godotObject *C.godot_object, methodData unsafe.Pointer, userData unsafe.Pointer, property *C.godot_variant) {
  514. // Convert the method data and user data into a Go string
  515. methodDataString := unsafeToGoString(methodData)
  516. userDataString := unsafeToGoString(userData)
  517. // Convert the property into a Go variant
  518. variant := Variant{base: property}
  519. // Look up the set property function in our SetPropertyFuncRegistry for
  520. // the function to call.
  521. setFunc := SetPropertyFuncRegistry[methodDataString]
  522. // Call the method
  523. setFunc(Object{base: godotObject}, methodDataString, userDataString, variant)
  524. }
  525. // This is a native Go function that is callable from C. It is called by the
  526. // gateway functions defined in nativescript.c.
  527. //export go_get_property_func
  528. func go_get_property_func(godotObject *C.godot_object, methodData unsafe.Pointer, userData unsafe.Pointer) C.godot_variant {
  529. // Convert the method data and user data into a Go string
  530. methodDataString := unsafeToGoString(methodData)
  531. userDataString := unsafeToGoString(userData)
  532. // Look up the get property function in our GetPropertyFuncRegistry for
  533. // the function to call.
  534. getFunc := GetPropertyFuncRegistry[methodDataString]
  535. // Call the method
  536. ret := getFunc(Object{base: godotObject}, methodDataString, userDataString)
  537. return *ret.getBase()
  538. }