mirror of
https://bitbucket.org/King_DuckZ/jumping-in-d.git
synced 2024-10-30 02:49:01 +00:00
New vector class.
This commit is contained in:
parent
b3e122eeef
commit
c51fdd7483
3 changed files with 129 additions and 0 deletions
|
@ -1,6 +1,8 @@
|
|||
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
|
||||
project(hello_d C D)
|
||||
|
||||
set(CMAKE_D_FLAGS_DEBUG "${CMAKE_D_FLAGS_DEBUG} -funittest -O0")
|
||||
|
||||
include_directories(
|
||||
src/
|
||||
)
|
||||
|
@ -15,6 +17,7 @@ add_executable(${PROJECT_NAME}
|
|||
src/bpg.d
|
||||
src/texture.d
|
||||
src/gameobjjumping.d
|
||||
src/vector.d
|
||||
|
||||
lib/DerelictSDL2/source/derelict/sdl2/functions.d
|
||||
lib/DerelictSDL2/source/derelict/sdl2/image.d
|
||||
|
|
|
@ -20,6 +20,9 @@ public import gameobj;
|
|||
import derelict.sdl2.sdl;
|
||||
import texture;
|
||||
import std.stdio;
|
||||
import vector : Vector;
|
||||
|
||||
alias vec2 = Vector!(float, 2);
|
||||
|
||||
//This is one possible game scene. It will draw a texture on the screen
|
||||
//and it will report user wants to quit if you press the close button in the
|
||||
|
@ -46,6 +49,15 @@ class GameObjJumping : GameObj {
|
|||
override void prepare() {
|
||||
string texture_name = "bcruiser_normal.bpg";
|
||||
writeln("Loading texture %s", texture_name);
|
||||
|
||||
//Note how this is doing a swap and not a copy. You can verify that
|
||||
//in the output. The first "Destroying texture (null)" message is the
|
||||
//temporary created here, which took m_texture's content (null) and gets
|
||||
//destroyed as it goes out of scope.
|
||||
//The following code for example won't compile as it would trigger a
|
||||
//copy construction, but this(this) is marked as @disable in Texture:
|
||||
// auto tmp = Texture(texture_name, renderer());
|
||||
// m_texture = tmp;
|
||||
m_texture = Texture(texture_name, renderer());
|
||||
}
|
||||
|
||||
|
|
114
src/vector.d
Normal file
114
src/vector.d
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* Copyright 2015, Michele Santullo
|
||||
* This file is part of "Jumping in D".
|
||||
*
|
||||
* "Jumping in D" 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* "Jumping in D" 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 "Jumping in D". If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
module vector;
|
||||
import std.algorithm : fill;
|
||||
|
||||
struct Vector(T, int N) {
|
||||
//With the if(condition) before the function body we can tell the compiler
|
||||
//this particular template should only be considered when condition is true.
|
||||
this(P...)(P parInit) if (N == parInit.length) {
|
||||
int index = 0;
|
||||
foreach(p;parInit) {
|
||||
m_data[index++] = p;
|
||||
}
|
||||
}
|
||||
|
||||
this(P...)(P parInit) if (N > 1 && 1 == parInit.length) {
|
||||
//m_data is a static array, by slicing it we get a dynamic array and
|
||||
//fill that one. You will get a build error if you dont add the [].
|
||||
fill(m_data[], parInit[0]);
|
||||
}
|
||||
|
||||
//Define x, y, z, w accessors. Vectors larger than 4 elements won't have any
|
||||
//of those.
|
||||
static if (N <= 4) {
|
||||
//Getter
|
||||
@property T x() const { return m_data[0]; }
|
||||
//Setter
|
||||
@property T x(in T parVal) { return m_data[0] = parVal; }
|
||||
static if (N >= 2) {
|
||||
@property T y() const { return m_data[1]; }
|
||||
@property T y(in T parVal) { return m_data[1] = parVal; }
|
||||
}
|
||||
static if (N >= 3) {
|
||||
@property T z() const { return m_data[2]; }
|
||||
@property T z(in T parVal) { return m_data[2] = parVal; }
|
||||
}
|
||||
static if (N >= 4) {
|
||||
@property T w() const { return m_data[3]; }
|
||||
@property T w(in T parVal) { return m_data[3] = parVal; }
|
||||
}
|
||||
}
|
||||
|
||||
//Other accessors that can make using vectors more convenient - same static
|
||||
//if as above, but written here to separate code for the sake of clarity.
|
||||
static if (N <= 4) {
|
||||
@property Vector!(T, 2) x0() const { return Vector!(T, 2)(x, T(0)); }
|
||||
@property Vector!(T, 2) x1() const { return Vector!(T, 2)(x, T(1)); }
|
||||
@property Vector!(T, 2) _0x() const { return Vector!(T, 2)(T(0), x); }
|
||||
@property Vector!(T, 2) _1x() const { return Vector!(T, 2)(T(1), x); }
|
||||
|
||||
static if (N > 1) {
|
||||
@property Vector!(T, 2) xy() const { return Vector!(T, 2)(x, y); }
|
||||
@property Vector!(T, 2) y0() const { return Vector!(T, 2)(y, T(0)); }
|
||||
@property Vector!(T, 2) y1() const { return Vector!(T, 2)(y, T(1)); }
|
||||
@property Vector!(T, 2) _0y() const { return Vector!(T, 2)(T(0), y); }
|
||||
@property Vector!(T, 2) _1y() const { return Vector!(T, 2)(T(1), y); }
|
||||
}
|
||||
static if (N > 2) {
|
||||
@property Vector!(T, 3) xyz() const { return Vector!(T, 3)(x, y, z); }
|
||||
@property Vector!(T, 3) zxy() const { return Vector!(T, 3)(z, x, y); }
|
||||
@property Vector!(T, 3) yzx() const { return Vector!(T, 3)(y, z, x); }
|
||||
@property Vector!(T, 3) xzy() const { return Vector!(T, 3)(x, z, y); }
|
||||
@property Vector!(T, 3) zyx() const { return Vector!(T, 3)(z, y, x); }
|
||||
@property Vector!(T, 3) yxz() const { return Vector!(T, 3)(y, x, z); }
|
||||
//add more if you need
|
||||
}
|
||||
}
|
||||
|
||||
//Overload operator[] to allow accessing the vector with array syntax
|
||||
//inout tells the compiler to generate both a const and a non-const
|
||||
//version of this method.
|
||||
ref inout(T) opIndex (size_t parIndex) inout {
|
||||
assert(parIndex < N);
|
||||
return m_data[parIndex];
|
||||
}
|
||||
|
||||
private:
|
||||
T m_data[N];
|
||||
}
|
||||
|
||||
//You can write unit tests inside unittest {} blocks. These will only be
|
||||
//compiled if you specify the -funittest switch (gdc). Unit tests are run as
|
||||
//your program starts, but needs to be grammatically correct even if you don't
|
||||
//use the -funittest switch.
|
||||
unittest {
|
||||
auto v1 = Vector!(int, 3)(2);
|
||||
assert(2 == v1.x);
|
||||
assert(2 == v1.y);
|
||||
assert(2 == v1.z);
|
||||
|
||||
auto v2 = Vector!(int, 4)(3, 4, 5, 6);
|
||||
assert(3 == v2.x);
|
||||
assert(4 == v2.y);
|
||||
assert(5 == v2.z);
|
||||
assert(6 == v2.w);
|
||||
assert(Vector!(int, 2)(3, 0) == v2.x0);
|
||||
assert(Vector!(int, 2)(4, 0) == v2.y0);
|
||||
assert(Vector!(int, 3)(5, 4, 3) == v2.zyx);
|
||||
}
|
Loading…
Reference in a new issue