Perl will now capture return values (lua style), yeah I said I wouldn't be improving much of perl from here on but I said if I found a way I'd do it.

This commit is contained in:
KimLS 2013-07-05 02:56:53 -07:00
parent b11ed32bcf
commit 3c8d83f2a8
4 changed files with 65 additions and 53 deletions

View File

@ -152,14 +152,14 @@ void PerlembParser::ReloadQuests() {
spell_quest_status_.clear();
}
void PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
uint32 extradata, bool global, std::vector<void*> *extra_pointers)
{
if(!perl)
return;
return 0;
if(event >= _LargestEventID)
return;
return 0;
bool isPlayerQuest = false;
bool isGlobalPlayerQuest = false;
@ -175,7 +175,7 @@ void PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * d
const char *sub_name = QuestEventSubroutines[event];
if(!perl->SubExists(package_name.c_str(), sub_name)) {
return;
return 0;
}
int char_id = 0;
@ -191,58 +191,52 @@ void PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * d
ExportEventVariables(package_name, event, objid, data, npcmob, iteminst, mob, extradata, extra_pointers);
if(isPlayerQuest || isGlobalPlayerQuest){
SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr);
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr);
}
else if(isItemQuest) {
SendCommands(package_name.c_str(), sub_name, 0, mob, mob, iteminst);
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, iteminst);
}
else if(isSpellQuest)
{
if(mob) {
SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr);
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr);
} else {
SendCommands(package_name.c_str(), sub_name, 0, npcmob, mob, nullptr);
return SendCommands(package_name.c_str(), sub_name, 0, npcmob, mob, nullptr);
}
}
else {
SendCommands(package_name.c_str(), sub_name, objid, npcmob, mob, nullptr);
return SendCommands(package_name.c_str(), sub_name, objid, npcmob, mob, nullptr);
}
}
int PerlembParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
std::vector<void*> *extra_pointers) {
EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, false, extra_pointers);
return 0;
return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, false, extra_pointers);
}
int PerlembParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
std::vector<void*> *extra_pointers) {
EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, true, extra_pointers);
return 0;
return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, true, extra_pointers);
}
int PerlembParser::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
std::vector<void*> *extra_pointers) {
EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, false, extra_pointers);
return 0;
return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, false, extra_pointers);
}
int PerlembParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
std::vector<void*> *extra_pointers) {
EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, true, extra_pointers);
return 0;
return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, true, extra_pointers);
}
int PerlembParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
std::vector<void*> *extra_pointers) {
EventCommon(evt, item->GetID(), nullptr, nullptr, item, client, extra_data, false, extra_pointers);
return 0;
return EventCommon(evt, item->GetID(), nullptr, nullptr, item, client, extra_data, false, extra_pointers);
}
int PerlembParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
std::vector<void*> *extra_pointers) {
EventCommon(evt, 0, itoa(spell_id), npc, nullptr, client, extra_data, false, extra_pointers);
return 0;
return EventCommon(evt, 0, itoa(spell_id), npc, nullptr, client, extra_data, false, extra_pointers);
}
bool PerlembParser::HasQuestSub(uint32 npcid, QuestEventID evt) {
@ -621,10 +615,11 @@ void PerlembParser::ExportVar(const char *pkgprefix, const char *varname, const
}
}
void PerlembParser::SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst* iteminst) {
int PerlembParser::SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst* iteminst) {
if(!perl)
return;
return 0;
int ret_value = 0;
if(mob && mob->IsClient())
quest_manager.StartQuest(other, mob->CastToClient(), iteminst);
else
@ -671,7 +666,7 @@ void PerlembParser::SendCommands(const char *pkgprefix, const char *event, uint3
#endif
//now call the requested sub
perl->dosub(std::string(pkgprefix).append("::").append(event).c_str());
ret_value = perl->dosub(std::string(pkgprefix).append("::").append(event).c_str());
#ifdef EMBPERL_XS_CLASSES
std::string eval_str = (std::string)"$" + (std::string)pkgprefix + (std::string)"::client = undef;";
@ -697,6 +692,7 @@ void PerlembParser::SendCommands(const char *pkgprefix, const char *event, uint3
}
quest_manager.EndQuest();
return ret_value;
}
void PerlembParser::MapFunctions() {

View File

@ -85,9 +85,9 @@ private:
void ExportVar(const char *pkgprefix, const char *varname, float value);
void ExportVarComplex(const char *pkgprefix, const char *varname, const char *value);
void EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
int EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
uint32 extradata, bool global, std::vector<void*> *extra_pointers);
void SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst *iteminst);
int SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst *iteminst);
void MapFunctions();
void GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,

View File

@ -250,56 +250,72 @@ void Embperl::init_eval_file(void)
,FALSE);
}
void Embperl::eval_file(const char * packagename, const char * filename)
int Embperl::eval_file(const char * packagename, const char * filename)
{
std::vector<std::string> args;
args.push_back(packagename);
args.push_back(filename);
dosub("main::eval_file", &args);
return dosub("main::eval_file", &args);
}
void Embperl::dosub(const char * subname, const std::vector<std::string> * args, int mode)
int Embperl::dosub(const char * subname, const std::vector<std::string> * args, int mode)
{
in_use = true;
bool err = false;
dSP; /* initialize stack pointer */
ENTER; /* everything created after here */
SAVETMPS; /* ...is a temporary variable. */
PUSHMARK(SP); /* remember the stack pointer */
dSP;
int ret_value = 0;
int count;
std::string error;
ENTER;
SAVETMPS;
PUSHMARK(SP);
if(args && args->size())
{
for(std::vector<std::string>::const_iterator i = args->begin(); i != args->end(); ++i)
{/* push the arguments onto the perl stack */
{
XPUSHs(sv_2mortal(newSVpv(i->c_str(), i->length())));
}
}
PUTBACK; /* make local stack pointer global */
call_pv(subname, mode); /*eval our code*/
SPAGAIN; /* refresh stack pointer */
PUTBACK;
count = call_pv(subname, mode);
SPAGAIN;
if(SvTRUE(ERRSV))
{
err = true;
error = SvPV_nolen(ERRSV);
POPs;
}
FREETMPS; /* free temp values */
LEAVE; /* ...and the XPUSHed "mortal" args.*/
in_use = false;
if(err)
else
{
errmsg = "Perl runtime error: ";
if(count == 1) {
SV *ret = POPs;
if(SvTYPE(ret) == SVt_IV) {
IV v = SvIV(ret);
ret_value = v;
}
PUTBACK;
}
}
FREETMPS;
LEAVE;
if(error.length() > 0)
{
std::string errmsg = "Perl runtime error: ";
errmsg += SvPVX(ERRSV);
throw errmsg.c_str();
}
return ret_value;
}
//evaluate an expression. throw error on fail
void Embperl::eval(const char * code)
int Embperl::eval(const char * code)
{
std::vector<std::string> arg;
arg.push_back(code);
// MYRA - added EVAL & KEEPERR to eval per Eglin's recommendation
dosub("main::my_eval", &arg, G_SCALAR|G_DISCARD|G_EVAL|G_KEEPERR);
//end Myra
return dosub("main::my_eval", &arg, G_SCALAR|G_EVAL|G_KEEPERR);
}
bool Embperl::SubExists(const char *package, const char *sub) {

View File

@ -89,9 +89,9 @@ public:
//return the last error msg
std::string lasterr(void) const { return errmsg;};
//evaluate an expression. throws string errors on fail
void eval(const char * code);
int eval(const char * code);
//execute a subroutine. throws lasterr on failure
void dosub(const char * subname, const std::vector<std::string> * args = nullptr, int mode = G_SCALAR|G_DISCARD|G_EVAL);
int dosub(const char * subname, const std::vector<std::string> * args = nullptr, int mode = G_SCALAR|G_EVAL);
//Access to perl variables
//all varnames here should be of the form package::name
@ -145,7 +145,7 @@ public:
//loads a file and compiles it into our interpreter (assuming it hasn't already been read in)
//idea borrowed from perlembed
void eval_file(const char * packagename, const char * filename);
int eval_file(const char * packagename, const char * filename);
inline bool InUse() const { return(in_use); }