sampgdk icon indicating copy to clipboard operation
sampgdk copied to clipboard

Preprocessor definition to disable any native function

Open IstuntmanI opened this issue 7 years ago • 6 comments

For example, I don't want to use functions like IsPlayerInRangeOfPoint, GetPlayer/VehicleDistanceFromPoint, VectorSize, etc. because they are being called through the AMX layer. There's no need for that, we can make faster alternatives in C++. In C++ we can make lots of separate files, so we may sometimes forget a default function call (instead of calling the faster alternative) in a small file when we definitely don't want that in any file at all. (example: we could use the default sampgdk::IsPlayerInRangeOfPoint instead of MyGameMode::IsPlayerInRangeOfPoint and the compiler won't warn us about that)

We should be able to add a preprocessor definition "SAMPGDK_NO_[FUNCTION]" and then its creation would be disabled in sampgdk.h/c, so we will receive an error if using a disabled function.

Example:

  • Preprocessor definition: "SAMPGDK_NO_ISPLAYERINRANGEOFPOINT" .
  • sampgdk.h:
// ...

/**
 * \ingroup natives
 * \see <a href="http://wiki.sa-mp.com/wiki/IsPlayerInRangeOfPoint">IsPlayerInRangeOfPoint on SA-MP Wiki</a>
 */
#ifndef SAMPGDK_NO_ISPLAYERINRANGEOFPOINT
SAMPGDK_NATIVE(bool, IsPlayerInRangeOfPoint(int playerid, float range, float x, float y, float z));
#endif

//...

#ifndef SAMPGDK_NO_ISPLAYERINRANGEOFPOINT
inline bool IsPlayerInRangeOfPoint(int playerid, float range, float x, float y, float z) {
  return sampgdk_IsPlayerInRangeOfPoint(playerid, range, x, y, z);
}
#endif

//...

#ifndef SAMPGDK_NO_ISPLAYERINRANGEOFPOINT
#undef  IsPlayerInRangeOfPoint
#define IsPlayerInRangeOfPoint sampgdk_IsPlayerInRangeOfPoint
#endif

//...
  • sampgdk.c:
// ...

#ifndef SAMPGDK_NO_ISPLAYERINRANGEOFPOINT
SAMPGDK_NATIVE(bool, IsPlayerInRangeOfPoint(int playerid, float range, float x, float y, float z)) {
  static AMX_NATIVE native;
  cell retval;
  cell params[6];
  sampgdk_log_debug("IsPlayerInRangeOfPoint(%d, %f, %f, %f, %f)", playerid, range, x, y, z);
  native = sampgdk_native_find_flexible("IsPlayerInRangeOfPoint", native);
  params[0] = 5 * sizeof(cell);
  params[1] = (cell)playerid;
  params[2] = amx_ftoc(range);
  params[3] = amx_ftoc(x);
  params[4] = amx_ftoc(y);
  params[5] = amx_ftoc(z);
  retval = native(sampgdk_fakeamx_amx(), params);
  return !!(retval);
}
#endif

//...

I checked the generate_code.py file and I think that this could be made pretty fast.

IstuntmanI avatar Jun 29 '17 23:06 IstuntmanI

You could do this the other way round. Instead of having a definition to not include the symbol, use #undef after the fact. If you are not using SAMPGDK_CPP_WRAPPERS and using namespace sampgdk;, they are created (as you posted) as:

#undef  IsPlayerInRangeOfPoint
#define IsPlayerInRangeOfPoint sampgdk_IsPlayerInRangeOfPoint

So just do:

#include <sampgdk/a_player.h>
#undef  IsPlayerInRangeOfPoint

Then define your own version. Put that in a header used to always include sampgdk and you have your protection.

Y-Less avatar Jul 29 '17 22:07 Y-Less

Well, doing that wouldn't allow alternatives in namespaces like MyNamespace::IsPlayerInRangeOfPoint, if including the declaration before sampGDK.

By the way, I am actually using SAMPGDK_CPP_WRAPPERS and not using using namespace sampgdk; .

IstuntmanI avatar Jul 31 '17 17:07 IstuntmanI

By the way, I am actually using SAMPGDK_CPP_WRAPPERS and not using using namespace sampgdk; .

That's quite the contradiction, by defining SAMPGDK_CPP_WRAPPERS, you enable the sampgdk namespace, containing the function defintions.

ikkentim avatar Jul 31 '17 20:07 ikkentim

That's not quite a contradiction. SAMPGDK_CPP_WRAPPERS enables the namespace, but you can have that and still not use using namespace sampgdk;, it just means you need to explicitly resolve every use as, say, sampgdk::SetPlayerPos.

Y-Less avatar Jul 31 '17 20:07 Y-Less

Yes, it CREATES the sampgdk namespace, so we can use sampgdk::SendClientMessage instead of sampgdk_SendClientMessage. If I would use using namespace sampgdk; I could use directly SendClientMessage. I think you got their meaning wrong.

IstuntmanI avatar Jul 31 '17 20:07 IstuntmanI

My bad, read @lstuntmanl 's message wrong, pretend I said nothing!

ikkentim avatar Jul 31 '17 20:07 ikkentim