I need to create/upload/start waypoint mission on one button. When user press button drone should move up for certain number of point based on current position. User can stop mission and again start new one. My logic here is next:
I initialize mission with points
Load mission
Add Listeners to mission operator
Upload mission
Mission starts on listener
missionOperator.addListener(toUploadEvent: self, with: DispatchQueue.main) { (event) in
if event.currentState == .readyToExecute {
self.startMission()
}
}
I'm reading documentation for days and trying to understand how this thing work, but I'm missing something obviously. Listeners are created on waypoint mission operator, but if I create listeners before loading mission they are not called. If I create listeners every time I load mission, startMission() is called multiple times (first time is called ones, but after one mission is stopped or finished, next time startMission() gets called two times)
So, I guess that my questions would be:
What is right moment to add listeners and to remove them since I'm calling startMission() from listeners? Actually what is appropriate way to init/upload/start mission on one button, and be able to do that multiple times?
You need to remove the upload listener when the the upload succeeded and the event state is readyToExecute. Also when the event contains an error, or the state is readytoupload/notsupported/disconnected. Pretty much in every case except when it's still in the state 'uploading'.
When you start the mission, add a listener for execution events, and one for finished. Remove those again when the mission is stopped/cancelled, has an error, or finishes successfully.
Even though you use Swift, I suggest looking at the more complete Objective C sample code, which includes examples of several different types of missions.
Related
We're using Realm (Swift binding currently in version 3.12.0) from the earliest days in our project. In some early versions before 1.0 Realm provided change listeners for Results without actually giving changeSets.
We used this a lot in order to find out if a specific Results list changed.
Later the guys at Realm exchanged this API with changeSet providing methods. We had to switch and are now mistreating this API just in order to find out if anything in a specific List changed (inserts, deletions, modifications).
Together with RxSwift we wrote our own implementation of Results change listening which looks like this:
public var observable: Observable<Base> {
return Observable.create { observer in
let token = self.base.observe { changes in
if case .update = changes {
observer.onNext(self.base)
}
}
observer.onNext(self.base)
return Disposables.create(with: {
observer.onCompleted()
token.invalidate()
})
}
}
When we now want to have consecutive updates on a list we subscribe like so:
someRealm.objects(SomeObject.self).filter(<some filter>).rx.observable
.subscribe(<subscription code that gets called on every update>)
//dispose code missing
We wrote the extension on RealmCollection so that we can subscribe to List type as well.
The concept is equal to RxRealm's approach.
So now in our App we have a lot of filtered lists/results that we are subscribing to.
When data gets more and more we notice significant performance losses when it comes to seeing a change visually after writing something into the DB.
For example:
Let's say we have a Car Realm Object class with some properties and some 1-to-n and some 1-to-1 relationships. One of the properties is a Bool, namely isDriving.
Now we have a lot of cars stored in the DB and bunch of change listeners with different filters listing to changes of the cars collection (collection observers listening for changeSets in order to find out if the list was changed).
If I take one car of some list and set the property of isDriving from false to true (important: we do writes in the background) ideally the change listener fires fast and I have the nearly immediate correct response to my write on the main thread.
Added with edit on 2019-06-19:
Let's make the scenario still a little more real:
Let's change something down the hierarchy, let's say the tires manufacturer's name. Let's say a Car has a List<Tire>, a Tire has a Manufacturer and a Manufacturer has aname.
Now we're still listing toResultscollection changes with some more or less complex filters applied.
Then we're changing the name of aManufacturer` which is connected to one of the tires which are connected to one of the cars which is in that filtered list.
Can this still be fast?
Obviously when the length of results/lists where change listeners are attached to gets longer Realm's internal change listener takes longer to calculate the differences and fires later.
So after a write we see the changes - in worst case - much later.
In our case this is not acceptable. So we are thinking through different scenarios.
One scenario would be to not use .observe on lists/results anymore and switch to Realm.observe which fires every time anything did change in the realm, which is not ideal, but it is fast because the change calculation process is skipped.
My question is: What can I do to solve this whole dilemma and make our app fast again?
The crucial thing is the threading stuff. We're always writing in the background due to our design. So the writes itself should be very fast, but then that stuff needs to synchronize to the other threads where Realms are open.
In my understanding that happens after the change detection for all Results has run through, is that right?
So when I read on another thread, the data is only fresh after the thread sync, which happens after all notifications were sent out. But I am not sure currently if the sync happens before, that would be more awesome, did not test it by now.
Problem Context
I am trying to generate a total (linear) order of event items per key from a real-time stream where the order is event time (derived from the event payload).
Approach
I had attempted to implement this using streaming as follows:
1) Set up a non overlapping sequential windows, e.g. duration 5 minutes
2) Establish an allowed lateness - it is fine to discard late events
3) Set accumulation mode to retain all fired panes
4) Use the "AfterwaterMark" trigger
5) When handling a triggered pane, only consider the pane if it is the final one
6) Use GroupBy.perKey to ensure all events in this window for this key will be processed as a unit on a single resource
While this approach ensures linear order for each key within a given window, it does not make that guarantee across multiple windows, e.g. there could be a window of events for the key which occurs after that is being processed at the same time as the earlier window, this could easily happen if the first window failed and had to be retried.
I'm considering adapting this approach where the realtime stream can first be processed so that it partitions the events by key and writes them to files named by their window range.
Due to the parallel nature of beam processing, these files will also be generated out of order.
A single process coordinator could then submit these files sequentially to a batch pipeline - only submitting the next one when it has received the previous file and that downstream processing of it has completed successfully.
The problem is that Apache Beam will only fire a pane if there was at least one time element in that time window. Thus if there are gaps in events then there could be gaps in the files that are generated - i.e. missing files. The problem with having missing files is that the coordinating batch processor cannot make the distinction between knowing whether the time window has passed with no data or if there has been a failure in which case it cannot proceed until the file finally arrives.
One way to force the event windows to trigger might be to somehow add dummy events to the stream for each partition and time window. However, this is tricky to do...if there are large gaps in the time sequence then if these dummy events occur surrounded by events much later then they will be discarded as being late.
Are there other approaches to ensuring there is a trigger for every possible event window, even if that results in outputting empty files?
Is generating a total ordering by key from a realtime stream a tractable problem with Apache Beam? Is there another approach I should be considering?
Depending on your definition of tractable, it is certainly possible to totally order a stream per key by event timestamp in Apache Beam.
Here are the considerations behind the design:
Apache Beam does not guarantee in-order transport, so there is no use within a pipeline. So I will assume you are doing this so you can write to an external system with only the capability to handle things if they come in order.
If an event has timestamp t, you can never be certain no earlier event will arrive unless you wait until t is droppable.
So here's how we'll do it:
We'll write a ParDo that uses state and timers (blog post still under review) in the global window. This makes it a per-key workflow.
We'll buffer elements in state when they arrive. So your allowed lateness affects how efficient of a data structure you need. What you need is a heap to peek and pop the minimum timestamp and element; there's no built-in heap state so I'll just write it as a ValueState.
We'll set a event time timer to receive a call back when an element's timestamp can no longer be contradicted.
I'm going to assume a custom EventHeap data structure for brevity. In practice, you'd want to break this up into multiple state cells to minimize the data transfered. A heap might be a reasonable addition to primitive types of state.
I will also assume that all the coders we need are already registered and focus on the state and timers logic.
new DoFn<KV<K, Event>, Void>() {
#StateId("heap")
private final StateSpec<ValueState<EventHeap>> heapSpec = StateSpecs.value();
#TimerId("next")
private final TimerSpec nextTimerSpec = TimerSpec.timer(TimeDomain.EVENT_TIME);
#ProcessElement
public void process(
ProcessContext ctx,
#StateId("heap") ValueState<EventHeap> heapState,
#TimerId("next") Timer nextTimer) {
EventHeap heap = firstNonNull(
heapState.read(),
EventHeap.createForKey(ctx.element().getKey()));
heap.add(ctx.element().getValue());
// When the watermark reaches this time, no more elements
// can show up that have earlier timestamps
nextTimer.set(heap.nextTimestamp().plus(allowedLateness);
}
#OnTimer("next")
public void onNextTimestamp(
OnTimerContext ctx,
#StateId("heap") ValueState<EventHeap> heapState,
#TimerId("next") Timer nextTimer) {
EventHeap heap = heapState.read();
// If the timer at time t was delivered the watermark must
// be strictly greater than t
while (!heap.nextTimestamp().isAfter(ctx.timestamp())) {
writeToExternalSystem(heap.pop());
}
nextTimer.set(heap.nextTimestamp().plus(allowedLateness);
}
}
This should hopefully get you started on the way towards whatever your underlying use case is.
I'm trying to send an exchange to another player in a GKTurnBasedMatch. When I send it, my completion handler gets a big error message, with these descriptions:
The requested operation could not be completed because the session is in an invalid state.
Game is not active, session state is Matching
I want the match to start when there are just two players, but to allow a total of 16 players. So naturally I'm setting maxPlayers = 16 and minPlayers = 2. I'd thought that would automatically start the match once two players were seated, but it's not so.
I've tried to do this once the match has two players, :
if match.participants?.count == 2 {
match.status = GKTurnBasedMatchStatus.open
}
But then I'm told that status is read-only. I can't manually set it.
Now, with a regular GKMatch, I officially start the match by calling:
GKMatchmaker.shared().finishMatchmaking(for: match)
But there doesn't seem to be a similar thingy for GKTurnBasedMatch.
How do I actually get the match started, so I can send an exchange between the two players?
Man, the documentation on GKTurnBasedMatch is sparse.
Here's the thing: you don't actually start a GKTurnBasedMatch explicitly. You only end it explicilty.
During gameplay, you just pass the turn from one active player to another active player. The game technically starts as soon as the first player is seated.
The problem I was having is that I had passed the turn when there was no other active player. So I accidentally told Game Center to assign the turn to an empty seat. So when the error message told me
Game is not active, session state is Matching
It meant that the current seat was empty and still looking for a player to fill it. The game apparently goes out of active status any time the current player's status is Matching (which denotes an empty seat).
Why on earth this would affect sending exchanges, whose whole purpose is to enable communication between any players, no matter who the current player is, is beyond me. But there you go.
The solution: make sure that the current turn is held by an actual person, and is not an empty seat. Then you can send exchanges. Otherwise you can't.
I'm trying to get two physicsBody, that are already in contact with each other (in fact they overlap because physicBody.collisionCategory = 0; for both physicsBody's), to restart/re-register/re-trigger their contact, on command. I've been unable to do this even though I tried to get body1 to move by one pixel within body2 to re-trigger the contact. I've also deleted one of the physicsBody's & re-instantiated it several seconds after that to re-trigger the contact. But nothing works. Is there some sort of method or technique to restart the contact process while both bodies are already in contact?
So, to make things a little clearer:
1) SpriteHuman walks onto SpritePanel.
2) -(void)didBeginContact:(SKPhysicsContact *)contact registers the contact.
3) I call a method that starts step 2 again, while SpriteHuman doesn't move and is still contacting SpritePanel.
You can set a BOOL property to YES for your player object if it contacts a certain object. This will allow you to continuously run whatever code you need to run. Just remember to do also set the BOOL back to NO when contact is lost.
I have the following code:
Button export = new Button("CSV");
export.addListener(new ClickListener()
{
public void buttonClick(ClickEvent event)
{
CsvExport csvExport;
csvExport = new CsvExport(_table);
csvExport.setDisplayTotals(false);
csvExport.setDoubleDataFormat("0");
csvExport.excludeCollapsedColumns();
csvExport.setReportTitle("Document title");
csvExport.setExportFileName("Nome_file_example.csv");
csvExport.export();
getWindow().showNotification("Document saved", "The document has been exported.");
}
}
I would like the notification to appear only after the file has been exported and downloaded, but actually the notification is not working, maybe because it does not "wait" for the statement
csvExport.export();
to finish. If I comment it, the notification works.
Does anybody have any suggestions?
Thanks very much,
You'll need to split the work into a separate thread, then provide a way to notify the user 'later'.
So, first, create a thread... if you're on Java EE, use the built-in thread pooling, otherwise use something else (we're on tomcat, we rolled our own, to allow us better control).
Then, when you're done, synchronize your thread, work your way back into your UI class (We use closures from Groovy, but you can make your own listener), and call the method to notify your user. window.showNotification('All Done')
So here's the tricky part, you've notified your user, but Vaadin has already sent the 'click' response back... so the Server part thinks it's notified the user, but it isn't able to show the user yet... You'll need a progress indicator on your page, as it asks the server every 5 seconds if anything has changed.
There are also some 'push' plugins, but I've found that most of the places that we we're spinning up threads, we want to show a 'loading' animation, so the progress indicator works well.