dx_core 0.3.0

Core functionality required by all the dx-rs crates. dx-rs is a DirectX wrapper for rust.
Documentation
/*
 * Copyright 2015 Joshua R. Rodgers
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 #![macro_use]

use std::ptr::null_mut;
use iid::HasIID;
use com_ref::ComRef;
use com_object::ComObject;

#[repr(C)]
pub struct UnknownVtable {
    query_interface: extern "stdcall" fn(*const Unknown, *const ::iid::IID, *mut *const Unknown) -> i32,
    add_ref: extern "stdcall" fn(*const Unknown) -> u32,
    release: extern "stdcall" fn(*const Unknown) -> u32
}

#[repr(C)]
pub struct Unknown {
    vtable: *const UnknownVtable
}

impl_iid! { Unknown : 0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }
impl_com_object! { Unknown : UnknownVtable }
unsafe impl Send for Unknown {}

pub trait IUnknown {
    fn query_interface<T>(&self) -> ::com::HResult<ComRef<T>> where T: IUnknown + HasIID;

    #[doc(hidden)]
    fn add_ref(&self) -> u32;

    #[doc(hidden)]
    fn release(&self) -> u32;
}

impl<TComObject: ComObject<UnknownVtable>> IUnknown for TComObject {
    fn query_interface<T>(&self) -> ::com::HResult<ComRef<T>> where T: IUnknown + HasIID {
        let mut interface: *const Unknown = null_mut();
        let result = (self.vtable().query_interface)(self.this(), <T as HasIID>::iid(), &mut interface);

        wrap_result! { result => ComRef::new(interface as *const T) }
    }

    fn add_ref(&self) -> u32 {
        (self.vtable().add_ref)(self.this())
    }

    fn release(&self) -> u32 {
        (self.vtable().release)(self.this())
    }
}