1 /// 2 module isodi.object3d; 3 4 import std.stdio; 5 import std.string; 6 7 public { 8 9 import isodi.bind; 10 import isodi.display; 11 import isodi.position; 12 import isodi.resource; 13 14 } 15 16 17 @safe: 18 19 20 /// Represents an object that can be drawn on a 3D space. 21 abstract class Object3D { 22 23 /// Display this object is connected to. 24 Display display; 25 26 /// Get the current position of the object. 27 abstract const(Position) position() const; 28 29 /// Get the current visual position of the object. 30 abstract const(Position) visualPosition() const; 31 32 /// Params: 33 /// display = Display to connect to. 34 this(Display display) { 35 36 this.display = display; 37 38 } 39 40 /// Add a basic implementation for the position as a property, includes a setter. 41 mixin template Implement() { 42 43 @safe: 44 45 private Position _position; 46 47 /// Get the current position of the object. 48 /// 49 /// This returns a const value, use `positionRef` to get a reference. 50 override const(Position) position() const { return _position; } 51 52 /// Ditto 53 override const(Position) visualPosition() const { return position; } 54 55 /// Get a reference to the position value. 56 ref Position positionRef() { return _position; } 57 58 /// Set the new position. 59 Position position(Position value) { return _position = value; } 60 61 } 62 63 /// 64 static unittest { 65 66 class Example : Object3D { 67 68 mixin Object3D.Implement; 69 70 this() { 71 super(null); 72 } 73 74 } 75 76 auto ex = new Example; 77 assert(ex.position == .position(0, 0)); 78 79 ex.positionRef.x += 1; 80 assert(ex.position == .position(1, 0)); 81 82 ex.position = .position(2, 2); 83 assert(ex.position == .position(2, 2)); 84 85 } 86 87 /// Implement the position as a const property. `_position` and `_visualPosition` must be set in constructor. 88 mixin template ImplementConst() { 89 90 @safe: 91 92 private const Position _position; 93 override const(Position) position() const { return _position; } 94 95 private Position _visualPosition; 96 97 /// Get the position the cell is displayed on. 98 override const(Position) visualPosition() const { 99 100 return _visualPosition; 101 102 } 103 104 /// Set an offset for the visual position. 105 /// 106 /// $(B Note:) Mind that depth is initialized to 1 by default, which might cause unwanted effects. If you don't 107 /// want to offset it, use `positionOff`. 108 const(Position) offset(Position value) { 109 110 return _visualPosition = _position.sum(value); 111 112 } 113 114 /// Reset the offset 115 void resetOffset() { 116 117 _visualPosition = _position; 118 119 } 120 121 } 122 123 }