nautilus_backtest/ffi/
engine.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Posei Systems Pty Ltd. All rights reserved.
3//  https://poseitrader.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16use std::{
17    fmt::Debug,
18    ops::{Deref, DerefMut},
19};
20
21use nautilus_common::ffi::{clock::TestClock_API, timer::TimeEventHandler};
22use nautilus_core::{
23    UnixNanos,
24    ffi::{cvec::CVec, parsing::u8_as_bool},
25};
26
27use crate::accumulator::TimeEventAccumulator;
28
29#[repr(C)]
30pub struct TimeEventAccumulatorAPI(Box<TimeEventAccumulator>);
31
32impl Deref for TimeEventAccumulatorAPI {
33    type Target = TimeEventAccumulator;
34
35    fn deref(&self) -> &Self::Target {
36        &self.0
37    }
38}
39
40impl Debug for TimeEventAccumulatorAPI {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        // Print the type name plus a pointer-style hint so callers can at least
43        // see that two wrappers refer to the same accumulator.
44        write!(f, "TimeEventAccumulatorAPI({:p})", &*self.0)
45    }
46}
47
48impl DerefMut for TimeEventAccumulatorAPI {
49    fn deref_mut(&mut self) -> &mut Self::Target {
50        &mut self.0
51    }
52}
53
54#[unsafe(no_mangle)]
55pub extern "C" fn time_event_accumulator_new() -> TimeEventAccumulatorAPI {
56    TimeEventAccumulatorAPI(Box::default())
57}
58
59#[unsafe(no_mangle)]
60pub extern "C" fn time_event_accumulator_drop(accumulator: TimeEventAccumulatorAPI) {
61    drop(accumulator); // Memory freed here
62}
63
64#[unsafe(no_mangle)]
65pub extern "C" fn time_event_accumulator_advance_clock(
66    accumulator: &mut TimeEventAccumulatorAPI,
67    clock: &mut TestClock_API,
68    to_time_ns: UnixNanos,
69    set_time: u8,
70) {
71    accumulator.advance_clock(clock, to_time_ns, u8_as_bool(set_time));
72}
73
74#[unsafe(no_mangle)]
75pub extern "C" fn time_event_accumulator_drain(accumulator: &mut TimeEventAccumulatorAPI) -> CVec {
76    let handlers: Vec<TimeEventHandler> = accumulator.drain().into_iter().map(Into::into).collect();
77    handlers.into()
78}