iter
This commit is contained in:
parent
5c30064d69
commit
04504a9a7e
13
Cargo.toml
13
Cargo.toml
@ -7,12 +7,13 @@ edition = "2021"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z" # Optimize for size.
|
||||
lto = true # Enable Link Time Optimization
|
||||
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
|
||||
panic = "abort" # Abort on panic
|
||||
strip = true # Automatically strip symbols from the binary.
|
||||
opt-level = "z" # Optimize for size.
|
||||
lto = true # Enable Link Time Optimization
|
||||
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
|
||||
panic = "abort" # Abort on panic
|
||||
strip = true # Automatically strip symbols from the binary.
|
||||
|
||||
[dependencies]
|
||||
color-eyre = "0.6.2"
|
||||
ureq = "2.7.1"
|
||||
utf16_lit="2.0"
|
||||
utf16_lit = "2.0"
|
||||
|
1
rustfmt.toml
Normal file
1
rustfmt.toml
Normal file
@ -0,0 +1 @@
|
||||
max_width = 80
|
@ -1,9 +1,8 @@
|
||||
use std::default;
|
||||
|
||||
use crate::ffi::{
|
||||
connection::Connection,
|
||||
types::{ParamValue, ReturnValue},
|
||||
};
|
||||
use color_eyre::eyre::{Result};
|
||||
|
||||
pub struct ComponentPropDescription {
|
||||
pub name: &'static [u16],
|
||||
@ -12,24 +11,31 @@ pub struct ComponentPropDescription {
|
||||
}
|
||||
|
||||
pub struct ComponentFuncDescription {
|
||||
pub name: &'static [u16],
|
||||
pub names: Vec<&'static [u16]>,
|
||||
pub params_count: usize,
|
||||
pub returns_val: bool,
|
||||
pub default_values: &'static [Option<ParamValue<'static>>],
|
||||
pub default_values: &'static [Option<ParamValue>],
|
||||
}
|
||||
impl ComponentFuncDescription {
|
||||
pub fn new<const params_count: usize>(
|
||||
name: &'static [u16],
|
||||
pub fn new<const PARAMS_COUNT: usize>(
|
||||
names: Vec<&'static [u16]>,
|
||||
returns_val: bool,
|
||||
default_values: &'static [Option<ParamValue<'static>>; params_count],
|
||||
default_values: &'static [Option<ParamValue>; PARAMS_COUNT],
|
||||
) -> Self {
|
||||
Self {
|
||||
name,
|
||||
params_count,
|
||||
names,
|
||||
params_count: PARAMS_COUNT,
|
||||
returns_val,
|
||||
default_values,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn str_names(&self ) -> Vec<String> {
|
||||
self.names.iter().map(|name_utf16| {
|
||||
let name_string = String::from_utf16_lossy(name_utf16).trim_matches(char::from(0)).to_string();
|
||||
name_string
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AddIn {
|
||||
@ -38,17 +44,17 @@ pub trait AddIn {
|
||||
fn list_parameters(&self) -> Vec<ComponentPropDescription> {
|
||||
Vec::new()
|
||||
}
|
||||
fn list_functions(&self) -> Vec<ComponentFuncDescription> {
|
||||
fn list_functions(&self) -> Vec<&ComponentFuncDescription> {
|
||||
Vec::new()
|
||||
}
|
||||
fn get_parameter(&self, name: &str) -> Option<ParamValue> {
|
||||
fn get_parameter(&self, _name: &str) -> Option<ParamValue> {
|
||||
None
|
||||
}
|
||||
fn set_parameter(&mut self, name: &str, value: &ParamValue) -> bool {
|
||||
fn set_parameter(&mut self, _name: &str, _value: &ParamValue) -> bool {
|
||||
false
|
||||
}
|
||||
fn call_function(&mut self, name: &str, params: &[ParamValue]) -> Option<ParamValue> {
|
||||
None
|
||||
fn call_function(&mut self, _name: &str, _params: &[ParamValue]) -> Result<Option<ParamValue>> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,8 +68,7 @@ impl<T: AddIn> AddInContainer<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AddIn> AddInWrapper for AddInContainer<T>{
|
||||
|
||||
impl<T: AddIn> AddInWrapper for AddInContainer<T> {
|
||||
fn init(&mut self, interface: &'static Connection) -> bool {
|
||||
self.add_in.init(interface)
|
||||
}
|
||||
@ -95,11 +100,9 @@ impl<T: AddIn> AddInWrapper for AddInContainer<T>{
|
||||
.list_parameters()
|
||||
.get(num)
|
||||
.map(|x| x.name)
|
||||
.or_else(|| self.add_in.list_parameters().get(alias).map(|x| x.name))
|
||||
}
|
||||
|
||||
fn get_prop_val(&self, num: usize, val: ReturnValue) -> bool {
|
||||
|
||||
fn get_prop_val(&self, num: usize, val: ReturnValue) -> bool {
|
||||
let param_desc_binding = self.add_in.list_parameters();
|
||||
let Some(param_desc) = param_desc_binding.get(num) else {
|
||||
return false
|
||||
@ -115,12 +118,12 @@ impl<T: AddIn> AddInWrapper for AddInContainer<T>{
|
||||
};
|
||||
|
||||
match param_data {
|
||||
ParamValue::Str(data_unwrapped) => val.set_str(data_unwrapped),
|
||||
ParamValue::I32(data_unwrapped) => val.set_i32(data_unwrapped),
|
||||
ParamValue::Bool(data_unwrapped) => val.set_bool(data_unwrapped),
|
||||
ParamValue::F64(data_unwrapped) => val.set_f64(data_unwrapped),
|
||||
ParamValue::Date(data_unwrapped) => val.set_date(data_unwrapped),
|
||||
ParamValue::Blob(data_unwrapped) => val.set_blob(data_unwrapped),
|
||||
ParamValue::Str(data_unwrapped) => val.set_str(&data_unwrapped),
|
||||
ParamValue::Blob(data_unwrapped) => val.set_blob(&data_unwrapped),
|
||||
ParamValue::Empty => val.set_empty(),
|
||||
}
|
||||
true
|
||||
@ -135,7 +138,7 @@ impl<T: AddIn> AddInWrapper for AddInContainer<T>{
|
||||
if !param_desc.writable {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
let name_string = String::from_utf16_lossy(param_desc.name);
|
||||
let name_utf8 = name_string.as_str().trim_matches(char::from(0));
|
||||
self.add_in.set_parameter(name_utf8, val)
|
||||
@ -146,7 +149,7 @@ impl<T: AddIn> AddInWrapper for AddInContainer<T>{
|
||||
let Some(param_desc) = param_desc_binding.get(num) else {
|
||||
return false
|
||||
};
|
||||
param_desc.readable
|
||||
param_desc.readable
|
||||
}
|
||||
|
||||
fn is_prop_writable(&self, num: usize) -> bool {
|
||||
@ -157,23 +160,25 @@ impl<T: AddIn> AddInWrapper for AddInContainer<T>{
|
||||
param_desc.writable
|
||||
}
|
||||
|
||||
fn get_n_methods(&self) -> usize{
|
||||
fn get_n_methods(&self) -> usize {
|
||||
self.add_in.list_functions().len()
|
||||
}
|
||||
|
||||
fn find_method(&self, name: &[u16]) -> Option<usize>{
|
||||
self.add_in.list_functions().iter().position(|x| x.name == name)
|
||||
fn find_method(&self, name: &[u16]) -> Option<usize> {
|
||||
self.add_in
|
||||
.list_functions()
|
||||
.iter()
|
||||
.position(|x| x.names.contains(&name))
|
||||
}
|
||||
|
||||
fn get_method_name(&self, num: usize, alias: usize) -> Option<&'static [u16]>{
|
||||
fn get_method_name(&self, num: usize, alias: usize) -> Option<&'static [u16]> {
|
||||
self.add_in
|
||||
.list_functions()
|
||||
.get(num)
|
||||
.map(|x| x.name)
|
||||
.or_else(|| self.add_in.list_functions().get(alias).map(|x| x.name))
|
||||
.map(|x| x.names[0])
|
||||
}
|
||||
|
||||
fn get_n_params(&self, num: usize) -> usize{
|
||||
fn get_n_params(&self, num: usize) -> usize {
|
||||
let binding = self.add_in.list_functions();
|
||||
let Some(func_desc) = binding.get(num) else {
|
||||
return 0
|
||||
@ -186,23 +191,23 @@ impl<T: AddIn> AddInWrapper for AddInContainer<T>{
|
||||
method_num: usize,
|
||||
param_num: usize,
|
||||
value: ReturnValue,
|
||||
) -> bool{
|
||||
) -> bool {
|
||||
let func_desc_binding = self.add_in.list_functions();
|
||||
let Some(func_desc) = func_desc_binding.get(method_num) else {
|
||||
return false
|
||||
};
|
||||
let Some(default_value_option) = func_desc.default_values.get(param_num) else {
|
||||
return false
|
||||
};
|
||||
};
|
||||
let Some(default_value) = default_value_option else {
|
||||
return false
|
||||
};
|
||||
|
||||
match default_value {
|
||||
ParamValue::Bool(data) => value.set_bool(data.clone()),
|
||||
ParamValue::I32(data) => value.set_i32(data.clone()),
|
||||
ParamValue::F64(data) => value.set_f64(data.clone()),
|
||||
ParamValue::Date(data) => value.set_date(data.clone()),
|
||||
ParamValue::Bool(data) => value.set_bool(*data),
|
||||
ParamValue::I32(data) => value.set_i32(*data),
|
||||
ParamValue::F64(data) => value.set_f64(*data),
|
||||
ParamValue::Date(data) => value.set_date(*data),
|
||||
ParamValue::Str(data) => value.set_str(data),
|
||||
ParamValue::Blob(data) => value.set_blob(data),
|
||||
ParamValue::Empty => value.set_empty(),
|
||||
@ -210,7 +215,7 @@ impl<T: AddIn> AddInWrapper for AddInContainer<T>{
|
||||
true
|
||||
}
|
||||
|
||||
fn has_ret_val(&self, method_num: usize) -> bool{
|
||||
fn has_ret_val(&self, method_num: usize) -> bool {
|
||||
let func_desc_binding = self.add_in.list_functions();
|
||||
let Some(func_desc) = func_desc_binding.get(method_num) else {
|
||||
return false
|
||||
@ -218,15 +223,18 @@ impl<T: AddIn> AddInWrapper for AddInContainer<T>{
|
||||
func_desc.returns_val
|
||||
}
|
||||
|
||||
fn call_as_proc(&mut self, method_num: usize, params: &[ParamValue]) -> bool{
|
||||
fn call_as_proc(&mut self, method_num: usize, params: &[ParamValue]) -> bool {
|
||||
let func_desc_binding = self.add_in.list_functions();
|
||||
let Some(func_desc) = func_desc_binding.get(method_num) else {
|
||||
return false
|
||||
};
|
||||
|
||||
let name_string = String::from_utf16_lossy(func_desc.name);
|
||||
let name_string = String::from_utf16_lossy(func_desc.names[0]);
|
||||
let name_utf8 = name_string.as_str().trim_matches(char::from(0));
|
||||
let _result = self.add_in.call_function(name_utf8, params);
|
||||
let call_result = match self.add_in.call_function(name_utf8, params) {
|
||||
Ok(r) => r,
|
||||
Err(err) => return false,
|
||||
};
|
||||
true
|
||||
}
|
||||
|
||||
@ -234,33 +242,36 @@ impl<T: AddIn> AddInWrapper for AddInContainer<T>{
|
||||
&mut self,
|
||||
method_num: usize,
|
||||
params: &[ParamValue],
|
||||
val: ReturnValue
|
||||
) -> bool{
|
||||
val: ReturnValue,
|
||||
) -> bool {
|
||||
let func_desc_binding = self.add_in.list_functions();
|
||||
let Some(func_desc) = func_desc_binding.get(method_num) else {
|
||||
return false
|
||||
};
|
||||
if !func_desc.returns_val {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
let name_string = String::from_utf16_lossy(func_desc.name);
|
||||
let name_string = String::from_utf16_lossy(func_desc.names[0]);
|
||||
let name_utf8 = name_string.as_str().trim_matches(char::from(0));
|
||||
let Some(result) = self.add_in.call_function(name_utf8, params) else {return false};
|
||||
match result {
|
||||
let call_result = match self.add_in.call_function(name_utf8, params) {
|
||||
Ok(r) => r,
|
||||
Err(err) => return false,
|
||||
};
|
||||
let Some(return_value) = call_result else {return false};
|
||||
match return_value {
|
||||
ParamValue::Bool(data) => val.set_bool(data),
|
||||
ParamValue::I32(data) => val.set_i32(data),
|
||||
ParamValue::F64(data) => val.set_f64(data),
|
||||
ParamValue::Date(data) => val.set_date(data),
|
||||
ParamValue::Str(data) => val.set_str(data),
|
||||
ParamValue::Blob(data) => val.set_blob(data),
|
||||
ParamValue::Str(data) => val.set_str(&data),
|
||||
ParamValue::Blob(data) => val.set_blob(&data),
|
||||
ParamValue::Empty => val.set_empty(),
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
fn set_locale(&mut self, loc: &[u16]){
|
||||
}
|
||||
fn set_user_interface_language_code(&mut self, lang: &[u16]){}
|
||||
fn set_locale(&mut self, _loc: &[u16]) {}
|
||||
fn set_user_interface_language_code(&mut self, _lang: &[u16]) {}
|
||||
}
|
||||
|
||||
pub trait AddInWrapper {
|
||||
@ -291,7 +302,12 @@ pub trait AddInWrapper {
|
||||
) -> bool;
|
||||
fn has_ret_val(&self, method_num: usize) -> bool;
|
||||
fn call_as_proc(&mut self, method_num: usize, params: &[ParamValue]) -> bool;
|
||||
fn call_as_func(&mut self, method_num: usize, params: &[ParamValue], val: ReturnValue) -> bool;
|
||||
fn call_as_func(
|
||||
&mut self,
|
||||
method_num: usize,
|
||||
params: &[ParamValue],
|
||||
val: ReturnValue,
|
||||
) -> bool;
|
||||
fn set_locale(&mut self, loc: &[u16]);
|
||||
fn set_user_interface_language_code(&mut self, lang: &[u16]);
|
||||
}
|
||||
|
@ -1,15 +1,19 @@
|
||||
use std::ffi::{c_long, c_ushort};
|
||||
use utf16_lit::utf16_null;
|
||||
|
||||
use super::types::TVariant;
|
||||
use super::{types::TVariant, utils::os_string};
|
||||
|
||||
#[repr(C)]
|
||||
struct ConnectionVTable {
|
||||
dtor: usize,
|
||||
#[cfg(target_family = "unix")]
|
||||
dtor2: usize,
|
||||
add_error:
|
||||
unsafe extern "system" fn(&Connection, c_ushort, *const u16, *const u16, c_long) -> bool,
|
||||
add_error: unsafe extern "system" fn(
|
||||
&Connection,
|
||||
c_ushort,
|
||||
*const u16,
|
||||
*const u16,
|
||||
c_long,
|
||||
) -> bool,
|
||||
read: unsafe extern "system" fn(
|
||||
&Connection,
|
||||
*mut u16,
|
||||
@ -21,7 +25,8 @@ struct ConnectionVTable {
|
||||
register_profile_as: unsafe extern "system" fn(&Connection, *mut u16) -> bool,
|
||||
set_event_buffer_depth: unsafe extern "system" fn(&Connection, c_long) -> bool,
|
||||
get_event_buffer_depth: unsafe extern "system" fn(&Connection) -> c_long,
|
||||
external_event: unsafe extern "system" fn(&Connection, *mut u16, *mut u16, *mut u16) -> bool,
|
||||
external_event:
|
||||
unsafe extern "system" fn(&Connection, *mut u16, *mut u16, *mut u16) -> bool,
|
||||
clean_event_buffer: unsafe extern "system" fn(&Connection),
|
||||
set_status_line: unsafe extern "system" fn(&Connection, *mut u16) -> bool,
|
||||
reset_status_line: unsafe extern "system" fn(&Connection),
|
||||
@ -46,9 +51,9 @@ impl Connection {
|
||||
|
||||
pub fn external_event(&self, caller: &str, name: &str, data: &str) -> bool {
|
||||
unsafe {
|
||||
let caller_ptr = caller.encode_utf16().collect::<Vec<u16>>().as_mut_ptr();
|
||||
let name_ptr = name.encode_utf16().collect::<Vec<u16>>().as_mut_ptr();
|
||||
let data_ptr = data.encode_utf16().collect::<Vec<u16>>().as_mut_ptr();
|
||||
let caller_ptr = os_string(caller).as_mut_ptr();
|
||||
let name_ptr = os_string(name).as_mut_ptr();
|
||||
let data_ptr = os_string(data).as_mut_ptr();
|
||||
(self.vptr1.external_event)(self, caller_ptr, name_ptr, data_ptr)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::ffi::c_long;
|
||||
|
||||
use super::{connection::Connection, memory_manager::MemoryManager, This};
|
||||
use crate::add_in::{AddIn, AddInWrapper};
|
||||
use crate::add_in::AddInWrapper;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct InitDoneBaseVTable<T: AddInWrapper> {
|
||||
|
@ -232,7 +232,7 @@ unsafe extern "system" fn call_as_proc<T: AddInWrapper>(
|
||||
let component = this.get_component();
|
||||
let param_values = from_raw_parts(params, size_array as usize)
|
||||
.iter()
|
||||
.map(|x| ParamValue::from(x))
|
||||
.map(ParamValue::from)
|
||||
.collect::<Vec<ParamValue>>();
|
||||
|
||||
component
|
||||
@ -261,7 +261,7 @@ unsafe extern "system" fn call_as_func<T: AddInWrapper>(
|
||||
|
||||
let param_values = from_raw_parts(params, size_array as usize)
|
||||
.iter()
|
||||
.map(|x| ParamValue::from(x))
|
||||
.map(ParamValue::from)
|
||||
.collect::<Vec<ParamValue>>();
|
||||
|
||||
component
|
||||
|
@ -20,9 +20,9 @@ pub mod utils;
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub enum AttachType {
|
||||
CanAttachNotIsolated = 1,
|
||||
CanAttachIsolated,
|
||||
CanAttachAny,
|
||||
NotIsolated = 1,
|
||||
Isolated,
|
||||
Any,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -12,3 +12,22 @@ pub unsafe fn get_str<'a>(s: *const u16) -> &'a [u16] {
|
||||
let len = strlen(s);
|
||||
from_raw_parts(s, len)
|
||||
}
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
pub fn os_string(s: &str) -> Vec<u16> {
|
||||
s.encode_utf16().collect()
|
||||
}
|
||||
|
||||
#[cfg(target_family = "windows")]
|
||||
pub fn os_string(s: &str) -> Vec<u16> {
|
||||
let os_str = std::ffi::OsStr::new(s);
|
||||
std::os::windows::prelude::OsStrExt::encode_wide(os_str)
|
||||
.chain(Some(0).into_iter())
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn from_os_string(s: &[u16]) -> String {
|
||||
String::from_utf16_lossy(s)
|
||||
.trim_end_matches(char::from(0))
|
||||
.to_string()
|
||||
}
|
||||
|
130
src/lib.rs
130
src/lib.rs
@ -1,6 +1,16 @@
|
||||
pub mod add_in;
|
||||
mod ffi;
|
||||
|
||||
use crate::ffi::create_component;
|
||||
use add_in::{
|
||||
AddIn, AddInContainer, ComponentFuncDescription, ComponentPropDescription,
|
||||
};
|
||||
use ffi::{
|
||||
connection::Connection, destroy_component, types::ParamValue,
|
||||
utils::from_os_string, AttachType,
|
||||
};
|
||||
|
||||
use color_eyre::eyre::{eyre, Result};
|
||||
use std::{
|
||||
ffi::{c_int, c_long, c_void},
|
||||
sync::{
|
||||
@ -10,19 +20,19 @@ use std::{
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use add_in::{AddIn, AddInContainer, ComponentFuncDescription, ComponentPropDescription};
|
||||
use ffi::{connection::Connection, destroy_component, types::ParamValue, AttachType};
|
||||
use utf16_lit::utf16_null;
|
||||
|
||||
use crate::ffi::create_component;
|
||||
|
||||
pub static mut PLATFORM_CAPABILITIES: AtomicI32 = AtomicI32::new(-1);
|
||||
|
||||
struct AddInDescription {
|
||||
name: &'static [u16],
|
||||
connection: Arc<Option<&'static Connection>>,
|
||||
|
||||
functions: Vec<(
|
||||
ComponentFuncDescription,
|
||||
fn(&mut Self, &[ParamValue]) -> Result<Option<ParamValue>>,
|
||||
)>,
|
||||
|
||||
some_prop_container: i32,
|
||||
}
|
||||
|
||||
@ -31,21 +41,66 @@ impl AddInDescription {
|
||||
Self {
|
||||
name: &utf16_null!("MyAddIn"),
|
||||
connection: Arc::new(None),
|
||||
|
||||
functions: vec![
|
||||
(
|
||||
ComponentFuncDescription::new::<0>(
|
||||
vec![
|
||||
&utf16_null!("Итерировать"),
|
||||
&utf16_null!("Iterate"),
|
||||
],
|
||||
false,
|
||||
&[],
|
||||
),
|
||||
Self::iterate,
|
||||
),
|
||||
(
|
||||
ComponentFuncDescription::new::<1>(
|
||||
vec![&utf16_null!("Таймер"), &utf16_null!("Timer")],
|
||||
true,
|
||||
&[Some(ParamValue::I32(1000))],
|
||||
),
|
||||
Self::timer,
|
||||
),
|
||||
],
|
||||
|
||||
some_prop_container: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn iterate(&mut self) -> Result<(), &str> {
|
||||
fn iterate(
|
||||
&mut self,
|
||||
_params: &[ParamValue],
|
||||
) -> Result<Option<ParamValue>> {
|
||||
if self.some_prop_container >= 105 {
|
||||
return Err("container is too big");
|
||||
return Err(eyre!("Prop is too big"));
|
||||
}
|
||||
self.some_prop_container += 1;
|
||||
Ok(())
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn timer(&mut self, params: &[ParamValue]) -> Result<Option<ParamValue>> {
|
||||
let sleep_duration_ms = match params.get(0) {
|
||||
Some(ParamValue::I32(val)) => *val,
|
||||
_ => return Err(eyre!("Invalid parameter")),
|
||||
};
|
||||
|
||||
let connection = self.connection.clone();
|
||||
let name = from_os_string(self.name);
|
||||
thread::spawn(move || {
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
if let Some(connection) = &*connection {
|
||||
connection.external_event(&name, "TimerEnd", "OK");
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Some(ParamValue::I32(sleep_duration_ms)))
|
||||
}
|
||||
}
|
||||
|
||||
impl AddIn for AddInDescription {
|
||||
fn init(&mut self, interface: &'static Connection) -> bool {
|
||||
interface.set_event_buffer_depth(10);
|
||||
self.connection = Arc::new(Some(interface));
|
||||
self.some_prop_container = 100;
|
||||
true
|
||||
@ -55,33 +110,18 @@ impl AddIn for AddInDescription {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn call_function(&mut self, name: &str, params: &[ParamValue]) -> Option<ParamValue> {
|
||||
match name.trim_end() {
|
||||
"iterate" => {
|
||||
let Err(_e) = self.iterate() else { return None};
|
||||
None
|
||||
}
|
||||
"err" => {
|
||||
let Some(con) = self.connection.as_deref() else { return None };
|
||||
con.add_error(13, "err", "error that was bound to happen");
|
||||
None
|
||||
}
|
||||
"timer" => {
|
||||
let ParamValue::I32(duration_ms) = params[0] else { return None };
|
||||
let con_clone = self.connection.clone();
|
||||
thread::spawn(move || {
|
||||
let Some(con) = con_clone.as_deref() else { return };
|
||||
if duration_ms <= 0 {
|
||||
return;
|
||||
}
|
||||
thread::sleep(Duration::from_millis(duration_ms as u64));
|
||||
con.external_event("timer", "timer", "timer");
|
||||
});
|
||||
fn call_function(
|
||||
&mut self,
|
||||
name: &str,
|
||||
params: &[ParamValue],
|
||||
) -> Result<Option<ParamValue>> {
|
||||
let func = self
|
||||
.functions
|
||||
.iter()
|
||||
.find(|(desc, _)| desc.str_names().iter().any(|n| n == name));
|
||||
|
||||
Some(ParamValue::I32(duration_ms))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
let Some(func) = func.map(|(_, callback)| callback) else { return Err(eyre!("No function with such name")) };
|
||||
func(self, params)
|
||||
}
|
||||
|
||||
fn get_parameter(&self, name: &str) -> Option<ParamValue> {
|
||||
@ -102,16 +142,8 @@ impl AddIn for AddInDescription {
|
||||
}
|
||||
}
|
||||
|
||||
fn list_functions(&self) -> Vec<ComponentFuncDescription> {
|
||||
vec![
|
||||
ComponentFuncDescription::new::<0>(&utf16_null!("iterate"), false, &[]),
|
||||
ComponentFuncDescription::new::<0>(&utf16_null!("err"), false, &[]),
|
||||
ComponentFuncDescription::new::<1>(
|
||||
&utf16_null!("timer"),
|
||||
true,
|
||||
&[Some(ParamValue::I32(0))],
|
||||
),
|
||||
]
|
||||
fn list_functions(&self) -> Vec<&ComponentFuncDescription> {
|
||||
self.functions.iter().map(|(desc, _)| desc).collect()
|
||||
}
|
||||
|
||||
fn list_parameters(&self) -> Vec<ComponentPropDescription> {
|
||||
@ -125,10 +157,14 @@ impl AddIn for AddInDescription {
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn GetClassObject(name: *const u16, component: *mut *mut c_void) -> c_long {
|
||||
pub unsafe extern "C" fn GetClassObject(
|
||||
name: *const u16,
|
||||
component: *mut *mut c_void,
|
||||
) -> c_long {
|
||||
match *name as u8 {
|
||||
b'1' => {
|
||||
let my_add_in_container = AddInContainer::new(AddInDescription::new());
|
||||
let my_add_in_container =
|
||||
AddInContainer::new(AddInDescription::new());
|
||||
create_component(component, my_add_in_container)
|
||||
}
|
||||
_ => 0,
|
||||
@ -158,5 +194,5 @@ pub unsafe extern "C" fn SetPlatformCapabilities(capabilities: c_int) -> c_int {
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn GetAttachType() -> AttachType {
|
||||
AttachType::CanAttachAny
|
||||
AttachType::Any
|
||||
}
|
||||
|
Reference in New Issue
Block a user