On 5/13/22 00:32, Chris Katko wrote:

> Luckily, because I'm painting them to the screen, the
> buffers only really need to be float even if they started as a boolean,
> int, or double. However, if I'm keeping a list of pointers to things I
> want to snoop when I call onTick(), I can't think of a way to support
> multiple types:

I think this is a classic example of OOP. You abstract data collection to classes that know how to deal with their own data type. The comments should explain it:

import std.algorithm;
import std.conv;
import std.range;
import std.random;
import std.stdio;

interface DataSource {
  // Represents "reporting" of data points to the graph.
  float[] dataPoints();

  // Represents a collection of data.
  void collect();
}

// A templatized implementation of DataSource that would
// work with fundamental types like 'int'.
class SimpleDataSource(T) : DataSource {
  T[] data;    // All collected data
  size_t next; // The beginning of data for next dataPoints()

  // Converts data to float[], the uniform representation.
  float[] dataPoints() {
    auto result = data[next..$].map!(to!float).array;
    next = data.length;
    return result;
  }

  void collect() {
    // Random number of random values
    const n = uniform(3, 10);
    iota(n).each!(i => data ~= uniform(10, 20));
  }
}

// Converted to a 'struct'. Could stay 'class'.
struct intrinsicGraph {
  DataSource[] dataSources;  // Same type collectors
  float[] buffer;            // Same type data

  void onTick() {
    // Go through all sources to update 'buffer'.
    dataSources.each!(source => buffer ~= source.dataPoints());
  }
}

void main() {
  // Independent collectors.
  auto source1 = new SimpleDataSource!int();
  auto source2 = new SimpleDataSource!double();

  auto g = intrinsicGraph();

  // This part is the "registration" of data sources,
  // which could be like g.register(source1).
  g.dataSources ~= source1;
  g.dataSources ~= source2;

  // Represents a time slice.
  foreach (i; 0 .. 3) {
    source1.collect();
    source2.collect();
    g.onTick();
  }

  // It works! :)
  writeln(g.buffer);
}

Ali

Reply via email to