use rs_teststand_sys::{Dispatch, Value};
use crate::Error;
use crate::dispids::thread;
#[derive(Debug)]
pub struct Thread {
dispatch: Box<dyn Dispatch>,
}
impl Thread {
pub(crate) fn new(dispatch: Box<dyn Dispatch>) -> Self {
Self { dispatch }
}
pub fn as_property_object(&self) -> Result<crate::PropertyObject, Error> {
Ok(crate::PropertyObject::new(
self.dispatch
.call(thread::AS_PROPERTY_OBJECT, &[])?
.into_object()?,
))
}
pub fn id(&self) -> Result<i32, Error> {
Ok(self.dispatch.get(thread::ID)?.as_i32()?)
}
pub fn unique_thread_id(&self) -> Result<String, Error> {
Ok(self.dispatch.get(thread::UNIQUE_THREAD_ID)?.into_string()?)
}
pub fn display_name(&self) -> Result<String, Error> {
Ok(self.dispatch.get(thread::DISPLAY_NAME)?.into_string()?)
}
pub fn call_stack_size(&self) -> Result<i32, Error> {
Ok(self.dispatch.get(thread::CALL_STACK_SIZE)?.as_i32()?)
}
pub fn externally_suspended(&self) -> Result<bool, Error> {
Ok(self.dispatch.get(thread::EXTERNALLY_SUSPENDED)?.as_bool()?)
}
pub fn execution(&self) -> Result<crate::Execution, Error> {
Ok(crate::Execution::new(
self.dispatch.get(thread::EXECUTION)?.into_object()?,
))
}
pub fn get_sequence_context(
&self,
call_stack_index: i32,
) -> Result<crate::execution::SequenceContext, Error> {
Ok(crate::execution::SequenceContext::new(
self.dispatch
.call(
thread::GET_SEQUENCE_CONTEXT,
&[Value::I32(call_stack_index)],
)?
.into_object()?,
))
}
pub fn post_ui_message_ex(
&self,
event_code: i32,
numeric_data: f64,
string_data: &str,
activex_data: Option<&crate::PropertyObject>,
synchronous: bool,
) -> Result<(), Error> {
let payload = object_argument(activex_data)?;
self.dispatch.call(
thread::POST_UI_MESSAGE_EX,
&[
Value::I32(event_code),
Value::F64(numeric_data),
Value::Str(string_data.to_owned()),
payload,
Value::Bool(synchronous),
],
)?;
Ok(())
}
}
impl Thread {
pub(crate) fn duplicate_dispatch(&self) -> Option<Box<dyn Dispatch>> {
self.dispatch.duplicate()
}
}
pub(crate) fn object_argument(object: Option<&crate::PropertyObject>) -> Result<Value, Error> {
object.map_or_else(
|| Ok(Value::NullObject),
|property_object| {
property_object
.duplicate_dispatch()
.map(Value::Object)
.ok_or(Error::UnexpectedType {
expected: "a live property object",
actual: "a test fake with no COM identity",
})
},
)
}