[HELP] One question about programing

03/07/2011 00:57 npcdoom#31
Well for send, you always have to copy the value of the data you wanna send into the buffer. Your way is fine, but i kinda prefer keeping a pointer to the current position.

Code:
 *(int*)ptrPos = 12;
Yours is access element n,get address and then dereference, mine is just deference also cleaner to read, but in overall is the same.
03/07/2011 01:06 kevin_owner#32
Quote:
Originally Posted by npcdoom View Post
Well for send, you always have to copy the value of the data you wanna send into the buffer. Your way is fine, but i kinda prefer keeping a pointer to the current position.

Code:
 *(int*)ptrPos = 12;
Yours is access element n,get address and then dereference, mine is just deference also cleaner to read, but in overall is the same.
Thanks indeed it's a bit clearer but how do you add the packet size at the beginning?

in my way I create a placeholder at the beginning of my buffer and when the packet is ready to send is store the current position into another variable set the current position at 0 en add the size which i saved in that other variable.
03/07/2011 01:12 dracek#33
Quote:
Originally Posted by kevin_owner View Post
actually I want to copy the value into that array cause that's the way I build the packet. the reason i'm using this is cause i didn't find another way yet cause this one works fine for me.

Look my packet writer has a member which is currentPosition which i'm using for the index in that char array. so when I add a value lets say a short but it could also be a int I increase the currentPosition with the size of an int or short so it doesn't overwrite some data.

I'm sure that there will be an easier way and that it'll confuse some people and i have to admit that i went way to far in the code. Sorry for that:P

but would you mind telling me how you would build a packet to send cause that's the only way I know and i'd like to know more/better ways:)?
Yes, if you actually want to copy the data, then you have to do it the way you are doing it, more or less. Given the code of yours, I would however suggest few slight modifications, just to polish it a bit. As I have (not) mentioned above, using brackets might be a bit slower than doing the incrementation of pointer; perhaps like this...

Code:
*(int*)(buffer + position) = value;
However, my approach to this issue would be very different...consider this way of doing it.

Code:
/* i will take an assumption of the buffer being a lovely pointer monster... */

struct packet_buffer {
  unsigned char *beg;
  unsigned char *end;
  unsigned char *cur;
};


/* and lets suppose we have some nice function that tries to append the
   given value to the buffer. if that fails, NULL is returned... */

int packet_buffer_append(void *value, size_t len, struct packet_buffer *buf) {
  if (buf->cur + len > buf->end)
    return 0;

  /* we could make use of the <string.h> function called <memcpy> which
     would do the dirty work of copying data over;

  memcpy(buf->cur, value, len);

  /* increment the current position by <len> bytes of the data copied */

  buf->cur += len;

  /* just return something; why not pointer to current position in buffer? */
  return buf->cur;
}
Anyway, maybe that kind of way is too C-ish, not modern enough nowadays, with all that C++ whatever rush.

Also, you should know that compilers have this nasty behaviour of aligning structures to fit certain number of bytes (well, usually to be multiple of the system atomic size - e.g multiple of 4 or 8 bytes).

This means that if you have struct packet { short length, opcode, secure; char element; } it wont have 7 bytes but rather 8 bytes, with one byte stuck somewhere...
03/07/2011 10:27 kevin_owner#34
Thanks that seems to be another good way to packet the data I'll run a little test to see which one is the fastest cause I'm curious about that part:)

about that struct I didn't know that I've never just such kind of struct to build my packet.

Thanks:)
03/07/2011 16:35 dracek#35
Quote:
Originally Posted by kevin_owner View Post
Thanks that seems to be another good way to packet the data I'll run a little test to see which one is the fastest cause I'm curious about that part:)

about that struct I didn't know that I've never just such kind of struct to build my packet.

Thanks:)
Well, it can be real issue not only in the packet related logic but also in raw data interpretation - imagine having a collision system that has to read meshes of the present 3d objects into memory in order to compute possible intersections.

The mesh has its very specific format and if you had, for example, structure that would represent single pack of vertices and used code like following one, you would find out that the data read are invalid, wrong.

Code:
struct object3d_mesh_node { float x, y, z; char flag; };
/* <real> size is 3*4 + 1 = 13 bytes; these will be aligned to fit 16 bytes */

object3d_mesh_node node;
for (i = 0; i < count; ++i) {
  fread(&node, sizeof(node), 1, fp);
}

/* now, you read 16 bytes instead of 13 bytes
   ... guess what happens? BAM! */
03/07/2011 18:05 kevin_owner#36
Quote:
Originally Posted by dracek View Post
Well, it can be real issue not only in the packet related logic but also in raw data interpretation - imagine having a collision system that has to read meshes of the present 3d objects into memory in order to compute possible intersections.

The mesh has its very specific format and if you had, for example, structure that would represent single pack of vertices and used code like following one, you would find out that the data read are invalid, wrong.

Code:
struct object3d_mesh_node { float x, y, z; char flag; };
/* <real> size is 3*4 + 1 = 13 bytes; these will be aligned to fit 16 bytes */

object3d_mesh_node node;
for (i = 0; i < count; ++i) {
  fread(&node, sizeof(node), 1, fp);
}

/* now, you read 16 bytes instead of 13 bytes
   ... guess what happens? BAM! */
yeah you're right but wasn't there an easy way to solve it?
something like:

Code:
#pragma pack(push, 1)
Edit: I just tested the pragma pack line and it does work. without that line of code the sizeof that struct would be 16 just like you said and with that line of code it's 13.
03/07/2011 23:32 dracek#37
Quote:
Originally Posted by kevin_owner View Post
yeah you're right but wasn't there an easy way to solve it?
something like:

Code:
#pragma pack(push, 1)
Edit: I just tested the pragma pack line and it does work. without that line of code the sizeof that struct would be 16 just like you said and with that line of code it's 13.
Yes, that does the trick. The #pragma pack directive is also [Only registered and activated users can see links. Click Here To Register...] in gcc (for msvc compatibility) - which is quite great; eases porting of code.
03/11/2011 08:05 lesderid#38
Quote:
Originally Posted by npcdoom View Post
Speed is always an important issue, not language, just because pc are getting really fast, you cant just do whatever you want =P, but it all depends on the requirements and the problem you trying to solve.
I was just saying that when you are measuring code performance, you'll see that how you code something is (often) more important than in what language you code it.

But indeed, when coding an emulator, you have to make sure that stuff isn't too slow. (but I think you know that...)

Edit: @dracek: Maybe something stupid but aren't you doing the "buf->cur + len" calculation twice? Or would the compiler optimize this?
Quote:
Originally Posted by dracek
Code:
/* i will take an assumption of the buffer being a lovely pointer monster... */

struct packet_buffer {
  unsigned char *beg;
  unsigned char *end;
  unsigned char *cur;
};


/* and lets suppose we have some nice function that tries to append the
   given value to the buffer. if that fails, NULL is returned... */

int packet_buffer_append(void *value, size_t len, struct packet_buffer *buf) {
  size_t endLength = buf->cur + len;
  //if (buf->cur + len > buf->end)
  if (endLength > buf->end)
    return 0;

  /* we could make use of the <string.h> function called <memcpy> which
     would do the dirty work of copying data over;

  memcpy(buf->cur, value, len);

  /* increment the current position by <len> bytes of the data copied */

  //buf->cur += len;
  buf->cur = endLength;

  /* just return something; why not pointer to current position in buffer? */
  return buf->cur;
}