Key blocking
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.
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,
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
to get the array?
Code:
void separate(cpArbiter *arb, struct cpSpace *space, void *data)
{
[(GameController *)data separate2];
}
- (void) separate2 {
bool m_keys = [circle getKeys];
if (m_keys[SPACE]){
//
}
}
Code:
- (bool)getKeys {
return m_keys;
}
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:
and:
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.
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.
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?
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:
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.
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.
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?
Which of the four Chipmunk function callbacks is the best for the purpose of adding a constant velocity to the body?
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.
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.
When I do
I get four "incompatible types in initialization" errors. What is the problem? Could someone also answer my previous post.
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))};
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.
I get the error "incompatible types in initialization" even when x, y and l are cpFloats. What is the problem?
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.
cpVect array[ 4 ] = { etc.
...should compile.
Mark Bishop
--
Student and freelance OS X & iOS developer
Possibly Related Threads...
Thread: | Author | Replies: | Views: | Last Post | |
blocking function for timing purposes | unknown | 6 | 6,130 |
Feb 20, 2006 11:03 AM Last Post: Skorche |
|
Non-blocking VBL sync? | TomorrowPlusX | 4 | 6,444 |
Feb 28, 2005 02:06 PM Last Post: arekkusu |