Created
October 29, 2025 13:27
-
-
Save Gnumaru/b337c3fa36ea6438673d07df913839b1 to your computer and use it in GitHub Desktop.
how to simulate in gdscript a class property that can be asigned only the first time, like a 'final' property in java or a 'readonly' property in C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # how to simulate a class property that can be asigned only the first time, like a 'final' property in java or a 'readonly' property in C# | |
| #class_name ReadOnly | |
| extends Node | |
| # READONLY NON OBJECT WITH SPECIFIC TYPE | |
| var readonly_int:int: | |
| set(p): | |
| if readonly_int != 0:printerr('cannot set readonly property "readonly_int" a second time'); return | |
| readonly_int = p | |
| # READONLY VARIANT WITHOUT SPECIFIC TYPE | |
| var readonly_variant:Variant: | |
| set(p): | |
| if typeof(readonly_variant) != TYPE_NIL: printerr('cannot set readonly property "readonly_variant" a second time'); return | |
| readonly_variant = p | |
| # READONLY OBJECT WITH HELPER READONLY ID INT | |
| var _readonly_object_id:int: | |
| set(p): | |
| if _readonly_object_id != 0: printerr('cannot set readonly property "_readonly_object_id" a second time'); return | |
| _readonly_object_id = p | |
| var readonly_object:Object: | |
| set(p): | |
| if _readonly_object_id != 0: printerr('cannot set readonly property "readonly_object" a second time'); return | |
| readonly_object = p # assigns the object, regardless if it is null or not | |
| # assigns the object id. uses -1 for null | |
| if is_instance_valid(p): _readonly_object_id = p.get_instance_id() | |
| else: _readonly_object_id = -1 | |
| # READONLY OBJECT WITH HELPER READONLY ID INT | |
| var _readonly_object_b_id:int: | |
| set(p): | |
| if _readonly_object_b_id != 0: printerr('cannot set readonly property "_readonly_object_b_id" a second time'); return | |
| _readonly_object_b_id = p | |
| var readonly_object_b:Object: | |
| set(p): | |
| if _readonly_object_b_id != 0: printerr('cannot set readonly property "readonly_object_b" a second time'); return | |
| readonly_object_b = p # assigns the object, regardless if it is null or not | |
| # assigns the object id. uses -1 for null | |
| if is_instance_valid(p): _readonly_object_b_id = p.get_instance_id() | |
| else: _readonly_object_b_id = -1 | |
| func _ready()->void: | |
| print('\n') | |
| print(readonly_int) # print '0' | |
| readonly_int = 12 # does not print anything | |
| print(readonly_int) # print '12' | |
| readonly_int = 8 # print 'cannot set readonly property "readonly_int"' | |
| print(readonly_int) # print '12' | |
| print('\n') | |
| print(readonly_variant) # prints '<null>' | |
| readonly_variant = 'my_string' # does not print anything | |
| print(readonly_variant) # prints 'my_string' | |
| readonly_variant = 8 # print 'cannot set readonly property "readonly_variant"' | |
| print(readonly_variant) # prints 'my_string' | |
| print('\n') | |
| print(readonly_object) # prints '<null>' | |
| readonly_object = Object.new() # does not print anything | |
| print(readonly_object) # prints something like '<Object#26088572288>' | |
| readonly_object = null # print 'cannot set readonly property "readonly_object"' | |
| print(readonly_object) # prints '<Object#26088572288>' | |
| readonly_object.free() | |
| print(readonly_object) # prints '<Freed Object>'. the object was freed but the property will still be unsetable | |
| readonly_object = null # print 'cannot set readonly property "readonly_object"' | |
| print(readonly_object) # prints '<Freed Object>' | |
| await get_tree().process_frame | |
| print(readonly_object) # prints '<Freed Object>'. I dont' know when godot will efectively recollect the freed object memory. | |
| print('\n') | |
| print(readonly_object_b) # prints '<null>' | |
| readonly_object_b = null # does not print anything, but this counts as the first set of the property, so it will be unsetable after this | |
| print(readonly_object_b) # prints '<null>' | |
| readonly_object_b = null # print 'cannot set readonly property "readonly_object_b' | |
| print(readonly_object_b) # prints '<null>' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment