1 /// Intermediate module for binding rendering libraries to Isodi. 2 /// 3 /// All functions in this module should be implemented by the bindings. 4 module isodi.bind; 5 6 import isodi.anchor; 7 import isodi.position; 8 9 public { 10 import isodi.cell; 11 import isodi.model; 12 import isodi.anchor; 13 import isodi.display; 14 import isodi.pack_list; 15 } 16 17 /// Defines type of a log message 18 enum LogType { 19 20 info, /// General information, usually white. 21 success, /// An operation (eg. test) has succeeded, usually green. 22 error, /// An operation (eg. test) has failed, usually red. 23 24 } 25 26 27 @safe: 28 29 30 /// Put text in color using ANSI codes on POSIX platforms. 31 /// 32 /// On other platforms, this just returns the original string. 33 string colorText(string text, LogType type) { 34 35 version (Posix) { 36 37 import std.format : format; 38 39 string fString() { 40 41 // Posix platforms 42 with (LogType) 43 final switch (type) { 44 45 case info: return "%s"; 46 case success: return "\033[32m%s\033[0m"; 47 case error: return "\033[91m%s\033[0m"; 48 49 } 50 51 } 52 53 return fString.format(text); 54 55 } 56 57 else return text; 58 59 } 60 61 /// Interface of Isodi renderer bindings. Implement the functions to match behavior of your renderer. 62 interface Bindings { 63 64 /// An instance of a binding object. 65 static Bindings inst; 66 67 /// Output the given text to log. 68 /// 69 /// This is renderer dependent, because some renderers supply their own logging functionality, for example, 70 /// $(LINK2 https://godotengine.org, Godot Engine). 71 /// 72 /// Params: 73 /// text = Text to output. 74 /// type = Type of the log message. 75 void log(string text, LogType type = LogType.info); 76 77 /// Create an instance of the `Display` in order to fit the needs of the renderer. 78 Display createDisplay(); 79 80 /// Create a pack list to manage packs. 81 PackList createPackList(); 82 83 /// Create a cell. 84 Cell createCell(Display display, const Position position, const string type); 85 86 /// Create an anchor 87 Anchor createAnchor(Display); 88 89 /// Create a model 90 Model createModel(Display, const string type); 91 92 /// Register a binding object 93 mixin template Register(T) { 94 95 static this() { 96 97 import isodi.bind : Bindings; 98 Bindings.inst = new T; 99 100 } 101 102 } 103 104 /// Register a constructor. 105 mixin template Constructor(BaseType, Extension) { 106 107 import std.traits : Parameters; 108 109 private enum Name = "create" ~ __traits(identifier, BaseType); 110 private alias ParamTypes = Parameters!(__traits(getMember, Bindings, Name)); 111 112 mixin("BaseType " ~ Name ~ q{ (ParamTypes args) { 113 114 return new Extension(args); 115 116 }}); 117 118 } 119 120 } 121 122 /// Helper for calling renderer bindings. 123 alias Renderer = Bindings.inst;