summaryrefslogtreecommitdiff
path: root/src/core/script/Function.hpp
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-10-24 22:22:26 +0000
committerandreas <andreas@daaaf23c-2e50-4459-9457-1e69db5a47bf>2014-10-24 22:22:26 +0000
commit7e51bf3804e50ea063fcc97b2682a32a8505902f (patch)
tree6a6097216708049b5dd7a4c43020c85aafb046a1 /src/core/script/Function.hpp
parent4a9912f516bf096c6f8c6259b3fc6ba4b95b8d69 (diff)
added Function, Property and Object classes; added CMakeLists entries for the mozjs-24 library (the Firefox JavaScript engine which is available as Package on Fedora); added Doxygen target to makefile
git-svn-id: file:///var/local/svn/basicwriter@75 daaaf23c-2e50-4459-9457-1e69db5a47bf
Diffstat (limited to 'src/core/script/Function.hpp')
-rw-r--r--src/core/script/Function.hpp243
1 files changed, 180 insertions, 63 deletions
diff --git a/src/core/script/Function.hpp b/src/core/script/Function.hpp
index 4c13dbc..2e92f08 100644
--- a/src/core/script/Function.hpp
+++ b/src/core/script/Function.hpp
@@ -29,12 +29,23 @@ namespace ousia {
namespace script {
/**
- * The abstract Function class is most basic version of a function handle --
- * just a virtual "call" function which calls the underlying code.
+ * The abstract Function class is most basic version of a function handle,
+ * maintaining a "call" function and basic virtual functions for lifecyle
+ * management.
*/
class Function {
-
public:
+ /**
+ * Virtual clone function (e.g. used in the variant class).
+ */
+ virtual Function *clone() const = 0;
+
+ /**
+ * Virtual destructor.
+ */
+ virtual ~Function()
+ {
+ }
/**
* Abstract function which is meant to call the underlying function (be it
@@ -51,26 +62,27 @@ public:
*
* @return a Variant containing the return value.
*/
- Variant call() const { return call({}); }
+ Variant call() const
+ {
+ return call({});
+ }
+ // TODO: Use () operator instead of the call function
};
/**
- * The ArgumentDescriptor class is used to describe the type of a function
+ * The Argument class is used to describe the type of a function
* argument.
*/
-struct ArgumentDescriptor {
-
+struct Argument {
const VariantType type;
const bool hasDefault;
const Variant defaultValue;
- ArgumentDescriptor(VariantType type) :
- type(type), hasDefault(false) {};
-
- ArgumentDescriptor(VariantType type, const Variant &defaultValue) :
- type(type), hasDefault(true), defaultValue(defaultValue) {};
+ Argument(VariantType type) : type(type), hasDefault(false){};
+ Argument(VariantType type, const Variant &defaultValue)
+ : type(type), hasDefault(true), defaultValue(defaultValue){};
};
/**
@@ -78,21 +90,18 @@ struct ArgumentDescriptor {
* validator errors.
*/
class ArgumentValidatorError : public std::exception {
-
public:
-
const int index;
const std::string msg;
- ArgumentValidatorError(int index, const std::string &msg) :
- index(index), msg(msg) {};
+ ArgumentValidatorError(int index, const std::string &msg)
+ : index(index), msg(msg){};
- virtual const char* what() const noexcept override
+ virtual const char *what() const noexcept override
{
return msg.c_str();
}
-
};
/**
@@ -100,12 +109,11 @@ public:
* arguments passed to a function match the description.
*/
class ArgumentValidator {
-
private:
/**
* List containing the argument descriptors.
*/
- const std::vector<ArgumentDescriptor> descriptors;
+ const std::vector<Argument> descriptors;
/**
* Argument index in the input array, at which the last error occured.
@@ -118,20 +126,22 @@ private:
std::string errorMessage;
std::pair<bool, std::vector<Variant>> setError(int idx,
- const std::string &msg, std::vector<Variant> &res);
+ const std::string &msg,
+ std::vector<Variant> &res);
void resetError();
public:
-
/**
* Constructor of the argument validator class.
*
- * @param descriptors is a list of ArgumentDescriptors which should be used
+ * @param descriptors is a list of Arguments which should be used
* for the validation.
*/
- ArgumentValidator(const std::vector<ArgumentDescriptor> &descriptors) :
- descriptors(descriptors) {}
+ ArgumentValidator(const std::vector<Argument> &descriptors)
+ : descriptors(descriptors)
+ {
+ }
/**
* Validates and augments the given argument list (e.g. adds the default
@@ -143,7 +153,8 @@ public:
* list of arguments. If false is returned, use the error function to get
* more information about the error.
*/
- std::pair<bool, std::vector<Variant>> validate(const std::vector<Variant> &args);
+ std::pair<bool, std::vector<Variant>> validate(
+ const std::vector<Variant> &args);
/**
* Returns an ArgumentValidatorError instance containing the argument index
@@ -157,68 +168,174 @@ public:
*/
ArgumentValidatorError error()
{
- return ArgumentValidatorError(errorIndex, errorMessage);
+ return ArgumentValidatorError{errorIndex, errorMessage};
}
-
};
/**
- * The HostFunction class represents a function that resides in the script host.
+ * A validating function
*/
-template<class T>
-class HostFunction : public Function {
-
+class ValidatingFunction : public Function {
private:
- T callback;
ArgumentValidator *validator;
- void *data;
-
-public:
-
- HostFunction(T callback, std::vector<ArgumentDescriptor> signature,
- void *data = nullptr) :
- callback(callback), validator(new ArgumentValidator(signature)),
- data(data) {}
- HostFunction(T callback, void *data = nullptr) :
- callback(callback), validator(nullptr), data(data) {}
-
- ~HostFunction()
- {
- delete validator;
- }
+protected:
+ virtual Variant validatedCall(const std::vector<Variant> &args) const = 0;
virtual Variant call(const std::vector<Variant> &args) const override
{
if (validator) {
- std::pair<bool, std::vector<Variant>> res = validator->validate(args);
+ std::pair<bool, std::vector<Variant>> res =
+ validator->validate(args);
if (!res.first) {
throw validator->error();
}
- return callback(res.second, data);
- } else {
- return callback(args, data);
+ return validatedCall(res.second);
}
+ return validatedCall(args);
}
using Function::call;
+public:
+ ValidatingFunction() : validator(nullptr)
+ {
+ }
+
+ ValidatingFunction(std::vector<Argument> signature)
+ : validator(new ArgumentValidator(signature))
+ {
+ }
+
+ ~ValidatingFunction() override
+ {
+ delete validator;
+ }
};
-template<class T>
-static HostFunction<T> createHostFunction(T callback,
- std::vector<ArgumentDescriptor> signature, void *data = nullptr)
-{
- return HostFunction<T>(callback, signature, data);
-}
+using HostFunctionCallback = Variant (*)(const std::vector<Variant> &args,
+ void *data);
+using GetterCallback = Variant (*)(void *data);
+using SetterCallback = void (*)(Variant arg, void *data);
-template<class T>
-static HostFunction<T> createHostFunction(T callback, void *data = nullptr)
-{
- return HostFunction<T>(callback, data);
-}
+class HostFunction : public ValidatingFunction {
+private:
+ HostFunctionCallback callback;
+ void *data;
+
+protected:
+ virtual Variant validatedCall(
+ const std::vector<Variant> &args) const override
+ {
+ return callback(args, data);
+ }
+
+public:
+ HostFunction(HostFunctionCallback callback, std::vector<Argument> signature,
+ void *data = nullptr)
+ : ValidatingFunction(signature), callback(callback), data(data)
+ {
+ }
+ HostFunction(HostFunctionCallback callback, void *data = nullptr)
+ : ValidatingFunction(), callback(callback), data(data)
+ {
+ }
+
+ Function *clone() const override
+ {
+ return new HostFunction(*this);
+ }
+
+ using ValidatingFunction::call;
+};
+
+class Getter : public ValidatingFunction {
+private:
+ GetterCallback callback;
+ void *data;
+
+protected:
+ virtual Variant validatedCall(
+ const std::vector<Variant> &args) const override
+ {
+ if (!callback) {
+ // TODO: Use another exception class here
+ throw "Getter not defined";
+ }
+ return callback(data);
+ }
+
+public:
+ Getter(GetterCallback callback, void *data = nullptr)
+ : ValidatingFunction(std::vector<Argument>{}),
+ callback(callback),
+ data(data){};
+
+ Function *clone() const override
+ {
+ return new Getter(*this);
+ }
+
+ Variant call() const
+ {
+ return ValidatingFunction::call();
+ }
+
+ Variant operator()() const
+ {
+ return call();
+ }
+ bool exists()
+ {
+ return callback != nullptr;
+ }
+};
+
+class Setter : public ValidatingFunction {
+private:
+ SetterCallback callback;
+ void *data;
+
+protected:
+ virtual Variant validatedCall(
+ const std::vector<Variant> &args) const override
+ {
+ if (!callback) {
+ // TODO: Use another exception class here
+ throw "Setter not defined";
+ }
+ callback(args[0], data);
+ return VarNull;
+ }
+
+public:
+ Setter(VariantType type, SetterCallback callback, void *data = nullptr)
+ : ValidatingFunction({Argument{type}}),
+ callback(callback),
+ data(data){};
+
+ Function *clone() const override
+ {
+ return new Setter(*this);
+ }
+
+ void call(Variant arg) const
+ {
+ ValidatingFunction::call({arg});
+ }
+
+ void operator()(Variant arg) const
+ {
+ return call(arg);
+ }
+
+ bool exists()
+ {
+ return callback != nullptr;
+ }
+};
}
}