Pre-processing a loop in Objective-C - objective-c

I am currently writing a program to help me control complex lights installations. The idea is I tell the program to start a preset, then the app has three options (depending on the preset type)
1) the lights go to one position (so only one group of data sent when the preset starts)
2) the lights follows a mathematical equation (ex: sinus with a timer to make smooth circles)
3) the lights respond to a flow of data (ex midi controller)
So I decided to go with an object I call the AppBrain, that receive data from the controllers and the templates, but also is able to send processed data to the lights.
Now, I come from non-native programming, and I kinda have trust issues concerning working with a lot of processing, events and timing; as well as troubles with understanding 100% the Cocoa logic.
This is where the actual question starts, sorry
What I want to do, would be when I load the preset, I parse it to prepare the timer/data receive event so it doesn't have to go trough every option for 100 lights 100 times per second.
To explain more deeply, here's how I would do it in Javascript (crappy pseudo code, of course)
var lightsFunctions = {};
function prepareTemplate(theTemplate){
//Let's assume here the template is just an array, and I won't show all the processing
switch(theTemplate.typeOfTemplate){
case "simpledata":
sendAllDataTooLights(); // Simple here
break;
case "periodic":
for(light in theTemplate.lights){
switch(light.typeOfEquation){
case "sin":
lightsFunctions[light.id] = doTheSinus; // doTheSinus being an existing function
break;
case "cos":
...
}
}
function onFrame(){
for(light in lightsFunctions){
lightsFunctions[light]();
}
}
var theTimer = setTimeout(onFrame, theTemplate.delay);
break;
case "controller":
//do the same pre-processing without the timer, to know which function to execute for which light
break;
}
}
}
So, my idea is to store the processing function I need in an NSArray, so I don't need to test on each frame the type and loose some time/CPU.
I don't know if I'm clear, or if my idea is possible/the good way to go. I'm mostly looking for algorithm ideas, and if you have some code that might direct me in the good direction... (I know of PerformSelector, but I don't know if it is the best for this situation.
Thanks;
I_

First of all, don't spend time optimizing what you don't know is a performance problem. 100 iterations of the type is nothing in the native world, even on the weaker mobile CPUs.
Now, to your problem. I take it you are writing some kind of configuration / DSL to specify the light control sequences. One way of doing it is to store blocks in your NSArray. A block is the equivalent of a function object in JavaScript. So for example:
typedef void (^LightFunction)(void);
- (NSArray*) parseProgram ... {
NSMutableArray* result = [NSMutableArray array];
if(...) {
LightFunction simpledata = ^{ sendDataToLights(); };
[result addObject:simpleData];
} else if(...) {
Light* light = [self getSomeLight:...];
LightFunction periodic = ^{
// Note how you can access the local scope of the outside function.
// Make sure you use automatic reference counting for this.
[light doSomethingWithParam:someParam];
};
[result addObject:periodic];
}
return result;
}
...
NSArray* program = [self parseProgram:...];
// To run your program
for(LightFunction func in program) {
func();
}

Related

State machine to handle sequential and async events

I created this state machine to handle events. I'm unsure about my implementation firstly because I don't use a transition table or anything like that, instead, I simply input the next event/state that needs to happen. I think this is cleaner than calling method to handle event b inside the method to handle event a, right?
Secondarily, since some of the methods have parameters - and this is not swift where enum members can have associated values, I added a param for that via withObj argument. I don't see a problem with this but want to know if this is confusing/violating something from your perspective.
I also found this useful for async task, so after the task completes I set resulting value to a local variable then update state to packData using that stored value amongst many other values already existing. This value is packed in a byte array which cannot be used in blocks so this was a useful workaround - although I haven't tested yet.
States are defined via enum like so:
typedef NS_ENUM(NSUInteger, ExampleState) {
ExampleStateIdle,
ExampleStateWaitingForAsyncTask,
ExampleStateReadyToPack,
ExampleStateRespond,
ExampleStateSomethingInProgress,
ExampleStateSomething2InProgress,
ExampleStateComplete
};
Here I define a method to handle each event using helper methods. I also have an extra argument for any state that might have an associated value.
- (void)updateState:(ExampleState)state withObj:(id)obj {
self.currentState = state;
switch (state) {
case ExampleStateWaitingForAsyncTask:
[self getAsyncInfo];
break;
case ExampleStateReadyToPack:
[self packData];
break;
case ExampleStateRespond:
[self respond:obj];
break;
case ExampleStateComplete:
[self showPopup];
break;
default:
break;
}
}
Example usage:
-(void)packData {
NSData *data = [NSData dataWithBytes:&result length:resultIndex];
// next step is to respond to `client`/`central` with data
[self updateState:ExampleStateRespond withObj:data];
}

How to Implement a Decision Table in Objective-C

I am a novice programmer, and I've just started reading about decision tables. I have read Chapter 18 in Code Complete and it was very enlightening. I looked around the web to try to find any kind of example of decision tables in Objective-C and I was unable to find any boilerplate or real world examples of how to implement this.
I am programming a game in Objective-C in my spare time, and I have been dealing with increasing complexity for the rules of the game. There are a handful of somewhat deeply nested if-else statements, as well as a few switch statements that already have 10 or more cases to deal with. I think it would be easier to work with decision tables, but I have no idea how to implement this in Objective-C for something non-trivial like the logic of a game.
For example, I need different methods to execute for different combinations of states. How would I implement a decision table in Objective-C that could take different combinations of states as keys, and run specific logic based on the combination of them?
Well I thought about decision tables in Objective-C some more and came up with a solution to implement a basic one. I will not post the entire code here, just the snippets that make the decision table work and their basic purpose. I posted this over at Code Review SE if you want to see the full code and some great suggestions for how to improve it. I'm posting this now because someone posted a comment requesting that I do so, but I will definitely end up improving this and integrating the suggestions from the review. Anyway, here is the code.
First before the initialization method I establish a number of NSString constants that will be used as the keys in an NSDictionary.
//Two options for the decision table, either access the dictionary directly with 0-x, the enum values, or make strings for their names
//the advantage of strings is that it is more extensible, and the position in the enum doesnt matter
NSString* const kEnemyMovementStateJustSpawned = #"enemyMovementStateJustSpawned";
NSString* const kEnemyMovementStateIdle = #"enemyMovementStateIdle";
NSString* const kEnemyMovementStateNeedsMoving = #"enemyMovementStateNeedsMoving";
NSString* const kEnemyMovementStateToFloor = #"enemyMovementStateToFloor";
NSString *const kEnemyMovementStateAtDestinationFloor = #"enemyMovementStateAtDestinationFloor";
NSString* const kEnemyMovementStateToFloorExit = #"enemyMovementStateToFloorExit";
NSString* const kEnemyMovementStateToAttackWalls = #"enemyMovementStateToAttackWalls";
NSString* const kEnemyMovementStateToAttackFloor = #"enemyMovementStateToAttackFloor";
NSString* const kEnemyMovementStateToAttackRoom = #"enemyMovementStateToAttackRoom";
Then I use these constants along with the names of methods in the class to build the NSDictionary:
-(void) setupDecisionTable {
//the string objects are the names of methods in the class
_decisionTable = #{kEnemyMovementStateJustSpawned: #"doEnemyJustSpawned",
kEnemyMovementStateIdle: #"doEnemyIdle",
kEnemyMovementStateNeedsMoving: #"doEnemyNeedsMoving",
kEnemyMovementStateToFloorExit: #"doFloorMovement",
kEnemyMovementStateToFloor: #"doVerticalMovement",
kEnemyMovementStateAtDestinationFloor: #"doEnemyAtDestinationFloor",
kEnemyMovementStateToAttackWalls: #"doFloorMovement",
kEnemyMovementStateToAttackFloor: #"doFloorMovement",
kEnemyMovementStateToAttackRoom: #"doFloorMovement"
};
}
Then every tick I call this method, which executes the method with the name of the object pulled from the dictionary:
-(void) doMovement {
//the selector is formed from a string inside the decision table dictionary
SEL methodToCallName = NSSelectorFromString([_decisionTable objectForKey:[self stringForState:self.state]]);
if (methodToCallName) {
IMP functionPointer = [self methodForSelector:methodToCallName];
void (*methodToCall)(id, SEL) = (void *)functionPointer;
methodToCall(self, methodToCallName);
}
}
-(NSString *) stringForState:(EnemyMovementState)state {
switch (state) {
case EnemyMovementStateJustSpawned:
return kEnemyMovementStateJustSpawned;
case EnemyMovementStateIdle:
return kEnemyMovementStateIdle;
case EnemyMovementStateNeedsMoving:
return kEnemyMovementStateNeedsMoving;
case EnemyMovementStateToFloor:
return kEnemyMovementStateToFloor;
case EnemyMovementStateAtDestinationFloor:
return kEnemyMovementStateAtDestinationFloor;
case EnemyMovementStateToFloorExit:
return kEnemyMovementStateToFloorExit;
case EnemyMovementStateToAttackWalls:
return kEnemyMovementStateToAttackWalls;
case EnemyMovementStateToAttackFloor:
return kEnemyMovementStateToAttackFloor;
case EnemyMovementStateToAttackRoom:
return kEnemyMovementStateToAttackRoom;
default:
return nil;
}
}
Finally here are a couple of the methods that execute, just for a complete example:
-(void) doEnemyIdle {
if ([self checkFloorsForJobs]) {
self.state = EnemyMovementStateNeedsMoving;
} else {
[self doIdleMovement];
}
}
-(void) doEnemyNeedsMoving {
[self calculateFloorExitPositionByFloor];
self.state = EnemyMovementStateToFloorExit;
}
This is a pretty simple implementation. Currently it can only deal with one input, and a better decision table would be able to evaluate multiple inputs and provide the proper output. I think it could be extended by having an intermediate method that took the state combined with other variables to choose the proper object from the dictionary.
After doing all this, I'm not sure that decision tables are worth the effort in Objective-C. I do not know if the code is easier to understand than a switch statement. In order to add new logic to the code, it has to be modified in more places than a switch statement would seem to require. I provide this code as an example, and it would be cool to see other versions of decision tables in Objective-C if anyone has one.

Cocoa - detect event when camera started recording

In my OSX application I'm using code below to show preview from camera.
[[self session] beginConfiguration];
NSError *error = nil;
AVCaptureDeviceInput *newVideoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (captureDevice != nil) {
[[self session] removeInput: [self videoDeviceInput]];
if([[self session] canAddInput: newVideoDeviceInput]) {
[[self session] addInput:newVideoDeviceInput];
[self setVideoDeviceInput:newVideoDeviceInput];
} else {
DLog(#"WTF?");
}
}
[[self session] commitConfiguration];
Yet, I need to detect the exact time when the preview from the camera becomes available.
In other words I'm trying to detect the same moment like in Facetime under OSX, where animation starts once the camera provides the preview.
What is the best way to achieve this?
I know this question is really old, but I stumbled upon it too when I was looking for this same question, and I have found answers so here goes.
For starters, AVFoundation is too high level, you'll need to drop down to a lower level, CoreMediaIO. There's not a lot of documentation on this, but basically you need to perform a couple queries.
To do this, we'll use a combination of calls. First, CMIOObjectGetPropertyDataSize lets us get the size of the data we'll query for next, which we can then use when we call CMIOObjectGetPropertyData. To set up the get property data size call, we need to start at the top, using this property address:
var opa = CMIOObjectPropertyAddress(
mSelector: CMIOObjectPropertySelector(kCMIOHardwarePropertyDevices),
mScope: CMIOObjectPropertyScope(kCMIOObjectPropertyScopeGlobal),
mElement: CMIOObjectPropertyElement(kCMIOObjectPropertyElementMaster)
)
Next, we'll set up some variables to keep the data we'll need:
var (dataSize, dataUsed) = (UInt32(0), UInt32(0))
var result = CMIOObjectGetPropertyDataSize(CMIOObjectID(kCMIOObjectSystemObject), &opa, 0, nil, &dataSize)
var devices: UnsafeMutableRawPointer? = nil
From this point on, we'll need to wait until we get some data out, so let's busy loop:
repeat {
if devices != nil {
free(devices)
devices = nil
}
devices = malloc(Int(dataSize))
result = CMIOObjectGetPropertyData(CMIOObjectID(kCMIOObjectSystemObject), &opa, 0, nil, dataSize, &dataUsed, devices);
} while result == OSStatus(kCMIOHardwareBadPropertySizeError)
Once we get past this point in our execution, devices will point to potentially many devices. We need to loop through them, somewhat like this:
if let devices = devices {
for offset in stride(from: 0, to: dataSize, by: MemoryLayout<CMIOObjectID>.size) {
let current = devices.advanced(by: Int(offset)).assumingMemoryBound(to: CMIOObjectID.self)
// current.pointee is your object ID you will want to keep track of somehow
}
}
Finally, clean up devices
free(devices)
Now at this point, you'll want to use that object ID you saved above to make another query. We need a new property address:
var CMIOObjectPropertyAddress(
mSelector: CMIOObjectPropertySelector(kCMIODevicePropertyDeviceIsRunningSomewhere),
mScope: CMIOObjectPropertyScope(kCMIOObjectPropertyScopeWildcard),
mElement: CMIOObjectPropertyElement(kCMIOObjectPropertyElementWildcard)
)
This tells CoreMediaIO that we want to know if the device is currently running somewhere (read: in any app), wildcarding the rest of the fields. Next we get to the meat of the query, camera below corresponds to the ID you saved before:
var (dataSize, dataUsed) = (UInt32(0), UInt32(0))
var result = CMIOObjectGetPropertyDataSize(camera, &opa, 0, nil, &dataSize)
if result == OSStatus(kCMIOHardwareNoError) {
if let data = malloc(Int(dataSize)) {
result = CMIOObjectGetPropertyData(camera, &opa, 0, nil, dataSize, &dataUsed, data)
let on = data.assumingMemoryBound(to: UInt8.self)
// on.pointee != 0 means that it's in use somewhere, 0 means not in use anywhere
}
}
With the above code samples you should have enough to test whether or not the camera is in use. You only need to get the device once (the first part of the answer); the check for if it's in use however, you'll have to do at any time you want this information. As an extra exercise, consider playing with CMIOObjectAddPropertyListenerBlock to be notified on event changes for the in use property address we used above.
While this answer is nearly 3 years too late for the OP, I hope it helps someone in the future. Examples here are given with Swift 3.0.
The previous answer from the user jer is definitely the correct answer, but I just wanted to add one additional important information.
If a listener block is registered with CMIOObjectAddPropertyListenerBlock, the current run loop must be run, otherwise no event will be received and the listener block will never fire.

How would you write fetching a collection the "Reactive Cocoa" way?

The client I'm building is using Reactive Cocoa with Octokit and so far it has been going very well. However now I'm at a point where I want to fetch a collection of repositories and am having trouble wrapping my head around doing this the "RAC way"
// fire this when an authenticated client is set
[[RACAbleWithStart([GHDataStore sharedStore], client)
filter:^BOOL (OCTClient *client) {
return client != nil && client.authenticated;
}]
subscribeNext:^(OCTClient *client) {
[[[client fetchUserRepositories] deliverOn:RACScheduler.mainThreadScheduler]
subscribeNext:^(OCTRepository *fetchedRepo) {
NSLog(#" Received new repo: %#",fetchedRepo.name);
}
error:^(NSError *error) {
NSLog(#"Error fetching repos: %#",error.localizedDescription);
}];
} completed:^{
NSLog(#"Completed fetching repos");
}];
I originally assumed that -subscribeNext: would pass an NSArray, but now understand that it sends the message every "next" object returned, which in this case is an OCTRepository.
Now I could do something like this:
NSMutableArray *repos = [NSMutableArray array];
// most of that code above
subscribeNext:^(OCTRepository *fetchedRepo) {
[repos addObject:fetchedRepo];
}
// the rest of the code above
Sure, this works, but it doesn't seem to follow the functional principles that RAC enables. I'm really trying to stick to conventions here. Any light on capabilities of RAC/Octokit are greatly appreciated!
It largely depends on what you want to do with the repositories afterward. It seems like you want to do something once you have all the repositories, so I'll set up an example that does that.
// Watch for the client to change
RAC(self.repositories) = [[[[[RACAbleWithStart([GHDataStore sharedStore], client)
// Ignore clients that aren't authenticated
filter:^ BOOL (OCTClient *client) {
return client != nil && client.authenticated;
}]
// For each client, execute the block. Returns a signal that sends a signal
// to fetch the user repositories whenever a new client comes in. A signal of
// of signals is often used to do some work in response to some other work.
// Often times, you'd want to use `-flattenMap:`, but we're using `-map:` with
// `-switchToLatest` so the resultant signal will only send repositories for
// the most recent client.
map:^(OCTClient *client) {
// -collect will send a single value--an NSArray with all of the values
// that were send on the original signal.
return [[client fetchUserRepositories] collect];
}]
// Switch to the latest signal that was returned from the map block.
switchToLatest]
// Execute a block when an error occurs, but don't alter the values sent on
// the original signal.
doError:^(NSError *error) {
NSLog(#"Error fetching repos: %#",error.localizedDescription);
}]
deliverOn:RACScheduler.mainThreadScheduler];
Now self.repositories will change (and fire a KVO notification) whenever the repositories are updated from the client.
A couple things to note about this:
It's best to avoid subscribeNext: whenever possible. Using it steps outside of the functional paradigm (as do doNext: and doError:, but they're also helpful tools at times). In general, you want to think about how you can transform the signal into something that does what you want.
If you want to chain one or more pieces of work together, you often want to use flattenMap:. More generally, you want to start thinking about signals of signals--signals that send other signals that represent the other work.
You often want to wait as long as possible to move work back to the main thread.
When thinking through a problem, it's sometimes valuable to start by writing out each individual signal to think about a) what you have, b) what you want, and c) how to get from one to the other.
EDIT: Updated to address #JustinSpahrSummers' comment below.
There is a -collect operator that should do exactly what you're looking for.
// Collect all receiver's `next`s into a NSArray. nil values will be converted
// to NSNull.
//
// This corresponds to the `ToArray` method in Rx.
//
// Returns a signal which sends a single NSArray when the receiver completes
// successfully.
- (RACSignal *)collect;

Registering for Display Reconfiguration Callbacks

I'm putting together a Mac OS X Application and I'm trying to register to receive Display Reconfiguration notices, but I'm very lost right now. I've been reading Apple's documentation and some forums posts, etc., but everything seems to assume a better knowledge of things than I apparently possess. I understand that I have to request the callback inside a run loop for it to work properly. I don't know how to set up a basic run loop for it, though. I also feel like the example Apple has in their documentation is missing stuff they are expecting me to already know. To display my ignorance here is what I feel like things should look like.
NSRunLoop *rLoop = [NSRunLoop currentRunLoop];
codeToStartRunLoop
void MyDisplayReconfigurationCallBack (
CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo);
{
if (flags & kCGDisplayAddFlag) {
NSLog (#"Display Added");
}
else if (kCGDisplayRemoveFlag) {
NSLog (#"Display Removed");
}
}
CGDisplayRegisterReconfigurationCallback(MyDisplayReconfigurationCallBack, NULL);
The actual code I got was from Apple's Example, but it tells me that flags is an undeclared identifier at this point and won't compile. Not that it would work right since I don't have it in a run loop. I was hoping to find a tutorial somewhere that explains registering for system callback in a run loop but have not been successful. If anyone could point me in the right direction I'd super appreciate it.
(I'm sure that you'll be able to tell from my question that I'm very green. I taught myself Objective-C out of a book as my first programming language. I skipped C, so every once in a while I hit a snag somewhere that I can't figure out.)
If you're writing a Mac OS X application, the AppKit has already set up a run loop for you, so you don't need to worry about that part. You really only need to create your own run loop in Cocoa when you are also creating your own thread.
For the "undeclared identifier" part, it looks like it's due to a typo/syntax mistake:
void MyDisplayReconfigurationCallBack (CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo);
// Semicolon makes this an invalid function definition^^
{
// This is an anonymous block,* and flags wasn't declared in it
if (flags & kCGDisplayAddFlag) {
// etc.
}
Also, unlike some other languages, you can't declare or define functions inside of other functions, methods, or blocks* -- they have to be at the top level of the file. You can't put this in the same place where you call CGDisplayRegisterReconfigurationCallback.
Just as an sample (I have no idea what the rest of your code really looks like):
// MyClassThatIsInterestedInDisplayConfiguration.m
#import "MyClassThatIsInterestedInDisplayConfiguration.h"
// Define callback function at top level of file
void MyDisplayReconfigurationCallBack (
CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo)
{
if (flags & kCGDisplayAddFlag) {
NSLog (#"Display Added");
}
else if (kCGDisplayRemoveFlag) {
NSLog (#"Display Removed");
}
}
#implementation MyClassThatIsInterestedInDisplayConfiguration
- (void) comeOnBabyAndDoTheRegistrationWithMe {
// Register callback function inside a method
CGDisplayRegisterReconfigurationCallback(MyDisplayReconfigurationCallBack,
NULL);
}
#end
*The basic C curly-brace-delimited thing, not the new cool Obj-C ad hoc function thing.