SAMPGDK Framework -
GWMPT - 24.05.2014
SAMPGDK Framework(C++)
In heavy development
The name says everything.
In the last week, i have been developing a framework for the SAMPGDK, which will allow you to do your gamemodes in a easier way!
This framework consists in Classes, and stuff like that, to handle the stuff in a organized way.
For example, to "run" functions inside a callback, you need to do something like:
pawn Code:
PLUGIN_EXPORT bool PLUGIN_CALL OnGameModeInit() {
MyFunc();
return true;
}
Right?
So, now imagine, having 1 simple function, called RegisterCallbacks, to "insert"[I know, not the correct term] the functions into your callbacks?
That function will need to be declared by you[the definition is done already, in the framework files], and it should look something like this:
pawn Code:
void RegisterCallbacks();
And, to "insert" your functions in a callback, you just need to call Events::AddHandler inside RegisterCallbacks function.
Below, you have a little example:
pawn Code:
void RegisterCallBacks() {
Events::AddHandler("OnGameModeInit", CB GMInit);
Events::AddHandler("OnGameModeInit", CB AC_Start);
Events::AddHandler("OnPlayerConnect", CB PLRCon);
Events::AddHandler("OnPlayerConnect", CB AC_AddPlr);
Events::AddHandler("OnGameModeExit", CB GMExit);
Events::AddHandler("OnGameModeExit", CB AC_Stop);
}
Easy, right?
Ok, but that ain't everything!
To handle players, we need to take his id and stuff.
Now imagine to have a class which do everything for you? That would be awesome!
And that will be included inside this framework as well.
So, instead defining and declaring your functions with void PlrCon(int playerid), you declare it like: PlrCon(PLAYER player)
It would look something like this:
pawn Code:
void PlrCon(PLAYER* player) {
char* name = new char[MAX_PLAYER_NAME];
player->GetName(name);
ChatBox::OutputEX(0xFFFFFF, "sss", "[SERVER] Player ", name, " joined the server");
player->SendMessageEX(0xFFFFFF, "ssc", "Welcome back", name, '!');
}
void RegisterCallbacks() {
Events::AddHandler("OnPlayerConnect", CB PlrCon);
}
However, now you're thinking... How can I get a specific player in a function being run in another thread, without parameters, or get another player besides the "player passed" into my function?
Well, that's easy too!
You just need to call Player::Find(<player id>) and it will give you the Player object[You can check if the player is connected or not with <player>->Connected function.]
Little example:
pawn Code:
PLAYER* player = Player::Find(20);
if(player->Connected()) {
//// the player is connected
} else {
//// the player isn't connected.
}
Yet, that isn't everything.
Normally, we prefer to run auxiliary threads instead timers, because it doesn't pause the main server thread while executing our instructions, for example, anticheat update and stuff.
This framework will have the possibility to run threads as well!
For example, you have a huge and slow code in OnPlayerConnect callback, you can add your slow code into the callback in the same way as the other callbacks[Events::AddHandlers], however, you just need to add the boolean "true" in the end of the function.
Example:
pawn Code:
void MyFunc() {
for(int i = 0; i < 100; i++)
Server::ConsoleOutEX("sd", "[NON-THREAD] ", i);
}
void MyTHRFunc() {
for(int i = 0; i < 100; i++)
Server::ConsoleOutEX("sd", "[THREAD] ", i);
}
void RegisterCallbacks() {
Events::AddHandler("OnGameModeInit", CB MyTHRFunc, true);
Events::AddHandler("OnGameModeInit", CB MyFunc);
}
OR, if you want to run your threaded function from another function[non-threaded], you can too!
Something like:
pawn Code:
Thread::CreateThread(CB MyFunc);
Will do the job.
Other functions, classes and stuff will be added during the development of it.
A public beta should be released in 2 weeks.
Anyways, what do you guys[and girls] think about it?
I will appreciate constructive criticism and questions!
PS: Sorry about the grammar mistakes.
LATEST UPDATE
There are some callbacks which the return of them will have effect over the server.
Such like: PlayerUpdate, PlayerText, etc.
Now, maybe you're thinking, how can I change the return of those callbacks over the framework?
That's easy to.
You just need to do Events::HandlerReturn, which the first parameter is the callback["OnPlayerText"], and the second parameter is a boolean.
Little example for OnPlayerText:
pawn Code:
void PlrTxt(PLAYER* player) {
int muted = GetPvarInt(player->ID, "Muted");
if(muted >= 1) {
player->SendMessage(0xFF0000, "You are still muted!");
Events::HandlerReturn("OnPlayerText", false);
}
}
The callback return is reseted after used.
PRE-ALPHA code preview
So, today I've got events being triggered without problems.
And the code[after having the libraries and include directories configurated], looked something like:
PHP Code:
#include <framework\framework.hpp>
void PlayerConnect(int playerid) {
char name[MAX_PLAYER_NAME], msg[MAX_CHATBUBBLE_LENGTH];
GetPlayerName(playerid, name, MAX_PLAYER_NAME);
sprintf(msg, "{FF9900}[SERVER]{ffffff} Player {00ff00}%s{ffffff} joined the server!", name);
SendClientMessageToAll(0xFFFFFF, msg);
}
void PlayerDisconnect(int playerid, int reason) {
char name[MAX_PLAYER_NAME], msg[MAX_CHATBUBBLE_LENGTH];
GetPlayerName(playerid, name, MAX_PLAYER_NAME);
sprintf(msg, "{FF9900}[SERVER]{ffffff} Player {00ff00}%s{ffffff} left the server!", name);
SendClientMessageToAll(0xFFFFFF, msg);
}
void GMInit() {
SetGameModeText("SAMPGDK Framework development");
SendRconCommand("mapname SA-MP © 2014");
}
void GMExit() {
sampgdk::logprintf("Exitting...");
}
void RegisterNatives(void) {
Events::AddHandler("OnGameModeInit", CB GMInit);
Events::AddHandler("OnGameModeExit", CB GMExit);
Events::AddHandler("OnPlayerConnect", CB PlayerConnect);
Events::AddHandler("OnPlayerDisconnect", CB PlayerDisconnect);
}
I seriously think it was a good improvement from [nothing]to the current stage.
More updates will came out during the week, as well, I'm still seeking for ALPHA testers, which can test this framework in a development environment.
Re: SAMPGDK Framework -
Kaperstone - 24.05.2014
Sounds nice, definitely would use.
But
Code:
Events::AddHandler("OnGameModeInit", CB GMInit);
What the CB stands for ?
Re: SAMPGDK Framework -
GWMPT - 24.05.2014
The CB stands for a define[of course], which is "replaced" by a typecast (int) and the "pointer"[not sure about the correct term] for the function memory address(&)
If you mean about the "name", it stands for Callback
@Edit, forgotten to mention that the bi-dimensional array which stores the functions addresses is dynamic.
Re: SAMPGDK Framework -
Jstylezzz - 24.05.2014
EDIT: Nevermind xd
Nice one Kikito, looks like something I'd try to use
Re: SAMPGDK Framework -
carz0159 - 24.05.2014
very nice, now maybe everything wont be a GF Edit.
Re: SAMPGDK Framework -
KingHual - 24.05.2014
as long as it complies with the 0x standard
Re: SAMPGDK Framework -
Kaperstone - 24.05.2014
Quote:
Originally Posted by carz0159
very nice, now maybe everything wont be a GF Edit.
|
"It was only just a dream ..."
Re: SAMPGDK Framework -
GWMPT - 24.05.2014
Quote:
Originally Posted by KingHual
as long as it complies with the 0x standard
|
It does[the pre-alpha tests results were perfect].
@Edit
As well, this framework will allow newbies in programming start learning C/++ in a easy way.
Re: SAMPGDK Framework -
AviPeker - 25.05.2014
Nice
Re: SAMPGDK Framework - Patrick - 25.05.2014
Interesting, maybe this is the time I will focus more on C++