diff mde/mergetag/defaultdata.d @ 9:1885a9080f2a

Joystick button input now works with config. committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Wed, 30 Jan 2008 11:33:56 +0000
parents
children 4c3575400769
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mde/mergetag/defaultdata.d	Wed Jan 30 11:33:56 2008 +0000
@@ -0,0 +1,189 @@
+/// This module contains the DefaultData class, and some notes possibly useful for implementing
+/// other types of DataSection.
+module mde.mergetag.defaultdata;
+
+public import mde.mergetag.dataset;
+
+import mde.text.util;
+import mde.text.parse : parse;
+import mde.text.format : format;
+
+/**
+* Default DataSection class.
+*
+* Supports all the basic types currently supported and array versions of
+* each (except no arrays of binary, but arrays of strings are supported).
+* Doesn't support custom types, but inheriting classes may add support.
+*/
+/* Note: I wrote this comment when the code looked rather worse. It's still partially applicable though.
+*
+* Due to a failure to use generic programming techniques for most of this (maybe because it's not
+* possible or maybe just because I don't know how to use templates properly) a lot of this code is
+* really horrible and has to refer to EVERY data member.
+* Be really careful if you add any items to this class.
+*
+* I really don't like having to do things like this, but it provides a lot of benefits such as no
+* need to store types and no need to check an argument's type for every access (this could be done
+* by throwing errors, but then an incorrect (perhaps hand-edited) data file could cause a lot of
+* errors to be thrown).
+*/
+class DefaultData : DataSection
+{
+    //BEGIN DATA
+    /** Data Members
+    *
+    * These names are available for direct access.
+    *
+    * An alternative access method is to use the provided templates:
+    * --------------------
+    * template Arg(T) {
+    *     alias Name Arg;
+    * }
+    * --------------------
+    *
+    * Use with a mixin or directly:
+    * --------------------
+    * mixin Arg!(type);
+    * auto x = Arg;
+    *
+    * type y = Arg!(type).Arg;
+    * --------------------
+    * Note: trying to use Arg!(type) to implicitly refer to Arg!(type).Arg causes compiler errors due to
+    * --- alias Name Arg; ---
+    * actually being a mixin.
+    */
+     
+    bool	[ID]	_bool;
+    byte	[ID]	_byte;		/// ditto
+    short	[ID]	_short;		/// ditto
+    int		[ID]	_int;		/// ditto
+    long	[ID]	_long;		/// ditto
+    ubyte	[ID]	_ubyte;		/// ditto
+    ushort	[ID]	_ushort;	/// ditto
+    uint	[ID]	_uint;		/// ditto
+    ulong	[ID]	_ulong;		/// ditto
+    
+    char	[ID]	_char;		/// ditto
+    
+    float	[ID]	_float;		/// ditto
+    double	[ID]	_double;	/// ditto
+    real	[ID]	_real;		/// ditto
+    
+    bool[]	[ID]	_boolA;		/// ditto
+    byte[]	[ID]	_byteA;		/// ditto
+    short[]	[ID]	_shortA;	/// ditto
+    int[]	[ID]	_intA;		/// ditto
+    long[]	[ID]	_longA;		/// ditto
+    ubyte[]	[ID]	_ubyteA;	/// ditto
+    ushort[]	[ID]	_ushortA;	/// ditto
+    uint[]	[ID]	_uintA;		/// ditto
+    ulong[]	[ID]	_ulongA;	/// ditto
+    
+    char[]	[ID]	_charA;		/// ditto
+    
+    float[]	[ID]	_floatA;	/// ditto
+    double[]	[ID]	_doubleA;	/// ditto
+    real[]	[ID]	_realA;		/// ditto
+    
+    char[][]	[ID]	_charAA;	/// ditto
+    
+    /** Alias names */
+    alias	_ubyteA	_binary;
+    alias	_charA	_string;	/// ditto
+    alias	_charAA	_stringA;	/// ditto
+    //END DATA
+    
+    void addTag (char[] tp, ID id, char[] dt) {	/// Supports all standard types.
+        if (tp.length == 0) throw new MTUnknownTypeException;
+        // split list up a bit for performance:
+        if (tp[0] < 'l') {
+            if (tp[0] < 'd') {
+                mixin ( `if (tp == "binary") addTag_add!(ubyte[]) (id, dt);`
+                ~ addTag_elifIsType_add!(bool)
+                ~ addTag_elifIsType_add!(bool[])
+                ~ addTag_elifIsType_add!(byte)
+                ~ addTag_elifIsType_add!(byte[])
+                ~ addTag_elifIsType_add!(char)
+                ~ addTag_elifIsType_add!(char[])
+                ~ addTag_elifIsType_add!(char[][])
+                ~ `else throw new MTUnknownTypeException;` );
+            } else {
+                mixin ( `if (tp == "double") addTag_add!(double) (id, dt);`
+                ~ addTag_elifIsType_add!(double[])
+                ~ addTag_elifIsType_add!(float)
+                ~ addTag_elifIsType_add!(float[])
+                ~ addTag_elifIsType_add!(int)
+                ~ addTag_elifIsType_add!(int[])
+                ~ `else throw new MTUnknownTypeException;` );
+            }
+        } else {
+            if (tp[0] < 'u') {
+                mixin ( `if (tp == "long") addTag_add!(long) (id, dt);`
+                ~ addTag_elifIsType_add!(long[])
+                ~ addTag_elifIsType_add!(real)
+                ~ addTag_elifIsType_add!(real[])
+                ~ addTag_elifIsType_add!(short)
+                ~ addTag_elifIsType_add!(short[])
+                ~ `else if (tp == "string") addTag_add!(char[]) (id, dt);`
+                ~ `else throw new MTUnknownTypeException;` );
+            } else {
+                mixin ( `if (tp == "ubyte") addTag_add!(ubyte) (id, dt);`
+                ~ addTag_elifIsType_add!(ubyte[])
+                ~ addTag_elifIsType_add!(ushort)
+                ~ addTag_elifIsType_add!(ushort[])
+                ~ addTag_elifIsType_add!(uint)
+                ~ addTag_elifIsType_add!(uint[])
+                ~ addTag_elifIsType_add!(ulong)
+                ~ addTag_elifIsType_add!(ulong[])
+                ~ `else throw new MTUnknownTypeException;` );
+            }
+        }
+        // try-catch block removed (caught by read)
+    }
+    private template addTag_elifIsType_add(T) {
+        const addTag_elifIsType_add =
+        `else if (tp == "`~T.stringof~`")`
+        `addTag_add!(`~T.stringof~`) (id, dt);` ;
+    }
+    private void addTag_add(T) (ID id, char[] dt) {
+        Arg!(T).Arg[id] = parse!(T) (dt);
+    }
+    
+    void writeAll (ItemDelg itemdlg) {
+        foreach (id, dt; _charA) itemdlg ("char[]", id, format!(char[])(dt));
+    }
+    
+    /* These make no attempt to check Arg is valid.
+    * But if the symbol doesn't exist the complier will throw an error anyway, e.g.:
+    * Error: identifier '_boolAA' is not defined
+    */
+    template Arg(T : T[]) {
+        const ArgString = Arg!(T).ArgString ~ `A`;
+        mixin(`alias `~ArgString~` Arg;`);
+    }
+    template Arg(T) {
+        const ArgString = `_` ~ T.stringof;
+        mixin(`alias `~ArgString~` Arg;`);
+    }
+}
+
+/+class DynamicData : DataSection
+{
+void*[TypeInfo] data;
+    
+}+/
+
+/+
+class TemplateData : DataSection
+{
+void addTag (char[] tp, ID id, char[] dt) {
+// runtime deduction of tp and aliasing?
+// CANNOT add data at runtime though.
+}
+// will this work? no idea.
+// templates can't be used to add non-static elements, so use a static array at index: this
+template Data(T,TemplateData* p) {
+static T[ID][TemplateData*] Data;
+}
+}
++/