I worked around these things, with help from your responses (thanks !) and now I came back with additional things:
--------------------------------------------------------
--------------------------------------------------------
Quote:
Originally Posted by WopsS
...
This is for AttachDynamicObjectToObject
Код:
const bool Object::AttachToObject(int32_t ID, int32_t AttachToID, float X, float Y, float Z, float RotationX, float RotationY, float RotationZ, bool SyncRotation)
{
static AMX_NATIVE Native = sampgdk::FindNative("AttachDynamicObjectToObject");
return !!sampgdk::InvokeNative(Native, "iiffffffb", ID, AttachToID, X, Y, Z, RotationX, RotationY, RotationZ, SyncRotation);
}
...
|
Thanks for these examples, you gave me an idea to use namespaces for plugins functions. For example, CreateDynamicObject from streamer now looks like Plugins::Streamer::Object::Create now (a bit too long, but perfectly organised). Here is how it looks like, for who wants to see it:
Код:
namespace Plugins
{
namespace Streamer
{
namespace Object
{
int Create( int modelid, float x, float y, float z, float rx, float ry, float rz, int worldid = -1, int interiorid = -1, int playerid = -1, float streamdistance = STREAMER_OBJECT_SD, float drawdistance = STREAMER_OBJECT_DD, int areaid = -1, int priority = 0 )
{
static AMX_NATIVE Native = sampgdk::FindNative( "CreateDynamicObject" );
return sampgdk::InvokeNative( Native, "iffffffiiiffii", modelid, x, y, z, rx, ry, rz, worldid, interiorid, playerid, streamdistance, drawdistance, areaid, priority );
}
};
};
};
--------------------------------------------------------
Quote:
Originally Posted by WopsS
I don't have anything in mind for mysql_pquery, but you can try to use a single parameter as a class or a struct.
|
A problem: I made this:
Код:
template< typename... Args >
const bool pquery( int connectionHandle, const char query[ ], const char callback[ ] = "", const char format[ ] = "", Args && ... args )
{
static AMX_NATIVE Native = sampgdk::FindNative( "mysql_pquery" );
std::string function_format = "isss";
for( int i = 0, s = std::strlen( format ); i < s; i ++ )
{
function_format += ( format[ i ] == 's' ? "s" : "r" );
}
return !!sampgdk::InvokeNative( Native, function_format.c_str( ), connectionHandle, query, callback, format, std::forward< Args >( args ) ... );
}
Код:
Plugins::MySQL::pquery( 1, "<query>", "Callback", "iii", &varint1, &varint2, &varint3 );
But the function is not called:
Quote:
Originally Posted by mysql_log.html
Log("00:19:31","mysql_pquery",4,"connection: 1, query: \"<query>\", callback: \"Callback\", format: \"iii\"",0);
Log("00:19:31","CMySQLQuery::Execute[OnQueryFinish]",4,"starting query execution",1);
Log("00:19:31","CMySQLQuery::Execute[Callback]",4,"starting query execution",1);
Log("00:19:31","CMySQLQuery::Execute[Callback]",4,"query was successfully executed within x.xxx milliseconds",1);
Log("00:19:31","CMySQLResult::CMySQLResult()",4,"c onstructor called",1);
|
OnPublicCall with the name of that Callback isn't called (I'm printing in console all calls with the parameters). I even added that callback in the .def file.
By the way, is it needed to add callbacks called by functions like mysql_pquery in the .def file ? Is it a problem of the MySQL, or I can solve this somehow ? I could really use some informations about this thing. Also, thanks for the idea of using &&, allowing me to pass both lvalues and rvalues, I just understood why you used that instead of pointers as arguments and "args ..." in InvokeNative.
--------------------------------------------------------
Quote:
Originally Posted by WopsS
When you call SetTimer you will pass a void* for parameters, in your function you need to know how to use that void*, that's why he is using a struct for that (you can use a class). This is the easy way. But if you want to use std::tuple go ahead, take a look here to see how you can achieve that.
|
Not that, I was asking if we can't make a more advanced timer system, using ProcessTick. Instead of passing some struct and doing retarded casts we could simply pass a std::tuple with a variable number of elements.
I actually did this, using variadic templates from newer C++ standards, which means that it is also type safe, as everything is known at compile time. Here is what it looks like:
Код:
Timers::SetTimerEx( TimerFunction, 1000, 0, std::make_tuple( playerid, 10.0, "hello" ) );
void TimerFunction( int timerid, std::tuple< int, float, char * > params )
{
int playerid = std::get< 0 >( params );
float posX = std::get< 1 >( params );
char * message = std::get< 2 >( params );
}
C++ compiler is really powerful. Maybe I'll release this timer system. It is based on Dan's timer system. It's a lot better than sampGDK's timer system.
--------------------------------------------------------
By the way, if anyone is interested in keeping to use the sscanf of ******, I also used these methods to call the sscanf function:
Код:
namespace Plugins
{
namespace SSCANF
{
template< typename... Args >
const int unformat( const char data[ ], const char format[ ], Args * ... args )
{
static AMX_NATIVE Native = sampgdk::FindNative( "sscanf" );
std::string function_format = "ss";
for( int i = 0, s = std::strlen( format ); i < s; i ++ )
{
switch( format[ i ] )
{
case 's': function_format += "S[128]"; break;
case 'i': case 'd': case 'c': case 'l': case 'b': case 'h': case 'x': case 'o': case 'n': case 'f': case 'g': case 'u': case 'q': case 'r': function_format += "R"; break;
default: break;
}
}
return sampgdk::InvokeNative( Native, function_format.c_str( ), data, format, args ... );
}
};
};
Usage:
Код:
Plugins::SSCANF::unformat( "Data 5.0 hello", "p< >s[5]fs[6]", varstring1, &varfloat, varstring2 );
I know that C has sscanf and this looks stupid, but I find the variant of ****** a lot better for SA-MP's needs. By the way, I know that my method of doing it won't work fine with all usage cases of sscanf, but it's better than nothing. It fits perfectly for my needs. I don't use sscanf's "a" specifier, kustom (I only used it in 4 cases, but I converted to "d" ) or other more advanced things. In future maybe I'll try to convert sscanf and include it in my gamemode.