Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a method to get a Callable's argument count #8596

Closed
dugramen opened this issue Dec 6, 2023 · 6 comments · Fixed by godotengine/godot#87680
Closed

Add a method to get a Callable's argument count #8596

dugramen opened this issue Dec 6, 2023 · 6 comments · Fixed by godotengine/godot#87680
Milestone

Comments

@dugramen
Copy link

dugramen commented Dec 6, 2023

Describe the project you are working on

Editor plugins

Describe the problem or limitation you are having in your project

Callable.unbind() allows unbinding a number of arguments, but there is no way to dynamically know how many arguments are allowed/should be unbound

Describe the feature / enhancement and how it helps to overcome the problem or limitation

A new method on Callable, called get_argument_count() or get_allowed_arguments_count() that returns the number of arguments allowed by the callable

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Here are 2 example usages:

To unbind some unknown Callable for a signal:

signal.connect(callable.unbind(callable.get_bound_arguments_count() - callable.get_allowed_arguments_count()))

Example of a reusable, JavaScript style, array mapper. Only possible if this is implemented (optional index and array)

class_name Utility 
static func map(arr: Array, callable: Callable):
    var result := []
    for (i = 0; i < arr.size(); i += 1):
        result.push_back(
            callable.callv(
                [arr[i], i, arr].slice(0, callable.get_allowed_argument_count())
            )
        )
    return result 

Which could be used like so:

Utility.map(
    [1, 2, 3],
    func(num): return num * 2
)
Utility.map(
    [0, 5, 10],
    func(num, i): return str(i) + ": " str(num)
)
Utility.map(
    [8, 15, 11],
    func(num, i, arr): return num / arr.size()
)

If this enhancement will not be used often, can it be worked around with a few lines of script?

It's only possible with known Callables, but it's not currently possible to implement something like the above utility function

Is there a reason why this should be core and not an add-on in the asset library?

I don't think an add-on can do this

@IntangibleMatter

This comment was marked as off-topic.

@AThousandShips
Copy link
Member

@IntangibleMatter Please don't bump issues without contributing significant new information. Use the 👍 reaction button on the first post instead.

@AThousandShips
Copy link
Member

Will take a look at possibly implementing this, will see how it goes

@AThousandShips
Copy link
Member

Made quite a bit of progress, will probably open a PR soon

@ThaddeusWilliams
Copy link

ThaddeusWilliams commented Mar 31, 2024

This is already possible with the following code:

func GetMethodArgCount(m: Callable):
	for f in get_method_list():
		var fn = get(f.name)
		if m.get_method() == f.name:
			return f.args.size()
	return 0

@AThousandShips
Copy link
Member

That doesn't cover everything, you can't use it for lambdas or for example, also it doesn't matter now since this has been added as a feature so you can just use the method

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

Successfully merging a pull request may close this issue.

5 participants