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 dir() function to improve API discoverability #5818

Merged
merged 15 commits into from Jun 21, 2022
Merged

Conversation

CelticMinstrel
Copy link
Member

This is intended to allow someone to explore the API right in the Lua console. The current commit implements the actual function, but there's a lot more work to support it throughout the API, which is why this is a draft. I don't expect this to be finished for 1.16.

@CelticMinstrel CelticMinstrel added the Lua API Issues with the Lua engine and API. label May 29, 2021
@stevecotton
Copy link
Contributor

Does this interact with the already-implemented tab completion?

@CelticMinstrel
Copy link
Member Author

It currently doesn't… I was thinking that unifying them might be nice though.

@github-actions github-actions bot added the AI Issues with the AI engine, including micro AIs. label Jul 2, 2021
* A list of keys is gathered from the following sources:
* - For a table, all keys defined in the table
* - Any keys accessible through the metatable chain (if __index on the metatable is a table)
* - The output of the __dir metafunction
Copy link
Contributor

Choose a reason for hiding this comment

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

How will this filter out deprecated stuff?

Replying to #5965 (comment) :

Renaming something because the old name is misleading is an accomplishment in and of itself

Removing the old name is an accomplishment, but merely adding a new name gives people more things to look at. It will improve the readability of code that uses the new name, but its affect on the task of writing new code is not always beneficial.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's a good point. For userdata types that rely on a __dir metafunction, they just wouldn't add those keys, but that won't help for tables. Perhaps I could add a __dir_exclude metafunction/table, which lists keys to exclude from the dir listing even if they exist in the table. This metafunction would need to be checked all the way up the metatable chain. (Actually, maybe even __dir should be?)

Copy link
Member Author

Choose a reason for hiding this comment

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

I implemented something a bit different in the "Exclude deprecated things from dir()" commit (not direct-linking it because the hash could evolve as I force-push). Does that look sufficient to you? There could in theory be a few deprecated things that are caught by that system but they should be rare.

The implementation is likely inefficient, but as this is intended for use in the Lua console to discover API (particularly experimental API), I don't think that matters much.

@CelticMinstrel CelticMinstrel force-pushed the lua_dir branch 2 times, most recently from 86d90bd to 154d563 Compare June 4, 2022 14:53
@github-actions github-actions bot added Editor Map/scenario editor issues. UI User interface issues, including both back-end and front-end issues. Units Issues that involve unit definitions or their implementation in the engine. labels Jun 5, 2022
@CelticMinstrel
Copy link
Member Author

Note: I merged part of new_rendering in so I could actually test stuff. That'll be merged to master before this is done and I'll force-push it into oblivion at that time, so just ignore those extra commits.

@CelticMinstrel CelticMinstrel removed UI User interface issues, including both back-end and front-end issues. Editor Map/scenario editor issues. Units Issues that involve unit definitions or their implementation in the engine. labels Jun 5, 2022
The purpose is to simply list everything that's available in a given module or object.

Currently, it only works for tables. The plan is to extend it to userdata objects if and when it is approved.
This places all read-only functions straight into the AI table, which means it sticks when stdlib.lua nulls out the old move map API.

The AI table then implements the __dir metamethod to add the mutating functions in if read_only is false.

This also adds a __dir metamethod for the aspects table which gets the list of aspects directly from the engine.
Note that using it on wesnoth.preferences only returns preferences that are currently set and may omit some preferences that are possible but currently unset. However, it DOES include all registered advanced preferences even if they are unset.
This fetches all known attributes for that widget type and also walks the widget tree to grab the IDs of any child widgets, so it SHOULD get everything.

Deprecated keys value_compat and callback are excluded.
- Named tuples
- Version
- vconfig
@github-actions github-actions bot added the UI User interface issues, including both back-end and front-end issues. label Jun 11, 2022
@stevecotton
Copy link
Contributor

A name as generic as dir shouldn't be added to the global namespace.

return 1;
}

static int impl_get_dir_suffix(lua_State*L)
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these suffixes a convention, either from Lua or another language?

If they're not a convention: for functions, the suffix () would seem more natural to me than ƒ, although both make sense. I'm not seeing the logic that associates daggers with tables.

General comment on the whole PR: more code-comments would help. Knowing what each function is meant to do makes reviewing both easier and better (because the reviewers don't make as many incorrect assumptions).

Copy link
Member Author

Choose a reason for hiding this comment

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

I chose dagger for table because it resembles a T, and florin for functions because it resembles an F. An italicized lower-case F (which the florin basically is) is commonly used for functions in mathematics, which influenced my decision.

Copy link
Member Author

Choose a reason for hiding this comment

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

Just for the record, I don't actually have any special attachment to these suffixes. If someone has better suggestions, I'm open to changing them.

@@ -574,4 +574,47 @@ int impl_widget_set(lua_State* L)
ERR_LUA << "invalid modifiable property of '" << typeid(w).name()<< "' widget:" << str << "\n";
return luaL_argerror(L, 2, "invalid modifiable property of widget");
}

int impl_widget_dir(lua_State* L)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a way to get to this in the Lua console?

After puzzling about it, I saw that https://wiki.wesnoth.org/LuaAPI/gui/widget says " Since these functions take a widget userdata as the first parameter, they can only be used in the preshow or postshow of a GUI2 dialog (directly or indirectly)". That makes me think it's not accessible from the Lua console, so it's unclear how to test it.

Copy link
Member Author

Choose a reason for hiding this comment

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

gui.show_dialog works from the Lua console, so I tested it via gui.show_dialog(dialog_wml, function(window) dir(whatever) end).

For my test case I loaded the tutorial character selection dialog into dialog_wml, and I also added an ID to every widget in the tutorial to prove that that aspect of it works correctly.

@@ -345,6 +366,7 @@ if wesnoth.kernel_type() ~= "Application Lua Kernel" then

local root_variable_mt = {
__metatable = "WML variables proxy",
__dir = dir_vars(true),
Copy link
Contributor

Choose a reason for hiding this comment

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

wml.variables is one of the things that tab-completion doesn't work for. I'm wondering if adding tab-completion for it would be a parallel mechanism, and whether it would be better to implement dir on top of that mechanism instead of adding a mechanism that's limited to only the dir function.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it would be the other way around – the tab completion could be made to use the dir mechanism instead of what it currently does. That doesn't mean calling the dir() function but rather using the underlying implementation that dir() uses. It also means tab-completion will not reveal deprecated functions, but that might be fine?

Copy link
Contributor

Choose a reason for hiding this comment

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

Have you already looked at the existing mechanism, and if so please would you give an overview of what existing functions are gaining parallel implementations in this PR?

(I'll have a look for myself, but the review can be quicker if I you give me a quick-start on that.)

Copy link
Member Author

Choose a reason for hiding this comment

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

The part of intf_object_dir that populates the keys array is basically doing the same thing that lua_kernel_base::get_attributes is doing. If pulled out into a separate function, both intf_object_dir and lua_kernel_base::get_attributes could call that function.

@CelticMinstrel
Copy link
Member Author

A name as generic as dir shouldn't be added to the global namespace.

I don't really agree; I feel that the global namespace is precisely where this belongs. It doesn't really fit in the wesnoth namespace or any of our other namespaces. That said, if the namespacing is the only blocker, I'm open to moving it.

@stevecotton
Copy link
Contributor

It doesn't really fit in the wesnoth namespace or any of our other namespaces.

Given that it's easy for anyone to alias dir = wesnoth.debugging_utils_or_something.dir, please move it out of global anyway. Having thought it over, I also suggest giving it a name that can be searched for - try typing dir into the forum and wiki's search boxes, and there will be lots of results for other things.

@CelticMinstrel
Copy link
Member Author

CelticMinstrel commented Jun 14, 2022

Um, if you're going to suggest a rename, please give specific suggestions rather than "maybe this isn't really a good name". Otherwise I'm going to stick with the current name.

Note that the name is the same as the WFL function that does the same thing, so I think that's one argument for keeping the name.

@CelticMinstrel
Copy link
Member Author

I'm still waiting to see if anyone has any suggestions for a different qualified name for this function. If no-one makes any specific suggestions, I'll just merge at some point with the current name (or maybe moved into wesnoth namespace since people seem to feel strongly about that).

@stevecotton
Copy link
Contributor

I'm still waiting to see if anyone has any suggestions for a different qualified name for this function.

  • list_attributes would work well on the Wiki, but still gets many unrelated matches on the forums.
  • print_attributes seems good in both.

Given that you can alias dir = wesnoth.print_attributes, I see no reason to put it in the global namespace.

@CelticMinstrel
Copy link
Member Author

CelticMinstrel commented Jun 17, 2022

Given that you can alias dir = wesnoth.print_attributes, I see no reason to put it in the global namespace.

There is one reason:

Note that the name is the same as the WFL function that does the same thing, so I think that's one argument for keeping the name.

Would you object to adding it as wesnoth.print_attributes and also adding a line dir = wesnoth.print_attributes in core.lua? Or if not in core.lua, then automatically aliasing it whenever you open the Lua console?

Also, to clarify the tab-completion situation… are you saying you intend to work on wiring this into it once I merge this, or did you want me to do that?

@CelticMinstrel
Copy link
Member Author

CelticMinstrel commented Jun 18, 2022

I believe this is ready for merge now, unless you wanted me to wire it into the tab-completion before merging. There was one other thing I wanted to do with it, but it's not urgent and could wait until later (basically, adapting the output to the actual width of the Lua console window).

@stevecotton
Copy link
Contributor

Note that the name is the same as the WFL function that does the same thing, so I think that's one argument for keeping the name.

Would you object to adding it as wesnoth.print_attributes and also adding a line dir = wesnoth.print_attributes in core.lua? Or if not in core.lua, then automatically aliasing it whenever you open the Lua console?

Look at how much unrelated stuff turns up when searching the Wiki for dir though.

I would object, because it's easy to add but hard to remove - removing it would take a deprecation cycle.

Also, to clarify the tab-completion situation… are you saying you intend to work on wiring this into it once I merge this, or did you want me to do that?

I meant that I intended to review, but wanted your knowledge as a head-start.

@CelticMinstrel
Copy link
Member Author

removing it would take a deprecation cycle.

Not if it's only in the Lua console. That's not API that can be used in Lua loaded into the scenario. You claim that aliasing it manually is "easy", and that's technically true, but it's still annoying to have to do it every single time you open a game. And the name "dir" is already used in WFL for a function that does the exact same thing. Sure it's not very searchable, but we can probably add something to the startup log in the Lua console if that's the only problem.

I meant that I intended to review, but wanted your knowledge as a head-start.

So you are planning to work on that…?

@CelticMinstrel CelticMinstrel merged commit ab9fe9e into master Jun 21, 2022
@CelticMinstrel CelticMinstrel deleted the lua_dir branch June 21, 2022 00:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AI Issues with the AI engine, including micro AIs. Lua API Issues with the Lua engine and API. UI User interface issues, including both back-end and front-end issues.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants