Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pre-processing a loop in 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_

like image 421
Moustach Avatar asked Oct 05 '22 00:10

Moustach


1 Answers

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();
}
like image 186
Krumelur Avatar answered Oct 13 '22 10:10

Krumelur