04.04.2017, 22:04
(
Последний раз редактировалось IstuntmanI; 06.04.2017 в 23:02.
)
I worked around these things, with help from your responses (thanks !) and now I came back with additional things:
--------------------------------------------------------
--------------------------------------------------------
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:
--------------------------------------------------------
A problem: I made this:
But the function is not called:
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.
--------------------------------------------------------
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:
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:
Usage:
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.
--------------------------------------------------------
--------------------------------------------------------
Quote:
...
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); } |
Код:
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:
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.
|
Код:
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 );
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); |
--------------------------------------------------------
Quote:
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.
|
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 ); }
--------------------------------------------------------
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 ... ); } }; };
Код:
Plugins::SSCANF::unformat( "Data 5.0 hello", "p< >s[5]fs[6]", varstring1, &varfloat, varstring2 );