How do you use "..."?

Started by
15 comments, last by Way Walker 18 years ago
Quote:Original post by PumpkinPieman
I don't use the boost library, is there any other way?


Are you willing to alter your function call syntax?
Are you willing to preprocess your source code with a custom tool?
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Advertisement
It means "I don't use it", just like it says. I'm not going to get in to the reasons why not. I'm just trying to find alternatives to running script functions without setting the arguements one by one. (angelscript has methods that set parameters one at a time for a loaded script function)

Quote:Original post by Fruny
Quote:Original post by PumpkinPieman
I don't use the boost library, is there any other way?


Are you willing to alter your function call syntax?
Are you willing to preprocess your source code with a custom tool?


Well that answers my question, all I was looking for was something simple to work with. I'll try to find another method around this little problem.

Thanks for all your help.
This might help: Gem: A Generic Function Binding Interface
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Quote:Original post by PumpkinPieman
I don't use the boost library, is there any other way?


How does AngelScript expect the arguments? That'd determine how I'd solve it.
Quote:Original post by Way Walker
Quote:Original post by PumpkinPieman
I don't use the boost library, is there any other way?


How does AngelScript expect the arguments? That'd determine how I'd solve it.


int SetArgDWord(asUINT arg, asDWORD value);
int SetArgQWord(asUINT arg, asQWORD value);
int SetArgFloat(asUINT arg, float value);
int SetArgDouble(asUINT arg, double value);
int SetArgAddress(asUINT arg, void *address);
int SetArgObject(asUINT arg, void *object);

arg = 0 .. n
Quote:
This might help: Gem: A Generic Function Binding Interface


Seconded. I've implemented a system based on this paper for Lua and it is wonderful. It requires some heavier up-front effort but it pays off in the long run.
Since I don't know how expensive context creation/destruction is, how often you'll want to make identical/similar calls, etc., this probably isn't the perfect solution for you, but it may give you an idea.

class CallASFunction {  public:    class Address {      public:        void *address;        Address(void *a = 0) : address(a) {}    };  private:    asIScriptContext *context;    unsigned int argumentCount;  public:    CallASFunction(asIScriptEngine &engine, int functionID)    : context(0), argumentCount(0) {        context = engine.CreateContext();        context->Prepare(functionID);    }    ~CallASFunction() {        context->Release();    }  private:    CallASFunction(); // No touchy    CallASFunction(const CallASFunction &cf); // No touchy    CallASFunction & operator=(const CallASFunciton &cf); // No touchy  public:    friend CallASFunction & operator<<(CallASFunction &cf, asDWORD  value);    friend CallASFunction & operator<<(CallASFunction &cf, asQWORD  value);    friend CallASFunction & operator<<(CallASFunction &cf, float    value);    friend CallASFunction & operator<<(CallASFunction &cf, double   value);    friend CallASFunction & operator<<(CallASFunction &cf, void    *value);    friend CallASFunction & operator<<(CallASFunction &cf, Address  value);  public:    void execute(asDWORD &out) {        out = context->Execute() == asEXECUTION_FINISHED            ? context->GetReturnDWord() : 0;    }    void execute(asQWORD &out) {        out = context->Execute() == asEXECUTION_FINISHED            ? context->GetReturnQWord() : 0;    }    void execute(float &out) {        out = context->Execute() == asEXECUTION_FINISHED            ? context->GetReturnFloat() : 0;    }    void execute(double &out) {        out = context->Execute() == asEXECUTION_FINISHED            ? context->GetReturnDouble() : 0;    }    void execute(void **out) {        *out = context->Execute() == asEXECUTION_FINISHED             ? context->GetReturnObject() : 0;    }    void execute(Address &out) {        out.address = context->Execute() == asEXECUTION_FINISHED                    ? context->GetReturnAddress() : 0;    }};CallASFunction & operator<<(CallASFunction &cf, asDWORD value) {    cf.context->SetArgDWord(argumentCount, value);    ++argumentCount;}CallASFunction & operator<<(CallASFunction &cf, asQWORD value) {    cf.context->SetArgQWord(argumentCount, value);    ++argumentCount;}CallASFunction & operator<<(CallASFunction &cf, float value) {    cf.context->SetArgFloat(argumentCount, value);    ++argumentCount;}CallASFunction & operator<<(CallASFunction &cf, double value) {    cf.context->SetArgDouble(argumentCount, value);    ++argumentCount;}CallASFunction & operator<<(CallASFunction &cf, void *value) {    cf.context->SetArgObject(argumentCount, value);    ++argumentCount;}CallASFunction & operator<<(CallASFunction &cf, Address value) {    cf.context->SetArgAddress(argumentCount, value.address);    ++argumentCount;}


CallASFunction::Address could be improved by making it act like a pointer, but I'm lazy. You might want to make CallASFunction::Object and not use void pointers directly (for consistency, it won't provide any more type safety), but I'm lazy. (Or, perhaps even better, create wrappers independent of this class that you use for those types so you don't have to convert just to call a function.) You could probably make copying and assignment feasible (context has reference counting), but I'm lazy. You should probably throw when a function doesn't return, but I'm lazy. I haven't tested it at all because I'm lazy, but you should get the idea.

Usage:
DWORD ret = 0;
CallASFunction someFunc(myEngine, someID);
someFunc << arg1 << arg2 << arg3 << CallASFunction::Address(arg4) << arg5;
someFunc.execute(ret);

[Edited by - Way Walker on April 29, 2006 8:51:59 PM]

This topic is closed to new replies.

Advertisement