Key blocking

Moderator
Posts: 3,579
Joined: 2003.06
Post: #31
Code:
void separate(cpArbiter *arb, struct cpSpace *space, void *data)
{
    bool *m_keys = (bool *)data;
    if (m_keys[SPACE]){
        //
    }
}

// assuming you're calling this from the class which has the m_keys member
cpSpaceAddCollisionHandler(space, 1, 2, NULL, NULL, NULL, separate, (void *)m_keys);

By the way, when you're dereferencing arrays and casting at the same time, it can also be done in a more funky way (note the extra pair of parentheses):

Code:
((bool *)data)[SPACE]){
        //
    }

I don't recommend doing it that way though, if you can avoid it, because it can make code really hard to read. It's also probably faster to have a local copy of it as in the first example.

There are even more cryptic ways of doing this, but generally speaking, if you see funky data access techniques, they're probably not the best way to do things.
Quote this message in a reply
Member
Posts: 131
Joined: 2010.08
Post: #32
Thanks. The two errors are solved. However, using the C way, I get "EXC_BAD_ACCESS" at if (m_keys[SPACE]). Using the Objective-C way,
Code:
void separate(cpArbiter *arb, struct cpSpace *space, void *data)
{
    [(GameController *)data separate2];
}

- (void) separate2 {
    bool m_keys = [circle getKeys];
    if (m_keys[SPACE]){
        //
    }
}
I get "subscripted value is neither array nor pointer" at if (m_keys[SPACE]). How to solve this problem? Is it something to do with the use of
Code:
- (bool)getKeys {
    return m_keys;
}
to get the array?
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #33
The error you're getting says exactly what is up. Assuming m_keys really is an array, you're not passing it around as such.

It needs to be:
Code:
- (void) separate2 {
    bool *m_keys = [circle getKeys];
    if (m_keys[SPACE]){
        //
    }
}

and:
Code:
- (bool *)getKeys {
    return m_keys;
}

An array isn't a single value, it is an *array* of values, starting at a particular memory address, which means the array itself is passed around as a pointer to that base memory address.
Quote this message in a reply
Member
Posts: 131
Joined: 2010.08
Post: #34
Is it not possible, although not recommended for arrays and objects because it takes so much memory, to pass anything, so that it is copied?
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #35
I guess you could copy the object or array and pass it as a parameter, but that doesn't make any sense at all because:
1) copying many bytes is much slower than just copying a memory address
2) without referring to the original object, you cannot modify it

While #2 would be preferable in many cases, it's not practical because of #1. So really, #1 is the main reason why it's never done. It's not that it's not recommended; it simply doesn't make sense to do things that way.

Referring to objects by memory address (pointer) is a core aspect to understand. For instance, an array isn't a singular object, but rather a chunk of memory that is referred to by its base address and then access to each element of the array is done by adding how many memory slots you need to that base address to refer to an element in the array. Consider this:

Code:
int myArray[1000];

// this ...
void *ptr = myArray + (50 * sizeof(int));
int myValue = *((int *)(ptr));
    
// ... is the same as this
int myValue = myArray[50];

You see, myArray really is just a memory address. The bracket notation clearly makes things easier to read. Now, if you were to be able to pass the entire array, the CPU would wind up copying 1000 integers. Let's assume an integer is 4 bytes long. That would be copying 4000 bytes just so you might access only one 4 byte element in the called function!

Doing it the normal way, you'd just pass the base address to the array instead. Let's say it's a 32 bit address. That means you'd only be copying 4 bytes. That's only one 1000/th the memory bandwidth!

An "object" (an instance of your class) is physically a chunk of RAM, just like an array is, so the same concept applies to "objects". When you're referring to the base address of the object from within the class, the address is "self". From outside, it's whatever symbol you declared it as, such as MyClass *myInstance = [[MyClass alloc] init]. In this case, "myInstance" is the base address. So when you pass myInstance to something, you're just passing its base address, not the whole freakin' object. Get it?

If you're just passing an single int or bool or something, then it makes sense to pass a copy of it, since it costs about the same as passing an address.
Quote this message in a reply
Member
Posts: 131
Joined: 2010.08
Post: #36
Thanks. It was nice to get a long answer.
Which of the four Chipmunk function callbacks is the best for the purpose of adding a constant velocity to the body?
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #37
I have no clue since I've used my own physics and collision detection forever (although I plan on taking Chipmunk for a spin some day). You'll have to wait for Skorche or someone else to come along, or read the docs.

My sense is that you probably don't want to add velocity, but rather input force or torque and let the engine do the velocity for you -- at least that's typically how physics engines are used.
Quote this message in a reply
Member
Posts: 131
Joined: 2010.08
Post: #38
When I do
Code:
        cpVect *array[4] = {cpv((cpFloat)(x - l), (cpFloat)(y + l)), cpv((cpFloat)(x + l), (cpFloat)(y + l)), cpv((cpFloat)(x + l), (cpFloat)(y - l)), cpv((cpFloat)(x - l), (cpFloat)(y - l))};
I get four "incompatible types in initialization" errors. What is the problem? Could someone also answer my previous post.
Quote this message in a reply
Member
Posts: 131
Joined: 2010.08
Post: #39
If a post is updated, is its title shown in bold? In case it is not, I now add information to my previous post using a new post: x, y and l are GLfloats.
Quote this message in a reply
Member
Posts: 131
Joined: 2010.08
Post: #40
I get the error "incompatible types in initialization" even when x, y and l are cpFloats. What is the problem?
Quote this message in a reply
Moderator
Posts: 704
Joined: 2002.04
Post: #41
Okay, I'm only just learning Chipmunk, but a quick glance at the documentation suggests that your error is that you're assigning to an array of pointers-to-structs, and cpv() returns a struct, not a pointer-to-a-struct; therefore, your error has nothing to do with the types of x and y, and changing your declaration/assignment to...

cpVect array[ 4 ] = { etc.

...should compile.

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  blocking function for timing purposes unknown 6 4,074 Feb 20, 2006 11:03 AM
Last Post: Skorche
  Non-blocking VBL sync? TomorrowPlusX 4 4,043 Feb 28, 2005 02:06 PM
Last Post: arekkusu