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

Potential solution for getting the calling window of a bound method. #3424

Closed

Conversation

leaanthony
Copy link
Member

Description

** This PR has been opened up to start a discussion on what the right solution is **

There will be times when you want to know what window made a call to a bound method. This PR offers 2 solutions for 2 different scenarios:

  1. When a bound method uses a standard context.Context in the first parameter, the context will have a value "window" which will return the calling window.
  2. For scenarios where you want to call these methods from Go, you can simply use an application.Window as the first parameter. It will always be populated with the calling window if called from JS.

The binding example has been updated to show both usages.

Copy link

cloudflare-pages bot commented Apr 25, 2024

Deploying wails with  Cloudflare Pages  Cloudflare Pages

Latest commit: a788b3a
Status:⚡️  Build in progress...

View logs

func (*GreetService) GreetPerson(person data.Person) string {
return "Hello " + person.Name
// GreetWithCtx greets a person
func (*GreetService) GreetWithCtx(ctx context.Context, name string) string {
Copy link
Member

@tmclane tmclane Apr 25, 2024

Choose a reason for hiding this comment

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

I actually like making this a specific type of Context aka a CallContext such that you can add porcelain to ask for the things you want to pull out. Would allow the user to not have to typecast for example.

type CallIdentifier string

type CallContext interface {
    Application() *application.App
    Attrs() map[string]any
    CallID() CallIdentifier 
    Get(string) any
    Window() application.Window
}

Copy link
Member

@tmclane tmclane left a comment

Choose a reason for hiding this comment

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

empty comment

@fbbdev
Copy link

fbbdev commented Apr 28, 2024

I was having a look at the code again and I noticed that checks for the window parameter happen in processCallMethod from messageprocessor_call.go.

Do you have a reason for that? I'm asking because @stffabi added very similar code in bindings.go for context parameters:

and I was thinking this change probably belongs there too?

Also please note that my PR #3431 is going to break this in its current form, because CallOptions.Args is changing from a slice of any to a slice of json.RawMessage.

Sorry for the late review, didn't notice this before.

@fbbdev
Copy link

fbbdev commented Apr 28, 2024

Also, I would ignore a window parameter in second place unless the first place is a context. I would do something along these lines:

In getMethods

if (!boundMethod.needsContext && inputIndex == 0) || (boundMethod.needsContext && inputIndex == 1) {
	if  input.AssignableTo(windowType) {
		boundMethod.needsWindow = true
	}
}

In BoundMethod.Call:

if b.needsWindow {
	args = append([]any{wnd}, args...)
}
if b.needsContext {
...

@leaanthony
Copy link
Member Author

I was having a look at the code again and I noticed that checks for the window parameter happen in processCallMethod from messageprocessor_call.go.

Do you have a reason for that? I'm asking because @stffabi added very similar code in bindings.go for context parameters:

Yeah, the bindings doesn't know about windows.

Also, I would ignore a window parameter in second place unless the first place is a context.

Would you pass nil instead?

@fbbdev
Copy link

fbbdev commented Apr 28, 2024

Yeah, the bindings doesn't know about windows.

That's true, but do you plan on using the binding system for anything else? If not, you could just pass the (possibly nil) window as an additional argument to BoundMethod.Call and handle things in there.

Anyways if you prefer the current approach that's ok, I can rework #3431 once this gets merged.

Also, I would ignore a window parameter in second place unless the first place is a context.

Would you pass nil instead?

I would just ignore it and let the binding system throw an error. We can also add a warning in the binding generator.

Let me explain better what I have in mind.

With the current implementation the following method:

func (s *Service) Method(num int, wnd application.Window, str string)

would receive a window as its second argument.

I think this is a bit contrived and should be avoided.

I'd go with something similar to the following check:

windowIndex := 0
if boundMethod.needsContext {
	windowIndex = 1
}
if windowIndex < len(boundMethod.Inputs) && boundMethod.Inputs[windowIndex].ReflectType == reflect.TypeFor[Window]() {
	options.Args = append([]any{window}, options.Args...)
}

Any other situation should trigger a runtime error.

leaanthony and others added 18 commits May 5, 2024 18:32
* Unmarshal arguments to appropriate type in binding calls

* Marshal multiple return values to arrays in binding calls

* Improve logging of remote method calls

* Add tests for `BoundMethod.Call`

* Fix return value if error is nil

* Update changelog

---------

Co-authored-by: Andreas Bichinger <[email protected]>
* Add `port` flag to dev command, ...

Add support for environment variable WAILS_VITE_PORT

* Check if port is already in use

* Update changelog

---------

Co-authored-by: Lea Anthony <[email protected]>
* add missing map init from `application.init()`

* add changelog entry for #3426

---------

Co-authored-by: Lea Anthony <[email protected]>
unknown key codes shouldn't print out to stdout
text was colored white and therefore invisible.
@leaanthony
Copy link
Member Author

git fun...

@leaanthony
Copy link
Member Author

Moved to #3457

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.

None yet

6 participants