dvcompute_dist/simulation/internal/
undoable_log.rs1use std::mem;
8
9use libc::*;
10
11use crate::simulation::Run;
12
13pub struct UndoableActionBox {
15 f: Box<dyn UndoableActionFnBox>
16}
17
18impl UndoableActionBox {
19
20 #[doc(hidden)]
22 #[inline]
23 pub fn new<F>(f: F) -> Self
24 where F: FnOnce(&Run) + 'static
25 {
26 UndoableActionBox {
27 f: Box::new(f)
28 }
29 }
30
31 #[doc(hidden)]
33 #[inline]
34 pub fn call_box(self, arg: (&Run,)) {
35 let UndoableActionBox { f } = self;
36 f.call_box(arg)
37 }
38}
39
40trait UndoableActionFnBox {
42
43 fn call_box(self: Box<Self>, args: (&Run,));
45}
46
47impl<F> UndoableActionFnBox for F
48 where F: for<'a> FnOnce(&'a Run)
49{
50 fn call_box(self: Box<Self>, args: (&Run,)) {
51 let this: Self = *self;
52 this(args.0)
53 }
54}
55
56#[repr(C)]
58#[derive(Copy, Clone)]
59struct UndoableActionTraitObject {
60
61 field1: *mut c_void,
62 field2: *mut c_void
63}
64
65#[repr(C)]
67pub struct UndoableActionRepr {
68
69 delete: unsafe extern "C" fn(obj: *mut UndoableActionTraitObject),
71
72 callback: unsafe extern "C" fn(obj: *mut UndoableActionTraitObject, r: *const Run),
74
75 trait_object: UndoableActionTraitObject
77}
78
79impl Drop for UndoableActionRepr {
80
81 fn drop(&mut self) {
82 unsafe {
83 (self.delete)(&mut self.trait_object);
84 }
85 }
86}
87
88impl UndoableActionRepr {
89
90 #[inline]
92 pub fn into_repr(comp: UndoableActionBox) -> UndoableActionRepr {
93 unsafe {
94 UndoableActionRepr {
95 delete: delete_undoable_action_repr,
96 callback: call_undoable_action_repr,
97 trait_object: mem::transmute(comp)
98 }
99 }
100 }
101
102 #[inline]
104 fn _call_repr(mut self, r: &Run) {
105 unsafe {
106 (self.callback)(&mut self.trait_object, r);
107 mem::forget(self);
108 }
109 }
110}
111
112unsafe extern "C" fn call_undoable_action_repr(comp: *mut UndoableActionTraitObject, r: *const Run) {
114 let comp: UndoableActionBox = mem::transmute(*comp);
115 comp.call_box((&*r,));
116}
117
118unsafe extern "C" fn delete_undoable_action_repr(comp: *mut UndoableActionTraitObject) {
120 let _: UndoableActionBox = mem::transmute(*comp);
121}
122
123pub type UndoableLog = c_void;
125
126#[cfg(all(feature="dist_mode", not(feature="dist_core_mode")))]
127#[cfg_attr(windows, link(name = "dvcompute_core_dist.dll"))]
128#[cfg_attr(not(windows), link(name = "dvcompute_core_dist"))]
129extern {
130
131 #[doc(hidden)]
133 pub fn create_extern_undoable_log() -> *mut UndoableLog;
134
135 #[doc(hidden)]
137 pub fn delete_extern_undoable_log(log: *mut UndoableLog);
138
139 #[doc(hidden)]
141 pub fn extern_write_log(log: *mut UndoableLog, t: f64, action: UndoableActionRepr);
142}
143
144#[cfg(all(feature="dist_mode", feature="dist_core_mode"))]
145extern {
146
147 #[doc(hidden)]
149 pub fn create_extern_undoable_log() -> *mut UndoableLog;
150
151 #[doc(hidden)]
153 pub fn delete_extern_undoable_log(log: *mut UndoableLog);
154
155 #[doc(hidden)]
157 pub fn extern_write_log(log: *mut UndoableLog, t: f64, action: UndoableActionRepr);
158}