Skip to content

Commit

Permalink
Merge pull request #145 from Rantanen/com-module
Browse files Browse the repository at this point in the history
Support for `com_module!(..)`
  • Loading branch information
Rantanen authored Nov 7, 2019
2 parents f532478 + dff0219 commit 710f50a
Show file tree
Hide file tree
Showing 25 changed files with 353 additions and 285 deletions.
27 changes: 23 additions & 4 deletions intercom-attributes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,24 +106,43 @@ pub fn com_class(attr: TokenStream, tokens: TokenStream) -> TokenStream
}
}

/// Defines a COM library sub-module.
///
/// ```rust,ignore
/// com_module!(items...)]
/// ```
///
/// - `items` - List of items contained in this module.
///
/// The macro results in the implementation of the object creation
/// infrastructure that allows external clients to load the library and
/// instantiate the specified types.
#[proc_macro]
pub fn com_module(args: TokenStream) -> TokenStream
{
match expand_com_module(args, false) {
Ok(t) => t,
Err(e) => panic!("{}", e),
}
}

/// Defines the COM library.
///
/// ```rust,ignore
/// com_library!( libid = "...", classes...)]
/// com_library!( libid = "...", items...)]
/// ```
///
/// - `libid` - A unique ID that specifies the current intercom library.
/// Optional, the libid is generated randomly if omitted.
/// - `classes` - List of intercom classes that can be constructed by the
/// clients.
/// - `items` - List of items contained in this library.
///
/// The macro results in the implementation of the object creation
/// infrastructure that allows external clients to load the library and
/// instantiate the specified types.
#[proc_macro]
pub fn com_library(args: TokenStream) -> TokenStream
{
match expand_com_library(args) {
match expand_com_module(args, true) {
Ok(t) => t,
Err(e) => panic!("{}", e),
}
Expand Down
4 changes: 2 additions & 2 deletions intercom-attributes/tests/data/macro/com_library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ pub(crate) fn get_intercom_coclass_info_for_SimpleType() -> intercom::typelib::T

com_library!(
libid = "00000000-0000-0000-0000-000000000000",
some::path::Type,
SimpleType );
class some::path::Type,
class SimpleType );
102 changes: 60 additions & 42 deletions intercom-attributes/tests/data/macro/com_library.rs.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@ pub(crate) fn get_intercom_coclass_info_for_SimpleType() -> intercom::typelib::T
unsafe { MaybeUninit::uninit().assume_init() }
}

#[allow(dead_code)]
#[doc(hidden)]
pub unsafe fn __get_module_class_factory(
rclsid: intercom::REFCLSID,
riid: intercom::REFIID,
pout: *mut intercom::RawComPtr,
) -> Option<intercom::raw::HRESULT> {
match *rclsid {
some::path::CLSID_Type => {
return Some(intercom::ClassFactory::<some::path::Type>::create(
riid, pout,
))
}
CLSID_SimpleType => return Some(intercom::ClassFactory::<SimpleType>::create(riid, pout)),
_ => {}
};
None
}
#[no_mangle]
#[allow(non_snake_case)]
#[allow(dead_code)]
Expand All @@ -34,53 +52,42 @@ pub unsafe extern "system" fn DllGetClassObject(
riid: intercom::REFIID,
pout: *mut intercom::RawComPtr,
) -> intercom::raw::HRESULT {
let mut com_struct =
intercom::ComBox::new(intercom::ClassFactory::new(rclsid, |clsid| match *clsid {
self::some::path::CLSID_Type => {
Ok(intercom::ComBoxData::new(some::path::Type::new()) as intercom::RawComPtr)
}
self::CLSID_SimpleType => {
Ok(intercom::ComBoxData::new(SimpleType::new()) as intercom::RawComPtr)
}
intercom::alloc::CLSID_Allocator => Ok(intercom::ComBoxData::new(
intercom::alloc::Allocator::default(),
) as intercom::RawComPtr),
intercom::error::CLSID_ErrorStore => Ok(intercom::ComBoxData::new(
intercom::error::ErrorStore::default(),
) as intercom::RawComPtr),
_ => Err(intercom::raw::E_NOINTERFACE),
}));
intercom::ComBoxData::query_interface(com_struct.as_mut(), riid, pout);
intercom::raw::S_OK
if let Some(hr) = __get_module_class_factory(rclsid, riid, pout) {
return hr;
}
if let Some(hr) = intercom::__get_module_class_factory(rclsid, riid, pout) {
return hr;
}
intercom::raw::E_CLASSNOTAVAILABLE
}
pub(crate) fn get_intercom_typelib() -> intercom::typelib::TypeLib {
let types = <[_]>::into_vec(box [
<intercom::alloc::Allocator as intercom::attributes::HasTypeInfo>::gather_type_info(),
<intercom::error::ErrorStore as intercom::attributes::HasTypeInfo>::gather_type_info(),
pub fn __gather_module_types() -> Vec<intercom::typelib::TypeInfo> {
<[_]>::into_vec(box [
<some::path::Type as intercom::attributes::HasTypeInfo>::gather_type_info(),
<SimpleType as intercom::attributes::HasTypeInfo>::gather_type_info(),
])
.into_iter()
.flatten()
.collect::<Vec<_>>();
intercom::typelib::TypeLib::__new(
.collect()
}
#[no_mangle]
pub unsafe extern "system" fn IntercomTypeLib(
type_system: intercom::type_system::TypeSystemName,
out: *mut intercom::RawComPtr,
) -> intercom::raw::HRESULT {
let mut tlib = intercom::ComBox::new(intercom::typelib::TypeLib::__new(
"TestLib".into(),
intercom::GUID {
data1: 0u32,
data2: 0u16,
data3: 0u16,
data4: [0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8],
},
"1.0".into(),
types,
)
}
#[no_mangle]
pub unsafe extern "system" fn IntercomTypeLib(
type_system: intercom::type_system::TypeSystemName,
out: *mut intercom::RawComPtr,
) -> intercom::raw::HRESULT {
let mut tlib = intercom::ComBox::new(get_intercom_typelib());
"0.1".into(),
intercom::__gather_module_types()
.into_iter()
.chain(__gather_module_types())
.collect(),
));
let rc = intercom::ComRc::<intercom::typelib::IIntercomTypeLib>::from(&tlib);
let itf = intercom::ComRc::detach(rc);
*out = match type_system {
Expand All @@ -107,13 +114,24 @@ pub unsafe extern "system" fn IntercomListClassObjects(
if pclsids.is_null() {
return intercom::raw::E_POINTER;
}
static AVAILABLE_CLASSES: [::intercom::CLSID; 4usize] = [
some::path::CLSID_Type,
CLSID_SimpleType,
intercom::alloc::CLSID_Allocator,
intercom::error::CLSID_ErrorStore,
];
*pcount = 4usize;
*pclsids = AVAILABLE_CLASSES.as_ptr();
static mut AVAILABLE_CLASSES: Option<Vec<intercom::CLSID>> = None;
static INIT_AVAILABLE_CLASSES: std::sync::Once = std::sync::Once::new();
INIT_AVAILABLE_CLASSES.call_once(|| unsafe {
AVAILABLE_CLASSES = Some(
__gather_module_types()
.into_iter()
.chain(intercom::__gather_module_types())
.filter_map(|ty| match ty {
intercom::typelib::TypeInfo::Class(cls) => Some(cls.clsid.clone()),
_ => None,
})
.collect(),
);
});
let available_classes = AVAILABLE_CLASSES
.as_ref()
.expect("AVAILABLE_CLASSES was not initialized");
*pcount = available_classes.len();
*pclsids = available_classes.as_ptr();
intercom::raw::S_OK
}
20 changes: 17 additions & 3 deletions intercom-attributes/tests/data/ui/multiple-mods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod interface {

mod class {
#[intercom::com_class(MyStruct, crate::interface::MyInterface)]
#[derive(Default)]
pub struct MyStruct;
}

Expand All @@ -24,12 +25,25 @@ mod class_impl {
#[intercom::com_impl]
#[intercom::com_interface]
impl crate::class::MyStruct {
pub fn new() -> Self { Self }

fn struct_method(&self) -> u32 { 0 }
}
}

mod submodule {
intercom::com_module!(
class SubmoduleClass
);

#[intercom::com_class(Self)]
#[derive(Default)]
pub struct SubmoduleClass;

#[intercom::com_interface]
#[intercom::com_impl]
impl SubmoduleClass {}
}

intercom::com_library!(
class::MyStruct
class class::MyStruct,
module submodule,
);
Loading

0 comments on commit 710f50a

Please sign in to comment.