You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.1 KiB
CoffeeScript
75 lines
2.1 KiB
CoffeeScript
isPowerOfTwo = (number) -> number != 0 and ((number & (number - 1)) == 0)
|
|
|
|
class Bitmask
|
|
constructor: (@handler, initialValue, initialOriginalValue) ->
|
|
@value = initialValue
|
|
@originalValue = initialOriginalValue
|
|
_getFlagValue: (flag) ->
|
|
if @handler.flagMap[flag]?
|
|
return @handler.flagMap[flag].value
|
|
else
|
|
throw new Error("No such flag exists.")
|
|
_getFlagInheritances: (flag) ->
|
|
if @handler.flagMap[flag]?
|
|
return @handler.flagMap[flag].inheritedFlags
|
|
else
|
|
throw new Error("No such flag exists.")
|
|
add: (flag) ->
|
|
flagValue = @_getFlagValue(flag)
|
|
flagInheritances = @_getFlagInheritances(flag)
|
|
|
|
if @originalValue?
|
|
@originalValue = @originalValue | flagValue
|
|
@value = @value | flagValue
|
|
|
|
for inheritance in flagInheritances
|
|
flagValue = @_getFlagValue(inheritance)
|
|
@value = @value | flagValue
|
|
remove: (flag) ->
|
|
flagValue = @_getFlagValue(flag)
|
|
flagInheritances = @_getFlagInheritances(flag)
|
|
|
|
if @originalValue?
|
|
@originalValue = @originalValue & ~flagValue
|
|
@value = @value & ~flagValue
|
|
|
|
for inheritance in flagInheritances
|
|
flagValue = @_getFlagValue(inheritance)
|
|
|
|
if @originalValue? and !(@originalValue & flagValue)
|
|
@value = @value & ~flagValue
|
|
has: (flag) ->
|
|
flagValue = @_getFlagValue(flag)
|
|
return !!(@value & flagValue)
|
|
getValue: ->
|
|
return @value
|
|
getOriginalValue: ->
|
|
return @originalValue
|
|
|
|
class BitmaskHandler
|
|
constructor: (flagMap) ->
|
|
@setFlagMap flagMap
|
|
setFlagMap: (flagMap) ->
|
|
# Sanity check
|
|
for flag, value of flagMap
|
|
if typeof value == "number"
|
|
# Encapsulate in an object...
|
|
value = {value: value}
|
|
flagMap[flag] = value
|
|
|
|
value.inheritedFlags ?= []
|
|
|
|
for inheritance in value.inheritedFlags
|
|
if inheritance not of flagMap
|
|
throw new Error("The #{flag} flag attempts to inherit the non-existent #{inheritance} flag.")
|
|
|
|
if not isPowerOfTwo value.value
|
|
throw new Error("The value for the #{flag} flag (#{value.value}) is not a power of two.")
|
|
|
|
@flagMap = flagMap
|
|
create: (initialValue = 0, initialOriginalValue) ->
|
|
instance = new Bitmask(this, initialValue, initialOriginalValue)
|
|
|
|
module.exports = (flagMap) -> new BitmaskHandler(flagMap)
|
|
|