Emanuel Gedin
Emanuel Gedin

Reputation: 1

Objective-c: Adding a custom object to a NSMutableArray

I usually program in java or c++ and I recently started with objective-c. Looking for vectors in objective-c, I found NSMutableArray which seems to be the best option. I'm working on an opengl game and I'm trying to create an NSMutableArray of textured quads for my sprites. Here is the relevant code:

I define textured quads:

typedef struct {
    CGPoint geometryVertex;
    CGPoint textureVertex;
} TexturedVertex;

typedef struct {
    TexturedVertex bl;
    TexturedVertex br;    
    TexturedVertex tl;
    TexturedVertex tr;    
} TexturedQuad;

I create an array in the interface:

@interface Sprite() {
    NSMutableArray *quads;
}

I initiate the array and I create the texturedQuads based on "width" and "height", which are the dimensions of a single sprite, and "self.textureInfo.width" and "self.textureInfo.height", which are the dimensions of the entire sprite sheet:

    quads = [NSMutableArray arrayWithCapacity:1];
    for(int x = 0; x < self.textureInfo.width/width; x++) {
    for(int y = 0; y < self.textureInfo.height/height; y++) {
        TexturedQuad q;
        q.bl.geometryVertex = CGPointMake(0, 0);
        q.br.geometryVertex = CGPointMake(width, 0);
        q.tl.geometryVertex = CGPointMake(0, height);
        q.tr.geometryVertex = CGPointMake(width, height);

        int x0 = (x*width)/self.textureInfo.width;
        int x1 = (x*width + width)/self.textureInfo.width;
        int y0 = (y*height)/self.textureInfo.height;
        int y1 = (y*height + height)/self.textureInfo.height;

        q.bl.textureVertex = CGPointMake(x0, y0);
        q.br.textureVertex = CGPointMake(x1, y0);
        q.tl.textureVertex = CGPointMake(x0, y1);
        q.tr.textureVertex = CGPointMake(x1, y1);

        //add q to quads
    }
    }

The problem is I don't know how to add the quad "q" to the array "quads". Simple writing [quads addObject:q] doesn't work because the parameter should be an id not a TexturedQuad. I've seen examples of how to make an id from an int etc, but I don't know how to do it with an object like my TexturedQuad.

Upvotes: 0

Views: 590

Answers (2)

N_A
N_A

Reputation: 19897

The essence of it is that you wrap your C struct in an Obj-C class. The Obj-C class to use is NSValue.

// assume ImaginaryNumber defined:
typedef struct {
    float real;
    float imaginary;
} ImaginaryNumber;

ImaginaryNumber miNumber;
miNumber.real = 1.1;
miNumber.imaginary = 1.41;

// encode using the type name
NSValue *miValue = [NSValue value: &miNumber withObjCType:@encode(ImaginaryNumber)]; 

ImaginaryNumber miNumber2;
[miValue getValue:&miNumber2];

See here for more information.

As @Bersaelor pointed out, if you need better performance use pure C or switch to Obj-C++ and use vectors instead of Obj-C objects.

Upvotes: 5

Bersaelor
Bersaelor

Reputation: 2577

An NSMutableArray takes any NSObject* but not just structs.

If you're serious about programming in Objective-C, take a look at some tutorials.

Furthermore, NSMutableArrays are meant for convenience, if your adding/deleting a lot of objects to that Array, use plain C-stacks. Especially for your use-case that more low-level approach will get better performance. Keep in mind, Objective-C(++) is just a superset of C(++), so you can use any C(++) code you are already familiar with.

When I wrote my game tactica for iOS, I switched to C-Code whenever I had to do heavy lifting (i.e. recursive AI-functions that get called hundreds of times per second).

Upvotes: 2

Related Questions