Skip to content

Clarify var_to_bytes() encoding empty Callables#120654

Open
Calinou wants to merge 1 commit into
godotengine:masterfrom
Calinou:doc-globalscope-var-to-bytes-callable-empty
Open

Clarify var_to_bytes() encoding empty Callables#120654
Calinou wants to merge 1 commit into
godotengine:masterfrom
Calinou:doc-globalscope-var-to-bytes-callable-empty

Conversation

@Calinou

@Calinou Calinou commented Jun 26, 2026

Copy link
Copy Markdown
Member

@Calinou Calinou requested a review from a team as a code owner June 26, 2026 01:26
@Calinou Calinou added this to the 4.8 milestone Jun 26, 2026
@GabCoolDude

Copy link
Copy Markdown
Contributor

Isn't the same true for Signal as well ? From my experience and from the description of var_to_str, it seems to be:

Note: Converting Signal or Callable is not supported and will result in an empty value for these types, regardless of their data.

This PR should probably mention that as well, or just outright copy the note from var_to_str.

AThousandShips
AThousandShips previously approved these changes Jun 26, 2026

@Mickeon Mickeon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please someone verify what was stated by @GabCoolDude and if true, just copy the note from var_to_str's description.

I myself can't imagine why it would be different between the bytes and string conversion functions.

@AThousandShips AThousandShips dismissed their stale review June 26, 2026 09:43

Needs further info

@AThousandShips

AThousandShips commented Jun 26, 2026

Copy link
Copy Markdown
Member

It is true, in a sense, it encodes an empty entry which is a padded array, and on decoding it simply constructs an empty callable:

godot/core/io/marshalls.cpp

Lines 789 to 791 in d3a5a85

case Variant::CALLABLE: {
r_variant = Callable();
} break;

The entry is still written though and stores the type

@GabCoolDude

Copy link
Copy Markdown
Contributor

Looking at the code for encoding Callable and Signal in bytes, Callable just does nothing, and Signal encodes the name of the signal along with its ObjectID:

godot/core/io/marshalls.cpp

Lines 1820 to 1831 in d3a5a85

case Variant::CALLABLE: {
} break;
case Variant::SIGNAL: {
Signal signal = p_variant;
_encode_string(signal.get_name(), buf, r_len);
if (buf) {
encode_uint64(signal.get_object_id(), buf);
}
r_len += 8;
} break;

This is actually different from how var_to_string does it, where both Callable and Signal are encoded as their default values (which are invalid):

// Do not really store these, but ensure that assignments are not empty.
case Variant::SIGNAL: {
p_store_string_func(p_store_string_ud, "Signal()");
} break;
case Variant::CALLABLE: {
p_store_string_func(p_store_string_ud, "Callable()");
} break;

The difference doesn't make much sense, seeing as the ObjectID becomes useless as soon as the program is closed, and also as long as the Object exists. I guess there could be a use case for wanting to save and load it back during the same session, but I really doubt anyone is using this, and that same use case could also apply to var_to_string (ignoring the git noise in scenes and resources that would be caused by this).

So I guess the correct thing to do would be to add another note saying that decoding a Signal only gives a valid signal if the object still exists and the program hasn't been closed in between encoding and decoding. Removing this weird behavior for encoding Signal is probably a better option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

False or misleading var_to_bytes() note about encoding Callable

4 participants