Last active
September 16, 2022 19:08
-
-
Save elycruz/52055e6260298d6f10a0c3c654ee5d66 to your computer and use it in GitHub Desktop.
Flags system using bitwise operators and binary numerals (in javascript).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Storing flags in one variable and checking for | |
* enabled/disabled states using | |
* bitwise operators. | |
* @author elycruz | |
* @reference: | |
* - https://www.youtube.com/watch?v=RRyxCmLX_ag | |
* - https://www.youtube.com/watch?v=6hnLMnid1M0 | |
*/ | |
// Calls count to print in console | |
let callCount = 0; | |
// Store flags as binary numbers to show in what bit each flag will be stored in - | |
// ## General Idea | |
// A `0`, or `1` will be stored/produced for any given flag at the position where | |
// a `1` exist, in the flags declaration. Using bitwise operations, later, | |
// we can perform sum, difference, union, etc. operations (using bitwise operators), | |
// to extract/update any given set of runtime flag values: | |
const FlagsEnum = { | |
A: 0b001, | |
B: 0b010, | |
C: 0b100 | |
}, | |
// Hexadecimal numbers matching the powers of two | |
// Can be used for the same purpose (to represent flags | |
// where a single bits represent flags, etc.). | |
// Powers of two (continued from `FlagsEnum`) | |
FlagsEnum2 = { | |
D: 0x08, | |
E: 0x10, | |
F: 0x20, | |
G: 0x40 | |
}, | |
// Extract enums for use | |
{A, B, C} = FlagsEnum, | |
{D, E, F, G} = FlagsEnum2, | |
{log} = console, | |
// String to print from log util | |
// @see the following for string format parameters: | |
// MDN console - Web APIs - | |
// https://developer.mozilla.org/en-US/docs/Web/API/console#examples | |
flagsFmt = "Feature %s enabled; Feature Id: %d; \"\" Id as: binary: 0b%s; hex: 0x%s;", | |
logFlagEnum = x => { | |
// log('Call no. %d', callCount++); | |
// Here if any bitwise `&` operation returns `0` that particular flag is | |
// disabled: | |
let chosen = 0; | |
if (x & A) log(flagsFmt, 'A', A, A.toString(2), A.toString(16)); | |
if (x & B) log(flagsFmt, 'B', B, B.toString(2), B.toString(16)); | |
if (x & C) log(flagsFmt, 'C', C, C.toString(2), C.toString(16)); | |
if (x & D) log(flagsFmt, 'D', D, D.toString(2), D.toString(16)); | |
if (x & E) log(flagsFmt, 'E', E, E.toString(2), E.toString(16)); | |
if (x & F) log(flagsFmt, 'F', F, F.toString(2), F.toString(16)); | |
if (x & G) log(flagsFmt, 'G', G, G.toString(2), G.toString(16)); | |
if (!x) log("No features enabled."); | |
}; | |
const enums = [A, B, C, D, E, F, G]; | |
log(...enums); | |
console.group('Individual Flags as features'); | |
[0].concat(enums).map(logFlagEnum); | |
console.groupEnd(); | |
logFlagEnum(A | B); // Bitwise `OR` (`|`), in our case it's a `SUM` op. | |
logFlagEnum(A | B | C); // "" | |
logFlagEnum(B | C); // "" | |
logFlagEnum(C); // "" | |
console.group('Disabling a flag'); | |
// ## Storing flags in memory location: | |
let bool_settings = A | B | C | D | E | F | G; // For this example we enable all flags (SUM operation (bitwise `OR`)). | |
log('Stored flags:'); | |
// Log enabled/disabled states | |
logFlagEnum(bool_settings); | |
// Disable a flag | |
bool_settings = bool_settings & (~B); // Flip bits in `B` (`0`s flipped to `1`s, and vice-versa) and then SUM that value with settings in `bool_settings` set. | |
log('Stored flags after `B` flag disable'); | |
// Log states | |
logFlagEnum(bool_settings); | |
// Close `log` group | |
console.groupEnd(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment