Commit 7a31216
[generator] Emit events for addListener(Listener,Handler) pattern (dotnet#458)
When [generating events][0], given a Java `Listener` interface and an
"add" method which takes the listener, `generator` will emit an event
for each method on the listener interface, and all method parameters
will become properties on a generated `EventArgs`. For example,
consider [`android.view.TextureView`][1]:
// Java
public class TextureView {
public interface SurfaceTextureListener {
void onSurfaceTextureAvailable (SurfaceTexture surface, int width, int height);
void onSurfaceTextureDestroyed (SurfaceTexture surface);
void onSurfaceTextureChanged (SurfaceTexture surface, int width, int height);
void onSurfaceTextureUpdated (SurfaceTexture surface);
}
public void setSurfaceTextureListener(SurfaceTextureListener listener);
}
`generator` will ["eventify" `TextureView` into][2]:
// C#
public partial class TextureView {
public interface ISurfaceTextureListener {
void OnSurfaceTextureAvailable (SurfaceTexture surface, int width, int height);
void OnSurfaceTextureDestroyed (SurfaceTexture surface);
void OnSurfaceTextureChanged (SurfaceTexture surface, int width, int height);
void OnSurfaceTextureUpdated (SurfaceTexture surface);
}
public partial class SurfaceTextureAvailableEventArgs {
public SurfaceTexture Surface {get;}
public int Width {get;}
pbulic int Height {get;}
}
public event EventHandler<SurfaceTextureAvailableEventArgs> SurfaceTextureAvailable;
public partial class SurfaceTextureDestroyedEventArgs {
public SurfaceTexture Surface {get;}
}
public event EventHandler<SurfaceTextureDestroyedEventArgs> SurfaceTextureDestroyed;
public partial class SurfaceTextureChangedEventArgs {
public SurfaceTexture Surface {get;}
public int Width {get;}
pbulic int Height {get;}
}
public event EventHandler<SurfaceTextureChangedEventArgs> SurfaceTextureChanged;
public partial class SurfaceTextureUpdatedEventArgs {
public SurfaceTexture Surface {get;}
}
public event EventHandler<SurfaceTextureUpdatedEventArgs> SurfaceTextureUpdated;
}
A requirement of the "event pattern" was that the "add" method must:
1. Start with `add` or `set`, e.g. `setSurfaceTextureListener()`.
2. Have a return type of `void`.
3. Have a *single* parameter which is an interface containing
`Listener` as a suffix.
As time has gone on, we've found a slight variation on this pattern
that we believe `generator` should natively support:
4. *Or*, the "add" method should have *two* parameters, the first
being an interface type with a `Listener` suffix, and the second
parameter is of type `Android.OS.Handler`.
When we encounter (4), we can emit a "Event_With_Handler_Helper"
method which calls the "add" method, passing `null` as the `Handler`
parameter.
The addition of (4) allows us to generate events for the
[`android.media.AudioRouting.OnRoutingChangedListener`][3]
interface on the [`android.media.AudioRecord`][4] type, which
provides the method:
// Java
class AudioRecord {
public void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener, Handler handler);
}
This would allow `generator` to emit an `AudioRecord.RoutingChanged`
event, a'la:
public event EventHandler<Android.Media.AudioRoutingOnRoutingChangedEventArgs> RoutingChanged {
add {
global::Java.Interop.EventHelper.AddEventHandler<Android.Media.IAudioRoutingOnRoutingChangedListener, Android.Media.IAudioRoutingOnRoutingChangedListenerImplementor>(
ref weak_implementor_AddOnRoutingChangedListener,
__CreateIAudioRoutingOnRoutingChangedListenerImplementor,
AddOnRoutingChangedListener_Event_With_Handler_Helper,
__h => __h.Handler += value);
}
remove {
global::Java.Interop.EventHelper.RemoveEventHandler<Android.Media.IAudioRoutingOnRoutingChangedListener, Android.Media.IAudioRoutingOnRoutingChangedListenerImplementor>(
ref weak_implementor_AddOnRoutingChangedListener,
Android.Media.IAudioRoutingOnRoutingChangedListenerImplementor.__IsEmpty,
__v => RemoveOnRoutingChangedListener (__v),
__h => __h.Handler -= value);
}
}
void AddOnRoutingChangedListener_Event_With_Handler_Helper (Android.Media.IAudioRoutingOnRoutingChangedListener value)
{
AddOnRoutingChangedListener (value, null);
}
Additionally, update `generate.sh` script to include API-29.
[0]: https://docs.microsoft.com/en-us/xamarin/android/internals/api-design#events-and-listeners
[1]: https://developer.android.com/reference/android/view/TextureView
[2]: https://docs.microsoft.com/en-us/dotnet/api/android.views.textureview?view=xamarin-android-sdk-9#events
[3]: https://developer.android.com/reference/android/media/AudioRouting.OnRoutingChangedListener.html
[4]: https://developer.android.com/reference/android/media/AudioRecord.html
[5]: https://developer.android.com/reference/android/media/AudioRecord.html#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener,%20android.os.Handler)1 parent a30523e commit 7a31216
File tree
6 files changed
+56
-8
lines changed- build-tools/xamarin-android-docimporter-ng
- tools/generator
- Java.Interop.Tools.Generator.CodeGeneration
- Java.Interop.Tools.Generator.ObjectModel
- Tests
- Unit-Tests
- CodeGeneratorExpectedResults/Common
6 files changed
+56
-8
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
Lines changed: 16 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
804 | 804 | | |
805 | 805 | | |
806 | 806 | | |
807 | | - | |
| 807 | + | |
808 | 808 | | |
809 | 809 | | |
810 | 810 | | |
811 | 811 | | |
812 | 812 | | |
813 | 813 | | |
814 | 814 | | |
815 | | - | |
| 815 | + | |
816 | 816 | | |
817 | 817 | | |
818 | 818 | | |
| |||
825 | 825 | | |
826 | 826 | | |
827 | 827 | | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
828 | 836 | | |
829 | 837 | | |
830 | 838 | | |
| |||
847 | 855 | | |
848 | 856 | | |
849 | 857 | | |
850 | | - | |
| 858 | + | |
851 | 859 | | |
852 | 860 | | |
853 | 861 | | |
| |||
914 | 922 | | |
915 | 923 | | |
916 | 924 | | |
917 | | - | |
918 | | - | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
| 929 | + | |
919 | 930 | | |
920 | 931 | | |
921 | 932 | | |
| |||
Lines changed: 2 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
67 | | - | |
| 67 | + | |
| 68 | + | |
68 | 69 | | |
69 | 70 | | |
70 | 71 | | |
| |||
Lines changed: 22 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
528 | 528 | | |
529 | 529 | | |
530 | 530 | | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
531 | 543 | | |
532 | 544 | | |
533 | 545 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
503 | 503 | | |
504 | 504 | | |
505 | 505 | | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
506 | 509 | | |
507 | 510 | | |
508 | 511 | | |
| |||
0 commit comments