forked from ValveSoftware/halflife
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterface.h
More file actions
162 lines (116 loc) · 5.44 KB
/
interface.h
File metadata and controls
162 lines (116 loc) · 5.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// This header defines the interface convention used in the valve engine.
// To make an interface and expose it:
// 1. Derive from IBaseInterface.
// 2. The interface must be ALL pure virtuals, and have no data members.
// 3. Define a name for it.
// 4. In its implementation file, use EXPOSE_INTERFACE or EXPOSE_SINGLE_INTERFACE.
// Versioning
// There are two versioning cases that are handled by this:
// 1. You add functions to the end of an interface, so it is binary compatible with the previous interface. In this case,
// you need two EXPOSE_INTERFACEs: one to expose your class as the old interface and one to expose it as the new interface.
// 2. You update an interface so it's not compatible anymore (but you still want to be able to expose the old interface
// for legacy code). In this case, you need to make a new version name for your new interface, and make a wrapper interface and
// expose it for the old interface.
// JoshA: Everything uses this now.
#if 1
#include "tier1/interface.h"
#else
#error use proper interface only
#ifndef INTERFACE_H
#define INTERFACE_H
#if !defined ( _WIN32 )
#include <dlfcn.h> // dlopen,dlclose, et al
#include <unistd.h>
#define HMODULE void *
#define GetProcAddress dlsym
#define _snprintf snprintf
#endif
void *Sys_GetProcAddress( void *pModuleHandle, const char *pName );
// All interfaces derive from this.
class IBaseInterface
{
public:
virtual ~IBaseInterface() {}
};
#define CREATEINTERFACE_PROCNAME "CreateInterface"
typedef IBaseInterface* (*CreateInterfaceFn)(const char *pName, int *pReturnCode);
typedef IBaseInterface* (*InstantiateInterfaceFn)();
// Used internally to register classes.
class InterfaceReg
{
public:
InterfaceReg(InstantiateInterfaceFn fn, const char *pName);
public:
InstantiateInterfaceFn m_CreateFn;
const char *m_pName;
InterfaceReg *m_pNext; // For the global list.
static InterfaceReg *s_pInterfaceRegs;
};
// Use this to expose an interface that can have multiple instances.
// e.g.:
// EXPOSE_INTERFACE( CInterfaceImp, IInterface, "MyInterface001" )
// This will expose a class called CInterfaceImp that implements IInterface (a pure class)
// clients can receive a pointer to this class by calling CreateInterface( "MyInterface001" )
//
// In practice, the shared header file defines the interface (IInterface) and version name ("MyInterface001")
// so that each component can use these names/vtables to communicate
//
// A single class can support multiple interfaces through multiple inheritance
//
// Use this if you want to write the factory function.
#define EXPOSE_INTERFACE_FN(functionName, interfaceName, versionName) \
static InterfaceReg __g_Create##className##_reg(functionName, versionName);
#define EXPOSE_INTERFACE(className, interfaceName, versionName) \
static IBaseInterface* __Create##className##_interface() {return (interfaceName *)new className;}\
static InterfaceReg __g_Create##className##_reg(__Create##className##_interface, versionName );
// Use this to expose a singleton interface with a global variable you've created.
#define EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, globalVarName) \
static IBaseInterface* __Create##className##interfaceName##_interface() {return (IBaseInterface *)&globalVarName;}\
static InterfaceReg __g_Create##className##interfaceName##_reg(__Create##className##interfaceName##_interface, versionName);
// Use this to expose a singleton interface. This creates the global variable for you automatically.
#if !defined(_STATIC_LINKED) || !defined(_SUBSYSTEM)
#define EXPOSE_SINGLE_INTERFACE(className, interfaceName, versionName) \
static className __g_##className##_singleton; \
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, __g_##className##_singleton)
#else
#define EXPOSE_SINGLE_INTERFACE(className, interfaceName, versionName) \
namespace _SUBSYSTEM \
{ \
static className __g_##className##_singleton; \
} \
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, __g_##className##_singleton)
#endif
#ifdef WIN32
#define EXPORT_FUNCTION __declspec(dllexport)
#else
#define EXPORT_FUNCTION __attribute__ ((visibility("default")))
#endif
// This function is automatically exported and allows you to access any interfaces exposed with the above macros.
// if pReturnCode is set, it will return one of the following values
// extend this for other error conditions/code
enum
{
IFACE_OK = 0,
IFACE_FAILED
};
extern "C"
{
EXPORT_FUNCTION IBaseInterface* CreateInterface(const char *pName, int *pReturnCode);
};
extern CreateInterfaceFn Sys_GetFactoryThis( void );
//-----------------------------------------------------------------------------
// UNDONE: This is obsolete, use the module load/unload/get instead!!!
//-----------------------------------------------------------------------------
extern CreateInterfaceFn Sys_GetFactory( const char *pModuleName );
// load/unload components
class CSysModule;
//-----------------------------------------------------------------------------
// Load & Unload should be called in exactly one place for each module
// The factory for that module should be passed on to dependent components for
// proper versioning.
//-----------------------------------------------------------------------------
extern CSysModule *Sys_LoadModule( const char *pModuleName );
extern void Sys_UnloadModule( CSysModule *pModule );
extern CreateInterfaceFn Sys_GetFactory( CSysModule *pModule );
#endif
#endif // MSVC 6.0