flag.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /* eslint-disable no-bitwise */
  2. export class FlagManager {
  3. get cell() {
  4. return this.view.cell;
  5. }
  6. constructor(view, actions, bootstrap = []) {
  7. this.view = view;
  8. const flags = {};
  9. const attrs = {};
  10. let shift = 0;
  11. Object.keys(actions).forEach((attr) => {
  12. let labels = actions[attr];
  13. if (!Array.isArray(labels)) {
  14. labels = [labels];
  15. }
  16. labels.forEach((label) => {
  17. let flag = flags[label];
  18. if (!flag) {
  19. shift += 1;
  20. flag = flags[label] = 1 << shift;
  21. }
  22. attrs[attr] |= flag;
  23. });
  24. });
  25. let labels = bootstrap;
  26. if (!Array.isArray(labels)) {
  27. labels = [labels];
  28. }
  29. labels.forEach((label) => {
  30. if (!flags[label]) {
  31. shift += 1;
  32. flags[label] = 1 << shift;
  33. }
  34. });
  35. // 26 - 30 are reserved for paper flags
  36. // 31+ overflows maximal number
  37. if (shift > 25) {
  38. throw new Error('Maximum number of flags exceeded.');
  39. }
  40. this.flags = flags;
  41. this.attrs = attrs;
  42. this.bootstrap = bootstrap;
  43. }
  44. getFlag(label) {
  45. const flags = this.flags;
  46. if (flags == null) {
  47. return 0;
  48. }
  49. if (Array.isArray(label)) {
  50. return label.reduce((memo, key) => memo | flags[key], 0);
  51. }
  52. return flags[label] | 0;
  53. }
  54. hasAction(flag, label) {
  55. return flag & this.getFlag(label);
  56. }
  57. removeAction(flag, label) {
  58. return flag ^ (flag & this.getFlag(label));
  59. }
  60. getBootstrapFlag() {
  61. return this.getFlag(this.bootstrap);
  62. }
  63. getChangedFlag() {
  64. let flag = 0;
  65. if (!this.attrs) {
  66. return flag;
  67. }
  68. Object.keys(this.attrs).forEach((attr) => {
  69. if (this.cell.hasChanged(attr)) {
  70. flag |= this.attrs[attr];
  71. }
  72. });
  73. return flag;
  74. }
  75. }
  76. //# sourceMappingURL=flag.js.map