Category talk:Wren-dynamic: Difference between revisions
Content added Content deleted
(→Source code: Added some enums and removed the type aliases which are no longer needed.) |
(→Source code: Flags enums now support an optional zero value member.) |
||
Line 59: | Line 59: | ||
} |
} |
||
/* Flags creates a 'flags' enum with up to 32 read-only static members. |
/* Flags creates a 'flags' enum with up to 32 read-only static members, plus an optional zero member. |
||
Members are assigned in order an integer value starting from 1 and multiplying by 2 each time |
Members are assigned in order an integer value starting from 1 and multiplying by 2 each time, unless |
||
they have a zero member, when the first member has a value of 0. |
|||
The flags enum has: |
The flags enum has: |
||
1. static property getters for each member, |
1. static property getters for each member, |
||
2. a static ' |
2. a static 'hasZero' property which returns whether or not there is a zero member, and |
||
3. a static 'members' property which returns a list of its members as strings. |
|||
*/ |
*/ |
||
class Flags { |
class Flags { |
||
// Creates a class for the Flags enum (with an underscore after the name) and |
// Creates a class for the Flags enum (with an underscore after the name) and |
||
// returns a reference to it. |
// returns a reference to it. |
||
static create(name, members) { |
static create(name, members, hasZero) { |
||
if (name.type != String || name == "") Fiber.abort("Name must be a non-empty string.") |
if (name.type != String || name == "") Fiber.abort("Name must be a non-empty string.") |
||
if (members.isEmpty ||members.count > 32) { |
if (members.isEmpty || members.count > (hasZero ? 33 : 32)) { |
||
Fiber.abort("A flags enum must have between 1 and 32 members.") |
Fiber.abort("A flags enum must have between 1 and 32 members, plus an optional zero member.") |
||
} |
} |
||
if (hasZero.type != Bool) Fiber.abort("'hasZero' must be true or false.") |
|||
name = name + "_" |
name = name + "_" |
||
var s = "class %(name) {\n" |
var s = "class %(name) {\n" |
||
for (i in 0...members.count) { |
for (i in 0...members.count) { |
||
var m = members[i] |
var m = members[i] |
||
if (i == 0 && hasZero) { |
|||
s = s + " static %(m) { 0 }\n" |
|||
} else if (hasZero) { |
|||
s = s + " static %(m) { %(1 << (i-1)) }\n" |
|||
} else { |
|||
s = s + " static %(m) { %(1 << i) }\n" |
|||
} |
|||
} |
} |
||
var mems = members.map { |m| "\"%(m)\"" }.join(", ") |
var mems = members.map { |m| "\"%(m)\"" }.join(", ") |
||
s = s + " static hasZero { %(hasZero) }\n" |
|||
s = s + " static members { [%(mems)] }\n}\n" |
s = s + " static members { [%(mems)] }\n}\n" |
||
s = s + "return %(name)" |
s = s + "return %(name)" |
||
Line 85: | Line 95: | ||
} |
} |
||
// |
// Convenience version of above method which does not have a member with a value of zero. |
||
static |
static create(name, members) { create(name, members, false) } |
||
// Returns the zero based index into the Fields property |
|||
// for a given Flags enum member and whether or not there is a zero member. |
|||
// Returns -1 if the member doesn't exist. |
|||
static indexOf(member, hasZero, memCount) { |
|||
if (hasZero.type != Bool) Fiber.abort("'hasZero' must be true or false.") |
|||
var maxCount = hasZero ? 33 : 32 |
|||
if (memCount.type != Num || !memCount.isInteger || memCount < 1 || memCount > maxCount) { |
|||
Fiber.abort("Member count must be between 1 and %(maxCount).") |
|||
} |
|||
var limit = hasZero ? 1 << (memCount-2) : 1 << (memCount-1) |
|||
if (member.type != Num || !member.isInteger || member < 0 || member > limit) { |
|||
Fiber.abort("Member must be a non-negative integer <= %(limit).") |
|||
} |
|||
if (member == 0) return hasZero ? 0 : -1 |
|||
if (member & (member-1) != 0) return -1 // not a power of two |
|||
var res = (member.log / 2.log).round |
|||
return hasZero ? res + 1 : res |
|||
} |
|||
// Convenience versions of above method where the number of members is assumed to be the maximum. |
|||
static indexOf(member, hasZero) { indexOf(member, hasZero, hasZero ? 33 : 32) } |
|||
static indexOf(member) { indexOf(member, false, 32) } // assumes no zero memmber |
|||
} |
} |
||