Last active
December 30, 2015 06:53
-
-
Save esnya/43ac84364c94482cf80c to your computer and use it in GitHub Desktop.
Minimal wrapper for DererictFI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public import derelict.freeimage.freeimage; | |
| import std.traits; | |
| static this() { | |
| DerelictFI.load(); | |
| } | |
| auto camelize(T)(T str) { | |
| import std.ascii : toUpper; | |
| return str[0].toUpper() ~ str[1 .. $]; | |
| } | |
| class Bitmap { | |
| this(FIBITMAP* handle) in { | |
| assert(handle); | |
| } body { | |
| this.handle = handle; | |
| } | |
| ~this() { | |
| this.unload(); | |
| } | |
| private FIBITMAP* _handle; | |
| @property FIBITMAP* handle() { return _handle; } | |
| protected @property void handle(FIBITMAP* handle) { _handle = handle; } | |
| auto opDispatch(string op, T...)(T args) if (isCallable!(FreeImage.FreeImageOf!op)) { | |
| return FreeImage.opDispatch!(op)(this, args); | |
| } | |
| auto opDispatch(string op, T...)(T args) if (T.length == 0 && !isCallable!(FreeImage.FreeImageOf!op) && isCallable!(FreeImage.FreeImageOf!("Get" ~ op.camelize))) { | |
| return this.opDispatch!("Get" ~ op.camelize)(args); | |
| } | |
| } | |
| struct FreeImage { | |
| template FreeImageOf(string name) { | |
| enum Name = "FreeImage_" ~ name.camelize; | |
| static if (is(typeof(mixin(Name)))) { | |
| mixin("alias FreeImageOf = " ~ Name ~ ";"); | |
| } else { | |
| alias FreeImageOf = void; | |
| } | |
| } | |
| alias ParameterTypeTupleOf(string name) = ParameterTypeTuple!(FreeImageOf!name); | |
| alias ParameterDefaultsOf(string name) = ParameterDefaults!(FreeImageOf!name); | |
| static auto opDispatch(string op, T...)(T args) if (isCallable!(FreeImageOf!op) && (T.length == ParameterTypeTupleOf!op.length || T.length < ParameterTypeTupleOf!op.length && !is(ParameterDefaultsOf!op[T.length] == void))) { | |
| alias Func = FreeImageOf!op; | |
| ParameterTypeTupleOf!op _args; | |
| foreach (i, D; ParameterTypeTupleOf!op) { | |
| static if (i >= T.length) { | |
| _args[i] = ParameterDefaultsOf!op[i]; | |
| } else { | |
| alias S = typeof(args[i]); | |
| static if (isAssignable!(D, S)) { | |
| _args[i] = args[i]; | |
| } else static if (hasMember!(S, "handle") && isAssignable!(D, typeof(mixin("args[i].handle")))) { | |
| _args[i] = args[i].handle; | |
| } else static if (isPointer!D && is(Unqual!(PointerTarget!D) == char)) { | |
| version(Windows) { | |
| import std.windows.charset; | |
| _args[i] = args[i].toMBSz(1); | |
| } else { | |
| import std.string; | |
| _args[i] = args[i].toStringz(); | |
| } | |
| } else static if (isPointer!D && is(Unqual!(PointerTarget!D) == wchar)) { | |
| import std.utf; | |
| _args[i] = args[i].toUTF16z(); | |
| } else { | |
| static assert("Can't convert " ~ S.stringof ~ " to " ~ D.stringof); | |
| } | |
| } | |
| } | |
| static if (is(ReturnType!Func == void)) { | |
| Func(_args); | |
| } else { | |
| auto result = Func(_args); | |
| static if (isPointer!(ReturnType!Func) || is(ReturnType!Func == BOOL)) { | |
| import std.exception : enforce; | |
| enforce(result, (() { | |
| char[] msg; | |
| msg ~= "Error occoured on FreeImage."; | |
| msg ~= op; | |
| msg ~= '('; | |
| foreach (i, arg; args) { | |
| import std.conv : to; | |
| if (i > 0) msg ~= ", "; | |
| msg ~= arg.to!string(); | |
| } | |
| msg ~= ')'; | |
| return msg.idup; | |
| })()); | |
| } | |
| static if (is(PointerTarget!(ReturnType!Func) == FIBITMAP)) { | |
| return new Bitmap(result); | |
| } else { | |
| return result; | |
| } | |
| } | |
| } | |
| } | |
| unittest { | |
| auto img = FreeImage.Allocate(320, 240, 32); | |
| assert(img.width == 320); | |
| assert(img.height == 240); | |
| delete img; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment