sensor.nas 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. # Sensor class to avoid repeated readout of properties.
  2. #
  3. # Each sensor object holds a list callbacks to other objects (usually filters or canvas elements) that
  4. # it calls to update in case of sensor value change
  5. # (original concept seen in Thorstens Zivko Edge)
  6. # set a default value for timer loop updates,
  7. # if none is defined
  8. if (!defined("FAST"))
  9. var FAST = 1/20;
  10. var Sensor = {
  11. new: func(param) {
  12. var m = { parents: [Sensor] };
  13. m.prop = contains(param, "prop") ? param.prop : nil;
  14. m.function = contains(param, "function") ? param.function : nil;
  15. m.thres = contains(param, "thres") ? param.thres : 0;
  16. m.disable = contains(param, "disable_listener") ? param.disable_listener : 0;
  17. m.istext = contains(param, "type") ? (param.type == "STRING") : 0;
  18. m.isbool = contains(param, "type") ? (param.type == "BOOL") : 0;
  19. m.isnum = contains(param, "type") ? (param.type == "FLOAT") : 1;
  20. m.val = nil;
  21. m.callbacks = [];
  22. m.timer = nil;
  23. m.li = nil;
  24. m.th = nil;
  25. setlistener("sim/signals/fdm-initialized", func() {
  26. if (m.function == nil)
  27. m._check(getprop(m.prop));
  28. else
  29. m._check(m.function());
  30. });
  31. if (m.disable>0 or m.function != nil) {
  32. if (ENABLE_THREADS) {
  33. thread.newthread( func {
  34. if (m.function == nil) {
  35. m.timer = maketimer(m.disable, func m._check( getprop(m.prop) ));
  36. } else {
  37. m.disable = (m.disable==0) ? FAST : m.disable;
  38. m.timer = maketimer(m.disable, func m._check( m.function() ));
  39. }
  40. m.timer.start();
  41. });
  42. } else {
  43. if (m.function == nil) {
  44. m.timer = maketimer(m.disable, func m._check( getprop(m.prop) ));
  45. } else {
  46. m.disable = (m.disable==0) ? FAST : m.disable;
  47. m.timer = maketimer(m.disable, func m._check( m.function() ));
  48. }
  49. m.timer.start();
  50. }
  51. } elsif (m.prop != nil) {
  52. if (ENABLE_THREADS)
  53. thread.newthread( func m.li = setlistener(m.prop , func m._check( getprop(m.prop) ) ));
  54. else
  55. m.li = setlistener(m.prop , func m._check( getprop(m.prop)));
  56. } else {
  57. # a constant value
  58. die("Sensor.new(): must give either 'function' or 'prop' argument!")
  59. }
  60. return m;
  61. },
  62. _check: func (x) {
  63. if (x == nil)
  64. return;
  65. if (me.val == nil) {
  66. me.val = (me.isbool) ? (!!x) : x;
  67. foreach(var cb; me.callbacks) {
  68. cb[2][cb[3]] = me.val;
  69. call(cb[1], cb[2], cb[0]);
  70. }
  71. return;
  72. }
  73. if (me.isnum) {
  74. if (abs(me.val-x) > me.thres) {
  75. me.val = x;
  76. foreach(var cb; me.callbacks) {
  77. cb[2][cb[3]] = me.val;
  78. call(cb[1], cb[2], cb[0]);
  79. }
  80. }
  81. } elsif (me.istext) {
  82. if (cmp(""~me.val, ""~x) != 0) {
  83. me.val = x;
  84. foreach(var cb; me.callbacks) {
  85. cb[2][cb[3]] = me.val;
  86. call(cb[1], cb[2], cb[0]);
  87. }
  88. }
  89. } else {
  90. if (me.val != !!x) {
  91. me.val = !!x;
  92. foreach(var cb; me.callbacks) {
  93. cb[2][cb[3]] = me.val;
  94. call(cb[1], cb[2], cb[0]);
  95. }
  96. }
  97. }
  98. },
  99. register: func (ob, fu, y=0 ) {
  100. append(me.callbacks, [ob, fu, [0,y], 0]);
  101. },
  102. register_y: func (ob, fu, x=0 ) {
  103. append(me.callbacks, [ob, fu, [x,0], 1]);
  104. },
  105. get: func () {
  106. return me.val;
  107. },
  108. del: func () {
  109. if (me.timer != nil)
  110. me.timer.stop();
  111. if (me.li != nil)
  112. removelistener(me.li);
  113. }
  114. };