Skip to content

Commit

Permalink
APL-CORE: December 2022 Release of APL 2022.2 compilant core engine (…
Browse files Browse the repository at this point in the history
…2022.2.2)

For more details on this release refer to CHANGELOG.md

To learn about APL see: https://developer.amazon.com/docs/alexa-presentation-language/understand-apl.html
  • Loading branch information
sasirajah committed Dec 8, 2022
1 parent 5c43a0b commit ee4363d
Show file tree
Hide file tree
Showing 328 changed files with 13,655 additions and 4,968 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Changelog

## [2022.2]
## [2022.2.1]

### Changed

- Bug fixes.
- Performance improvements.
- Build improvements.

## [2022.2.0]

This release adds support for version 2022.2 of the APL specification.

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# on older systems
include(FetchContent OPTIONAL RESULT_VARIABLE HAS_FETCH_CONTENT)

cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.11)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

Expand Down
8 changes: 8 additions & 0 deletions aplcore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024")
endif()

# Disable what needs to be disabled
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-exceptions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")

include(target_sources_local.cmake)

# Check for the presence of GIT
Expand Down Expand Up @@ -179,6 +183,10 @@ if (USE_PROVIDED_YOGA_AS_LIB)
# We built the bundled yoga lib, install it
install(FILES ${YOGA_LIB}
DESTINATION lib)
install(DIRECTORY ${YOGA_INCLUDE}/yoga
DESTINATION include
FILES_MATCHING PATTERN "*.h")
set(YOGA_EXTERNAL_LIB ${YOGA_LIB}) # used by aplcoreConfig.cmake.in
endif()

if (NOT USE_PROVIDED_YOGA_INLINE)
Expand Down
9 changes: 6 additions & 3 deletions aplcore/aplcoreConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ else()

endif()

set(ENABLE_ALEXAEXTENSIONS @ENABLE_ALEXAEXTENSIONS@)
set(USE_INTERNAL_ALEXAEXT @BUILD_ALEXAEXTENSIONS@)

if(NOT USE_INTERNAL_ALEXAEXT)
find_package(alexaext REQUIRED)
endif()
if(ENABLE_ALEXAEXTENSIONS)
if(NOT USE_INTERNAL_ALEXAEXT)
find_package(alexaext REQUIRED)
endif()
endif(ENABLE_ALEXAEXTENSIONS)

include("${CMAKE_CURRENT_LIST_DIR}/aplcoreTargets.cmake")

Expand Down
15 changes: 14 additions & 1 deletion aplcore/include/apl/animation/easing.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#ifndef _APL_EASING_H
#define _APL_EASING_H

#include "apl/primitives/objectdata.h"
#include "apl/primitives/objecttype.h"

namespace apl {

Expand Down Expand Up @@ -67,6 +67,19 @@ class Easing : public ObjectData {
virtual bool operator==(const Easing& other) const = 0;
virtual bool operator==(const CoreEasing& other) const = 0;
virtual ~Easing() noexcept;

class ObjectType final : public PointerHolderObjectType<Easing> {
public:
bool isCallable() const override { return true; }

bool equals(const Object::DataHolder& lhs, const Object::DataHolder& rhs) const override {
return *lhs.data == *rhs.data;
}

Object call(const Object::DataHolder& dataHolder, const ObjectArray& args) const override {
return dataHolder.data->call(args);
}
};
};

} // namespace apl
Expand Down
106 changes: 68 additions & 38 deletions aplcore/include/apl/animation/easinggrammar.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@
#ifndef _APL_EASING_GRAMMAR_H
#define _APL_EASING_GRAMMAR_H

#include <tao/pegtl.hpp>
#include <tao/pegtl/contrib/abnf.hpp>

#include "apl/animation/coreeasing.h"
#include "apl/datagrammar/grammarpolyfill.h"
#include "apl/utils/log.h"
#include "apl/utils/stringfunctions.h"

Expand Down Expand Up @@ -86,7 +84,7 @@ struct action
: nothing< Rule > {
};

struct easing_state
struct easing_state : fail_state
{
float lastTime = 0;
size_t startIndex = 0;
Expand Down Expand Up @@ -118,14 +116,18 @@ template<> struct action< path >
template< typename Input >
static void apply(const Input& in, easing_state& state) {
auto argCount = state.args.size() - state.startIndex;
if (argCount % 2 == 1)
throw parse_error("Path easing function needs an even number of arguments", in);
if (argCount % 2 == 1) {
state.fail("Path easing function needs an even number of arguments", in);
return;
}

// Push each linear segment. Check to ensure time is incrementing
for (auto offset = state.startIndex ; offset < state.args.size() ; offset += 2) {
auto time = state.args.at(offset);
if (time <= state.lastTime || time >= 1)
throw parse_error("Path easing function needs ordered array of segments", in);
if (time <= state.lastTime || time >= 1) {
state.fail("Path easing function needs ordered array of segments", in);
return;
}
state.lastTime = time;
state.segments.emplace_back(EasingSegment(kLinearSegment, offset));
}
Expand Down Expand Up @@ -153,8 +155,10 @@ template<> struct action< cubicbezier >
template< typename Input >
static void apply(const Input& in, easing_state& state) {
auto argCount = state.args.size() - state.startIndex;
if (argCount != 4)
throw parse_error("Cubic-bezier easing function requires 4 arguments", in);
if (argCount != 4) {
state.fail("Cubic-bezier easing function requires 4 arguments", in);
return;
}

// Add a final segment at (1,1)
state.segments.emplace_back(EasingSegment(kEndSegment, state.args.size()));
Expand All @@ -176,12 +180,16 @@ template<> struct action< end >
template< typename Input >
static void apply(const Input& in, easing_state& state) {
auto argCount = state.args.size() - state.startIndex;
if (argCount != 2)
throw parse_error("End easing function segment requires 2 arguments", in);
if (argCount != 2) {
state.fail("End easing function segment requires 2 arguments", in);
return;
}

auto time = state.args.at(state.startIndex);
if (time <= state.lastTime && state.startIndex > 0)
throw parse_error("End easing function segment cannot start at this time", in);
if (time <= state.lastTime && state.startIndex > 0) {
state.fail("End easing function segment cannot start at this time", in);
return;
}

state.lastTime = time;
state.segments.emplace_back(EasingSegment(kEndSegment, state.startIndex));
Expand All @@ -201,12 +209,16 @@ template<> struct action< line >
template< typename Input >
static void apply(const Input& in, easing_state& state) {
auto argCount = state.args.size() - state.startIndex;
if (argCount != 2)
throw parse_error("Line easing function segment requires 2 arguments", in);
if (argCount != 2) {
state.fail("Line easing function segment requires 2 arguments", in);
return;
}

auto time = state.args.at(state.startIndex);
if (time <= state.lastTime && state.startIndex > 0)
throw parse_error("Line easing function segment cannot start at this time", in);
if (time <= state.lastTime && state.startIndex > 0) {
state.fail("Line easing function segment cannot start at this time", in);
return;
}

state.lastTime = time;
state.segments.emplace_back(EasingSegment(kLinearSegment, state.startIndex));
Expand All @@ -226,12 +238,16 @@ template<> struct action< curve >
template< typename Input >
static void apply(const Input& in, easing_state& state) {
auto argCount = state.args.size() - state.startIndex;
if (argCount != 6)
throw parse_error("Curve easing function segment requires 6 arguments", in);
if (argCount != 6) {
state.fail("Curve easing function segment requires 6 arguments", in);
return;
}

auto time = state.args.at(state.startIndex);
if (time <= state.lastTime && state.startIndex > 0)
throw parse_error("Curve easing function segment cannot start at this time", in);
if (time <= state.lastTime && state.startIndex > 0) {
state.fail("Curve easing function segment cannot start at this time", in);
return;
}

state.lastTime = time;
state.segments.emplace_back(EasingSegment(kCurveSegment, state.startIndex));
Expand All @@ -246,16 +262,22 @@ template<> struct action< spatial >
assert(state.startIndex == 0);

auto argCount = state.args.size();
if (argCount != 2)
throw parse_error("Wrong number of arguments to spatial", in);
if (argCount != 2) {
state.fail("Wrong number of arguments to spatial", in);
return;
}

auto dof = static_cast<int>(state.args.at(0));
if (dof < 2)
throw parse_error("invalid number of indices in spatial segment", in);
if (dof < 2) {
state.fail("invalid number of indices in spatial segment", in);
return;
}

auto index = static_cast<int>(state.args.at(1));
if (index < 0 || index >= dof)
throw parse_error("select index out of range in spatial segment", in);
if (index < 0 || index >= dof) {
state.fail("select index out of range in spatial segment", in);
return;
}
}
};

Expand All @@ -274,13 +296,17 @@ template<> struct action< send >
auto argCount = state.args.size() - state.startIndex;

// Time, pcount for value
auto dof = ::abs(static_cast<int>(state.args[0]));
if (argCount != 1 + dof)
throw parse_error("Wrong number of arguments to send", in);
auto dof = std::abs(static_cast<int>(state.args[0]));
if (argCount != 1 + dof) {
state.fail("Wrong number of arguments to send", in);
return;
}

auto time = state.args.at(state.startIndex);
if (time <= state.lastTime && !state.segments.empty())
throw parse_error("send easing function segment cannot start at this time", in);
if (time <= state.lastTime && !state.segments.empty()) {
state.fail("send easing function segment cannot start at this time", in);
return;
}

state.lastTime = time;
state.segments.emplace_back(EasingSegment(kSEndSegment, state.startIndex));
Expand All @@ -302,13 +328,17 @@ template<> struct action< scurve >
auto argCount = state.args.size() - state.startIndex;

// Time, pcount * 3 for value, tin, tout, 4 for the time curve =
auto dof = ::abs(static_cast<int>(state.args[0]));
if (argCount != 5 + dof * 3)
throw parse_error("Wrong number of arguments to scurve", in);
auto dof = std::abs(static_cast<int>(state.args[0]));
if (argCount != 5 + dof * 3) {
state.fail("Wrong number of arguments to scurve", in);
return;
}

auto time = state.args.at(state.startIndex);
if (time <= state.lastTime && !state.segments.empty())
throw parse_error("scurve easing function segment cannot start at this time", in);
if (time <= state.lastTime && !state.segments.empty()) {
state.fail("scurve easing function segment cannot start at this time", in);
return;
}

state.lastTime = time;
state.segments.emplace_back(EasingSegment(kSCurveSegment, state.startIndex));
Expand Down
1 change: 1 addition & 0 deletions aplcore/include/apl/apl.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include "apl/primitives/range.h"
#include "apl/primitives/roundedrect.h"
#include "apl/primitives/styledtext.h"
#include "apl/primitives/transform2d.h"
#include "apl/scaling/metricstransform.h"
#ifdef SCENEGRAPH
#include "apl/scenegraph/accessibility.h"
Expand Down
Loading

0 comments on commit ee4363d

Please sign in to comment.