Raised This Month: $51 Target: $400
 12% 

Custom MMS Interfaces


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
CrimsonGT
Veteran Member
Join Date: Oct 2007
Location: Gainesville, FL
Old 11-19-2010 , 11:51   Custom MMS Interfaces
Reply With Quote #1

I've used the normal HL2SDK Interfaces for years, but never contemplated making my own before. Since I am constantly reusing the same code in each MMS plugin I do, I figured creating some Interfaces for handling/managing Menus/UserMessages/GameEvents/etc. wouldn't be a bad idea.

I am however a little confused on what the exact setup of Interfaces is. Just from looking around, it looks like you can use

g_SMAPI->MetaFactory(INTERFACE_NAME, NULL, NULL);

to get the interface pointer on the iface you create in another plugin, but I am not sure what else I need (such as the version defines, version names, and anything else such as how to expose it to other MMS plugins once its loaded and running). I didn't see anything on the Wiki regarding this (could have sworn I did a while back) so I would like any information on doing this.
CrimsonGT is offline
API
Veteran Member
Join Date: May 2006
Old 11-19-2010 , 13:30   Re: Custom MMS Interfaces
Reply With Quote #2

I am pretty sure that the interface system requires implementation of QueryInterface(). Creating a pointer to the interface is created within your plugin, then your QueryInterface() should return the pointer you create. I believe it is a simple string comparison. Let me know if you need more help, I know my explanation was kind of quick.
__________________
API is offline
Send a message via AIM to API
Keeper
Senior Member
Join Date: Nov 2006
Old 11-19-2010 , 13:36   Re: Custom MMS Interfaces
Reply With Quote #3

Are you looking to use one binary between all of your MMS plugins so you don't have to have that code in each one? Or are you looking for your own library that you can link into each plugin so you don't have to have rehash the same code over and over again?
Keeper is offline
CrimsonGT
Veteran Member
Join Date: Oct 2007
Location: Gainesville, FL
Old 11-19-2010 , 13:54   Re: Custom MMS Interfaces
Reply With Quote #4

I am looking to create a binary file, and expose specific customs functions via interfaces that I create. I actually never thought about doing this until I saw Voogru's hat extension/MMS plugin that does this, and I realized how nice that would be.
CrimsonGT is offline
API
Veteran Member
Join Date: May 2006
Old 11-19-2010 , 15:42   Re: Custom MMS Interfaces
Reply With Quote #5

An interface isn't anything fancy. Check this out, this is the file you would distribute:

IMyInterface.h
Code:
#define MYINTERFACE_VERSION "MYINTERFACE001" // Increment the version number any time you a) add a function or b) remove a function. If you neglect to do this, the virtual table will not match.

class IMyInterface
{
    public:
        // I forget if you need constructor/destructor, consider this my warning that you might need this:
        // virtual ~IMyInterface() = 0;
        virtual void FunctionA() = 0; // The "= 0" means the function is purely virtual. It MUST be overriden. Don't worry, this is shown later.
        virtual int FunctionB(int Param1, int Param2) = 0;
        virtual bool FunctionC() = 0;
};
Now in your plugin, you have to define the interface's true functionality.

MyInterface.h
Code:
class CMyInterface : public IMyInterface
{
    public:
        CInterface() {}
        ~CInterface() {}
        void FunctionA()
        {
            // Do something fancy.
        }
        int FunctionB(int P1, int P2)
        {
            return P1 + P2; // Just an example to show return value.
        }
        bool FunctionC()
        {
            // Do something fancy.
            return true; // or false, :P
        }
};

extern CMyInterface g_MyInterface;
You're also going to need to put this in a CPP file:
Code:
CMyInteface g_MyInterface;
Then you need to implement the QueryInterface, I think it is an optional member for the metamod plugin class:
Code:
void *MyPlugin::QueryInterface(const char *version_string)
{
    if(FStrEq(version_string, MYINTERFACE_VERSION))
    {
        return (void*)g_MyInterface;
    }
    return (void*)0;
}
The MetaFactory function actually calls every QueryInterface and uses the non-null result.

Something like this for any plugin that tries to use MyInterface...
Code:
#include "IMyInterface.h"

...

IMyInterface *theInterface = (IMyInterface*)MetaFactory(MYINTERFACE_VERSION);
if(theInterface)
{
    theInterface->FunctionA();
    int result 1 = theInterface->FunctionB(1, 2);
    bool result2 = theInterface->FunctionC();
}
else
{
    Msg("Failed to find interface!\n");
}
Good luck.
__________________
API is offline
Send a message via AIM to API
CrimsonGT
Veteran Member
Join Date: Oct 2007
Location: Gainesville, FL
Old 11-19-2010 , 17:03   Re: Custom MMS Interfaces
Reply With Quote #6

I was just looking for a recommendation as far as another MMS plugin that used a custom iface, but that is perfect, thank you.
CrimsonGT is offline
Chrisber
AlliedModders Donor
Join Date: Jul 2007
Location: localhost
Old 11-20-2010 , 11:22   Re: Custom MMS Interfaces
Reply With Quote #7

Hi,
one thing I don't understand is why you use different interface versions? If you, for example, have BLA_VER002, do you instantiate CBla001 and CBla002 and then pass that one that fits the version string? Or do I misunderstand something?

Thanks!
Chrisber is offline
API
Veteran Member
Join Date: May 2006
Old 11-20-2010 , 16:07   Re: Custom MMS Interfaces
Reply With Quote #8

The version number ensures proper virtual function index mapping. For example, if I released a new version of my interface with new functions, lets say FunctionD and FunctionE:

Code:
#define MYINTERFACE_VERSION "MYINTERFACE002"

class IMyInterface
{
    public:
        // I forget if you need constructor/destructor, consider this my warning that you might need this:
        // virtual ~IMyInterface() = 0;
        virtual void FunctionA() = 0; // The "= 0" means the function is purely virtual. It MUST be overriden. Don't worry, this is shown later.
        virtual int FunctionB(int Param1, int Param2) = 0;
        virtual bool FunctionC() = 0;
        // The following functions were added in version 2 of the interface.
        virtual void FunctionD() = 0;
        virtual void FunctionE() = 0;
};
Now, if someone was using a plugin that required FunctionD and FunctionE, but it hasn't been updated, then their version 001 will not match the instance of 002 that exists. The plugin using your interface would not get a valid result from the meta factory. Here is an example.
Code:
if(StrEqual("INTERFACE_001", "INTERFACE_002")) {
// not true
}
else
{
    return NULL;
}
This is a good behavior. Without matching versions there is no way to ensure that the virtual table matches, and any calls to FunctionD or FunctionE would result in crashes.
__________________
API is offline
Send a message via AIM to API
BAILOPAN
Join Date: Jan 2004
Old 11-20-2010 , 16:28   Re: Custom MMS Interfaces
Reply With Quote #9

FWIW, SourceMod exposes its extension system through MM:S, so you can use MM:S plugins as if they were also extensions.
__________________
egg
BAILOPAN is offline
Chrisber
AlliedModders Donor
Join Date: Jul 2007
Location: localhost
Old 11-21-2010 , 07:10   Re: Custom MMS Interfaces
Reply With Quote #10

Thanks! And when exactly I need to add a pure virtual destructor? If I'm informed correctly, it is not possible to instantiate abstract classes, so it shouldn't matter if it has a constructor/destructor?!
Chrisber is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 01:15.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode