From 6a2d132873ce7b40405a3dc000a12539fffd969b Mon Sep 17 00:00:00 2001 From: tslil clingman <> Date: Wed, 1 Sep 2021 12:59:50 -0400 Subject: Init --- src/sfml/system/Clock.zig | 59 +++++++++++++++++++++++ src/sfml/system/Time.zig | 114 +++++++++++++++++++++++++++++++++++++++++++++ src/sfml/system/vector.zig | 104 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 277 insertions(+) create mode 100644 src/sfml/system/Clock.zig create mode 100644 src/sfml/system/Time.zig create mode 100644 src/sfml/system/vector.zig (limited to 'src/sfml/system') diff --git a/src/sfml/system/Clock.zig b/src/sfml/system/Clock.zig new file mode 100644 index 0000000..17b6e5b --- /dev/null +++ b/src/sfml/system/Clock.zig @@ -0,0 +1,59 @@ +//! Utility class that measures the elapsed time. + +const sf = struct { + pub usingnamespace @import("../sfml.zig"); + pub usingnamespace system; + pub usingnamespace graphics; +}; + +const Clock = @This(); + +// Constructor/destructor + +/// Inits a clock. The clock will have its time set at 0 at this point, and automatically starts +/// Std.time timer also is a good alternative +pub fn create() !Clock { + var clock = sf.c.sfClock_create(); + if (clock == null) + return sf.Error.nullptrUnknownReason; + + return Clock{ .ptr = clock.? }; +} + +/// Destroys this clock +pub fn destroy(self: Clock) void { + sf.c.sfClock_destroy(self.ptr); +} + +// Clock control +/// Gets the elapsed seconds +pub fn getElapsedTime(self: Clock) sf.Time { + var time = sf.c.sfClock_getElapsedTime(self.ptr).microseconds; + return sf.Time{ .us = time }; +} + +/// Gets the elapsed seconds and restarts the timer +pub fn restart(self: Clock) sf.Time { + var time = sf.c.sfClock_restart(self.ptr).microseconds; + return sf.Time{ .us = time }; +} + +/// Pointer to the csfml structure +ptr: *sf.c.sfClock, + +test "clock: sleep test" { + const tst = @import("std").testing; + + // This tests just sleeps and check what the timer measured (not very accurate but eh) + var clk = try Clock.create(); + defer clk.destroy(); + + sf.Time.milliseconds(500).sleep(); + + try tst.expectApproxEqAbs(@as(f32, 0.5), clk.getElapsedTime().asSeconds(), 0.1); + + sf.Time.sleep(sf.Time.seconds(0.2)); + + try tst.expectApproxEqAbs(@as(f32, 0.7), clk.restart().asSeconds(), 0.1); + try tst.expectApproxEqAbs(@as(f32, 0), clk.getElapsedTime().asSeconds(), 0.01); +} diff --git a/src/sfml/system/Time.zig b/src/sfml/system/Time.zig new file mode 100644 index 0000000..2e8a34c --- /dev/null +++ b/src/sfml/system/Time.zig @@ -0,0 +1,114 @@ +//! Represents a time value. + +const sf = @import("../sfml.zig"); + +const Time = @This(); + +// Constructors + +/// Converts a time from a csfml object +/// For inner workings +pub fn fromCSFML(time: sf.c.sfTime) Time { + return Time{ .us = time.microseconds }; +} + +/// Converts a time to a csfml object +/// For inner workings +pub fn toCSFML(self: Time) sf.c.sfTime { + return sf.c.sfTime{ .microseconds = self.us }; +} + +/// Creates a time object from a seconds count +pub fn seconds(s: f32) Time { + return Time{ .us = @floatToInt(i64, s * 1_000) * 1_000 }; +} + +/// Creates a time object from milliseconds +pub fn milliseconds(ms: i32) Time { + return Time{ .us = @intCast(i64, ms) * 1_000 }; +} + +/// Creates a time object from microseconds +pub fn microseconds(us: i64) Time { + return Time{ .us = us }; +} + +// Getters + +/// Gets this time measurement as microseconds +pub fn asMicroseconds(self: Time) i64 { + return self.us; +} + +/// Gets this time measurement as milliseconds +pub fn asMilliseconds(self: Time) i32 { + return @truncate(i32, @divFloor(self.us, 1_000)); +} + +/// Gets this time measurement as seconds (as a float) +pub fn asSeconds(self: Time) f32 { + return @intToFloat(f32, self.us) / 1_000_000; +} + +// Misc + +/// Sleeps the amount of time specified +pub fn sleep(time: Time) void { + sf.c.sfSleep(time.toCSFML()); +} + +/// A time of zero +pub const Zero = microseconds(0); + +us: i64, + +pub const TimeSpan = struct { + // Constructors + + /// Construcs a time span + pub fn init(begin: Time, length: Time) TimeSpan { + return TimeSpan{ + .offset = begin, + .length = length, + }; + } + + /// Converts a timespan from a csfml object + /// For inner workings + pub fn fromCSFML(span: sf.c.sfTimeSpan) TimeSpan { + return TimeSpan{ + .offset = Time.fromCSFML(span.offset), + .length = Time.fromCSFML(span.length), + }; + } + + /// Converts a timespan to a csfml object + /// For inner workings + pub fn toCSFML(self: TimeSpan) sf.c.sfTimeSpan { + return sf.c.sfTimeSpan{ + .offset = self.offset.toCSFML(), + .length = self.length.toCSFML(), + }; + } + + /// The beginning of this span + offset: Time, + /// The length of this time span + length: Time, +}; + +test "time: conversion" { + const tst = @import("std").testing; + + var t = Time.microseconds(5_120_000); + + try tst.expectEqual(@as(i32, 5_120), t.asMilliseconds()); + try tst.expectApproxEqAbs(@as(f32, 5.12), t.asSeconds(), 0.0001); + + t = Time.seconds(12); + + try tst.expectApproxEqAbs(@as(f32, 12), t.asSeconds(), 0.0001); + + t = Time.microseconds(800); + try tst.expectApproxEqAbs(@as(f32, 0.0008), t.asSeconds(), 0.0001); +} diff --git a/src/sfml/system/vector.zig b/src/sfml/system/vector.zig new file mode 100644 index 0000000..7e3e500 --- /dev/null +++ b/src/sfml/system/vector.zig @@ -0,0 +1,104 @@ +//! Utility struct for manipulating 2-dimensional vectors. + +const sf = @import("../sfml_import.zig"); + +pub fn Vector2(comptime T: type) type { + return packed struct { + const Self = @This(); + + /// The CSFML vector type equivalent + const CsfmlEquivalent = switch (T) { + c_uint => sf.c.sfVector2u, + c_int => sf.c.sfVector2i, + f32 => sf.c.sfVector2f, + else => void, + }; + + /// Makes a CSFML vector with this vector (only if the corresponding type exists) + /// This is mainly for the inner workings of this wrapper + pub fn toCSFML(self: Self) CsfmlEquivalent { + if (CsfmlEquivalent == void) @compileError("This vector type doesn't have a CSFML equivalent."); + return @bitCast(CsfmlEquivalent, self); + } + + /// Creates a vector from a CSFML one (only if the corresponding type exists) + /// This is mainly for the inner workings of this wrapper + pub fn fromCSFML(vec: CsfmlEquivalent) Self { + if (CsfmlEquivalent == void) @compileError("This vector type doesn't have a CSFML equivalent."); + return @bitCast(Self, vec); + } + + /// Adds two vectors + pub fn add(self: Self, other: Self) Self { + return Self{ .x = self.x + other.x, .y = self.y + other.y }; + } + + /// Substracts two vectors + pub fn substract(self: Self, other: Self) Self { + return Self{ .x = self.x - other.x, .y = self.y - other.y }; + } + + /// Scales a vector + pub fn scale(self: Self, scalar: T) Self { + return Self{ .x = self.x * scalar, .y = self.y * scalar }; + } + + /// x component of the vector + x: T, + /// y component of the vector + y: T + }; +} + +pub const Vector3f = struct { + const Self = @This(); + + /// Makes a CSFML vector with this vector (only if the corresponding type exists) + /// This is mainly for the inner workings of this wrapper + pub fn toCSFML(self: Self) sf.c.sfVector3f { + return @bitCast(sf.c.sfVector3f, self); + } + + /// Creates a vector from a CSFML one (only if the corresponding type exists) + /// This is mainly for the inner workings of this wrapper + pub fn fromCSFML(vec: sf.c.sfVector3f) Self { + return @bitCast(Self, vec); + } + + /// x component of the vector + x: f32, + /// y component of the vector + y: f32, + /// z component of the vector + z: f32, +}; + +test "vector: sane from/to CSFML vectors" { + const tst = @import("std").testing; + + inline for ([_]type{ c_int, c_uint, f32 }) |T| { + const VecT = Vector2(T); + const vec = VecT{ .x = 1, .y = 3 }; + const cvec = vec.toCSFML(); + + try tst.expectEqual(vec.x, cvec.x); + try tst.expectEqual(vec.y, cvec.y); + + const vec2 = VecT.fromCSFML(cvec); + + try tst.expectEqual(vec, vec2); + } + + { + const vec = Vector3f{ .x = 1, .y = 3.5, .z = -12 }; + const cvec = vec.toCSFML(); + + try tst.expectEqual(vec.x, cvec.x); + try tst.expectEqual(vec.y, cvec.y); + try tst.expectEqual(vec.z, cvec.z); + + const vec2 = Vector3f.fromCSFML(cvec); + + try tst.expectEqual(vec, vec2); + } +} -- cgit v1.3.1