What is a simple way to have multiple inner classes mutually refer to each other?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By raymoo
:warning: Old Version Published before Godot 3 was released.

Suppose I have code like this:

class Class1:
    var pie

class Class2:
    func blah():
        return Class1.new()

This works fine and Class2 can refer to Class1. However, the following doesn’t work:

class Class1:
    func blah():
        return Class2.new()

class Class2:
    func blah():
        return Class1.new()

because Class2 has not been declared when Class1 refers to it. What is a simple way to get them to be able to refer to each other?

A similar question has been asked here [GDscript] How i can't "instanciate class A" in "class A" code with gdcript? - Archive - Godot Forum

Zylann | 2016-12-11 03:34

The answer there doesn’t work for this case, since get_script will only give a reference to the current class.

raymoo | 2016-12-11 04:04

This one too is similar: class can't be identified if typed after the caller class - Archive - Godot Forum
I believe GDScript has a limitation about cross-references between classes.

Zylann | 2016-12-11 04:34

get_script retrieves own class so won’t work, maybe creating a dummy class like in one of the comments here https://forum.godotengine.org/10459/gdscript-how-cant-instanciate-class-class-code-with-gdcript
Not sure if this is safe though, looks more like a bug…


Or using one file for each class (I don’t know if there is a performance cost for doing that).

eons | 2016-12-11 14:21

I doubt the cost would be significant considering classes would only be instantiated on state changes, but it might be annoying to have my states spread across multiple files (my use case is similar to the second link you provided).

Currently I’m going with having a dictionary of classes passed to each state object on construction, but that causes a bunch of boilerplate.

raymoo | 2016-12-11 18:15

If you are doing a Finite State Machine, you should try this plugin: FSM (Finite State Machine) - Godot Asset Library
Maybe it will help you have less boilerplates ^^

rafeu | 2016-12-16 12:59

I don’t think that plugin lends itself well to parameterized states, since it uses nodes for states, and parameterizing nodes requires the ugly hack of setting its parameters after creating them. It also makes it hard to have states that have another state nested inside of them (e.g. a menu state that holds a reference to the state the game was in before the menu was entered).

raymoo | 2016-12-16 23:28

class Class1:
    func blah():
        return Class2.new()

class Class2:
    func blah():
        return Class1.new()

var Class2 = Class2
var Class1 = Class1

Jatz | 2016-12-18 20:47

That doesn’t work, for multiple reasons. The Class2 var comes after Class1’s definition where it’s needed, and inner classes can’t access vars of the outer class (since vars can’t be made static, vars need an instance to be part of).

raymoo | 2016-12-20 00:55

I wasn’t sure it would work either… that’s why I commented -_-

How about this?

class Class1:
    var Class2
    func blah():
        return Class2.new()

class Class2:
    Class1
    func blah():
        return Class1.new()

func _ready():
    Class1.Class2 = Class2
    Class2.Class1 = Class1

Jatz | 2016-12-20 08:02

That doesn’t work either because Godot has no static variables.

raymoo | 2016-12-20 08:56