#pragma once
+
+CLASS(DataSource, Object)
+ entity DataSource_true;
+ entity DataSource_false;
+ INIT_STATIC(DataSource) {
+ DataSource_true = NEW(Object);
+ DataSource_false = NULL;
+ }
+ /**
+ * get entry `i` passing `name` and `icon` through `returns` if it is not null
+ * returns `DataSource_false` if out of bounds
+ * otherwise returns an entity or `DataSource_true`
+ */
+ METHOD(DataSource, getEntry, entity(entity this, int i, void(string name, string icon) returns)) { return DataSource_false; }
+ /** return the index of the first match for `find`. optional */
+ METHOD(DataSource, indexOf, int(entity this, string find)) { return -1; }
+ /** reload all entries matching `filter` returning how many matches were found */
+ METHOD(DataSource, reload, int(entity this, string filter)) { return 0; }
+ /** cleanup on shutdown. optional */
+ METHOD(DataSource, destroy, void(entity this)) { }
+ENDCLASS(DataSource)
+
+
+CLASS(StringSource, DataSource)
+ ATTRIB(StringSource, StringSource_str, string, string_null)
+ ATTRIB(StringSource, StringSource_sep, string, string_null)
+ CONSTRUCTOR(StringSource, string str, string sep);
+ METHOD(StringSource, getEntry, entity(entity this, int i, void(string name, string icon) returns));
+ METHOD(StringSource, reload, int(entity this, string filter));
+ENDCLASS(StringSource)
+
+CLASS(CvarStringSource, StringSource)
+ ATTRIB(CvarStringSource, CvarStringSource_cvar, string, string_null)
+ CONSTRUCTOR(CvarStringSource, string cv, string sep);
+ METHOD(CvarStringSource, getEntry, entity(entity this, int i, void(string name, string icon) returns));
+ METHOD(CvarStringSource, reload, int(entity this, string filter));
+ENDCLASS(CvarStringSource)