Mercurial > projects > mde
view mde/file/mergetag/DefaultData.d @ 179:1f9d00f392bd default tip
Fixed a bug where (non-resizible) widgets wouldn't get shrunk when minimal size decreases, meaning optional context menus are hiden properly now.
Optimised when ServiceContentList.opCall is called, I think without breaking anything.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Tue, 15 Sep 2009 20:09:59 +0200 |
parents | 01f4f5f1acc9 |
children |
line wrap: on
line source
/* LICENSE BLOCK Part of mde: a Modular D game-oriented Engine Copyright © 2007-2008 Diggory Hardy This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** This module contains the DefaultData class, and some notes possibly useful for implementing * other types of DataSection. */ module mde.file.mergetag.DefaultData; public import mde.file.mergetag.iface.IDataSection; import mde.file.serialize; /************************************************************************************************* * Default DataSection class. * * Supported types are given by dataTypes. * * Currently DefaultData is only used for headers, and thus the list of supported types has been * reduced to just those used in headers. Load order is HIGH_LOW, i.e. existing entries aren't * overwritten. *************************************************************************************************/ /* The implementation now uses a fair bit of generic programming. Adjusting the types supported * should be as simple as adjusting the list dataTypes, and possibly implemting new conversions in * parseFrom and parseTo if you add new types (e.g. for cent or imaginary/complex types, or user types). * * There shouldn't really be any need to adjust the implementation, except perhaps to add new * functions to the class (such as another type of output where the delegate used in writeAll isn't * enough). */ class DefaultData : IDataSection { //BEGIN META /* These functions are used to generate code. Compile-time functions rather than templates are * used because they are easier to write and understand. Mixins are used to compile the resultant * code. Must be declared before used since forward references aren't supported for compile-time * functions. */ // Generate the correct name for each variable type. static char[] varName (char[] type) { char[] append = ""; while (type.length >= 2 && type[$-2..$] == "[]") { type = type[0..$-2]; append ~= "A"; } return "_" ~ type ~ append; } // Int-to-string converter, which may not be efficient but will run at compile time. static char[] int2str (uint i) { char[] ret; const digits = "0123456789"; if (i == 0) ret = "0"; else for (; i > 0; i /= 10) ret = digits[i%10] ~ ret; return ret; } // Generate the code for variable declarations. static char[] declerations (char[][] types) { char[] ret = ""; foreach (char[] type; types) ret ~= type ~ "[ID]\t" ~ varName(type) ~ ";\n"; return ret; } // Purely to add indentation. Could just return "" without affecting functionality. static char[] indent (uint i) { char[] ret = ""; for (; i > 0; --i) ret ~= " "; // This is not executable at compile time: //ret.length = i * 4; // number of characters for each indentation //ret[] = ' '; // character to indent with return ret; } /* Generates a binary search algorithm. * * Currently this is tailored to it's particular use (addTag). */ static char[] binarySearch (char[] var, char[][] consts, int indents = 0) { if (consts.length > 3) { return indent(indents) ~ "if (" ~ var ~ " <= \"" ~ consts[$/2 - 1] ~ "\") {\n" ~ binarySearch (var, consts[0 .. $/2], indents + 1) ~ indent(indents) ~ "} else {\n" ~ binarySearch (var, consts[$/2 .. $], indents + 1) ~ indent(indents) ~ "}\n"; } else { char[] ret; ret ~= indent(indents); foreach (c; consts) { ret ~= "if (" ~ var ~ " == \"" ~ c ~ "\") {\n" ~ //indent(indents+1) ~ varName(c) ~ "[id] = parseTo!(" ~ c ~ ") (dt);\n" ~ indent(indents+1) ~ "if ((id in "~varName(c)~") is null)\n" ~ indent(indents+2) ~ varName(c)~"[id] = parseTo!(" ~ c ~ ") (dt);\n" ~ indent(indents) ~ "} else "; } ret = ret[0..$-6] ~ '\n'; // remove last else return ret; } } // Generates the code to write data members (writeAll). static char[] writeVars () { char[] code = ""; foreach (i,type; dataTypes) { code ~= "foreach (id, dt; " ~ varName(type) ~ ") itemdlg (dataTypes[" ~ int2str(i) ~ "], id, parseFrom!(" ~ type ~ ")(dt));\n"; } return code; } //END META /** Data Members * * These types are all stored directly, as below, are available for direct access. The variable * names are created dynamically at compile-time based on the dataTypes list. * ------------------ * int[ID] _int; // name is type prefixed by _ * char[][ID] _charA; // [] is replaced by A * ------------------ */ /+ All types previously supported. Most of these weren't used. const char[][] dataTypes = ["bool","bool[]", "byte","byte[]", "char","char[]","char[][]", "double","double[]", "float","float[]", "int","int[]", "long","long[]", "real","real[]", "short","short[]", "ubyte","ubyte[]", "uint","uint[]", "ulong","ulong[]", "ushort","ushort[]"]; +/ const char[][] dataTypes = ["char[]", "char[][]"]; mixin (declerations (dataTypes)); // Declare all the variables. void addTag (char[] type, ID id, char[] dt) { /// Supports all types listed in dataTypes. mixin (binarySearch ("type", dataTypes)); } void writeAll (ItemDelg itemdlg) { /// Supports all types listed in dataTypes. mixin (writeVars ()); } }