Can the recordsToSave property of CKModifyRecordsOperation object be safely used in its modifyRecordsCompletionBlock - objective-c

Suppose I start a saveOperation using a CKModifyRecordsOperation object. Can I safely assume that the recordsToSave of the object will store the list of records given at start when I access it within the modifyRecordsCompletionBlock that is executed after the operation completes.
I would assume so, but then I saw this line in the Apple doc (basically not sure what they mean by "initial": The initial contents of the array are set to the records you specified in the initWithRecordsToSave:recordIDsToDelete: method. You can modify this array as needed before executing the operation.
If there are rare circumstances where it can change, then I want to go another way in my retry logic.
EDIT added code
CKModifyRecordsOperation *saveOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave recordIDsToDelete:nil] ;
saveOperation.modifyRecordsCompletionBlock = completionBlock ; //see completion block definition below
[self.publicDatabase addOperation:saveOperation] ;
[self.OperationQ addObject: saveOperation] ; //Saved in Q for later retrieval
completionBlock is defined as
^(NSArray *savedRecords, NSArray *deletedRecordIDs, NSError * operationError){
if(operationError)
{
DDLogError(#"Save of Touch event records failed with error %#",operationError) ;
//Retry, can I do this and safely assume first record retrieved here is the first record I inserted into original recordsToSave array
CKRecord *cardinalRecord = self.OperationQ[0].recordsToSave[0] ;
//Read a field from it to decide how to handle retry (e.g: retry after delay if important set of records, don't retry if not etc)..
}
else
{
//Handle success case
}
}

Based on the code you added to the question, it seems that you wish to retrieve the array of records originally passed to the modification operation.
Accessing self.OperationQ[0].recordsToSave will certainly give you back the same array passed into [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave recordIDsToDelete:nil]
The message you reference from Apple's docs simply means that if your code updated the contents of recordsToSave, it is safe to make those changes up until you call addOperation:.
The operation won't ever change that array. So if you don't change it, then accessing it in the completion block will give you back exactly what you passed in originally.

In short No. The list of records you get at the end will be the ones that CloudKit has successfully updated. There is a possibility that it failed to update one or more in which case you need to take appropriate action.
Take a closer look at this apple documentation page https://developer.apple.com/library/ios/documentation/CloudKit/Reference/CloudKit_constants/index.html#//apple_ref/doc/constant_group/Record_Changed_Error_Keys
Which details the sort of scenarios that you need to think about.

Related

Akka.net scheduler sends just first value and doesn't update it, How fix it

I can't find the answer to an interesting moment.
in akka.net I have the scheduler. It will work in actor which are sort out a number.
here a simple implementation
_statusScheduler = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(
TimeSpan.FromSeconds(_shedulerInterval),
TimeSpan.FromSeconds(_shedulerInterval),
_reporterActor,
new ProgressReport(requestId, _testedQuantity),
Self);
where
_shedulerInterval - 5-second interval,
_testedQuantity - quantity of tested number all time updated.
and after 5 seconds it is sent 0; always, not a changed number. And here is a question: is it possible to send updated quantity?
I can't send the message to the updating quantity from Recieve<> methods, because my actor is handled the counting message and it is counted the quantity all the time and updated it(when it finished it will receive next message). But all five seconds I should generate a report by a scheduler. Is it possible to fix it?
I think now I need to send all logic because it works fine, and the stone of my problem is scheduler behavior.
The issue you have here is that the message you pass into the scheduler, new ProgressReport(requestId, _testedQuantity), is what is going to be sent each time. Since you're passing in those integer values by value, the object is going to have the original values for those fields at the time you created the message and therefore the message will never update.
If you want to be able to change the content that is sent in the recurring scheduler, do this instead:
var self = Self; // need a closure here, since ActorContext won't be available
_statusScheduler = Context.System.Scheduler.Advanced.ScheduleRepeatedlyCancelable(interval, interval, () => {
_reporterActor.Tell(new ProgressReport(requestId, _testedQuantity), self);
});
This usage of the scheduler will generate a new message each time when it invokes the lambda function and thus you'll be able to include the updated integer values inside your object.

What is the best way to read input from keyboard using SDL?

I'm running an update() method n times per second to "update" the keyboard input from the user so I can read it later in the logic part of the program. So I find two ways of implementing this in the SDL Docs and I'm not sure which one should I use.
1; Loop for all events using SDL_PollEvent searching for key down/up events and saving the key states in a map so I can check for each key state in the logic of the program.
Note: Alternatively, I can also use SDL_PeepEvents instead of SDL_PollEvent to take only the event types that matter; so, it would not "thrown away" the events on the queue.
std::map<int, bool> keyboard; // Saves the state(true=pressed; false=released) of each SDL_Key.
void update()
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
keyboard[event.key.keysym.sym] = false;
break;
case SDL_KEYUP:
keyboard[event.key.keysym.sym] = true;
break;
}
}
}
2; Taking a snapshot from the keyboard each frame so I can read it easily.
Uint8* keyboard;
void update()
{
SDL_PumpEvents();
keyboard = SDL_GetKeyState(NULL);
}
With any of above implementations I can read keyboard just like this:
if (key_map[SDLK_Return]) printf("Return has been pressed.");
Also, is there another way to do so?
I prefer to do a variation of 1, where I fill three arrays, indicating not only the current state, but also which keys just went down and which keys just went up. This allows me to easily check for those events in code (without comparing to the previous snapshot), but, most importantly, it won't miss events that last less than a frame. For example, if your game is running at 10 fps due to a slow machine, the user might press and release an important key between two calls of your update routine, and then your system will never register it. This is extremely frustrating.
SDL also sends key events when the key is held down, which allow you to have multiple key down events for each key up. I find this particularly useful when implementing keyboard scrolling through a list of items, e.g. a keyboard-controlled menu.
You should use solution 2.
Why? As SDL_GetKeyState() docs point out, before using it you are expected to call SDL_PumpEvents() to update the state array.
When you are calling SDL_PollEvent(), it implicitly calls SDL_PumpEvents(). So, it basically updates the array for SDL_GetKeyState() anyway. By parsing these events manually, you just create a second array (well, actually a much slower map) holding the same information which SDL already collected for you.
So, I would dare say that first solution means doing the same thing twice. And if you ever decide to support things such as repeated keystrokes (SDL_EnableKeyRepeat()), you'll be reimplementing even a larger part of SDL.
I realize this question is quite old, but my answer could benefit someone. Personally, I use two arrays with SDL_GetKeyState. I store one array holding the current frame's keyboard state, and one array holding that last frame's keyboard state. (With some memcpy commands, it's really easy to update them.) Along with those two arrays, I have a map that converts strings like "A" to the SDL scancode values, but that is optional.
Then, when you need to check if something is released or pressed, you can combine the two arrays to check. (I made this a function.) For example, if you know that the key is pressed this frame, but wasn't pressed last frame, it was clearly just pressed this frame. if (currentFrame["A"] == true && lastFrame["A"] == false) {/*just pressed*/}
You would then do the opposite for the released. I find that method super easy to implement and use.

Quartz Composer Objective C compare previous with current input

I'm trying to build something that will only fire a command once per keyboard input (as opposed to every frame like QC does natively). In order to do so, I'm trying to listen in on the keyboard inputs (via Freeboard) and compare the current input versus a previous version.
What seems to be happening is the previous version is getting wiped every time the patch executes, so my conditional to compare strings is failing every time. Here's some code to make it a bit clearer:
- (BOOL)execute:(id <QCPlugInContext>)context atTime:(NSTimeInterval)time withArguments:(NSDictionary *)arguments
{
self.outputPrevious=previousCharacter;
if ([self.inputCharacter caseInsensitiveCompare:previousCharacter]){
self.outputText=#"SAME";
}
else {
self.outputText=#"CHANGE";
}
previousCharacter = [NSString stringWithString:self.inputCharacter];
[previousCharacter retain];
return YES;
}
where self.outputText is the text that tells me the result of the if, self.outputPrevious is telling me what the previous character input was, and self.inputCharacter is the current keyboard input.
previousCharacter is defined in the header and instantiated in -init, so it shouldn't be being reset every time.
I've tried pretty much everything with this, so if you have any ideas or insights, that would be awesome. Thanks!
Figured it out eventually. Full solution can be found here

Advice how to present calculation of #records

I have an app that have a lot of records that i am loading into a core data DB. The actual loading is done in a module called "loadDBRecords". This module is called from "MainViewController", which is connected to "MainViewController.xib".
As the loading takes quite some time i have added an UIActivityIndicatorView to the .xib during the load. However, i would like to use a UIProgressView. When i look at this i do not see any way of using that unless i move the loading code from "loadDBRecords" to the "MainViewController".
My question is: What is the best way of leveraging the UIProgressView with my setup?
You could add a "progressHandler" block to the -loadDBRecords method. Execute the block for every record you load, and pass back a floating-point value between 0.0 and 1.0 indicating the progress thus far. The block can then assign that value to the progress bar, or print it to the console, or whatever you need it to do. (Traditionally, this would be done with a function pointer or a delegate/selector combination, but I've found blocks tend to make your intent clearer—or at least make it easier to show your intent.)
- (void)loadDBRecords:(void (^)(CGFloat progress))progressHandler {
NSUInteger count = /* number of records*/;
for (NSUInteger i = 0; i < count; i++) {
/* load the record */
progressHandler((CGFloat)n / (CGFloat)count);
}
}

Handling player on turn with Objective C

I'm creating a simple app which has a list of characters and a list of (4) players, the players is simply a reference to a playable character.
I'm stuck on how to do the following:
Make a reference to the current player on turn
Find out who the next player on turn is
Handling the last player so that it will return to the first player on turn.
Ideally, I would like to be able to do AFTER, FIRST, LAST BEFORE commands on a NSMutableArray, of these I'm able to do lastObject, but there is no firstObject, afterObject, etc.
I believe you can fake BEFORE,AFTER,FIRST commands with objectAtIndex; but ideally I do not want to rely on numeric references because it could be incorrect -- also if its mutable, the size will always change.
Typically, I would be able to do the following in Pseudocode.
Global player_on_turn.player = Null //player_on_turn is a pointer to the player object
; Handle next player on turn
If (player_on_turn.player = Null) Then Error("No player on turn assigned")
If (sizeOf[playerList]==0) Then Error("There are no players in the game")
If After player_on_turn = null Then
; We reset it
player_on_turn.player = First player
Else
; Move to the next player on turn
player_on_turn.player = After player_on_turn.player
End If
With this in mind, what is the best strategy to help handle a player on turn concept as described in the 1-2-3 example above.
Thanks
It probably doesn’t matter what data structure you’re using - at some level you will have to rely on a numerical index (except if you are using linked lists). And this is alright. If you don’t want to use it in your main game implementation that is alright, too. Just create a class that encapsulates those things. First think of the operations you need it to support. My guess here would be those:
- (PlayerObject *) currentPlayer;
- (void) startNextTurn;
If you have this you can write your game using those primitives and worry about how to best implement that later. You can change those at any time without breaking your actual game.
My recommendation would be something like this:
- (PlayerObject *) currentPlayer; {
return [players objectAtIndex: currentPlayerIndex];
}
- (void) startNextTurn; {
++currentPlayerIndex;
if (currentPlayerIndex >= [players count]) {
currentPlayerIndex = 0;
}
}
Using the index there is OK, even if the array is mutable. If you have methods that change the player array they also can take care of the necessary changes to the currentPlayerIndex.
Having this object makes it easy to write unit tests. The global variable you suggest in your pseudo-code makes it impossible to write meaningful unit tests.
Use a State Pattern for the main runloop of the software. Draw it out as a diagram and create variables to control which state the system is in.
You should use a circular list of the players to return current, next, and previous players.
This is also a great question for GameDev on the Stack Exchange.
PS
CocoaHeads puts out a relatively nice set of data objects, including a circular buffer.