1 /** 2 Base class for all non built-in types. 3 4 Copyright: 5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. 6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) 7 Copyright (c) 2017-2018 Godot-D contributors 8 9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License) 10 11 12 */ 13 module godot.object; 14 import std.meta : AliasSeq, staticIndexOf; 15 import std.traits : Unqual; 16 import godot.d.meta; 17 import godot.core; 18 import godot.c; 19 import godot.d.bind; 20 import godot.d.reference; 21 import godot.classdb; 22 import godot.reference; 23 /** 24 Base class for all non built-in types. 25 26 Everything not a built-in type starts the inheritance chain from this class. 27 Objects do not manage memory, if inheriting from one the object will most likely have to be deleted manually (call the $(D free) function from the script or delete from C++). 28 Some derivatives add memory management, such as $(D Reference) (which keeps a reference count and deletes itself automatically when no longer referenced) and $(D Node), which deletes the children tree when deleted. 29 Objects export properties, which are mainly useful for storage and editing, but not really so much in programming. Properties are exported in $(D _getPropertyList) and handled in $(D _get) and $(D _set). However, scripting languages and C++ have simpler means to export them. 30 Objects also receive notifications ($(D _notification)). Notifications are a simple way to notify the object about simple events, so they can all be handled together. 31 */ 32 @GodotBaseClass struct GodotObject 33 { 34 enum string _GODOT_internal_name = "Object"; 35 public: 36 @nogc nothrow: 37 godot_object _godot_object; 38 alias BaseClasses = AliasSeq!(); 39 package(godot) __gshared bool _classBindingInitialized = false; 40 package(godot) static struct _classBinding 41 { 42 __gshared: 43 @GodotName("free") GodotMethod!(void) free; 44 @GodotName("_notification") GodotMethod!(void, long) _notification; 45 @GodotName("_set") GodotMethod!(bool, String, Variant) _set; 46 @GodotName("_get") GodotMethod!(Variant, String) _get; 47 @GodotName("_get_property_list") GodotMethod!(Array) _getPropertyList; 48 @GodotName("_init") GodotMethod!(void) _init; 49 @GodotName("get_class") GodotMethod!(String) getClass; 50 @GodotName("is_class") GodotMethod!(bool, String) isClass; 51 @GodotName("set") GodotMethod!(void, String, Variant) set; 52 @GodotName("get") GodotMethod!(Variant, String) get; 53 @GodotName("set_indexed") GodotMethod!(void, NodePath, Variant) setIndexed; 54 @GodotName("get_indexed") GodotMethod!(Variant, NodePath) getIndexed; 55 @GodotName("get_property_list") GodotMethod!(Array) getPropertyList; 56 @GodotName("get_method_list") GodotMethod!(Array) getMethodList; 57 @GodotName("notification") GodotMethod!(void, long, bool) notification; 58 @GodotName("get_instance_id") GodotMethod!(long) getInstanceId; 59 @GodotName("set_script") GodotMethod!(void, Reference) setScript; 60 @GodotName("get_script") GodotMethod!(Reference) getScript; 61 @GodotName("set_meta") GodotMethod!(void, String, Variant) setMeta; 62 @GodotName("get_meta") GodotMethod!(Variant, String) getMeta; 63 @GodotName("has_meta") GodotMethod!(bool, String) hasMeta; 64 @GodotName("get_meta_list") GodotMethod!(PoolStringArray) getMetaList; 65 @GodotName("add_user_signal") GodotMethod!(void, String, Array) addUserSignal; 66 @GodotName("has_user_signal") GodotMethod!(bool, String) hasUserSignal; 67 @GodotName("emit_signal") GodotMethod!(Variant, String, GodotVarArgs) emitSignal; 68 @GodotName("call") GodotMethod!(Variant, String, GodotVarArgs) call; 69 @GodotName("call_deferred") GodotMethod!(Variant, String, GodotVarArgs) callDeferred; 70 @GodotName("callv") GodotMethod!(Variant, String, Array) callv; 71 @GodotName("has_method") GodotMethod!(bool, String) hasMethod; 72 @GodotName("get_signal_list") GodotMethod!(Array) getSignalList; 73 @GodotName("get_signal_connection_list") GodotMethod!(Array, String) getSignalConnectionList; 74 @GodotName("get_incoming_connections") GodotMethod!(Array) getIncomingConnections; 75 @GodotName("connect") GodotMethod!(GodotError, String, GodotObject, String, Array, long) connect; 76 @GodotName("disconnect") GodotMethod!(void, String, GodotObject, String) disconnect; 77 @GodotName("is_connected") GodotMethod!(bool, String, GodotObject, String) isConnected; 78 @GodotName("set_block_signals") GodotMethod!(void, bool) setBlockSignals; 79 @GodotName("is_blocking_signals") GodotMethod!(bool) isBlockingSignals; 80 @GodotName("property_list_changed_notify") GodotMethod!(void) propertyListChangedNotify; 81 @GodotName("set_message_translation") GodotMethod!(void, bool) setMessageTranslation; 82 @GodotName("can_translate_messages") GodotMethod!(bool) canTranslateMessages; 83 @GodotName("tr") GodotMethod!(String, String) tr; 84 @GodotName("is_queued_for_deletion") GodotMethod!(bool) isQueuedForDeletion; 85 } 86 bool opEquals(in GodotObject other) const { return _godot_object.ptr is other._godot_object.ptr; } 87 GodotObject opAssign(T : typeof(null))(T n) { _godot_object.ptr = null; } 88 bool opEquals(typeof(null) n) const { return _godot_object.ptr is null; } 89 mixin baseCasts; 90 static GodotObject _new() 91 { 92 static godot_class_constructor constructor; 93 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("Object"); 94 if(constructor is null) return typeof(this).init; 95 return cast(GodotObject)(constructor()); 96 } 97 @disable new(size_t s); 98 /// 99 enum ConnectFlags : int 100 { 101 /** 102 Connect a signal in deferred mode. This way, signal emissions are stored in a queue, then set on idle time. 103 */ 104 connectDeferred = 1, 105 /** 106 Persisting connections are saved when the object is serialized to file. 107 */ 108 connectPersist = 2, 109 /** 110 One shot connections disconnect themselves after emission. 111 */ 112 connectOneshot = 4, 113 /** 114 115 */ 116 connectReferenceCounted = 8, 117 } 118 /// 119 enum Constants : int 120 { 121 /** 122 Called right when the object is initialized. Not available in script. 123 */ 124 notificationPostinitialize = 0, 125 connectDeferred = 1, 126 /** 127 Called before the object is about to be deleted. 128 */ 129 notificationPredelete = 1, 130 connectPersist = 2, 131 connectOneshot = 4, 132 connectReferenceCounted = 8, 133 } 134 /** 135 Deletes the object from memory. 136 */ 137 void free() 138 { 139 checkClassBinding!(typeof(this))(); 140 ptrcall!(void)(_classBinding.free, _godot_object); 141 } 142 /** 143 Notify the object internally using an ID. 144 */ 145 void _notification(in long what) 146 { 147 Array _GODOT_args = Array.empty_array; 148 _GODOT_args.append(what); 149 String _GODOT_method_name = String("_notification"); 150 this.callv(_GODOT_method_name, _GODOT_args); 151 } 152 /** 153 Sets a property. Returns `true` if the `property` exists. 154 */ 155 bool _set(StringArg0, VariantArg1)(in StringArg0 property, in VariantArg1 value) 156 { 157 Array _GODOT_args = Array.empty_array; 158 _GODOT_args.append(property); 159 _GODOT_args.append(value); 160 String _GODOT_method_name = String("_set"); 161 return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!bool); 162 } 163 /** 164 Returns the given property. Returns `null` if the `property` does not exist. 165 */ 166 Variant _get(StringArg0)(in StringArg0 property) 167 { 168 Array _GODOT_args = Array.empty_array; 169 _GODOT_args.append(property); 170 String _GODOT_method_name = String("_get"); 171 return this.callv(_GODOT_method_name, _GODOT_args); 172 } 173 /** 174 Returns the object's property list as an $(D Array) of dictionaries. Dictionaries must contain: name:String, type:int (see TYPE_* enum in $(D @GlobalScope)) and optionally: hint:int (see PROPERTY_HINT_* in $(D @GlobalScope)), hint_string:String, usage:int (see PROPERTY_USAGE_* in $(D @GlobalScope)). 175 */ 176 Array _getPropertyList() 177 { 178 Array _GODOT_args = Array.empty_array; 179 String _GODOT_method_name = String("_get_property_list"); 180 return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!Array); 181 } 182 /** 183 The virtual method called upon initialization. 184 */ 185 void _init() 186 { 187 Array _GODOT_args = Array.empty_array; 188 String _GODOT_method_name = String("_init"); 189 this.callv(_GODOT_method_name, _GODOT_args); 190 } 191 /** 192 Returns the object's class as a $(D String). 193 */ 194 String getClass() const 195 { 196 checkClassBinding!(typeof(this))(); 197 return ptrcall!(String)(_classBinding.getClass, _godot_object); 198 } 199 /** 200 Returns `true` if the object inherits from the given `type`. 201 */ 202 bool isClass(StringArg0)(in StringArg0 type) const 203 { 204 checkClassBinding!(typeof(this))(); 205 return ptrcall!(bool)(_classBinding.isClass, _godot_object, type); 206 } 207 /** 208 Set property into the object. 209 */ 210 void set(StringArg0, VariantArg1)(in StringArg0 property, in VariantArg1 value) 211 { 212 checkClassBinding!(typeof(this))(); 213 ptrcall!(void)(_classBinding.set, _godot_object, property, value); 214 } 215 /** 216 Returns a $(D Variant) for a `property`. 217 */ 218 Variant get(StringArg0)(in StringArg0 property) const 219 { 220 checkClassBinding!(typeof(this))(); 221 return ptrcall!(Variant)(_classBinding.get, _godot_object, property); 222 } 223 /** 224 225 */ 226 void setIndexed(NodePathArg0, VariantArg1)(in NodePathArg0 property, in VariantArg1 value) 227 { 228 checkClassBinding!(typeof(this))(); 229 ptrcall!(void)(_classBinding.setIndexed, _godot_object, property, value); 230 } 231 /** 232 Get indexed object property by String. 233 Property indices get accessed with colon separation, for example: `position:x` 234 */ 235 Variant getIndexed(NodePathArg0)(in NodePathArg0 property) const 236 { 237 checkClassBinding!(typeof(this))(); 238 return ptrcall!(Variant)(_classBinding.getIndexed, _godot_object, property); 239 } 240 /** 241 Returns the list of properties as an $(D Array) of dictionaries. Dictionaries contain: name:String, type:int (see TYPE_* enum in $(D @GlobalScope)) and optionally: hint:int (see PROPERTY_HINT_* in $(D @GlobalScope)), hint_string:String, usage:int (see PROPERTY_USAGE_* in $(D @GlobalScope)). 242 */ 243 Array getPropertyList() const 244 { 245 checkClassBinding!(typeof(this))(); 246 return ptrcall!(Array)(_classBinding.getPropertyList, _godot_object); 247 } 248 /** 249 Returns the object's methods and their signatures as an $(D Array). 250 */ 251 Array getMethodList() const 252 { 253 checkClassBinding!(typeof(this))(); 254 return ptrcall!(Array)(_classBinding.getMethodList, _godot_object); 255 } 256 /** 257 Notify the object of something. 258 */ 259 void notification(in long what, in bool reversed = false) 260 { 261 checkClassBinding!(typeof(this))(); 262 ptrcall!(void)(_classBinding.notification, _godot_object, what, reversed); 263 } 264 /** 265 Returns the object's unique instance ID. 266 */ 267 long getInstanceId() const 268 { 269 checkClassBinding!(typeof(this))(); 270 return ptrcall!(long)(_classBinding.getInstanceId, _godot_object); 271 } 272 /** 273 Set a script into the object, scripts extend the object functionality. 274 */ 275 void setScript(Reference script) 276 { 277 checkClassBinding!(typeof(this))(); 278 ptrcall!(void)(_classBinding.setScript, _godot_object, script); 279 } 280 /** 281 Returns the object's $(D Script) or `null` if one doesn't exist. 282 */ 283 Reference getScript() const 284 { 285 checkClassBinding!(typeof(this))(); 286 return ptrcall!(Reference)(_classBinding.getScript, _godot_object); 287 } 288 /** 289 Set a metadata into the object. Metadata is serialized. Metadata can be $(I anything). 290 */ 291 void setMeta(StringArg0, VariantArg1)(in StringArg0 name, in VariantArg1 value) 292 { 293 checkClassBinding!(typeof(this))(); 294 ptrcall!(void)(_classBinding.setMeta, _godot_object, name, value); 295 } 296 /** 297 Returns the object's metadata for the given `name`. 298 */ 299 Variant getMeta(StringArg0)(in StringArg0 name) const 300 { 301 checkClassBinding!(typeof(this))(); 302 return ptrcall!(Variant)(_classBinding.getMeta, _godot_object, name); 303 } 304 /** 305 Returns `true` if a metadata is found with the given `name`. 306 */ 307 bool hasMeta(StringArg0)(in StringArg0 name) const 308 { 309 checkClassBinding!(typeof(this))(); 310 return ptrcall!(bool)(_classBinding.hasMeta, _godot_object, name); 311 } 312 /** 313 Returns the object's metadata as a $(D PoolStringArray). 314 */ 315 PoolStringArray getMetaList() const 316 { 317 checkClassBinding!(typeof(this))(); 318 return ptrcall!(PoolStringArray)(_classBinding.getMetaList, _godot_object); 319 } 320 /** 321 Adds a user-defined `signal`. Arguments are optional, but can be added as an $(D Array) of dictionaries, each containing "name" and "type" (from $(D @GlobalScope) TYPE_*). 322 */ 323 void addUserSignal(StringArg0)(in StringArg0 signal, in Array arguments = Array.empty_array) 324 { 325 checkClassBinding!(typeof(this))(); 326 ptrcall!(void)(_classBinding.addUserSignal, _godot_object, signal, arguments); 327 } 328 /** 329 Returns `true` if the given user-defined `signal` exists. 330 */ 331 bool hasUserSignal(StringArg0)(in StringArg0 signal) const 332 { 333 checkClassBinding!(typeof(this))(); 334 return ptrcall!(bool)(_classBinding.hasUserSignal, _godot_object, signal); 335 } 336 /** 337 Emits the given `signal`. 338 */ 339 Variant emitSignal(StringArg0, VarArgs...)(in StringArg0 signal, VarArgs varArgs) 340 { 341 Array _GODOT_args = Array.empty_array; 342 _GODOT_args.append(signal); 343 foreach(vai, VA; VarArgs) 344 { 345 _GODOT_args.append(varArgs[vai]); 346 } 347 String _GODOT_method_name = String("emit_signal"); 348 return this.callv(_GODOT_method_name, _GODOT_args); 349 } 350 /** 351 Calls the `method` on the object and returns a result. Pass parameters as a comma separated list. 352 */ 353 Variant call(StringArg0, VarArgs...)(in StringArg0 method, VarArgs varArgs) 354 { 355 Array _GODOT_args = Array.empty_array; 356 _GODOT_args.append(method); 357 foreach(vai, VA; VarArgs) 358 { 359 _GODOT_args.append(varArgs[vai]); 360 } 361 String _GODOT_method_name = String("call"); 362 return this.callv(_GODOT_method_name, _GODOT_args); 363 } 364 /** 365 Calls the `method` on the object during idle time and returns a result. Pass parameters as a comma separated list. 366 */ 367 Variant callDeferred(StringArg0, VarArgs...)(in StringArg0 method, VarArgs varArgs) 368 { 369 Array _GODOT_args = Array.empty_array; 370 _GODOT_args.append(method); 371 foreach(vai, VA; VarArgs) 372 { 373 _GODOT_args.append(varArgs[vai]); 374 } 375 String _GODOT_method_name = String("call_deferred"); 376 return this.callv(_GODOT_method_name, _GODOT_args); 377 } 378 /** 379 Calls the `method` on the object and returns a result. Pass parameters as an $(D Array). 380 */ 381 Variant callv(StringArg0)(in StringArg0 method, in Array arg_array) const 382 { 383 checkClassBinding!(typeof(this))(); 384 return ptrcall!(Variant)(_classBinding.callv, _godot_object, method, arg_array); 385 } 386 /** 387 Returns `true` if the object contains the given `method`. 388 */ 389 bool hasMethod(StringArg0)(in StringArg0 method) const 390 { 391 checkClassBinding!(typeof(this))(); 392 return ptrcall!(bool)(_classBinding.hasMethod, _godot_object, method); 393 } 394 /** 395 Returns the list of signals as an $(D Array) of dictionaries. 396 */ 397 Array getSignalList() const 398 { 399 checkClassBinding!(typeof(this))(); 400 return ptrcall!(Array)(_classBinding.getSignalList, _godot_object); 401 } 402 /** 403 Returns an $(D Array) of connections for the given `signal`. 404 */ 405 Array getSignalConnectionList(StringArg0)(in StringArg0 signal) const 406 { 407 checkClassBinding!(typeof(this))(); 408 return ptrcall!(Array)(_classBinding.getSignalConnectionList, _godot_object, signal); 409 } 410 /** 411 Returns an $(D Array) of dictionaries with information about signals that are connected to the object. 412 Inside each $(D Dictionary) there are 3 fields: 413 - "source" is a reference to signal emitter. 414 - "signal_name" is name of connected signal. 415 - "method_name" is a name of method to which signal is connected. 416 */ 417 Array getIncomingConnections() const 418 { 419 checkClassBinding!(typeof(this))(); 420 return ptrcall!(Array)(_classBinding.getIncomingConnections, _godot_object); 421 } 422 /** 423 Connects a `signal` to a `method` on a `target` object. Pass optional `binds` to the call. Use `flags` to set deferred or one shot connections. See `CONNECT_*` constants. A `signal` can only be connected once to a `method`. It will throw an error if already connected. To avoid this, first use $(D isConnected) to check for existing connections. 424 */ 425 GodotError connect(StringArg0, StringArg2)(in StringArg0 signal, GodotObject target, in StringArg2 method, in Array binds = Array.empty_array, in long flags = 0) 426 { 427 checkClassBinding!(typeof(this))(); 428 return ptrcall!(GodotError)(_classBinding.connect, _godot_object, signal, target, method, binds, flags); 429 } 430 /** 431 Disconnects a `signal` from a `method` on the given `target`. 432 */ 433 void disconnect(StringArg0, StringArg2)(in StringArg0 signal, GodotObject target, in StringArg2 method) 434 { 435 checkClassBinding!(typeof(this))(); 436 ptrcall!(void)(_classBinding.disconnect, _godot_object, signal, target, method); 437 } 438 /** 439 Returns `true` if a connection exists for a given `signal`, `target`, and `method`. 440 */ 441 bool isConnected(StringArg0, StringArg2)(in StringArg0 signal, GodotObject target, in StringArg2 method) const 442 { 443 checkClassBinding!(typeof(this))(); 444 return ptrcall!(bool)(_classBinding.isConnected, _godot_object, signal, target, method); 445 } 446 /** 447 If set to true, signal emission is blocked. 448 */ 449 void setBlockSignals(in bool enable) 450 { 451 checkClassBinding!(typeof(this))(); 452 ptrcall!(void)(_classBinding.setBlockSignals, _godot_object, enable); 453 } 454 /** 455 Returns `true` if signal emission blocking is enabled. 456 */ 457 bool isBlockingSignals() const 458 { 459 checkClassBinding!(typeof(this))(); 460 return ptrcall!(bool)(_classBinding.isBlockingSignals, _godot_object); 461 } 462 /** 463 464 */ 465 void propertyListChangedNotify() 466 { 467 checkClassBinding!(typeof(this))(); 468 ptrcall!(void)(_classBinding.propertyListChangedNotify, _godot_object); 469 } 470 /** 471 Define whether the object can translate strings (with calls to $(D tr)). Default is true. 472 */ 473 void setMessageTranslation(in bool enable) 474 { 475 checkClassBinding!(typeof(this))(); 476 ptrcall!(void)(_classBinding.setMessageTranslation, _godot_object, enable); 477 } 478 /** 479 Returns `true` if the object can translate strings. 480 */ 481 bool canTranslateMessages() const 482 { 483 checkClassBinding!(typeof(this))(); 484 return ptrcall!(bool)(_classBinding.canTranslateMessages, _godot_object); 485 } 486 /** 487 Translate a message. Only works if message translation is enabled (which it is by default). See $(D setMessageTranslation). 488 */ 489 String tr(StringArg0)(in StringArg0 message) const 490 { 491 checkClassBinding!(typeof(this))(); 492 return ptrcall!(String)(_classBinding.tr, _godot_object, message); 493 } 494 /** 495 Returns `true` if the `queue_free` method was called for the object. 496 */ 497 bool isQueuedForDeletion() const 498 { 499 checkClassBinding!(typeof(this))(); 500 return ptrcall!(bool)(_classBinding.isQueuedForDeletion, _godot_object); 501 } 502 }