mita icon indicating copy to clipboard operation
mita copied to clipboard

Progress Tracker: Event System Improvements

Open wegendt-bosch opened this issue 5 years ago • 3 comments

This is the progress tracker for upcoming changes to the current event system. Feedback is welcome as comments to this!

  • [ ] Allow events per signal instance
    • [ ] Platform language change (detailed in #301)
    • [ ] Generator changes
  • [ ] Give Events types: a payload
    • [x] Language changes
    • [x] Generator changes
      • ~~To support queues, since payloads have arbitrary size, they need to be passed by reference~~ It's probably better to not have the platform handle this but instead present a ringbuffer interface to platforms.
    • [ ] Implement types per signal instance, for example for messages received on some MQTT topic, see #301
    • [ ] Implementations in existing platforms that have events
      • [ ] XDK110
      • [ ] Arduino
  • [ ] Allow user events
    • [ ] Language changes
    • [ ] Generator changes
  • [ ] Allow suspension of execution until event happens
    • [ ] Language design/changes
    • [ ] Generator changes
      • Implementation: Singleton coroutines
      • [ ] Detect if method is coroutine (has await statements or special syntax)
      • [ ] Insert runtime check for singleton
      • [ ] Statically or dynamically keep track of which functions are waiting for event and trigger them
      • [ ] ...
    • [ ] Implementations in existing platforms that have events
      • [ ] XDK110
      • [ ] Arduino

wegendt-bosch avatar Mar 12 '19 08:03 wegendt-bosch

Regarding payloads:

  • Language change:
event any_motion: vec3d

every accelerometer.any_motion(v) {
  let x_axis = v.x;
}
  • Backwards compatibility can be achieved by allowing no brackets (every accelerometer.any_motion {...}).

  • Generated C code change:

Retcode_T HandleEvery1Millisecond1(void* userParameter1, uint32_t userParameter2) {
  vec3d_t v = pop(ringBufferEvery1Millisecond);
  int32_t x_axis = v.x;
}

~~Platform generators are responsible for ensuring that the passed pointer points to valid memory.~~ Platforms insert values into a ringbuffer managed by core Mita.

todo:

  • give generators a nice interface to insert values into the ringbuffer
  • Allow platform to reclaim used resources after event handlers are done

wegendt-bosch avatar Mar 12 '19 08:03 wegendt-bosch

Hit a wall at ringbuffer<string>. Going to rewrite size inference, first try as part of the type system.

wegendt-bosch avatar May 24 '19 12:05 wegendt-bosch

The type inferrer can't infer sizes. However sizes will still be part of types.

Reasoning:

Type inferrer can't handle sizes

Constraints are not compatible with state. Consider the following:

var a = [1,2,3];
let b = [4,5,6];
a += b;

Solving via constraints would give constraints like the following:

typeof(a) >= array<xint8, 3>
typeof(b) >= array<xint8, 3>
typeof(a) >= typeof(a) + typeof(b) // a += b is really just a = a + b

Logically the last constraint means that typeof(a) = typeof(a) + typeof(b). This means that typeof(b) ~ 0, however, typeof(b) >= t, t ~ sizeof(8)*3. What we really would like to infer is that the capacity of an array is at least as much as all assignments. For this we need cross references (like the current implementation already uses). Those don't exist during constraint generation though, and adding a special constraint that expands to a cross reference checks is really not what the solver should do. Therefore size inference will remain an extra step after typing.

Sizes as types

Consider an array of strings. In Mita right now you have different ways to specify a variable of this type:

  • let a: array<string>;
  • let a = new array<string>(size=10);
  • let a = ["a", "bc", "def"];

Variant one does not specify a size at all. Variant two does not work for nested types that require inference, unless you come up with some special syntax or data type for sizes. Variant three is not flexible enough, since you can't for example first allocate the array and then populate it with strings.

The only remaining solution therefore is to bind sizes to the variable declaration itself, i.e. label the variable, also known as "typing" it. We could introduce a new concept alongside types for sizes, for example let a: array<string>(10,3) to make the separation clearer. I think that that introduces way more complexity than making users accept that numbers are types, too. Therefore I'm going forward with

let a: array<string<100>, 5>

wegendt-bosch avatar Jun 04 '19 12:06 wegendt-bosch