2021-03-04 19:30:25 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2021 Google LLC.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SKSL_DSL_FUNCTION
|
|
|
|
#define SKSL_DSL_FUNCTION
|
|
|
|
|
|
|
|
#include "include/sksl/DSLBlock.h"
|
2021-04-09 16:25:03 +00:00
|
|
|
#include "include/sksl/DSLExpression.h"
|
2021-03-04 19:30:25 +00:00
|
|
|
#include "include/sksl/DSLType.h"
|
2021-04-09 16:25:03 +00:00
|
|
|
#include "include/sksl/DSLVar.h"
|
2021-05-06 14:47:06 +00:00
|
|
|
#include "include/sksl/DSLWrapper.h"
|
2021-03-04 19:30:25 +00:00
|
|
|
|
|
|
|
namespace SkSL {
|
|
|
|
|
|
|
|
class Block;
|
2021-04-09 16:25:03 +00:00
|
|
|
class FunctionDeclaration;
|
2021-03-04 19:30:25 +00:00
|
|
|
class Variable;
|
|
|
|
|
|
|
|
namespace dsl {
|
|
|
|
|
|
|
|
class DSLType;
|
|
|
|
|
|
|
|
class DSLFunction {
|
|
|
|
public:
|
|
|
|
template<class... Parameters>
|
2022-02-01 20:31:57 +00:00
|
|
|
DSLFunction(const DSLType& returnType, std::string_view name, Parameters&... parameters)
|
2021-07-14 13:52:16 +00:00
|
|
|
: DSLFunction(DSLModifiers(), returnType, name, parameters...) {}
|
|
|
|
|
|
|
|
template<class... Parameters>
|
2022-02-01 20:31:57 +00:00
|
|
|
DSLFunction(const DSLModifiers& modifiers, const DSLType& returnType, std::string_view name,
|
2021-07-14 13:52:16 +00:00
|
|
|
Parameters&... parameters) {
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
SkTArray<DSLParameter*> parameterArray;
|
2021-05-06 14:47:06 +00:00
|
|
|
parameterArray.reserve_back(sizeof...(parameters));
|
2021-03-04 19:30:25 +00:00
|
|
|
|
|
|
|
// in C++17, we could just do:
|
|
|
|
// (parameterArray.push_back(¶meters), ...);
|
|
|
|
int unused[] = {0, (static_cast<void>(parameterArray.push_back(¶meters)), 0)...};
|
|
|
|
static_cast<void>(unused);
|
2021-08-31 11:40:24 +00:00
|
|
|
// We can't have a default parameter and a template parameter pack at the same time, so
|
|
|
|
// unfortunately we can't capture position info from this overload.
|
|
|
|
this->init(modifiers, returnType, name, std::move(parameterArray), PositionInfo());
|
2021-07-14 13:52:16 +00:00
|
|
|
}
|
|
|
|
|
2022-02-01 20:31:57 +00:00
|
|
|
DSLFunction(const DSLType& returnType, std::string_view name,
|
2021-08-31 11:40:24 +00:00
|
|
|
SkTArray<DSLParameter*> parameters, PositionInfo pos = PositionInfo::Capture()) {
|
|
|
|
this->init(DSLModifiers(), returnType, name, std::move(parameters), pos);
|
2021-03-04 19:30:25 +00:00
|
|
|
}
|
|
|
|
|
2022-02-01 20:31:57 +00:00
|
|
|
DSLFunction(const DSLModifiers& modifiers, const DSLType& returnType, std::string_view name,
|
2021-08-31 11:40:24 +00:00
|
|
|
SkTArray<DSLParameter*> parameters, PositionInfo pos = PositionInfo::Capture()) {
|
|
|
|
this->init(modifiers, returnType, name, std::move(parameters), pos);
|
2021-05-06 14:47:06 +00:00
|
|
|
}
|
|
|
|
|
2021-05-18 14:12:58 +00:00
|
|
|
DSLFunction(const SkSL::FunctionDeclaration* decl)
|
|
|
|
: fDecl(decl) {}
|
|
|
|
|
2021-03-04 19:30:25 +00:00
|
|
|
virtual ~DSLFunction() = default;
|
|
|
|
|
|
|
|
template<class... Stmt>
|
|
|
|
void define(Stmt... stmts) {
|
|
|
|
DSLBlock block = DSLBlock(DSLStatement(std::move(stmts))...);
|
|
|
|
this->define(std::move(block));
|
|
|
|
}
|
|
|
|
|
2021-09-10 15:57:46 +00:00
|
|
|
void define(DSLBlock block, PositionInfo pos = PositionInfo::Capture());
|
2021-03-04 19:30:25 +00:00
|
|
|
|
2021-05-06 14:47:06 +00:00
|
|
|
/**
|
|
|
|
* Invokes the function with the given arguments.
|
|
|
|
*/
|
2021-03-04 19:30:25 +00:00
|
|
|
template<class... Args>
|
2021-04-09 16:25:03 +00:00
|
|
|
DSLExpression operator()(Args&&... args) {
|
2021-09-09 19:03:22 +00:00
|
|
|
ExpressionArray argArray;
|
2021-03-04 19:30:25 +00:00
|
|
|
argArray.reserve_back(sizeof...(args));
|
2021-04-09 16:25:03 +00:00
|
|
|
this->collectArgs(argArray, std::forward<Args>(args)...);
|
2021-03-04 19:30:25 +00:00
|
|
|
return this->call(std::move(argArray));
|
|
|
|
}
|
|
|
|
|
2021-05-06 14:47:06 +00:00
|
|
|
/**
|
|
|
|
* Invokes the function with the given arguments.
|
|
|
|
*/
|
2021-10-04 19:35:59 +00:00
|
|
|
DSLExpression call(SkTArray<DSLWrapper<DSLExpression>> args,
|
|
|
|
PositionInfo pos = PositionInfo::Capture());
|
2021-05-06 14:47:06 +00:00
|
|
|
|
2021-10-04 19:35:59 +00:00
|
|
|
DSLExpression call(ExpressionArray args, PositionInfo pos = PositionInfo::Capture());
|
2021-09-09 19:03:22 +00:00
|
|
|
|
2021-03-04 19:30:25 +00:00
|
|
|
private:
|
2021-09-09 19:03:22 +00:00
|
|
|
void collectArgs(ExpressionArray& args) {}
|
2021-04-09 16:25:03 +00:00
|
|
|
|
|
|
|
template<class... RemainingArgs>
|
2021-09-09 19:03:22 +00:00
|
|
|
void collectArgs(ExpressionArray& args, DSLVar& var, RemainingArgs&&... remaining) {
|
|
|
|
args.push_back(DSLExpression(var).release());
|
2021-04-09 16:25:03 +00:00
|
|
|
collectArgs(args, std::forward<RemainingArgs>(remaining)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class... RemainingArgs>
|
2021-09-09 19:03:22 +00:00
|
|
|
void collectArgs(ExpressionArray& args, DSLExpression expr, RemainingArgs&&... remaining) {
|
|
|
|
args.push_back(expr.release());
|
2021-04-09 16:25:03 +00:00
|
|
|
collectArgs(args, std::forward<RemainingArgs>(remaining)...);
|
|
|
|
}
|
|
|
|
|
2022-02-01 20:31:57 +00:00
|
|
|
void init(DSLModifiers modifiers, const DSLType& returnType, std::string_view name,
|
2021-08-31 11:40:24 +00:00
|
|
|
SkTArray<DSLParameter*> params, PositionInfo pos);
|
2021-03-04 19:30:25 +00:00
|
|
|
|
2021-05-04 18:30:02 +00:00
|
|
|
const SkSL::FunctionDeclaration* fDecl = nullptr;
|
2021-09-01 13:39:34 +00:00
|
|
|
SkSL::PositionInfo fPosition;
|
2021-03-04 19:30:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace dsl
|
|
|
|
|
|
|
|
} // namespace SkSL
|
|
|
|
|
|
|
|
#endif
|