diff --git a/crates/cxx-qt-lib-headers/include/core/qelapsedtimer.h b/crates/cxx-qt-lib-headers/include/core/qelapsedtimer.h new file mode 100644 index 000000000..6d993f4b7 --- /dev/null +++ b/crates/cxx-qt-lib-headers/include/core/qelapsedtimer.h @@ -0,0 +1,19 @@ +// clang-format off +// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company +// clang-format on +// SPDX-FileContributor: Laurent Montel +// +// SPDX-License-Identifier: MIT OR Apache-2.0 +#pragma once + +#include + +#include "rust/cxx.h" + +namespace rust { +namespace cxxqtlib1 { +::std::int64_t +qelapsedtimerRestart(QElapsedTimer& elapsedTimer); + +} +} diff --git a/crates/cxx-qt-lib-headers/src/lib.rs b/crates/cxx-qt-lib-headers/src/lib.rs index c87cb2207..fdc1a763d 100644 --- a/crates/cxx-qt-lib-headers/src/lib.rs +++ b/crates/cxx-qt-lib-headers/src/lib.rs @@ -24,6 +24,10 @@ pub fn write_headers(directory: impl AsRef) { ), (include_str!("../include/core/qdate.h"), "qdate.h"), (include_str!("../include/core/qdatetime.h"), "qdatetime.h"), + ( + include_str!("../include/core/qelapsedtimer.h"), + "qelapsedtimer.h", + ), (include_str!("../include/core/qhash.h"), "qhash.h"), (include_str!("../include/core/qline.h"), "qline.h"), (include_str!("../include/core/qlinef.h"), "qlinef.h"), diff --git a/crates/cxx-qt-lib/build.rs b/crates/cxx-qt-lib/build.rs index 1c77f747f..e69770cda 100644 --- a/crates/cxx-qt-lib/build.rs +++ b/crates/cxx-qt-lib/build.rs @@ -35,6 +35,7 @@ fn main() { "core/qbytearray", "core/qcoreapplication", "core/qdate", + "core/qelapsedtimer", "core/qhash/qhash_i32_qbytearray", "core/qhash/qhash_qstring_qvariant", "core/qline", @@ -201,6 +202,7 @@ fn main() { "core/qbytearray", "core/qcoreapplication", "core/qdate", + "core/qelapsedtimer", "core/qhash/qhash", "core/qline", "core/qlinef", diff --git a/crates/cxx-qt-lib/src/core/mod.rs b/crates/cxx-qt-lib/src/core/mod.rs index 53ee88917..72d09e0df 100644 --- a/crates/cxx-qt-lib/src/core/mod.rs +++ b/crates/cxx-qt-lib/src/core/mod.rs @@ -17,6 +17,9 @@ mod qdatetime; #[cfg(not(target_os = "emscripten"))] pub use qdatetime::QDateTime; +mod qelapsedtimer; +pub use qelapsedtimer::QElapsedTimer; + mod qhash; pub use qhash::{QHash, QHashPair, QHashPair_QString_QVariant, QHashPair_i32_QByteArray}; diff --git a/crates/cxx-qt-lib/src/core/qelapsedtimer.cpp b/crates/cxx-qt-lib/src/core/qelapsedtimer.cpp new file mode 100644 index 000000000..31b972967 --- /dev/null +++ b/crates/cxx-qt-lib/src/core/qelapsedtimer.cpp @@ -0,0 +1,35 @@ +// clang-format off +// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company +// clang-format on +// SPDX-FileContributor: Laurent Montel +// +// SPDX-License-Identifier: MIT OR Apache-2.0 +#include "cxx-qt-lib/qelapsedtimer.h" + +#include "../assertion_utils.h" + +#include + +// QElapsedTimer has two "int64" members +// Rust represents these as 2 64-bit integers. +// https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/kernel/qelapsedtimer.h#n57 +// +// https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/kernel/qelapsedtimer.h?h=v6.2.4#n89 +assert_alignment_and_size(QElapsedTimer, + alignof(::std::int64_t), + sizeof(::std::int64_t[2])); + +static_assert(::std::is_trivially_copyable::value, + "QElapsedTimer must be trivially copyable!"); + +namespace rust { +namespace cxxqtlib1 { + +::std::int64_t +qelapsedtimerRestart(QElapsedTimer& elapsedTimer) +{ + return static_cast<::std::int64_t>(elapsedTimer.restart()); +} + +} +} diff --git a/crates/cxx-qt-lib/src/core/qelapsedtimer.rs b/crates/cxx-qt-lib/src/core/qelapsedtimer.rs new file mode 100644 index 000000000..e7c665459 --- /dev/null +++ b/crates/cxx-qt-lib/src/core/qelapsedtimer.rs @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company +// SPDX-FileContributor: Laurent Montel +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use cxx::{type_id, ExternType}; + +#[cxx::bridge] +mod ffi { + unsafe extern "C++" { + include!("cxx-qt-lib/qelapsedtimer.h"); + type QElapsedTimer = crate::QElapsedTimer; + + /// Returns false if the timer has never been started or invalidated by a call to invalidate(). + #[rust_name = "is_valid"] + fn isValid(self: &QElapsedTimer) -> bool; + + /// Marks this QElapsedTimer object as invalid. + fn invalidate(self: &mut QElapsedTimer); + + /// Starts this timer. Once started, a timer value can be checked with elapsed() or msecsSinceReference(). + fn start(self: &mut QElapsedTimer); + } + + #[namespace = "rust::cxxqtlib1"] + unsafe extern "C++" { + #[doc(hidden)] + #[rust_name = "qelapsedtimer_restart"] + fn qelapsedtimerRestart(e: &mut QElapsedTimer) -> i64; + } + + #[namespace = "rust::cxxqtlib1"] + unsafe extern "C++" { + include!("cxx-qt-lib/common.h"); + + #[doc(hidden)] + #[rust_name = "qelapsedtimer_init_default"] + fn construct() -> QElapsedTimer; + } +} + +/// The QElapsedTimer struct provides a fast way to calculate elapsed times. +#[derive(Debug, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct QElapsedTimer { + t1: i64, + t2: i64, +} + +impl Default for QElapsedTimer { + /// Constructs an invalid QElapsedTimer. A timer becomes valid once it has been started. + fn default() -> Self { + ffi::qelapsedtimer_init_default() + } +} + +impl QElapsedTimer { + /// Restarts the timer and returns the number of milliseconds elapsed since the previous start. + /// This function is equivalent to obtaining the elapsed time with elapsed() and then starting the timer again with start(), + /// but it does so in one single operation, avoiding the need to obtain the clock value twice. + pub fn restart(mut self) -> i64 { + ffi::qelapsedtimer_restart(&mut self) + } +} + +// Safety: +// +// Static checks on the C++ side ensure that QElapsedTimer is trivial. +unsafe impl ExternType for QElapsedTimer { + type Id = type_id!("QElapsedTimer"); + type Kind = cxx::kind::Trivial; +}