Skip to content

Add qelapsedtimer support #762

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions crates/cxx-qt-lib-headers/include/core/qelapsedtimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// clang-format off
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// clang-format on
// SPDX-FileContributor: Laurent Montel <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0
#pragma once

#include <QtCore/QElapsedTimer>

#include "rust/cxx.h"

namespace rust {
namespace cxxqtlib1 {
::std::int64_t
qelapsedtimerRestart(QElapsedTimer& elapsedTimer);

}
}
4 changes: 4 additions & 0 deletions crates/cxx-qt-lib-headers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ pub fn write_headers(directory: impl AsRef<Path>) {
),
(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"),
Expand Down
2 changes: 2 additions & 0 deletions crates/cxx-qt-lib/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -201,6 +202,7 @@ fn main() {
"core/qbytearray",
"core/qcoreapplication",
"core/qdate",
"core/qelapsedtimer",
"core/qhash/qhash",
"core/qline",
"core/qlinef",
Expand Down
3 changes: 3 additions & 0 deletions crates/cxx-qt-lib/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
35 changes: 35 additions & 0 deletions crates/cxx-qt-lib/src/core/qelapsedtimer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// clang-format off
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// clang-format on
// SPDX-FileContributor: Laurent Montel <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0
#include "cxx-qt-lib/qelapsedtimer.h"

#include "../assertion_utils.h"

#include <cstdint>

// 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<QElapsedTimer>::value,
"QElapsedTimer must be trivially copyable!");

namespace rust {
namespace cxxqtlib1 {

::std::int64_t
qelapsedtimerRestart(QElapsedTimer& elapsedTimer)
{
return static_cast<::std::int64_t>(elapsedTimer.restart());
}

}
}
72 changes: 72 additions & 0 deletions crates/cxx-qt-lib/src/core/qelapsedtimer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// SPDX-FileContributor: Laurent Montel <[email protected]>
//
// 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 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assume we want a QElapsedTimer in Rust and you don't just use the std stuff, guess it's still useful to have the Qt ones?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's useful to have Qt class for user which wants to use cxx-qt

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having not needed QElapsedTimer yet, I'd prefer if this was in cxx-qt-lib-extra.
As you've already wrapped it for this PR, there's no reason to throw this away, but I also don't know if it's worth adding it to our maintenance list.

In my opinion, CXX-Qt-lib should only wrap the most fundamental types without which Qt as a framework is hardly usable. The main benefit of CXX-Qt as a framework is not to provide the most exhaustive list of wrapped Qt API, but rather that it provides you with the bare minimum and makes it easy to wrap everything else you may need yourself.
Of course wrapping more in CXX-Qt is going to be easier for our users,, but I think not maintainable, given the enormous size of Qt.

Overall, we need a good guideline to decide which types to wrap in CXX-Qt-lib and which not.
I agree that stuff like QMargins is not really fundamental, so probably shouldn't have been added to CXX-Qt-lib. We could even consider moving it out of lib for 0.7.
A first draft of such a guideline:

  • Default to adding anything you think may be useful to CXX-Qt-lib-extra
  • Only add types to CXX-Qt-lib directly, if they're both:
    • Hard to wrap optimally (i.e. should be trivial/templates, etc.)
    • Are often used as parameters/return values within the Qt codebase
  • We can then always promote types from lib-extra to lib, if/when people request this.

I've added an issue about this, see: #766

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;
}