\r
// unique_ptr\r
\r
+/**\r
+ * A wrapper around std::unique_ptr ensuring that the pointer is never null\r
+ * except in the case of a moved from instance.\r
+ *\r
+ * The default constructor will point the wrapped pointer to a default \r
+ * contructed instance of T.\r
+ *\r
+ * Use the make_unique overloads for perfectly forwarding the contructor \r
+ * arguments of T and creating a unique_ptr to the created T instance.\r
+ */\r
template<typename T, typename D = std::default_delete<T>>\r
class unique_ptr\r
{ \r
\r
// shared_ptr\r
\r
+/**\r
+ * A wrapper around std::shared_ptr ensuring that it never points to a null \r
+ * pointer except in the case of a moved from instance.\r
+ * \r
+ * A default constructed shared_ptr will point to a default constructed T.\r
+ * \r
+ * Use the make_shared overloads for perfect forwarding of the constructor \r
+ * arguments of T which will return a shared_ptr pointing to the constructed T.\r
+ */\r
template<typename T>\r
class shared_ptr\r
{ \r
#include <boost/assign/list_of.hpp>\r
#include <boost/regex.hpp>\r
#include <boost/lexical_cast.hpp>\r
+#include <boost/range/adaptor/map.hpp>\r
\r
#include <unordered_map>\r
#include <string>\r
return ease_in_bounce((t*2)-d, b+c/2, c/2, d, params);\r
}\r
\r
-tweener_t get_tweener(std::wstring name)\r
-{\r
- std::transform(name.begin(), name.end(), name.begin(), std::tolower);\r
+typedef std::function<double(double, double, double, double, const std::vector<double>&)> tween_t; \r
\r
- if(name == L"linear")\r
- return [](double t, double b, double c, double d){return ease_none(t, b, c, d, std::vector<double>());};\r
- \r
- std::vector<double> params;\r
- \r
- static const boost::wregex expr(L"(?<NAME>\\w*)(:(?<V0>\\d+\\.?\\d?))?(:(?<V1>\\d+\\.?\\d?))?"); // boost::regex has no repeated captures?\r
- boost::wsmatch what;\r
- if(boost::regex_match(name, what, expr))\r
- {\r
- name = what["NAME"].str();\r
- if(what["V0"].matched)\r
- params.push_back(boost::lexical_cast<double>(what["V0"].str()));\r
- if(what["V1"].matched)\r
- params.push_back(boost::lexical_cast<double>(what["V1"].str()));\r
- }\r
- \r
- typedef std::function<double(double, double, double, double, const std::vector<double>&)> tween_t; \r
+const std::unordered_map<std::wstring, tween_t>& get_tweens()\r
+{\r
static const std::unordered_map<std::wstring, tween_t> tweens = boost::assign::map_list_of \r
(L"", ease_none ) \r
(L"linear", ease_none ) \r
(L"easeinoutbounce", ease_in_out_bounce )\r
(L"easeoutinbounce", ease_out_in_bounce );\r
\r
+ return tweens;\r
+}\r
+\r
+tweener_t get_tweener(std::wstring name)\r
+{\r
+ std::transform(name.begin(), name.end(), name.begin(), std::tolower);\r
+\r
+ if(name == L"linear")\r
+ return [](double t, double b, double c, double d){return ease_none(t, b, c, d, std::vector<double>());};\r
+ \r
+ std::vector<double> params;\r
+ \r
+ static const boost::wregex expr(L"(?<NAME>\\w*)(:(?<V0>\\d+\\.?\\d?))?(:(?<V1>\\d+\\.?\\d?))?"); // boost::regex has no repeated captures?\r
+ boost::wsmatch what;\r
+ if(boost::regex_match(name, what, expr))\r
+ {\r
+ name = what["NAME"].str();\r
+ if(what["V0"].matched)\r
+ params.push_back(boost::lexical_cast<double>(what["V0"].str()));\r
+ if(what["V1"].matched)\r
+ params.push_back(boost::lexical_cast<double>(what["V1"].str()));\r
+ }\r
+ \r
+ auto tweens = get_tweens();\r
+\r
auto it = tweens.find(name);\r
if(it == tweens.end())\r
CASPAR_THROW_EXCEPTION(invalid_argument() << msg_info("Could not find tween.") << arg_value_info(name));\r
return func_(t, b, c, d);\r
}\r
\r
-}}
\ No newline at end of file
+const std::vector<std::wstring>& tweener::names()\r
+{\r
+ using namespace boost::adaptors;\r
+\r
+ static const std::vector<std::wstring> names(\r
+ (get_tweens() | map_keys).begin(),\r
+ (get_tweens() | map_keys).end());\r
+\r
+ return names;\r
+}\r
+\r
+}}\r
#pragma once\r
\r
#include <functional>\r
+#include <vector>\r
\r
namespace caspar { namespace core {\r
\r
+/**\r
+ * A tweener can be used for creating any kind of (image position, image fade\r
+ * in/out, audio volume etc) transition, by invoking it for each temporal\r
+ * timepoint when a tweened value is needed.\r
+ *\r
+ * For video the temporal resolution will usually be each frame or field (for\r
+ * interlaced material).\r
+ *\r
+ * For audio the smoothest transitions will be generated by using the samplerate\r
+ * as temporal resolution, but using the video frame/field rate is probably fine\r
+ * most of the times and much less time consuming.\r
+ */\r
class tweener\r
{\r
public:\r
+ /**\r
+ * Constructor.\r
+ *\r
+ * @param name The name of the tween function to use.\r
+ */\r
tweener(const std::wstring& name = L"linear");\r
tweener(const wchar_t* name);\r
+\r
+ /**\r
+ * @return The possible tween function names. Some of them may also support\r
+ * additional parameters appended to the name.\r
+ */\r
+ static const std::vector<std::wstring>& names();\r
+\r
+ /**\r
+ * Calculate a tweened value given a timepoint within the total duration\r
+ * and the starting value and the destination delta value.\r
+ *\r
+ * Usually b, c and d remains constant during a transition, while t changes\r
+ * for each temporal tweened value.\r
+ * \r
+ * @param t The timepoint within the total duration (0 <= n <= d).\r
+ * @param b The starting value.\r
+ * @param c The destination value delta from the starting value\r
+ * (absolute destination value - b).\r
+ * @param d The total duration (when t = d, the destination value should\r
+ * have been reached).\r
+ *\r
+ * @return The tweened value for the given timepoint. Can sometimes be less\r
+ * than b or greater than b + c for some tweener functions.\r
+ */\r
double operator()(double t, double b , double c, double d) const;\r
private:\r
std::function<double(double, double, double, double)> func_;\r