use std::{
cell::{Ref, RefCell, RefMut},
rc::Rc,
};
use nautilus_common::{
cache::Cache,
clock::Clock,
msgbus::{
MessagingSwitchboard, TypedHandler, TypedIntoHandler, register_trading_command_endpoint,
},
};
use nautilus_core::{UUID4, WeakCell};
use nautilus_model::identifiers::TraderId;
use ustr::Ustr;
use crate::{
order_emulator::{emulator::OrderEmulator, handlers::OrderEmulatorOnEventHandler},
order_manager::handlers::{
CancelOrderHandlerAny, ModifyOrderHandlerAny, SubmitOrderHandlerAny,
},
};
#[derive(Debug)]
pub struct OrderEmulatorAdapter {
emulator: Rc<RefCell<OrderEmulator>>,
}
impl OrderEmulatorAdapter {
pub fn new(
trader_id: TraderId,
clock: Rc<RefCell<dyn Clock>>,
cache: Rc<RefCell<Cache>>,
) -> Self {
let emulator = Rc::new(RefCell::new(OrderEmulator::new(
clock.clone(),
cache.clone(),
)));
emulator
.borrow_mut()
.register(trader_id, clock, cache)
.expect("Failed to register OrderEmulator");
Self::initialize_self_ref(&emulator);
Self::initialize_execute_handler(&emulator);
Self::initialize_on_event_handler(&emulator);
Self::initialize_submit_order_handler(&emulator);
Self::initialize_cancel_order_handler(&emulator);
Self::initialize_modify_order_handler(&emulator);
Self { emulator }
}
fn initialize_self_ref(emulator: &Rc<RefCell<OrderEmulator>>) {
let self_ref = WeakCell::from(Rc::downgrade(emulator));
emulator.borrow_mut().set_self_ref(self_ref);
}
fn initialize_submit_order_handler(emulator: &Rc<RefCell<OrderEmulator>>) {
let handler = SubmitOrderHandlerAny::OrderEmulator(WeakCell::from(Rc::downgrade(emulator)));
emulator.borrow_mut().set_submit_order_handler(handler);
}
fn initialize_cancel_order_handler(emulator: &Rc<RefCell<OrderEmulator>>) {
let handler = CancelOrderHandlerAny::OrderEmulator(WeakCell::from(Rc::downgrade(emulator)));
emulator.borrow_mut().set_cancel_order_handler(handler);
}
fn initialize_modify_order_handler(emulator: &Rc<RefCell<OrderEmulator>>) {
let handler = ModifyOrderHandlerAny::OrderEmulator(WeakCell::from(Rc::downgrade(emulator)));
emulator.borrow_mut().set_modify_order_handler(handler);
}
fn initialize_execute_handler(emulator: &Rc<RefCell<OrderEmulator>>) {
let emulator_weak = WeakCell::from(Rc::downgrade(emulator));
let handler = TypedIntoHandler::from(move |cmd| {
if let Some(emulator_rc) = emulator_weak.upgrade() {
emulator_rc.borrow_mut().execute(cmd);
}
});
let endpoint = MessagingSwitchboard::order_emulator_execute();
register_trading_command_endpoint(endpoint, handler);
}
fn initialize_on_event_handler(emulator: &Rc<RefCell<OrderEmulator>>) {
let handler = TypedHandler::new(OrderEmulatorOnEventHandler::new(
Ustr::from(UUID4::new().as_str()),
WeakCell::from(Rc::downgrade(emulator)),
));
emulator.borrow_mut().set_on_event_handler(handler);
}
#[must_use]
pub fn get_emulator(&self) -> Ref<'_, OrderEmulator> {
self.emulator.borrow()
}
#[must_use]
pub fn get_emulator_mut(&self) -> RefMut<'_, OrderEmulator> {
self.emulator.borrow_mut()
}
}