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

Editor: add local variables to watch panel automatically #2451

Draft
wants to merge 3 commits into
base: ags4
Choose a base branch
from

Conversation

ericoporto
Copy link
Member

@ericoporto ericoporto commented Jun 19, 2024

This change assumes local variables are usually meaningful in the context of the function being debugged.
The user can still add and remove variables to watch, for meaningful global variables.

This is a draft that perhaps should have been an issue, but anyway, I wanted to show to see what is useful or not from this. The limitation here is the GetListOfLocalVariablesForCurrentPosition function, which relies on parsers in both AutoComplete and ScintillaWrapper which aren't perfect - perhaps they could be improved with more testing.

2024-06-19.19-55-54.mp4

Made a fix for the blinking in the video above please try and see what you think of this change.

watch_panel.mp4

@ericoporto ericoporto force-pushed the hack-editor-local-var-watch branch 2 times, most recently from e511176 to 9eaac57 Compare July 3, 2024 23:05
@ericoporto
Copy link
Member Author

ericoporto commented Jul 3, 2024

Added a very minimal left click context menu to add things to watch pane - I tried deducing if a string was actually a variable but it isn't simple, you need to check the autocomplete cache of all scripts using FindVariable and it still may come up empty if one of them failed to parse correctly, which can be very frustrating, it turns out a dumber approach that allows adding any word to the watchpane is better.

image

This is useful for things in the global context that aren't automatically added to the watch pane but that you still want to keep track.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Oct 24, 2024

Sorry for not responding earlier, I'd like to review and deal with this PR draft now if possible.
@ericoporto could you please rebase this, it seems to have few conflicts with the recent ags4 branch?

@ericoporto
Copy link
Member Author

ericoporto commented Oct 24, 2024

Right, I will do it tonight. The reason I never took it off of draft status is it had an issue that it would occasionally lock the AGS game when I ran. After I rebase, if I find the issue again I will mention it.

The last commit is probably safe without the rest of it btw.

This change assumes local variables are usually meaningful in the context of the function being debugged.

The user can still add and remove variables to watch, for meaningful global variables.
@ericoporto
Copy link
Member Author

Hey, I did the rebase but I haven't been able to test it yet. :/

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Oct 30, 2024

There's something funny, having new Type anywhere in the code would add a local variable "Type" entry (of course it won't be resolved).

For example:

int arr[] = new int[1];

will add "int" variable to the watch panel.

Not sure which part of this feature is causing this.
EDIT: this is a mistake in ScintillaWrapper.GetListOfLocalVariablesForCurrentPosition()

I'll continue testing.

@@ -97,7 +97,7 @@ protected IScript Script
/// <summary>
/// Lets for a child class to assign an actual Scintilla control.
/// </summary>
protected ScintillaWrapper Scintilla
public ScintillaWrapper Scintilla
Copy link
Contributor

Choose a reason for hiding this comment

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

This change appears to not be necessary,
but if it's necessary to let make ScintillaWrapper public, then the property setter should still be made protected, to not let external code modify the text control.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Oct 31, 2024

So, I noticed that this method GetListOfLocalVariablesForCurrentPosition requires ScintillaWrapper, and as a consequence you have to get ScriptEditor control. While we may assume that a active script's control should be available when you hit a breakpoint, I think this should be avoided.

Looking at GetListOfLocalVariablesForCurrentPosition, it seems like this method does not have to be in ScintillaWrapper at all, because it does not access any of scintilla's functionality, but only AutoComplete functionality. It may be possible to move this method to AutoComplete class, where it would accept only IScript, and work with its Text and AutoCompleteData directly.

EDIT: hmm, the only thing that we need from scintilla in that case is line's position. I suppose that this position may be get without scintilla's goto by calculating linebreaks in script text.

At last, even if above is not done, I think the position may be received without calling "Goto", AFAIK Scintilla has a method to return text position for each given line, it may be exposed in ScintillaWrapper too.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Oct 31, 2024

Overall, I think that this is a pretty good PR. This extra feature is achieved with a small amount of code, and is rather straightforward. The only questionable thing there is how local variables are scanned every time, but they are limited by a single function's scope, and it's rather the problem of autocomplete system. IMO it's a shame that AutoComplete does not cache local variables as it does globals. But this may be improved separately.

Something that bothers me slightly in the code is that extra stuff is done under _updateItemLock when syncing local vars, usually it's a good thing to minimize time spent under a lock by doing everything that does not have to be protected before or after. Maybe this code could be reorganized. OTOH I found a place in my earlier code that also could be improved for a similar purpose (one where it calls UpdateSingleWatch in a loop).

Bugs:

  • ScintillaWrapper.GetListOfLocalVariablesForCurrentPosition() adds type names if it meets "new Type" syntax. This may be fixed separately from this PR, and in ags3 branch too, as it likely affects autocomplete in general.

I suggest adding a checkable option in the panel's context menu that turns automatic local variables on and off, in case a user does not want to see them.

Then, in my opinion, the context menu should not let Remove or Clear automatically added local variables. Since they get re-added after a single step anyway.

To summarize:

  • local variables are added automatically only if this option is enabled;
  • automatically added variables are always on top of the list;
  • cannot be removed by Remove or Clear menu commands;
  • removed completely if user unchecks the option.

"Add to Watch" menu command is a very nice addition, but it has couple of bugs:

  1. It is enabled for any symbols not just variables,
  2. When a variable gets added to the list this way, there's an extra empty item inserted before for some reason.

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

Successfully merging this pull request may close these issues.

2 participants