[release]
[highlight]What is this and how is this useful?![/highlight]
Basically, compressed [I]booleans[/I]. [I]Boolean[/I] variables, which are used to declare a variable with a value of either [I]true[/I] or [I]false[/I], consume 1 byte of memory. But in actuality, you only need 1 bit. A bit (contraction of [I]binary digit[/I]) can only have two possible values, usually denoted by 0 and 1.
This is very useful if, for example, you have devised an quite complex admin system and now want to send admin flags/rights/allowances from server to client. Let's say you allow the admin to kick, ban, freeze, slap etc players. Usually, you'd do this.
[lua]
--Send from server.
umsg.Start( "AdminFlags", ply )
umsg.Bool( ply:CanKick() )
umsg.Bool( ply:CanBan() )
umsg.Bool( ply:CanFreeze() )
umsg.Bool( ply:CanSlap() )
umsg.End()
--Receive on client.
usermessage.Hook( "AdminFlags", function( data )
data:ReadBool() --CanKick.
data:ReadBool() --CanBan.
...
end )
[/lua]
But using bitflags, you can do this.
[lua]
--Init flags.
local flags = 0
flags = bf.FlagsOn( flags, { canKick, canBan, canSlap, canFreeze } )
--Send from server.
umsg.Start( "AdminFlags", ply )
umsg.Short( flags )
umsg.End()
--Receive on client.
usermessage.Hook( "AdminFlags", function( data )
local flags = data:ReadShort()
if( bf.FlagsEnabled( flags, { } ) ) then
<code>
end
...
end )
[/lua]
Now, you may ask: "How is this useful?". The answer is simple. With this module, you can send [B]4 bytes[/B] containing [B]32 bits[/B] instead of 32 booleans ([B]32 bytes[/B]).
[/release]
[release]
[highlight]Functions[/highlight]
[lua]
bf.FlagOn( number, flag ) --Enables flag.
bf.FlagsOn( number, table ) --Enables flags.
bf.FlagOff( number, flag ) --Disables flag.
bf.FlagsOff( number, table ) --Disables flags.
bf.FlagToggle( number, flag ) --Toggles flag.
bf.FlagsToggle( number, table ) --Toggles flags.
bf.FlagEnabled( number, flag ) --Returns true if flag is enabled.
bf.FlagsEnabled( number, table ) --Returns true if flags are enabled.
[/lua]
[/release]
[release]
[highlight]Examples[/highlight]
First, we have to define the flags somewhere. In gamemodes, [I]shared.lua[/I] is a good place to do that.
[lua]
local AdminFlags = { } --Each flag value MUST be a power of two. Maximum value: 2^32.
AdminFlags.TrialAdmin = 1 --2^0
AdminFlags.BasicAdmin = 2 --2^1
AdminFlags.SuperAdmin = 4 --2^2
AdminFlags.CanSlap = 8 --2^3
AdminFlags.CanFreeze = 16 --2^4
AdminFlags.CanChangeMap = 32 --2^5
[/lua]
Example #1.
[lua]
require( 'bitflags' )
ply.AdminFlags = 0 --Reset all flags.
ply.AdminFlags = bf.FlagsOn( ply.AdminFlags, { AdminFlags.BasicAdmin, AdminFlags.CanSlap, AdminFlags.CanFreeze } )
print( bf.FlagsEnabled( ply.AdminFlags, { AdminFlags.SuperAdmin, AdminFlags.CanSlap, AdminFlags.CanFreeze } ) )
ply.AdminFlags = bf.FlagOn( bf.FlagOff( ply.AdminFlags, AdminFlags.BasicAdmin ), AdminFlags.SuperAdmin )
print( bf.FlagsEnabled( ply.AdminFlags, { AdminFlags.SuperAdmin, AdminFlags.CanSlap, AdminFlags.CanFreeze } ) )
--Output:
--false
--true
[/lua]
Example #2.
[lua]
require( 'bitflags' )
ply.AdminFlags = 0 --Reset all flags.
ply.AdminFlags = bf.FlagOn( ply.AdminFlags, AdminFlags.BasicAdmin )
ply.AdminFlags = bf.FlagOn( ply.AdminFlags, AdminFlags.CanSlap )
if( bf.FlagEnabled( ply.AdminFlags, AdminFlags.BasicAdmin ) ) then
if( bf.FlagEnabled( ply.AdminFlags, AdminFlags.CanSlap ) ) then
print( "I'mma slap yo ass." )
end
if( bf.FlagEnabled( ply.AdminFlags, AdminFlags.CanFreeze ) ) then
print( "I'mma freeze yo ass." )
end
end
--Output:
--I'mma slap yo ass.
[/lua]
[/release]
[release]
[highlight]Download & Source[/highlight]
Latest release date: [I]29/01/2012[/I].
[URL="http://dl.dropbox.com/u/59073685/gm_bitflags/gm_bitflags.dll"]Click me to download![/URL]
[URL="http://dl.dropbox.com/u/59073685/gm_bitflags/gm_bitflags.cpp"]gm_bitflags.cpp[/URL]
[URL="http://dl.dropbox.com/u/59073685/gm_bitflags/gm_bitflags.h"]gm_bitflags.h[/URL]
[/release]
Nice! I will definitely be using this in my admin mod! Quality release bro!
Why do you need a binary module for this?
GMod's lua is missing the bitwise NOT and bitwise XOR. Besides, writing this...
[lua]
if( bf.FlagsEnabled( epicshit, { Flags.ConditionOne, Flags.ConditionTwo, ... } ) ) then
<code>
end
[/lua]
... looks a lot cleaner than this.
[lua]
if( (epicshit & (Flags.ConditionOne | Flags.ConditionTwo | ...)) == (Flags.ConditionOne | Flags.ConditionTwo | ...) ) then
<code>
end
[/lua]
Nice work, though a binary module for something that requires... about 30 lines of Lua is overkill.
[lua]local pairs = pairs
module "flag"
function set( bits, ... )
for _, b in pairs( { ... } ) do
bits = bits | b
end
return bits
end
function is_set( bits, ... )
for _, b in pairs( { ... } ) do
if bits & b ~= b then return false end
end
return true
end
function unset( bits, ... )
for _, b in pairs( { ... } ) do
if bits & b == b then
bits = bits - b
end
end
return bits
end[/lua]
[lua]require "flag"
local stuff = STUFF1 | STUFF2
if flag.is_set( stuff, STUFF1, STUFF3 ) then
-- Do stuff
end
stuff = flag.unset( stuff, STUFF2 )[/lua]
[editline]29th January 2012[/editline]
Also, you need to release the source. It's required.
It's not too hard to implement band/bnot /xor in lua.
Nice work, raBBish. Your code renders my module completely obsolete. :suicide:
[QUOTE=Panto;34451447]Nice work, raBBish. Your code renders my module completely obsolete. :suicide:[/QUOTE]
Sorry [img]http://www.facepunch.com/fp/emoot/shobon.gif[/img]
Although you still need to release the source. All releases here need it.
Alright, done.
[QUOTE=raBBish;34451180]Nice work, though a binary module for something that requires... about 30 lines of Lua is overkill.
[lua]local pairs = pairs
module "flag"
function set( bits, ... )
for _, b in pairs( { ... } ) do
bits = bits | b
end
return bits
end
function is_set( bits, ... )
for _, b in pairs( { ... } ) do
if bits & b ~= b then return false end
end
return true
end
function unset( bits, ... )
for _, b in pairs( { ... } ) do
if bits & b == b then
bits = bits - b
end
end
return bits
end[/lua]
[lua]require "flag"
local stuff = STUFF1 | STUFF2
if flag.is_set( stuff, STUFF1, STUFF3 ) then
-- Do stuff
end
stuff = flag.unset( stuff, STUFF2 )[/lua]
[editline]29th January 2012[/editline]
Also, you need to release the source. It's required.[/QUOTE]
Holy shit this is really useful, thanks!
Sorry, you need to Log In to post a reply to this thread.