~eliasnaur/gio

9 5

Handling thousands of clickable areas

Dominik Honnef <dominik@honnef.co>
Details
Message ID
<87sfnpcbgx.fsf@honnef.co>
DKIM signature
missing
Download raw message
Hi,

let me first describe my current scenario: I am visualizing a trace,
which results in thousands of spans. I'd like to know which, if
any, span a user has clicked on, and act on that. The spans
themselves don't act as independent widgets, and are controlled by a
timeline widget.

The naive solution would be to record a pointer.InputOp per span.
But to be able to differentiate the spans, I would need one tag
per. To check which span has been clicked, then, I would need to
check each and every tag, doing O(n) work. This seems like a waste of
resources, considering Gio already knows what I clicked and could tell
me in O(1). We would also have to maintain additional state - the list
of possible tags - as only a subset of the trace is displayed, and the
entire trace may consist of millions of spans, which are too many to
check for.

The other solution is to record a single InputOp for the entire trace,
and compute the clicked span from the position. This has the
downside of duplicating both code and work. When handling a click, we
either need to lay out the previous frame again to compute what the user
clicked on, or otherwise maintain some state designed for spatial
lookups, like a 2d-tree. This seems like work Gio has already
implemented, but is only exposing via tags.

A solution that came to mind is based on how callbacks in C tend to
work, accepting and delivering a void* for user data. The Go equivalent
would add a `UserData interface{}` field to pointer.InputOp and
pointer.Event. Any UserData provided in the InputUp would be copied to
the Event. It would then be possible to use a single tag for many
different InputOps and differentiate based on the UserData. Much like
the Tag, this would incur no additional allocations as long as the user
uses pointers.

What do you think about this? Would this be an addition that would fit
into the Gio architecture and intended use? Are there other options that
I've missed that I could use right now?

Cheers
Details
Message ID
<CAMAFT9W-HyX11j54GL6JhFbCK=4P6hXKr5aQuZbLKNfsbQn=gA@mail.gmail.com>
In-Reply-To
<87sfnpcbgx.fsf@honnef.co> (view parent)
DKIM signature
pass
Download raw message
On Tue, 28 Jun 2022 at 12:46, Dominik Honnef <dominik@honnef.co> wrote:
>
> Hi,
>
> let me first describe my current scenario: I am visualizing a trace,
> which results in thousands of spans. I'd like to know which, if
> any, span a user has clicked on, and act on that. The spans
> themselves don't act as independent widgets, and are controlled by a
> timeline widget.
>
> The naive solution would be to record a pointer.InputOp per span.
> But to be able to differentiate the spans, I would need one tag
> per. To check which span has been clicked, then, I would need to
> check each and every tag, doing O(n) work. This seems like a waste of
> resources, considering Gio already knows what I clicked and could tell
> me in O(1). We would also have to maintain additional state - the list
> of possible tags - as only a subset of the trace is displayed, and the
> entire trace may consist of millions of spans, which are too many to
> check for.
>
> The other solution is to record a single InputOp for the entire trace,
> and compute the clicked span from the position. This has the
> downside of duplicating both code and work. When handling a click, we
> either need to lay out the previous frame again to compute what the user
> clicked on, or otherwise maintain some state designed for spatial
> lookups, like a 2d-tree. This seems like work Gio has already
> implemented, but is only exposing via tags.
>
> A solution that came to mind is based on how callbacks in C tend to
> work, accepting and delivering a void* for user data. The Go equivalent
> would add a `UserData interface{}` field to pointer.InputOp and
> pointer.Event. Any UserData provided in the InputUp would be copied to
> the Event. It would then be possible to use a single tag for many
> different InputOps and differentiate based on the UserData. Much like
> the Tag, this would incur no additional allocations as long as the user
> uses pointers.
>
> What do you think about this? Would this be an addition that would fit
> into the Gio architecture and intended use? Are there other options that
> I've missed that I could use right now?
>

Interesting use-case. My suggestion is go with a single InputOp for the entire
trace, for the simple reason that Gio doesn't (yet) implement a fancy 2d spatial
tree, and will do hit-testing in O(n).

Note that even if Gio had a fancy hit area representation, we would
have to process
all InputOps every frame to rebuild (or re-diff) the acceleration structure.
So to gain the full advantage of a acceleration structure, you'd have
to place your
InputOps in a re-used macro, and the hypothetical structure had to
support sub-structure
updates.

Elias
Details
Message ID
<CAFcc3FQ6Xj-4WQYS=7Oqw7=kDUAOZmccYWNHX77zMsOoL9Gh3w@mail.gmail.com>
In-Reply-To
<87sfnpcbgx.fsf@honnef.co> (view parent)
DKIM signature
pass
Download raw message
Hey Dominik,

> let me first describe my current scenario: I am visualizing a trace,
> which results in thousands of spans. I'd like to know which, if
> any, span a user has clicked on, and act on that. The spans
> themselves don't act as independent widgets, and are controlled by a
> timeline widget.
>
> The naive solution would be to record a pointer.InputOp per span.
> But to be able to differentiate the spans, I would need one tag
> per. To check which span has been clicked, then, I would need to
> check each and every tag, doing O(n) work. This seems like a waste of
> resources, considering Gio already knows what I clicked and could tell
> me in O(1). We would also have to maintain additional state - the list
> of possible tags - as only a subset of the trace is displayed, and the
> entire trace may consist of millions of spans, which are too many to
> check for.

You may have already tried and rejected this approach, but I'll
suggest it anyway. I would first evaluate the performance of using 1
pointer.InputOp per span, but only generating operations for the spans
that are visible on screen. I'd expect testing whether a given span is
in the viewport to be pretty easy (you already need code to do that in
order to position the viewport, right?), and it should narrow the
number of input operations at any given point in time pretty far. It
could still be hundreds, but I guess I'd be surprised if it were
thousands. Then again, perhaps I'm just unfamiliar with the domain.

At any rate, this would enable you to leverage Gio's existing event
routing without iterating *every* span. You would instead only pay for
the visible spans.

If you've already tried this and found the performance unsatisfactory,
I'd love to hear more about the experience.

Cheers,
Chris
Dominik Honnef <dominik@honnef.co>
Details
Message ID
<87letgcwh1.fsf@honnef.co>
In-Reply-To
<CAFcc3FQ6Xj-4WQYS=7Oqw7=kDUAOZmccYWNHX77zMsOoL9Gh3w@mail.gmail.com> (view parent)
DKIM signature
missing
Download raw message
Chris Waldon <christopher.waldon.dev@gmail.com> writes:

> Hey Dominik,
>
>> let me first describe my current scenario: I am visualizing a trace,
>> which results in thousands of spans. I'd like to know which, if
>> any, span a user has clicked on, and act on that. The spans
>> themselves don't act as independent widgets, and are controlled by a
>> timeline widget.
>>
>> The naive solution would be to record a pointer.InputOp per span.
>> But to be able to differentiate the spans, I would need one tag
>> per. To check which span has been clicked, then, I would need to
>> check each and every tag, doing O(n) work. This seems like a waste of
>> resources, considering Gio already knows what I clicked and could tell
>> me in O(1). We would also have to maintain additional state - the list
>> of possible tags - as only a subset of the trace is displayed, and the
>> entire trace may consist of millions of spans, which are too many to
>> check for.
>
> You may have already tried and rejected this approach, but I'll
> suggest it anyway. I would first evaluate the performance of using 1
> pointer.InputOp per span, but only generating operations for the spans
> that are visible on screen. I'd expect testing whether a given span is
> in the viewport to be pretty easy (you already need code to do that in
> order to position the viewport, right?), and it should narrow the
> number of input operations at any given point in time pretty far.

> It > could still be hundreds, but I guess I'd be surprised if it were
> thousands. Then again, perhaps I'm just unfamiliar with the domain.

In one of my real-world traces, the largest number of simultaneously
visible spans I could find was 4000. It _is_ a fraction of the total
number of spans, which is easily in the millions.

You're right that I already have to test for visibility; rendering
millions of off-screen spans would be silly. However, my original
argument was already based on only handling visible spans.

I haven't concretely benchmarked checking 4000 separate InputOps. It
would surely be "fast enough", but I'm more concerned about the total
number of instructions executed per rendered frame, from a wastage
perspective. I don't want to check 4000 tags on every frame – especially
considering that for most frames, the user will not have clicked
anything whatsoever – when instead I can check once and do some math, or
check in O(log n) using some data structure.
Details
Message ID
<CAG3idSfLt3G_jV_p10ygsr+2ndxmsLFZwdfa7pB4k0oPG9+3tQ@mail.gmail.com>
In-Reply-To
<87letgcwh1.fsf@honnef.co> (view parent)
DKIM signature
pass
Download raw message
[resending as plain text and to the mailing list]
Hi,

My solution to this, while building an image pixel editor where I had
to draw pixels as squares, was to use an ImageOp and draw the items in
it. This allowed me to handle large images. In my case it was also
simple to handle which pixel was clicked as they were all of the same
size, so one InputOp and some maths got me there.

HTH


Le mar. 28 juin 2022 à 23:24, Dominik Honnef <dominik@honnef.co> a écrit :
>
> Chris Waldon <christopher.waldon.dev@gmail.com> writes:
>
> > Hey Dominik,
> >
> >> let me first describe my current scenario: I am visualizing a trace,
> >> which results in thousands of spans. I'd like to know which, if
> >> any, span a user has clicked on, and act on that. The spans
> >> themselves don't act as independent widgets, and are controlled by a
> >> timeline widget.
> >>
> >> The naive solution would be to record a pointer.InputOp per span.
> >> But to be able to differentiate the spans, I would need one tag
> >> per. To check which span has been clicked, then, I would need to
> >> check each and every tag, doing O(n) work. This seems like a waste of
> >> resources, considering Gio already knows what I clicked and could tell
> >> me in O(1). We would also have to maintain additional state - the list
> >> of possible tags - as only a subset of the trace is displayed, and the
> >> entire trace may consist of millions of spans, which are too many to
> >> check for.
> >
> > You may have already tried and rejected this approach, but I'll
> > suggest it anyway. I would first evaluate the performance of using 1
> > pointer.InputOp per span, but only generating operations for the spans
> > that are visible on screen. I'd expect testing whether a given span is
> > in the viewport to be pretty easy (you already need code to do that in
> > order to position the viewport, right?), and it should narrow the
> > number of input operations at any given point in time pretty far.
>
> > It > could still be hundreds, but I guess I'd be surprised if it were
> > thousands. Then again, perhaps I'm just unfamiliar with the domain.
>
> In one of my real-world traces, the largest number of simultaneously
> visible spans I could find was 4000. It _is_ a fraction of the total
> number of spans, which is easily in the millions.
>
> You're right that I already have to test for visibility; rendering
> millions of off-screen spans would be silly. However, my original
> argument was already based on only handling visible spans.
>
> I haven't concretely benchmarked checking 4000 separate InputOps. It
> would surely be "fast enough", but I'm more concerned about the total
> number of instructions executed per rendered frame, from a wastage
> perspective. I don't want to check 4000 tags on every frame – especially
> considering that for most frames, the user will not have clicked
> anything whatsoever – when instead I can check once and do some math, or
> check in O(log n) using some data structure.
Details
Message ID
<CAFcc3FRpiLZUmZguYCc=Pp-YGYMh=PX2_mjFhC0Aud+xq7cA-Q@mail.gmail.com>
In-Reply-To
<87letgcwh1.fsf@honnef.co> (view parent)
DKIM signature
pass
Download raw message
On Tue, Jun 28, 2022 at 5:24 PM Dominik Honnef <dominik@honnef.co> wrote:
>
> Chris Waldon <christopher.waldon.dev@gmail.com> writes:
>
> > Hey Dominik,
> >
> >> let me first describe my current scenario: I am visualizing a trace,
> >> which results in thousands of spans. I'd like to know which, if
> >> any, span a user has clicked on, and act on that. The spans
> >> themselves don't act as independent widgets, and are controlled by a
> >> timeline widget.
> >>
> >> The naive solution would be to record a pointer.InputOp per span.
> >> But to be able to differentiate the spans, I would need one tag
> >> per. To check which span has been clicked, then, I would need to
> >> check each and every tag, doing O(n) work. This seems like a waste of
> >> resources, considering Gio already knows what I clicked and could tell
> >> me in O(1). We would also have to maintain additional state - the list
> >> of possible tags - as only a subset of the trace is displayed, and the
> >> entire trace may consist of millions of spans, which are too many to
> >> check for.
> >
> > You may have already tried and rejected this approach, but I'll
> > suggest it anyway. I would first evaluate the performance of using 1
> > pointer.InputOp per span, but only generating operations for the spans
> > that are visible on screen. I'd expect testing whether a given span is
> > in the viewport to be pretty easy (you already need code to do that in
> > order to position the viewport, right?), and it should narrow the
> > number of input operations at any given point in time pretty far.
>
> > It > could still be hundreds, but I guess I'd be surprised if it were
> > thousands. Then again, perhaps I'm just unfamiliar with the domain.
>
> In one of my real-world traces, the largest number of simultaneously
> visible spans I could find was 4000. It _is_ a fraction of the total
> number of spans, which is easily in the millions.

Okay, well if that many can be on screen simultaneously, I totally agree.

> I haven't concretely benchmarked checking 4000 separate InputOps. It
> would surely be "fast enough", but I'm more concerned about the total
> number of instructions executed per rendered frame, from a wastage
> perspective. I don't want to check 4000 tags on every frame – especially
> considering that for most frames, the user will not have clicked
> anything whatsoever – when instead I can check once and do some math, or
> check in O(log n) using some data structure.

Indeed, your case calls for something else.

Revisiting your initial proposal about attaching an extra empty
interface to the pointer input op so that tags could be reused, it
does seem like a neat solution to the domain. It allows you to rely
upon Gio's own event routing abstractions for this complex
canvas-style use-case instead of rolling your own, which I think is
appealing. Now, Gio's own routing abstraction is currently less
efficient for your use-case than doing it yourself, but it might not
always be. I'd be interested to see an implementation of this.

Cheers,
Chris
Details
Message ID
<CAE_4BPBvDUh=2_zSt9qidFGHpzXp-MJpe+WN20_r-H2ZJH7tqA@mail.gmail.com>
In-Reply-To
<87letgcwh1.fsf@honnef.co> (view parent)
DKIM signature
missing
Download raw message
Since pointer events can be marked "pass through", it seems like you
could put a single large pass through area over your entire trace, so
that you know if a span was clicked at all, and only then search the
list of visible spans.

It seems like you could do this recursively and thus have something
similar to a binary- or B-tree search, or failing that use a single
layer of multiple top-level areas to divide up your list of widgets by
some (perhaps variable) factor.

-- Larry

On Tue, Jun 28, 2022 at 5:24 PM Dominik Honnef <dominik@honnef.co> wrote:
>
> Chris Waldon <christopher.waldon.dev@gmail.com> writes:
>
> > Hey Dominik,
> >
> >> let me first describe my current scenario: I am visualizing a trace,
> >> which results in thousands of spans. I'd like to know which, if
> >> any, span a user has clicked on, and act on that. The spans
> >> themselves don't act as independent widgets, and are controlled by a
> >> timeline widget.
> >>
> >> The naive solution would be to record a pointer.InputOp per span.
> >> But to be able to differentiate the spans, I would need one tag
> >> per. To check which span has been clicked, then, I would need to
> >> check each and every tag, doing O(n) work. This seems like a waste of
> >> resources, considering Gio already knows what I clicked and could tell
> >> me in O(1). We would also have to maintain additional state - the list
> >> of possible tags - as only a subset of the trace is displayed, and the
> >> entire trace may consist of millions of spans, which are too many to
> >> check for.
> >
> > You may have already tried and rejected this approach, but I'll
> > suggest it anyway. I would first evaluate the performance of using 1
> > pointer.InputOp per span, but only generating operations for the spans
> > that are visible on screen. I'd expect testing whether a given span is
> > in the viewport to be pretty easy (you already need code to do that in
> > order to position the viewport, right?), and it should narrow the
> > number of input operations at any given point in time pretty far.
>
> > It > could still be hundreds, but I guess I'd be surprised if it were
> > thousands. Then again, perhaps I'm just unfamiliar with the domain.
>
> In one of my real-world traces, the largest number of simultaneously
> visible spans I could find was 4000. It _is_ a fraction of the total
> number of spans, which is easily in the millions.
>
> You're right that I already have to test for visibility; rendering
> millions of off-screen spans would be silly. However, my original
> argument was already based on only handling visible spans.
>
> I haven't concretely benchmarked checking 4000 separate InputOps. It
> would surely be "fast enough", but I'm more concerned about the total
> number of instructions executed per rendered frame, from a wastage
> perspective. I don't want to check 4000 tags on every frame – especially
> considering that for most frames, the user will not have clicked
> anything whatsoever – when instead I can check once and do some math, or
> check in O(log n) using some data structure.
Details
Message ID
<CAE_4BPA00ZfkkBfJs9i4YMXHshPZkpQNdJBVqqz=HPwq05xGsg@mail.gmail.com>
In-Reply-To
<CAE_4BPBvDUh=2_zSt9qidFGHpzXp-MJpe+WN20_r-H2ZJH7tqA@mail.gmail.com> (view parent)
DKIM signature
missing
Download raw message
Another solution that comes to mind is to extend Gio such that if you
provide a slice of tags, it returns events for any/all of them.  Then
you could have a "global" tag for all spans, *and also* a unique tag
per span.  This would also let you group non-contiguous spans, which
my previous idea wouldn't.

Actually, that brings up a third solution: Combine the two.  For each
span, generate a pass-through area with the global tag (to see if
anything was clicked at all), and then underneath it an area with a
unique tag.

So far, of the three, I like this last one best.

-- Larry

On Wed, Jun 29, 2022 at 11:18 AM Larry Clapp <larry@theclapp.org> wrote:
>
> Since pointer events can be marked "pass through", it seems like you
> could put a single large pass through area over your entire trace, so
> that you know if a span was clicked at all, and only then search the
> list of visible spans.
>
> It seems like you could do this recursively and thus have something
> similar to a binary- or B-tree search, or failing that use a single
> layer of multiple top-level areas to divide up your list of widgets by
> some (perhaps variable) factor.
>
> -- Larry
>
> On Tue, Jun 28, 2022 at 5:24 PM Dominik Honnef <dominik@honnef.co> wrote:
> >
> > Chris Waldon <christopher.waldon.dev@gmail.com> writes:
> >
> > > Hey Dominik,
> > >
> > >> let me first describe my current scenario: I am visualizing a trace,
> > >> which results in thousands of spans. I'd like to know which, if
> > >> any, span a user has clicked on, and act on that. The spans
> > >> themselves don't act as independent widgets, and are controlled by a
> > >> timeline widget.
> > >>
> > >> The naive solution would be to record a pointer.InputOp per span.
> > >> But to be able to differentiate the spans, I would need one tag
> > >> per. To check which span has been clicked, then, I would need to
> > >> check each and every tag, doing O(n) work. This seems like a waste of
> > >> resources, considering Gio already knows what I clicked and could tell
> > >> me in O(1). We would also have to maintain additional state - the list
> > >> of possible tags - as only a subset of the trace is displayed, and the
> > >> entire trace may consist of millions of spans, which are too many to
> > >> check for.
> > >
> > > You may have already tried and rejected this approach, but I'll
> > > suggest it anyway. I would first evaluate the performance of using 1
> > > pointer.InputOp per span, but only generating operations for the spans
> > > that are visible on screen. I'd expect testing whether a given span is
> > > in the viewport to be pretty easy (you already need code to do that in
> > > order to position the viewport, right?), and it should narrow the
> > > number of input operations at any given point in time pretty far.
> >
> > > It > could still be hundreds, but I guess I'd be surprised if it were
> > > thousands. Then again, perhaps I'm just unfamiliar with the domain.
> >
> > In one of my real-world traces, the largest number of simultaneously
> > visible spans I could find was 4000. It _is_ a fraction of the total
> > number of spans, which is easily in the millions.
> >
> > You're right that I already have to test for visibility; rendering
> > millions of off-screen spans would be silly. However, my original
> > argument was already based on only handling visible spans.
> >
> > I haven't concretely benchmarked checking 4000 separate InputOps. It
> > would surely be "fast enough", but I'm more concerned about the total
> > number of instructions executed per rendered frame, from a wastage
> > perspective. I don't want to check 4000 tags on every frame – especially
> > considering that for most frames, the user will not have clicked
> > anything whatsoever – when instead I can check once and do some math, or
> > check in O(log n) using some data structure.
Details
Message ID
<CAE_4BPDxQyqeEaMXhJC5sXN79=kprQHnE3V0jHXXcWm2wiTGZQ@mail.gmail.com>
In-Reply-To
<CAE_4BPA00ZfkkBfJs9i4YMXHshPZkpQNdJBVqqz=HPwq05xGsg@mail.gmail.com> (view parent)
DKIM signature
missing
Download raw message
Could pointer.Event be extended to include the InputOp that triggered it?

-- Larry

On Wed, Jun 29, 2022 at 11:27 AM Larry Clapp <larry@theclapp.org> wrote:
>
> Another solution that comes to mind is to extend Gio such that if you
> provide a slice of tags, it returns events for any/all of them.  Then
> you could have a "global" tag for all spans, *and also* a unique tag
> per span.  This would also let you group non-contiguous spans, which
> my previous idea wouldn't.
>
> Actually, that brings up a third solution: Combine the two.  For each
> span, generate a pass-through area with the global tag (to see if
> anything was clicked at all), and then underneath it an area with a
> unique tag.
>
> So far, of the three, I like this last one best.
>
> -- Larry
>
> On Wed, Jun 29, 2022 at 11:18 AM Larry Clapp <larry@theclapp.org> wrote:
> >
> > Since pointer events can be marked "pass through", it seems like you
> > could put a single large pass through area over your entire trace, so
> > that you know if a span was clicked at all, and only then search the
> > list of visible spans.
> >
> > It seems like you could do this recursively and thus have something
> > similar to a binary- or B-tree search, or failing that use a single
> > layer of multiple top-level areas to divide up your list of widgets by
> > some (perhaps variable) factor.
> >
> > -- Larry
> >
> > On Tue, Jun 28, 2022 at 5:24 PM Dominik Honnef <dominik@honnef.co> wrote:
> > >
> > > Chris Waldon <christopher.waldon.dev@gmail.com> writes:
> > >
> > > > Hey Dominik,
> > > >
> > > >> let me first describe my current scenario: I am visualizing a trace,
> > > >> which results in thousands of spans. I'd like to know which, if
> > > >> any, span a user has clicked on, and act on that. The spans
> > > >> themselves don't act as independent widgets, and are controlled by a
> > > >> timeline widget.
> > > >>
> > > >> The naive solution would be to record a pointer.InputOp per span.
> > > >> But to be able to differentiate the spans, I would need one tag
> > > >> per. To check which span has been clicked, then, I would need to
> > > >> check each and every tag, doing O(n) work. This seems like a waste of
> > > >> resources, considering Gio already knows what I clicked and could tell
> > > >> me in O(1). We would also have to maintain additional state - the list
> > > >> of possible tags - as only a subset of the trace is displayed, and the
> > > >> entire trace may consist of millions of spans, which are too many to
> > > >> check for.
> > > >
> > > > You may have already tried and rejected this approach, but I'll
> > > > suggest it anyway. I would first evaluate the performance of using 1
> > > > pointer.InputOp per span, but only generating operations for the spans
> > > > that are visible on screen. I'd expect testing whether a given span is
> > > > in the viewport to be pretty easy (you already need code to do that in
> > > > order to position the viewport, right?), and it should narrow the
> > > > number of input operations at any given point in time pretty far.
> > >
> > > > It > could still be hundreds, but I guess I'd be surprised if it were
> > > > thousands. Then again, perhaps I'm just unfamiliar with the domain.
> > >
> > > In one of my real-world traces, the largest number of simultaneously
> > > visible spans I could find was 4000. It _is_ a fraction of the total
> > > number of spans, which is easily in the millions.
> > >
> > > You're right that I already have to test for visibility; rendering
> > > millions of off-screen spans would be silly. However, my original
> > > argument was already based on only handling visible spans.
> > >
> > > I haven't concretely benchmarked checking 4000 separate InputOps. It
> > > would surely be "fast enough", but I'm more concerned about the total
> > > number of instructions executed per rendered frame, from a wastage
> > > perspective. I don't want to check 4000 tags on every frame – especially
> > > considering that for most frames, the user will not have clicked
> > > anything whatsoever – when instead I can check once and do some math, or
> > > check in O(log n) using some data structure.
Details
Message ID
<CAE_4BPAozBNXhDLLGcddZ1Df68WVYsaTJqcYMrFV10GUeB19gA@mail.gmail.com>
In-Reply-To
<CAE_4BPDxQyqeEaMXhJC5sXN79=kprQHnE3V0jHXXcWm2wiTGZQ@mail.gmail.com> (view parent)
DKIM signature
missing
Download raw message
On Wed, Jun 29, 2022 at 12:30 PM Larry Clapp larry@theclapp.org wrote:
> Could pointer.Event be extended to include the InputOp that triggered it?

I realize now that this is basically a specialization of an idea you
mentioned in your initial email:

> A solution that came to mind is based on how callbacks in C tend to work, accepting and delivering a void* for user data. The Go equivalent would add a UserData interface{} field to pointer.InputOp and pointer.Event. Any UserData provided in the InputUp would be copied to the Event. It would then be possible to use a single tag for many different InputOps and differentiate based on the UserData. Much like the Tag, this would incur no additional allocations as long as the user uses pointers.

:shrug:

-- Larry
Reply to thread Export thread (mbox)