Skip to content

Pycckue-Bnepeg/cpp-class

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cpp-class

adds ability to create structs and traits compatible with c++ virtual classes.

currently supports only multiple inheritance classes without any data. only virtual functions.

gcc only?

example

this has been written to support ragemp cpp sdk to develop plugins.

sdk repo at: https://github.com/ragemultiplayer/ragemp-cppsdk

class IEventHandler
{
    public:
        virtual IEntityHandler *GetEntityHandler();
        virtual IPlayerHandler *GetPlayerHandler();
        virtual IVehicleHandler *GetVehicleHandler();
        virtual IColshapeHandler *GetColshapeHandler();
        virtual ICheckpointHandler *GetCheckpointHandler();
        virtual IMarkerHandler *GetMarkerHandler();
        virtual IPickupHandler *GetPickupHandler();
        virtual ITickHandler *GetTickHandler();
        virtual ILocalEventHandler *GetLocalEventHandler();
        virtual IConnectionHandler *GetConnectionHandler();
        virtual IDebugHandler *GetDebugHandler();
        virtual IServerHandler *GetServerHandler();
        virtual IRpcHandler *GetRpcHandler();
};

class ITickHandler
{
    public:
        virtual void Tick();
};

// it would be like
class EventHandler: public IEventHandler, public ITickHandler {
    public:
        virtual ITickHandler *GetTickHandler() {
            return this;
        }

        // .....

        virtual void Tick() { std::cout << "tick!!!!" << std::endl; }
}

RAGE_API rage::IPlugin *InitializePlugin(rage::IMultiplayer *mp)
{
	mp->AddEventHandler(new EventHandler);
	return new rage::IPlugin;
}

rust version

use cpp_class::vtable;

// supports this:
// __cxxabiv1::__vmi_class_type_info
// __cxxabiv1::__class_type_info
#[vtable]
pub mod handler {

    // list of parents, it should be 2+
    // your struct can contain any data with any repr
    #[vtable::derive(IEventHandler, ITickHandler)]
    pub struct Handler {
        pub my_data: String,
        pub counter: u32,
    }

    // default abi is fastcall
    // type_name is a name of a class name defined at headers (or in a executable) (nul char is append by the macro)
    // no data
    #[vtable::virtual_class(abi = fastcall, type_name = "N4rage13IEventHandlerE")]
    trait IEventHandler {
        // no default impl at this moment
        // also destructors are not supported
        // returns bool because the return value is not used by ragemp (simple check if it is not 0)
        fn entity_handler(&mut self) -> bool;
        fn player_handler(&mut self) -> bool;
        fn vehicle_handler(&mut self) -> bool;
        fn colshape_handler(&mut self) -> bool;
        fn checkpoint_handler(&mut self) -> bool;
        fn unk_0(&mut self) -> bool;
        fn unk_1(&mut self) -> bool;
        fn tick_handler(&mut self) -> bool;
        fn local_event_handler(&mut self) -> bool;
        fn connection_handler(&mut self) -> bool;
        fn debug_handler(&mut self) -> bool;
        fn server_handler(&mut self) -> bool;
        fn rpc_handler(&mut self) -> bool;
    }

    #[vtable::virtual_class(abi = fastcall, type_name = "N4rage12ITickHandlerE")]
    trait ITickHandler {
        fn tick(&mut self);
    }

    impl IEventHandler for Handler {
        fn tick_handler(&mut self) -> bool {
            true
        }

        // ...
    }

    impl ITickHandler for Handler {
        fn tick(&mut self) {
            println!("tick! my_data {:?} prev_count {}", self.my_data, self.counter);
            self.counter += 1;
            println!("new {}", self.counter);
        }
    }
}

// definition of rage::PluginManager is omitted
#[no_mangle]
pub extern "C" fn InitializePlugin(mp: *mut rage::PluginManager) -> u64 {
    let object = handler::Handler {
        my_data: String::from("what?"),
        counter: 0,
    };

    // cpp_class::vtable generates make_boxed and from_boxed functions
    // from_boxed should be used to destroy an object
    // returns `RefHandler` pointer that contains vtables and points at the start
    let raw = handler::make_boxed(object);

    unsafe {
        ((*(*mp).vftable).add_event_handler)(mp, raw as *mut _);
    }

    return 1;
}

About

Macro to create cpp comp structs

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages