-
Notifications
You must be signed in to change notification settings - Fork 34
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
Allow Users to Pass Function to Measure-Tools Feature Tracking #1029
base: master
Are you sure you want to change the base?
Conversation
I guess I'm OK with this, but I'm not entirely sure why it's even needed. Couldn't you just update the readme to instruct people to use |
private _props: Omit<RecursiveRequired<MeasureToolsUiProviderOptions>, 'onFeatureUsed'> & { | ||
onFeatureUsed?: (feature: Feature) => void; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is getting a bit confusing, especially since it doesn't seem like this._props.onFeatureUsed
is used outside of the constructor: why should it be added to this._props
at all? One idea is to each of the _props
members into its own private member. Then we wouldn't have this unnecessary coupling between internal state and arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, onFeatureUsed is indeed used in constructor only. I will remove & { onFeatureUsed?: (feature: Feature) => void; };
part and directly use props?.onFeatureUsed
instead. This is also reasonable as it does not make a lot of sense to initialize onFeatureUsed with any default value if it is a member of this._props
this._props = {
itemPriority: props?.itemPriority ?? 20,
groupPriority: props?.groupPriority ?? 10,
widgetPlacement: {
location: props?.widgetPlacement?.location ?? StagePanelLocation.Right,
section: props?.widgetPlacement?.section ?? StagePanelSection.Start,
},
enableSheetMeasurement: props?.enableSheetMeasurement ?? false,
stageUsageList: props?.stageUsageList ?? [StageUsage.General],
onFeatureUsed: props?.onFeatureUsed, // will also remove this line
};
About the idea to each of the _props
members into its own private member, I think we can do that in another PR where we can replace _props
usage with those private properties. But does that mean we do not need RecursiveRequired
introduced in this commit (to make sure all _props
members initialized with at least some value) anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I was just thinking that perhaps someone would come along and do something similar for another arg that wasn't used outside of the constructor, but whichever you feel more comfortable doing. Just an observation. This repo/file isn't my code so don't want to impose.
I see that, but on the other hand it's sort of reaching into the library's internals? I know FeatureTracking is currently public, but if we do want to change the implementation it's better to have consumers use this. Consumers shouldn't be able to fire off feature tracking events, either, so we really shouldn't be exposing the BeEvent itself. |
@aruniverse Is there a push for packages to adopt this pattern? It doesn't really add much other than better discoverability, and beginning to move away from package statics. I just want to understand what/who is driving this. @ben-polinsky IMO the same can then be said for every public event on any public API, but it's a common pattern to expose it in the style of a C# event. |
}; | ||
if (!FeatureTracking.onFeature.numberOfListeners && this._props.onFeatureUsed) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd nix the condition checking the number of listeners.
@aruniverse Do UI providers ever get cleaned up? Or only ever created once per app lifetime?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for !FeatureTracking.onFeature.numberOfListeners
is as I tested on a sample viewer this listener was added twice. I guess the UI provider might get cleaned up and we have not removed this listener before re-creating the UI provider (but I am not really clear on when it gets cleaned up or why it might be created twice).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With FeatureTracking.onFeature being public, I don't think it's appropriate to assume that nobody else is listening for that event. It doesn't seem acceptable to have this not work because the event is already being listened to by somebody else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the interface has a cleanup mechanism: https://www.itwinjs.org/reference/appui-react/uiprovider/uiitemsprovider/onunregister/
TBH something like this belongs better in the MeasureTools.startup
which the app has to call anyways. It also has an associated terminate, which should be called alongside the IModelApp startup/shutdown by the app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I can implement it as a startup option instead. However, its usage will be different from tree-widget package (where you can provide onFeatureUsed callback function to UI Provider). If you are fine with that, I will do it right away. Thank you!
Perhaps, but doesn't make it great for situations where there's really no reason for consumers to emit. Just my two cents, I get it's already public, so maybe more trouble than it is worth. |
There is no immediate push for packages to adopt this pattern. If packages need to provide feature tracking this is probably the most preferred way to do it so apps can inject that themselves, instead of every package having to create their own static feature tracker and event emitter. This PR mainly stems from removing the internal Feature tracking apis from core, and making it easier in case people need a replacement. I have no guarantees Apps are even hooking into the existing feature tracking. |
Although it's marked "public" but technically its a |
Resolve Issue #980
Description: Based off solutions on tree-widget package and idea mentioned in this PR.
Now, users can pass their callback function
onFeatureUsed
toMeasureToolsUiItemsProvider
to handle features being used. There is an usage example in the updated README.Affected File(s):
(Modified) packages/itwin/measure-tools/src/ui-2.0/MeasureToolsUiProvider.tsx,
(Modified) packages/itwin/measure-tools/README.md