|
1. Unlimited Bitvectors
|
|
Fri Jul 16, 2004 [5:14 PM]
|
leabear
Email not supplied
member since: Dec 25, 2003
|
Reply
|
|
I keep seeing snippets for unlimited bitvectors and It got me thinking, would this really be worth it? Wouldn't it be harder to manage as you can open up a pfile and see what bits are on the character easily when using the standard bitvector method. Anyother dis/advantages from it?
Its late and I hope this makes sense, just looking for feedback on this subject for when i wake up in the morning.
|
|
|
|
|
2. RE: Unlimited Bitvectors
|
|
Fri Jul 16, 2004 [6:45 PM]
|
Brihtwulf
boyerj@sbcglobal.net
member since: Sep 29, 2003
|
In Reply To
Reply
|
|
The advantage is having more than enough bitvectors for assigning affects, specials, or anything that you need. Most MUDs will quickly hit the ceiling as they grow. Now, if you don't need more than the 32 or something that was coded into most original codebases, then you don't need to waste your time. :) I hope this helps a bit.
|
|
|
|
|
3. RE: Unlimited Bitvectors
|
|
Fri Jul 16, 2004 [7:07 PM]
|
KrayzieK
krayziek@mchsi.com
member since: Mar 10, 2004
|
In Reply To
Reply
|
|
Yeah, it's a lot harder in the readability factor, but gives you unlimited options in adding new flags.
|
|
|
|
|
4. RE: Unlimited Bitvectors
|
|
Sat Jul 17, 2004 [10:22 AM]
|
scandum
Email not supplied
member since: Aug 30, 2002
|
In Reply To
Reply
|
|
Using a long long you have 64 bits.
|
|
|
|
|
5. RE: Unlimited Bitvectors
|
|
Sun Jul 18, 2004 [3:55 PM]
|
lindahlb
Email not supplied
member since: Mar 2, 2001
|
In Reply To
Reply
|
|
It's been a while since I used plain C, but in C++ (and I'm pretty sure in C), you can do the following - what I consider to be the best method of implementing flags or bitvectors:
struct { bool a : 1; bool b : 1; bool c : 1; ... bool z : 1; } flags;
Access the flags in the following manner: if (flags.a && flags.b && flags.c) print("condition true")
This syntax is very readable, each flag only occupies 1 bit, and you can have as many as you want.
To write it out to a file:
size_t sz = sizeof(flags); fwrite(fp, &sz, sizeof(size_t)); fwrite(fp, &flags, sizeof(flags));
To read in from a file: size_t sz; fread(fp, &sz, sizeof(size_t)); if (sz > sizeof(flags) &sp;&sp;fread(fp, &flags, sz); else &sp;&sp;fread(fp, &flags, sizeof(flags));
The reason for the else statement is because of size mismatches. By adding or removing flags from the 'flag' structure you'll change the size of the 'flag' structure - so be warned. And only add flags to the end of the structure, otherwise you won't read in the flags properly (the code doesn't know where each individual flag is located).
For those of you interested in the compiler output, the compiler will generate the bit masking code independantly - and with compile-time optimization.
(Comment added by lindahlb on Sun Jul 18 16:56:09 2004)
Oops, I thought it still parsed HTML. Each "&sp;" should be a space.
(Comment added by lindahlb on Sun Jul 18 17:06:25 2004)
Oh, and hey, I still recognize some names around here. It's been a while. Tromping through 'The Cathyle Project' (www.cathyleproject.com) code still, with MudDB almost finished (for those of you that remember either). I see Kas & Tyche, haven't recognized any other names lately.
-Brian Lindahl
|
|
|
|
|
6. RE: Unlimited Bitvectors
|
|
Sun Jul 18, 2004 [4:09 PM]
|
muir
Email not supplied
member since: Sep 14, 2003
|
In Reply To
Reply
|
|
The struct bitvector is strictly a C++ feature, unfortunately.
Oh, and to get a space put (nonbreaking space) :)
.
|
|
|
|
|
7. RE: Unlimited Bitvectors
|
|
Mon Jul 19, 2004 [11:01 AM]
|
Razzer_9
Email not supplied
member since: Mar 5, 2001
|
In Reply To
Reply
|
|
It's been a while since I used plain C, but in C++ (and I'm pretty sure in C
To clarify, only unsigned int, signed int, or _Bool (C99) can be used portably.
[snip bitfields]
I've always been curious to why MUD programmers would use bitfields as a replacement for typical bitvectors. Bitfields pose so many portability issues. Since the data is written in binary to a file, you can't gaurantee than any of your database can be moved from one computer to another. You can't even gaurantee that you can use your database after upgrading your compiler! Using typical bitvectors is a better option because you won't have the long-term maintance and porting issues that bitfields carry. It isn't like bitfields are faster or save space.
|
|
|
|
|
8. RE: Unlimited Bitvectors
|
|
Mon Jul 19, 2004 [2:23 PM]
|
quix
Email not supplied
member since: Oct 9, 2000
|
In Reply To
Reply
|
|
It's mainly for code readability, not data.
If I can say:
struct foo { unsigned int x : 1, unsigned int y : 2, unsigned int z : 1 );
Then I get to access things just like any other structure.
if(player->x && player->y < 2) seems more readable than
if((player->bits & BIT_X) && (player->bits & BIT_Y) < (2 << BIT_Y_POS))
which isn't eactly proper code... but you get the idea.
As to it being binary with respect to a file.. it's no more or less binary than your load/save routines make it. Do people still actually use non-ASCII save files anywhere?
fprintf(fp, "X\t%d\n", (player->x ? 1 : 0));
etc...
If you want portability, you shouldn't ever write anything binary out anyways. If you're the one defining the save file format, you can do whatever you like.. use XML, then you can just import it into a database when you get tired of all the fread_blah() silliness.
|
|
|
|
|
9. RE: Unlimited Bitvectors
|
|
Mon Jul 19, 2004 [5:11 PM]
|
lindahlb
Email not supplied
member since: Mar 2, 2001
|
In Reply To
Reply
|
|
Writing binary files is just fine if you pack and unpack the bytes properly. My database system does this. You define how your current machine packs bytes with a #DEFINE, and the database takes care of converting if necessary.
If you're doing a flat-file interface, then ya, by all means use ASCII.
|
|
|
|
|
10. RE: Unlimited Bitvectors
|
|
Tue Jul 20, 2004 [2:15 AM]
|
Kastagaar
Email not supplied
member since: Jul 29, 1999
|
In Reply To
Reply
|
|
> I've always been curious to why MUD programmers would use > bitfields as a replacement for typical bitvectors. Bitfields > pose so many portability issues. Since the data is written > in binary to a file [...]
There's no reason that you can't have bitvectors AND write them in a human-readable format.
(ObHi: Hi, Brian. Nice to see you around again)
|
|
|
There are two ways of constructing software: to make it so simple that there are obviously no errors, and to make it so complex that there are no obvious errors.
|
|
11. RE: Unlimited Bitvectors
|
|
Tue Jul 20, 2004 [9:59 AM]
|
KaVir
Email not supplied
member since: Aug 19, 1999
|
In Reply To
Reply
|
|
> Then I get to access things just like any other structure. > > if(player->x && player->y < 2) seems more readable than
Actually (assuming you had correctly declared the bitfield struct) it would be:
if(player->foo.x && player->foo.y < 2)
Which would be the equivilent of the following bitvector:
if ( FOO(player->x) && FOO(player->y) < 2 )
Is it more readable? I guess that's a matter of personal opinion...
> If you want portability, you shouldn't ever write anything > binary out anyways.
Nonsense - binary files are perfectly portable. If they weren't, you wouldn't have gifs, jpgs, mpgs, etc. The disadvantage of binary files isn't portability, it's maintainance; try fixing a corrupted pfile when it's stored in a binary format.
However as has been pointed out already, bitfields are not portable. With a bitvector you can simply tell the save code to pump out the values in numeric form and it wouldn't require any further maintainance after that, but with a bitfield you're forced to specify each and every element - eg in the case of your "foo" struct, you'd have to explicitly write out x, y and z, and every time you added a new element you'd have to update the saving code again.
There are also other implementation-specific problems with bitfields...for example your "unsigned int y : 2" might work, or it might not, depending on whether or not it falls over a word boundry.
|
|
|
|
|
12. RE: Unlimited Bitvectors
|
|
Tue Jul 20, 2004 [1:37 PM]
|
quix
Email not supplied
member since: Oct 9, 2000
|
In Reply To
Reply
|
|
You're absolutly correct on the syntax... too many years of perl programming has made me SOFT! :)
When I said you shouldn't write binary structures to disk, I mean you shouldn't do things like:
fwrite(player, sizeof(struct player), 1, fp);
AND expect to always be able to do an fread() on a different target platform back into your memory structure.
While this will usually work, it will fail if your architectures have different word sizes AND your compiler silently pads structures to those boundaries AND your data structure would have one of these pads added to it.
Example:
struct foo { int a; char b; int c; };
On some systems, this will be a structure that takes up 9 bytes... on others, it will take up 10 bytes, and on others still it may take up 12 bytes.
If I remember correctly, motorola chips (68020) could address on 16-bit words, but pentium4 chips require 32-bit alignment. If you took that structure and fed it to gcc, you'd get 10 or 12 bytes, depending on the platform.
If you write that to disk on one platform and read it back in on the other, you will likely get either corrupt data, or a segmentation fault if the larger strucutre spills over the allocation block edge.
The other big problem I have with binary dumps is that you STILL have to serialize your data somehow, unless you managed to not use any pointers in your structures (in C, congrats!). Since you have to do it for some of them, why not just do it for all of them and have a nice readable data file?
I forget which of the many diku offshoots used this (I want to say NiMUD?), but at least one of them serialzed bit flags as strings like 'INVIS|GLOW|NPC', which made it quite handy to edit/fix.
|
|
|
|
|
13. RE: Unlimited Bitvectors
|
|
Tue Jul 20, 2004 [2:35 PM]
|
KaVir
Email not supplied
member since: Aug 19, 1999
|
In Reply To
Reply
|
|
> When I said you shouldn't write binary structures to disk, > I mean you shouldn't do things like: > > fwrite(player, sizeof(struct player), 1, fp); > > AND expect to always be able to do an fread() on a > different target platform back into your memory structure.
Well no, but it wouldn't take much extra effort to pump the pfile out in a highly portable binary format. In particular, you could read/write the bitvectors without any problem, while the bitfields would require you to know the ordering, padding, etc for each platform.
> While this will usually work, it will fail if your > architectures have different word sizes AND your compiler > silently pads structures to those boundaries AND your > data structure would have one of these pads added to it.
It wouldn't fail if you read and wrote the data as unsigned chars.
> Example: > > struct foo { > int a; > char b; > int c; > }; > > On some systems, this will be a structure that takes up 9 > bytes... on others, it will take up 10 bytes, and on > others still it may take up 12 bytes.
*nod* - it could take up anything from 3 bytes upwards.
|
|
|
|
|