mirror of
https://github.com/Bayselonarrend/OpenIntegrations.git
synced 2025-01-12 04:34:10 +02:00
Правка структуры компонент, компонента TCP сервера
This commit is contained in:
parent
bcd825b147
commit
c2826a8b40
118
src/addins/tcp_server/Cargo.lock
generated
Normal file
118
src/addins/tcp_server/Cargo.lock
generated
Normal file
@ -0,0 +1,118 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addin1c"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef34e8b7ff4c43e87491a4cc30a4779a9f67c50db43378a36362c7a56246e05b"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
"utf16_lit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "opi_addin"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"addin1c",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.216"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.216"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
|
||||
[[package]]
|
||||
name = "utf16_lit"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14706d2a800ee8ff38c1d3edb873cd616971ea59eb7c0d046bb44ef59b06a1ae"
|
17
src/addins/tcp_server/Cargo.toml
Normal file
17
src/addins/tcp_server/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "opi_addin"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[profile.release]
|
||||
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]
|
||||
addin1c = "0.5.0"
|
||||
serde_json = "1.0.133"
|
7
src/addins/tcp_server/MANIFEST.XML
Normal file
7
src/addins/tcp_server/MANIFEST.XML
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<bundle xmlns='http://v8.1c.ru/8.2/addin/bundle' name='OPIADDIN'>
|
||||
<component os='Windows' path='AddIn_x86_windows.dll' type='native' arch='i386' />
|
||||
<component os='Windows' path='AddIn_x64_windows.dll' type='native' arch='x86_64' />
|
||||
<component os='Linux' path='AddIn_x86_linux.so' type='native' arch='i386' />
|
||||
<component os='Linux' path='AddIn_x64_linux.so' type='native' arch='x86_64' />
|
||||
</bundle>
|
63
src/addins/tcp_server/release.bat
Normal file
63
src/addins/tcp_server/release.bat
Normal file
@ -0,0 +1,63 @@
|
||||
@echo off
|
||||
|
||||
:: Установить переменную
|
||||
set LIB_NAME=opi_addin
|
||||
set OPENSSL_DIR=C:\msys64\mingw64
|
||||
set OPENSSL_LIB_DIR=%OPENSSL_DIR%\lib
|
||||
set OPENSSL_INCLUDE_DIR=%OPENSSL_DIR%\include
|
||||
|
||||
|
||||
:: Перейти в директорию проекта
|
||||
cd /d "%~dp0"
|
||||
|
||||
:: Создать папку для артефактов
|
||||
set OUTPUT_DIR=artifacts
|
||||
if not exist "%OUTPUT_DIR%" mkdir "%OUTPUT_DIR%"
|
||||
|
||||
:: Сборка для x86_64-pc-windows-msvc
|
||||
cargo build --release --target x86_64-pc-windows-msvc
|
||||
if errorlevel 1 goto :error
|
||||
|
||||
:: Сборка для x86_64-unknown-linux-gnu
|
||||
cargo zigbuild --release --target x86_64-unknown-linux-gnu
|
||||
if errorlevel 1 goto :error
|
||||
|
||||
:: Сборка для i686-pc-windows-msvc
|
||||
cargo build --release --target i686-pc-windows-msvc
|
||||
if errorlevel 1 goto :error
|
||||
|
||||
:: Сборка для i686-unknown-linux-gnu
|
||||
cargo zigbuild --release --target i686-unknown-linux-gnu
|
||||
if errorlevel 1 goto :error
|
||||
|
||||
:: Копирование файлов .dll и .so
|
||||
copy /y target\x86_64-pc-windows-msvc\release\%LIB_NAME%.dll "%OUTPUT_DIR%\AddIn_x64_windows.dll"
|
||||
if errorlevel 1 goto :error
|
||||
|
||||
copy /y target\i686-pc-windows-msvc\release\%LIB_NAME%.dll "%OUTPUT_DIR%\AddIn_x86_windows.dll"
|
||||
if errorlevel 1 goto :error
|
||||
|
||||
copy /y target\x86_64-unknown-linux-gnu\release\lib%LIB_NAME%.so "%OUTPUT_DIR%\AddIn_x64_linux.so"
|
||||
if errorlevel 1 goto :error
|
||||
|
||||
copy /y target\i686-unknown-linux-gnu\release\lib%LIB_NAME%.so "%OUTPUT_DIR%\AddIn_x86_linux.so"
|
||||
if errorlevel 1 goto :error
|
||||
|
||||
copy /y MANIFEST.XML "%OUTPUT_DIR%\MANIFEST.XML"
|
||||
if errorlevel 1 goto :error
|
||||
|
||||
:: Архивация
|
||||
set ZIP_NAME=addin.zip
|
||||
powershell -Command "Compress-Archive -Path '%OUTPUT_DIR%\*' -Force -DestinationPath '%ZIP_NAME%'"
|
||||
if errorlevel 1 goto :error
|
||||
|
||||
if exist "%OUTPUT_DIR%" (
|
||||
rmdir /S /Q "%OUTPUT_DIR%"
|
||||
)
|
||||
|
||||
@echo Build and packaging completed successfully.
|
||||
exit /b 0
|
||||
|
||||
:error
|
||||
@echo An error occurred during the build or packaging process.
|
||||
exit /b 1
|
101
src/addins/tcp_server/src/component/methods.rs
Normal file
101
src/addins/tcp_server/src/component/methods.rs
Normal file
@ -0,0 +1,101 @@
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::io::{Read, Write};
|
||||
use std::time::Instant;
|
||||
use serde_json::json;
|
||||
use crate::component::AddIn;
|
||||
|
||||
pub enum ServerEvent {
|
||||
NewConnection(String),
|
||||
MessageReceived(String, Vec<u8>),
|
||||
}
|
||||
|
||||
pub fn start_server(addin: &mut AddIn) -> String {
|
||||
|
||||
let addr = format!("0.0.0.0:{}", addin.port);
|
||||
let listener = TcpListener::bind(&addr);
|
||||
|
||||
match listener {
|
||||
Ok(listener) => {
|
||||
|
||||
let sender = addin.sender.clone();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
for stream in listener.incoming() {
|
||||
if let Ok(mut stream) = stream {
|
||||
|
||||
let addr = stream.peer_addr().unwrap().to_string();
|
||||
sender.send(ServerEvent::NewConnection(addr.clone())).unwrap();
|
||||
let sender = sender.clone();
|
||||
std::thread::spawn(move || {
|
||||
let mut buffer = [0; 1024];
|
||||
while let Ok(bytes_read) = stream.read(&mut buffer) {
|
||||
if bytes_read == 0 {
|
||||
break;
|
||||
}
|
||||
sender
|
||||
.send(ServerEvent::MessageReceived(
|
||||
addr.clone(),
|
||||
buffer[..bytes_read].to_vec(),
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
"Success".to_string()
|
||||
}
|
||||
Err(e) => e.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn await_connections(addin: &mut AddIn, timeout: i32) -> String {
|
||||
let start_time = Instant::now();
|
||||
let mut active_connections = Vec::new();
|
||||
|
||||
while start_time.elapsed().as_secs() < timeout as u64 {
|
||||
if let Ok(event) = addin.receiver.try_recv() {
|
||||
match event {
|
||||
ServerEvent::NewConnection(addr) => {
|
||||
active_connections.push(addr.clone());
|
||||
addin.connections.insert(addr, TcpStream::connect("127.0.0.1:0").unwrap());
|
||||
}
|
||||
ServerEvent::MessageReceived(addr, _data) => {
|
||||
if !active_connections.contains(&addr) {
|
||||
active_connections.push(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
|
||||
json!(active_connections).to_string()
|
||||
}
|
||||
|
||||
pub fn receive_message(addin: &mut AddIn, addr: &str) -> Vec<u8> {
|
||||
if let Some(stream) = addin.connections.get_mut(addr) {
|
||||
let mut buffer = [0; 1024];
|
||||
if let Ok(bytes_read) = stream.read(&mut buffer) {
|
||||
if bytes_read > 0 {
|
||||
return buffer[..bytes_read].to_vec();
|
||||
}
|
||||
}
|
||||
}
|
||||
vec![]
|
||||
}
|
||||
|
||||
pub fn send_response(addin: &mut AddIn, addr: &str, data: &[u8]) -> String {
|
||||
if let Some(stream) = addin.connections.get_mut(addr) {
|
||||
if stream.write_all(data).is_ok() {
|
||||
return "Success".to_string();
|
||||
}
|
||||
}
|
||||
"Failed to send response".to_string()
|
||||
}
|
||||
|
||||
pub fn stop(addin: &mut AddIn) -> String {
|
||||
addin.connections.clear();
|
||||
"Success".to_string()
|
||||
}
|
108
src/addins/tcp_server/src/component/mod.rs
Normal file
108
src/addins/tcp_server/src/component/mod.rs
Normal file
@ -0,0 +1,108 @@
|
||||
mod methods;
|
||||
|
||||
use addin1c::{name, Variant};
|
||||
use crate::core::getset;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::net::TcpStream;
|
||||
use std::sync::mpsc::{Sender, Receiver};
|
||||
use self::methods::{ServerEvent};
|
||||
|
||||
|
||||
// МЕТОДЫ КОМПОНЕНТЫ -------------------------------------------------------------------------------
|
||||
|
||||
// Синонимы
|
||||
pub const METHODS: &[&[u16]] = &[
|
||||
name!("Start"),
|
||||
name!("Await"),
|
||||
name!("ReceiveMessage"),
|
||||
name!("SendResponse"),
|
||||
name!("Stop"),
|
||||
|
||||
];
|
||||
|
||||
// Число параметров функций компоненты
|
||||
pub fn get_params_amount(num: usize) -> usize {
|
||||
match num {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 1,
|
||||
3 => 2,
|
||||
4 => 0,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
// Соответствие функций Rust функциям компоненты
|
||||
// Вызовы должны быть обернуты в Box::new
|
||||
pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn getset::ValueType> {
|
||||
|
||||
match num {
|
||||
|
||||
0 => Box::new(methods::start_server(obj)),
|
||||
1 => {
|
||||
let timeout = params[0].get_i32().unwrap_or(0);
|
||||
Box::new(methods::await_connections(obj, timeout))
|
||||
}
|
||||
2 => {
|
||||
let addr = params[0].get_string().unwrap_or("".to_string());
|
||||
Box::new(methods::receive_message(obj, &addr))
|
||||
}
|
||||
3 =>{
|
||||
let empty_array: [u8; 0] = [];
|
||||
|
||||
let addr = params[0].get_string().unwrap_or("".to_string());
|
||||
let data = params[1].get_blob().unwrap_or(&empty_array);
|
||||
|
||||
Box::new(methods::send_response(obj, &addr, data))
|
||||
}
|
||||
4 => Box::new(methods::stop(obj)),
|
||||
_ => Box::new(false), // Неверный номер команды
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
// ПОЛЯ КОМПОНЕНТЫ ---------------------------------------------------------------------------------
|
||||
|
||||
// Синонимы
|
||||
pub const PROPS: &[&[u16]] = &[
|
||||
name!("Port")
|
||||
];
|
||||
|
||||
|
||||
pub struct AddIn {
|
||||
pub port: i32,
|
||||
pub connections: HashMap<String, TcpStream>,
|
||||
pub sender: Sender<ServerEvent>,
|
||||
pub receiver: Receiver<ServerEvent>,
|
||||
}
|
||||
|
||||
impl AddIn {
|
||||
pub fn new() -> Self {
|
||||
let (sender, receiver) = std::sync::mpsc::channel();
|
||||
AddIn {
|
||||
port: 0,
|
||||
connections: HashMap::new(),
|
||||
sender,
|
||||
receiver,
|
||||
}
|
||||
}
|
||||
pub fn get_field_ptr(&self, index: usize) -> *const dyn getset::ValueType {
|
||||
match index {
|
||||
0 => &self.port as &dyn getset::ValueType as *const _,
|
||||
_ => panic!("Index out of bounds"),
|
||||
}
|
||||
}
|
||||
pub fn get_field_ptr_mut(&mut self, index: usize) -> *mut dyn getset::ValueType { self.get_field_ptr(index) as *mut _ }
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
// Обработка удаления объекта
|
||||
impl Drop for AddIn {
|
||||
fn drop(&mut self) {
|
||||
methods::stop(self);
|
||||
}
|
||||
}
|
78
src/addins/tcp_server/src/core/getset.rs
Normal file
78
src/addins/tcp_server/src/core/getset.rs
Normal file
@ -0,0 +1,78 @@
|
||||
use addin1c::{Variant, Tm};
|
||||
|
||||
|
||||
pub trait ValueType {
|
||||
fn get_value(&self, val: &mut Variant) -> bool;
|
||||
fn set_value(&mut self, val: &Variant);
|
||||
}
|
||||
|
||||
// Реализация для i32
|
||||
impl ValueType for i32 {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
val.set_i32(*self);
|
||||
true
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_i32().unwrap_or(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Реализация для f64
|
||||
impl ValueType for f64 {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
val.set_f64(*self);
|
||||
true
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_f64().unwrap_or(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
// Реализация для bool
|
||||
impl ValueType for bool {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
val.set_bool(*self);
|
||||
true
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_bool().unwrap_or(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Реализация для tm
|
||||
impl ValueType for Tm {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
val.set_date(*self);
|
||||
true
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_date().unwrap_or(Tm::default());
|
||||
}
|
||||
}
|
||||
|
||||
// Реализация для String
|
||||
impl ValueType for String {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
let s: Vec<u16> = self.encode_utf16().collect();
|
||||
val.set_str1c(s.as_slice()).is_ok()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_string().unwrap_or("".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// Реализация для Vec<u8>
|
||||
impl ValueType for Vec<u8> {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
val.set_blob(self.as_slice()).is_ok()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_blob().unwrap_or(&[]).to_vec()
|
||||
}
|
||||
}
|
53
src/addins/tcp_server/src/core/mod.rs
Normal file
53
src/addins/tcp_server/src/core/mod.rs
Normal file
@ -0,0 +1,53 @@
|
||||
pub mod getset;
|
||||
|
||||
use addin1c::{name, RawAddin, Variant};
|
||||
|
||||
use crate::component::METHODS;
|
||||
use crate::component::PROPS;
|
||||
use crate::component::get_params_amount;
|
||||
use crate::component::cal_func;
|
||||
use crate::component::AddIn;
|
||||
|
||||
// Определение класса
|
||||
impl RawAddin for AddIn {
|
||||
|
||||
fn register_extension_as(&mut self) -> &'static [u16] {
|
||||
name!("Main")
|
||||
}
|
||||
fn get_n_props(&mut self) -> usize {
|
||||
PROPS.len()
|
||||
}
|
||||
fn find_prop(&mut self, name: &[u16]) -> Option<usize> {
|
||||
PROPS.iter().position(|&x| x == name)
|
||||
}
|
||||
fn get_prop_name(&mut self, num: usize, _alias: usize) -> Option<&'static [u16]> { PROPS.get(num).copied() }
|
||||
fn get_prop_val(&mut self, num: usize, val: &mut Variant) -> bool {let field: &dyn getset::ValueType = &self[num]; field.get_value(val) }
|
||||
fn set_prop_val(&mut self, num: usize, val: &Variant) -> bool {let field: &mut dyn getset::ValueType = &mut self[num]; field.set_value(val); true }
|
||||
fn is_prop_readable(&mut self, _nm: usize) -> bool { true }
|
||||
fn is_prop_writable(&mut self, num: usize) -> bool { true }
|
||||
fn get_n_methods(&mut self) -> usize { METHODS.len() }
|
||||
fn find_method(&mut self, name: &[u16]) -> Option<usize> { METHODS.iter().position(|&x| x == name) }
|
||||
fn get_method_name(&mut self, num: usize, _alias: usize) -> Option<&'static [u16]> { METHODS.get(num).copied() }
|
||||
fn get_n_params(&mut self, num: usize) -> usize { get_params_amount(num) }
|
||||
fn get_param_def_value(&mut self, _method_num: usize, _param_num: usize, _value: Variant, ) -> bool { true }
|
||||
fn has_ret_val(&mut self, num: usize) -> bool { true }
|
||||
fn call_as_proc(&mut self, _num: usize, _params: &mut [Variant]) -> bool { false }
|
||||
fn call_as_func(&mut self, num: usize, params: &mut [Variant], ret_value: &mut Variant, ) -> bool { cal_func(self, num, params).get_value(ret_value) }
|
||||
|
||||
}
|
||||
|
||||
impl std::ops::Index<usize> for AddIn {
|
||||
type Output = dyn getset::ValueType;
|
||||
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
unsafe { &*self.get_field_ptr(index) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::IndexMut<usize> for AddIn {
|
||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||
unsafe { &mut *self.get_field_ptr_mut(index) }
|
||||
}
|
||||
}
|
||||
|
||||
|
48
src/addins/tcp_server/src/lib.rs
Normal file
48
src/addins/tcp_server/src/lib.rs
Normal file
@ -0,0 +1,48 @@
|
||||
pub mod component;
|
||||
mod core;
|
||||
|
||||
|
||||
use std::{
|
||||
ffi::{c_int, c_long, c_void},
|
||||
sync::atomic::{AtomicI32, Ordering},
|
||||
};
|
||||
|
||||
use component::AddIn;
|
||||
use addin1c::{create_component, destroy_component, name, AttachType};
|
||||
|
||||
pub static mut PLATFORM_CAPABILITIES: AtomicI32 = AtomicI32::new(-1);
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn GetClassObject(name: *const u16, component: *mut *mut c_void) -> c_long {
|
||||
|
||||
let addin = AddIn::new();
|
||||
create_component(component, addin)
|
||||
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long {
|
||||
destroy_component(component)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn GetClassNames() -> *const u16 {
|
||||
// small strings for performance
|
||||
name!("Main").as_ptr()
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn SetPlatformCapabilities(capabilities: c_int) -> c_int {
|
||||
PLATFORM_CAPABILITIES.store(capabilities, Ordering::Relaxed);
|
||||
3
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn GetAttachType() -> AttachType {
|
||||
AttachType::Any
|
||||
}
|
@ -60,4 +60,11 @@ impl AddIn {
|
||||
}
|
||||
pub fn get_field_ptr_mut(&mut self, index: usize) -> *mut dyn getset::ValueType { self.get_field_ptr(index) as *mut _ }
|
||||
}
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
// УНИЧТОЖЕНИЕ ОБЪЕКТА -----------------------------------------------------------------------------
|
||||
|
||||
// Обработка удаления объекта
|
||||
impl Drop for AddIn {
|
||||
fn drop(&mut self) {}
|
||||
}
|
@ -8,12 +8,6 @@ use crate::component::get_params_amount;
|
||||
use crate::component::cal_func;
|
||||
use crate::component::AddIn;
|
||||
|
||||
|
||||
// Обработка удаления объекта
|
||||
impl Drop for AddIn {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
// Определение класса
|
||||
impl RawAddin for AddIn {
|
||||
|
||||
|
@ -31,7 +31,7 @@ pub unsafe extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn GetClassNames() -> *const u16 {
|
||||
// small strings for performance
|
||||
name!("Client").as_ptr()
|
||||
name!("Main").as_ptr()
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
|
Loading…
Reference in New Issue
Block a user