* Created a new executable called generate_docs which generates the relevant parts of the wiki which can be auto generated from the online help.
frame/geometry.cpp
help/help_repository.cpp
+ help/util.cpp
mixer/audio/audio_mixer.cpp
mixer/image/blend_modes.cpp
help/help_repository.h
help/help_sink.h
+ help/util.h
interaction/interaction_aggregator.h
interaction/interaction_event.h
FORWARD2(caspar, core, struct frame_producer_dependencies);
FORWARD2(caspar, core, class help_sink);
FORWARD2(caspar, core, class help_repository);
+FORWARD2(caspar, core, struct module_dependencies);
+FORWARD2(caspar, core, class frame_producer_registry);
--- /dev/null
+/*
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
+*
+* This file is part of CasparCG (www.casparcg.com).
+*
+* CasparCG is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* CasparCG is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
+*
+* Author: Helge Norberg, helge.norberg@svt.se
+*/
+
+#include "util.h"
+
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
+#include <list>
+#include <vector>
+#include <sstream>
+
+namespace caspar { namespace core {
+
+void wordwrap_line(const std::wstring& line, int width, std::wostream& result)
+{
+ std::list<std::wstring> words;
+ boost::split(words, line, boost::is_any_of(L" "), boost::algorithm::token_compress_on);
+
+ size_t current_width = 0;
+ bool first = true;
+
+ while (!words.empty())
+ {
+ auto word = std::move(words.front());
+ words.pop_front();
+
+ if (first)
+ {
+ current_width = word.length();
+ result << std::move(word);
+ first = false;
+ }
+ else if (current_width + 1 + word.length() > width)
+ {
+ result << L"\n";
+ current_width = word.length();
+ result << std::move(word);
+ }
+ else
+ {
+ current_width += 1 + word.length();
+ result << L" " << std::move(word);
+ }
+ }
+}
+
+std::wstring wordwrap(const std::wstring& text, int width)
+{
+ std::vector<std::wstring> lines;
+ boost::split(lines, text, boost::is_any_of(L"\n"));
+
+ std::wstringstream result;
+
+ for (auto& line : lines)
+ {
+ wordwrap_line(line, width, result);
+ result << L"\n";
+ }
+
+ return result.str();
+}
+
+std::wstring indent(std::wstring text, const std::wstring& indent)
+{
+ text.insert(0, indent);
+ bool last_is_newline = text.at(text.length() - 1) == L'\n';
+
+ if (last_is_newline)
+ text.erase(text.length() - 1);
+
+ boost::replace_all(text, L"\n", L"\n" + indent);
+
+ if (last_is_newline)
+ text += L'\n';
+
+ return text;
+}
+
+}}
--- /dev/null
+/*
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
+*
+* This file is part of CasparCG (www.casparcg.com).
+*
+* CasparCG is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* CasparCG is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
+*
+* Author: Helge Norberg, helge.norberg@svt.se
+*/
+
+#pragma once
+
+#include <string>
+
+namespace caspar { namespace core {
+
+std::wstring wordwrap(const std::wstring& text, int width);
+std::wstring indent(std::wstring text, const std::wstring& indent);
+
+}}
#include "system_info_provider.h"
#include "producer/cg_proxy.h"
#include "producer/media_info/media_info_repository.h"
+#include "producer/frame_producer.h"
namespace caspar { namespace core {
const spl::shared_ptr<system_info_provider_repository> system_info_provider_repo;
const spl::shared_ptr<cg_producer_registry> cg_registry;
const spl::shared_ptr<media_info_repository> media_info_repo;
+ const spl::shared_ptr<frame_producer_registry> producer_registry;
module_dependencies(
spl::shared_ptr<system_info_provider_repository> system_info_provider_repo,
spl::shared_ptr<cg_producer_registry> cg_registry,
- spl::shared_ptr<media_info_repository> media_info_repo)
+ spl::shared_ptr<media_info_repository> media_info_repo,
+ spl::shared_ptr<frame_producer_registry> producer_registry)
: system_info_provider_repo(std::move(system_info_provider_repo))
, cg_registry(std::move(cg_registry))
, media_info_repo(std::move(media_info_repo))
+ , producer_registry(std::move(producer_registry))
{
}
};
#include <boost/thread.hpp>
namespace caspar { namespace core {
-
-std::vector<producer_factory_t> g_producer_factories;
-std::vector<producer_factory_t> g_thumbnail_factories;
-void register_producer_factory(const producer_factory_t& factory)
+struct frame_producer_registry::impl
+{
+ std::vector<producer_factory_t> producer_factories;
+ std::vector<producer_factory_t> thumbnail_factories;
+};
+
+frame_producer_registry::frame_producer_registry()
+ : impl_(new impl)
+{
+}
+
+void frame_producer_registry::register_producer_factory(const producer_factory_t& factory)
{
- g_producer_factories.push_back(factory);
+ impl_->producer_factories.push_back(factory);
}
-void register_thumbnail_producer_factory(const producer_factory_t& factory)
+
+void frame_producer_registry::register_thumbnail_producer_factory(const producer_factory_t& factory)
{
- g_thumbnail_factories.push_back(factory);
+ impl_->thumbnail_factories.push_back(factory);
}
frame_producer_dependencies::frame_producer_dependencies(
const spl::shared_ptr<core::frame_factory>& frame_factory,
const std::vector<spl::shared_ptr<video_channel>>& channels,
- const video_format_desc& format_desc)
+ const video_format_desc& format_desc,
+ const spl::shared_ptr<const frame_producer_registry> producer_registry)
: frame_factory(frame_factory)
, channels(channels)
, format_desc(format_desc)
+ , producer_registry(producer_registry)
{
}
return producer;
}
-spl::shared_ptr<core::frame_producer> create_thumbnail_producer(const frame_producer_dependencies& dependencies, const std::wstring& media_file)
+spl::shared_ptr<core::frame_producer> frame_producer_registry::create_thumbnail_producer(const frame_producer_dependencies& dependencies, const std::wstring& media_file) const
{
- std::vector<std::wstring> params;
- params.push_back(media_file);
+ auto& thumbnail_factories = impl_->thumbnail_factories;
+ std::vector<std::wstring> params;
+ params.push_back(media_file);
- auto producer = do_create_producer(dependencies, params, g_thumbnail_factories, true);
- auto key_producer = frame_producer::empty();
+ auto producer = do_create_producer(dependencies, params, thumbnail_factories, true);
+ auto key_producer = frame_producer::empty();
- try // to find a key file.
- {
- auto params_copy = params;
- if (params_copy.size() > 0)
+ try // to find a key file.
{
- params_copy[0] += L"_A";
- key_producer = do_create_producer(dependencies, params_copy, g_thumbnail_factories, true);
- if (key_producer == frame_producer::empty())
- {
- params_copy[0] += L"LPHA";
- key_producer = do_create_producer(dependencies, params_copy, g_thumbnail_factories, true);
- }
+ auto params_copy = params;
+ if (params_copy.size() > 0)
+ {
+ params_copy[0] += L"_A";
+ key_producer = do_create_producer(dependencies, params_copy, thumbnail_factories, true);
+ if (key_producer == frame_producer::empty())
+ {
+ params_copy[0] += L"LPHA";
+ key_producer = do_create_producer(dependencies, params_copy, thumbnail_factories, true);
+ }
+ }
}
- }
- catch(...){}
+ catch(...){}
- if (producer != frame_producer::empty() && key_producer != frame_producer::empty())
- return create_separated_producer(producer, key_producer);
+ if (producer != frame_producer::empty() && key_producer != frame_producer::empty())
+ return create_separated_producer(producer, key_producer);
- return producer;
+ return producer;
}
-spl::shared_ptr<core::frame_producer> create_producer(const frame_producer_dependencies& dependencies, const std::vector<std::wstring>& params)
+spl::shared_ptr<core::frame_producer> frame_producer_registry::create_producer(const frame_producer_dependencies& dependencies, const std::vector<std::wstring>& params) const
{
- auto producer = do_create_producer(dependencies, params, g_producer_factories);
+ auto& producer_factories = impl_->producer_factories;
+ auto producer = do_create_producer(dependencies, params, producer_factories);
auto key_producer = frame_producer::empty();
try // to find a key file.
if(params_copy.size() > 0)
{
params_copy[0] += L"_A";
- key_producer = do_create_producer(dependencies, params_copy, g_producer_factories);
+ key_producer = do_create_producer(dependencies, params_copy, producer_factories);
if(key_producer == frame_producer::empty())
{
params_copy[0] += L"LPHA";
- key_producer = do_create_producer(dependencies, params_copy, g_producer_factories);
+ key_producer = do_create_producer(dependencies, params_copy, producer_factories);
}
}
}
}
-spl::shared_ptr<core::frame_producer> create_producer(const frame_producer_dependencies& dependencies, const std::wstring& params)
+spl::shared_ptr<core::frame_producer> frame_producer_registry::create_producer(const frame_producer_dependencies& dependencies, const std::wstring& params) const
{
std::wstringstream iss(params);
std::vector<std::wstring> tokens;
std::shared_ptr<impl> impl_;
};
+class frame_producer_registry;
+
struct frame_producer_dependencies
{
- spl::shared_ptr<core::frame_factory> frame_factory;
- std::vector<spl::shared_ptr<video_channel>> channels;
- video_format_desc format_desc;
+ spl::shared_ptr<core::frame_factory> frame_factory;
+ std::vector<spl::shared_ptr<video_channel>> channels;
+ video_format_desc format_desc;
+ spl::shared_ptr<const frame_producer_registry> producer_registry;
frame_producer_dependencies(
const spl::shared_ptr<core::frame_factory>& frame_factory,
const std::vector<spl::shared_ptr<video_channel>>& channels,
- const video_format_desc& format_desc);
+ const video_format_desc& format_desc,
+ const spl::shared_ptr<const frame_producer_registry> producer_registry);
};
typedef std::function<spl::shared_ptr<core::frame_producer>(const frame_producer_dependencies&, const std::vector<std::wstring>&)> producer_factory_t;
-void register_producer_factory(const producer_factory_t& factory); // Not thread-safe.
-void register_thumbnail_producer_factory(const producer_factory_t& factory); // Not thread-safe.
-spl::shared_ptr<core::frame_producer> create_producer(const frame_producer_dependencies&, const std::vector<std::wstring>& params);
-spl::shared_ptr<core::frame_producer> create_producer(const frame_producer_dependencies&, const std::wstring& params);
+class frame_producer_registry : boost::noncopyable
+{
+public:
+ frame_producer_registry();
+ void register_producer_factory(const producer_factory_t& factory); // Not thread-safe.
+ void register_thumbnail_producer_factory(const producer_factory_t& factory); // Not thread-safe.
+ spl::shared_ptr<core::frame_producer> create_producer(const frame_producer_dependencies&, const std::vector<std::wstring>& params) const;
+ spl::shared_ptr<core::frame_producer> create_producer(const frame_producer_dependencies&, const std::wstring& params) const;
+ spl::shared_ptr<core::frame_producer> create_thumbnail_producer(const frame_producer_dependencies&, const std::wstring& media_file) const;
+private:
+ struct impl;
+ spl::shared_ptr<impl> impl_;
+};
spl::shared_ptr<core::frame_producer> create_destroy_proxy(spl::shared_ptr<core::frame_producer> producer);
-spl::shared_ptr<core::frame_producer> create_thumbnail_producer(const frame_producer_dependencies&, const std::wstring& media_file);
}}
void init(module_dependencies dependencies)
{
- register_producer_factory(create_xml_scene_producer);
+ dependencies.producer_registry->register_producer_factory(create_xml_scene_producer);
dependencies.cg_registry->register_cg_producer(
L"scene",
{ L".scene" },
for (auto& elem : root.get_child(L"scene.layers"))
{
auto id = elem.second.get<std::wstring>(L"<xmlattr>.id");
- auto producer = create_producer(dependencies, elem.second.get<std::wstring>(L"producer"));
+ auto producer = dependencies.producer_registry->create_producer(dependencies, elem.second.get<std::wstring>(L"producer"));
auto& layer = scene->create_layer(producer, 0, 0, id);
auto variable_prefix = L"layer." + id + L".";
#include <core/frame/geometry.h>
#include <core/frame/frame.h>
#include <core/frame/draw_frame.h>
-
#include <core/frame/frame_factory.h>
#include <core/frame/pixel_format.h>
#include <core/monitor/monitor.h>
-
#include <core/consumer/frame_consumer.h>
+#include <core/module_dependencies.h>
+
#include <modules/image/consumer/image_consumer.h>
#include <common/except.h>
return result;
}
- void init()
+ void init(module_dependencies dependencies)
{
fonts = enumerate_fonts();
- register_producer_factory(&create_text_producer);
+ dependencies.producer_registry->register_producer_factory(create_text_producer);
}
text_info& find_font_file(text_info& info)
namespace caspar { namespace core {
namespace text
{
- void init();
+ void init(module_dependencies dependencies);
}
class text_producer : public frame_producer_base
struct thumbnail_generator::impl
{
private:
- boost::filesystem::path media_path_;
- boost::filesystem::path thumbnails_path_;
- int width_;
- int height_;
- spl::shared_ptr<image_mixer> image_mixer_;
- spl::shared_ptr<diagnostics::graph> graph_;
- video_format_desc format_desc_;
- spl::unique_ptr<thumbnail_output> output_;
- mixer mixer_;
- thumbnail_creator thumbnail_creator_;
- spl::shared_ptr<media_info_repository> media_info_repo_;
- bool mipmap_;
- filesystem_monitor::ptr monitor_;
+ boost::filesystem::path media_path_;
+ boost::filesystem::path thumbnails_path_;
+ int width_;
+ int height_;
+ spl::shared_ptr<image_mixer> image_mixer_;
+ spl::shared_ptr<diagnostics::graph> graph_;
+ video_format_desc format_desc_;
+ spl::unique_ptr<thumbnail_output> output_;
+ mixer mixer_;
+ thumbnail_creator thumbnail_creator_;
+ spl::shared_ptr<media_info_repository> media_info_repo_;
+ spl::shared_ptr<const frame_producer_registry> producer_registry_;
+ bool mipmap_;
+ filesystem_monitor::ptr monitor_;
public:
impl(
filesystem_monitor_factory& monitor_factory,
int generate_delay_millis,
const thumbnail_creator& thumbnail_creator,
spl::shared_ptr<media_info_repository> media_info_repo,
+ spl::shared_ptr<const frame_producer_registry> producer_registry,
bool mipmap)
: media_path_(media_path)
, thumbnails_path_(thumbnails_path)
, mixer_(graph_, image_mixer_)
, thumbnail_creator_(thumbnail_creator)
, media_info_repo_(std::move(media_info_repo))
+ , producer_registry_(std::move(producer_registry))
, monitor_(monitor_factory.create(
media_path,
filesystem_event::ALL,
try
{
- producer = create_thumbnail_producer(
- frame_producer_dependencies(image_mixer_, { }, format_desc_),
+ producer = producer_registry_->create_thumbnail_producer(
+ frame_producer_dependencies(image_mixer_, { }, format_desc_, producer_registry_),
media_file);
}
catch (const boost::thread_interrupted&)
int generate_delay_millis,
const thumbnail_creator& thumbnail_creator,
spl::shared_ptr<media_info_repository> media_info_repo,
+ spl::shared_ptr<const frame_producer_registry> producer_registry,
bool mipmap)
: impl_(new impl(
monitor_factory,
generate_delay_millis,
thumbnail_creator,
media_info_repo,
+ producer_registry,
mipmap))
{
}
int generate_delay_millis,
const thumbnail_creator& thumbnail_creator,
spl::shared_ptr<media_info_repository> media_info_repo,
+ spl::shared_ptr<const frame_producer_registry> producer_registry,
bool mipmap);
~thumbnail_generator();
void generate(const std::wstring& media_file);
{
core::register_consumer_factory(create_consumer);
core::register_preconfigured_consumer_factory(L"decklink", create_preconfigured_consumer);
- core::register_producer_factory(create_producer);
+ dependencies.producer_registry->register_producer_factory(create_producer);
dependencies.system_info_provider_repo->register_system_info_provider([](boost::property_tree::wptree& info)
{
info.add(L"system.decklink.version", version());
core::register_consumer_factory(create_streaming_consumer);
core::register_preconfigured_consumer_factory(L"file", create_preconfigured_consumer);
core::register_preconfigured_consumer_factory(L"stream", create_preconfigured_streaming_consumer);
- core::register_producer_factory(create_producer);
+ dependencies.producer_registry->register_producer_factory(create_producer);
dependencies.media_info_repo->register_extractor(
[](const std::wstring& file, const std::wstring& extension, core::media_info& info) -> bool
void init(core::module_dependencies dependencies)
{
- core::register_producer_factory(create_ct_producer);
- core::register_producer_factory(create_swf_producer);
+ dependencies.producer_registry->register_producer_factory(create_ct_producer);
+ dependencies.producer_registry->register_producer_factory(create_swf_producer);
dependencies.media_info_repo->register_extractor([](const std::wstring& file, const std::wstring& extension, core::media_info& info)
{
if (extension != L".CT" && extension != L".SWF")
void init(core::module_dependencies dependencies)
{
- core::register_producer_factory(html::create_producer);
+ dependencies.producer_registry->register_producer_factory(html::create_producer);
CefMainArgs main_args;
g_cef_executor.reset(new executor(L"cef"));
void init(core::module_dependencies dependencies)
{
FreeImage_Initialise();
- core::register_producer_factory(create_scroll_producer);
- core::register_producer_factory(create_producer);
- core::register_thumbnail_producer_factory(create_thumbnail_producer);
+ dependencies.producer_registry->register_producer_factory(create_scroll_producer);
+ dependencies.producer_registry->register_producer_factory(create_producer);
+ dependencies.producer_registry->register_thumbnail_producer_factory(create_thumbnail_producer);
core::register_consumer_factory(create_consumer);
dependencies.media_info_repo->register_extractor([](const std::wstring& file, const std::wstring& extension, core::media_info& info)
{
void init(core::module_dependencies dependencies)
{
- core::register_producer_factory(create_psd_scene_producer);
+ dependencies.producer_registry->register_producer_factory(create_psd_scene_producer);
dependencies.media_info_repo->register_extractor(
[](const std::wstring& file, const std::wstring& upper_case_extension, core::media_info& info)
{
void init(core::module_dependencies dependencies)
{
- core::register_producer_factory(reroute::create_producer);
+ dependencies.producer_registry->register_producer_factory(reroute::create_producer);
}
}}
spl::shared_ptr<core::cg_producer_registry> cg_registry;
spl::shared_ptr<core::system_info_provider_repository> system_info_repo;
std::shared_ptr<core::thumbnail_generator> thumb_gen;
+ spl::shared_ptr<const core::frame_producer_registry> producer_registry;
std::promise<bool>& shutdown_server_now;
std::vector<std::wstring> parameters;
spl::shared_ptr<core::cg_producer_registry> cg_registry,
spl::shared_ptr<core::system_info_provider_repository> system_info_repo,
std::shared_ptr<core::thumbnail_generator> thumb_gen,
+ spl::shared_ptr<const core::frame_producer_registry> producer_registry,
std::promise<bool>& shutdown_server_now)
: client(std::move(client))
, channel(channel)
, cg_registry(std::move(cg_registry))
, system_info_repo(std::move(system_info_repo))
, thumb_gen(std::move(thumb_gen))
+ , producer_registry(std::move(producer_registry))
, shutdown_server_now(shutdown_server_now)
{
}
#include <core/producer/frame_producer.h>
#include <core/help/help_repository.h>
#include <core/help/help_sink.h>
+#include <core/help/util.h>
#include <core/video_format.h>
#include <core/producer/transition/transition_producer.h>
#include <core/frame/frame_transform.h>
cpplinq::from(ctx.channels)
.select([](channel_context c) { return spl::make_shared_ptr(c.channel); })
.to_vector(),
- channel->video_format_desc());
+ channel->video_format_desc(),
+ ctx.producer_registry);
}
// Basic Commands
core::diagnostics::call_context::for_thread().layer = ctx.layer_index();
auto channel = ctx.channel.channel;
- auto pFP = create_producer(get_producer_dependencies(channel, ctx), ctx.parameters);
+ auto pFP = ctx.producer_registry->create_producer(get_producer_dependencies(channel, ctx), ctx.parameters);
if (pFP == frame_producer::empty())
CASPAR_THROW_EXCEPTION(file_not_found() << msg_info(ctx.parameters.size() > 0 ? ctx.parameters[0] : L""));
core::diagnostics::scoped_call_context save;
core::diagnostics::call_context::for_thread().video_channel = ctx.channel_index + 1;
core::diagnostics::call_context::for_thread().layer = ctx.layer_index();
- auto pFP = create_producer(get_producer_dependencies(ctx.channel.channel, ctx), ctx.parameters);
+ auto pFP = ctx.producer_registry->create_producer(get_producer_dependencies(ctx.channel.channel, ctx), ctx.parameters);
ctx.channel.channel->stage().load(ctx.layer_index(), pFP, true);
return L"202 LOAD OK\r\n";
->text(L"If no argument is given the current state is returned.");
sink.para()->text(L"Mipmapping reduces aliasing when downscaling/perspective transforming.");
sink.para()->text(L"Examples:");
- sink.example(L">> MIXER 1-10 MIPMAP 1", L"for turing mipmapping on");
+ sink.example(L">> MIXER 1-10 MIPMAP 1", L"for turning mipmapping on");
sink.example(
L">> MIXER 1-10 MIPMAP\n"
L"<< 201 MIXER OK\n"
if (channel.channel != self.channel)
{
core::diagnostics::call_context::for_thread().layer = index;
- auto producer = create_producer(get_producer_dependencies(channel.channel, ctx), L"route://" + boost::lexical_cast<std::wstring>(channel.channel->index()));
+ auto producer = ctx.producer_registry->create_producer(get_producer_dependencies(channel.channel, ctx), L"route://" + boost::lexical_cast<std::wstring>(channel.channel->index()));
self.channel->stage().load(index, producer, false);
self.channel->stage().play(index);
index++;
std::wstring help_command(command_context& ctx)
{
+ static const int WIDTH = 80;
struct max_width_sink : public core::help_sink
{
std::size_t max_width = 0;
struct simple_paragraph_builder : core::paragraph_builder
{
- std::wstringstream& out;
+ std::wostringstream out;
+ std::wstringstream& commit_to;
- simple_paragraph_builder(std::wstringstream& out) : out(out) { }
+ simple_paragraph_builder(std::wstringstream& out) : commit_to(out) { }
~simple_paragraph_builder()
{
- out << L"\n\n";
+ commit_to << core::wordwrap(out.str(), WIDTH) << L"\n";
}
spl::shared_ptr<paragraph_builder> text(std::wstring text) override
{
std::wstringstream& out;
simple_definition_list_builder(std::wstringstream& out) : out(out) { }
+ ~simple_definition_list_builder()
+ {
+ out << L"\n";
+ }
+
spl::shared_ptr<definition_list_builder> item(std::wstring term, std::wstring description) override
{
- out << L" " << std::move(term) << L"\n";
- out << L" " << std::move(description) << L"\n\n";
+ out << core::indent(core::wordwrap(term, WIDTH - 2), L" ");
+ out << core::indent(core::wordwrap(description, WIDTH - 4), L" ");
return shared_from_this();
}
};
void syntax(const std::wstring& syntax) override
{
- out << L"Syntax\n";
- out << L" " << syntax << L"\n\n";
+ out << L"Syntax:\n";
+ out << core::indent(core::wordwrap(syntax, WIDTH - 2), L" ") << L"\n";
};
spl::shared_ptr<core::paragraph_builder> para() override
void example(const std::wstring& code, const std::wstring& caption = L"") override
{
- out << L" " << code << L"\n";
+ out << core::indent(core::wordwrap(code, WIDTH - 2), L" ");
+
if (!caption.empty())
- out << L" ..." << caption << L"\n";
+ out << core::indent(core::wordwrap(L"..." + caption, WIDTH - 2), L" ");
+
out << L"\n";
}
private:
spl::shared_ptr<core::system_info_provider_repository> system_info_provider_repo;
spl::shared_ptr<core::cg_producer_registry> cg_registry;
spl::shared_ptr<core::help_repository> help_repo;
+ spl::shared_ptr<const core::frame_producer_registry> producer_registry;
std::promise<bool>& shutdown_server_now;
std::map<std::wstring, std::pair<amcp_command_func, int>> commands;
const spl::shared_ptr<core::system_info_provider_repository>& system_info_provider_repo,
const spl::shared_ptr<core::cg_producer_registry>& cg_registry,
const spl::shared_ptr<core::help_repository>& help_repo,
+ const spl::shared_ptr<const core::frame_producer_registry>& producer_registry,
std::promise<bool>& shutdown_server_now)
: thumb_gen(thumb_gen)
, media_info_repo(media_info_repo)
, system_info_provider_repo(system_info_provider_repo)
, cg_registry(cg_registry)
, help_repo(help_repo)
+ , producer_registry(producer_registry)
, shutdown_server_now(shutdown_server_now)
{
int index = 0;
const spl::shared_ptr<core::system_info_provider_repository>& system_info_provider_repo,
const spl::shared_ptr<core::cg_producer_registry>& cg_registry,
const spl::shared_ptr<core::help_repository>& help_repo,
+ const spl::shared_ptr<const core::frame_producer_registry>& producer_registry,
std::promise<bool>& shutdown_server_now)
- : impl_(new impl(channels, thumb_gen, media_info_repo, system_info_provider_repo, cg_registry, help_repo, shutdown_server_now))
+ : impl_(new impl(channels, thumb_gen, media_info_repo, system_info_provider_repo, cg_registry, help_repo, producer_registry, shutdown_server_now))
{
}
-AMCPCommand::ptr_type amcp_command_repository::create_command(const std::wstring& s, IO::ClientInfoPtr client, std::list<std::wstring>& tokens)
+AMCPCommand::ptr_type amcp_command_repository::create_command(const std::wstring& s, IO::ClientInfoPtr client, std::list<std::wstring>& tokens) const
{
auto& self = *impl_;
command_context ctx(
- client,
+ std::move(client),
channel_context(),
-1,
-1,
self.cg_registry,
self.system_info_provider_repo,
self.thumb_gen,
+ self.producer_registry,
self.shutdown_server_now);
auto command = find_command(self.commands, s, ctx, tokens);
IO::ClientInfoPtr client,
unsigned int channel_index,
int layer_index,
- std::list<std::wstring>& tokens)
+ std::list<std::wstring>& tokens) const
{
auto& self = *impl_;
self.cg_registry,
self.system_info_provider_repo,
self.thumb_gen,
+ self.producer_registry,
self.shutdown_server_now);
auto command = find_command(self.channel_commands, s, ctx, tokens);
const spl::shared_ptr<core::system_info_provider_repository>& system_info_provider_repo,
const spl::shared_ptr<core::cg_producer_registry>& cg_registry,
const spl::shared_ptr<core::help_repository>& help_repo,
+ const spl::shared_ptr<const core::frame_producer_registry>& producer_registry,
std::promise<bool>& shutdown_server_now);
- AMCPCommand::ptr_type create_command(const std::wstring& s, IO::ClientInfoPtr client, std::list<std::wstring>& tokens);
+ AMCPCommand::ptr_type create_command(const std::wstring& s, IO::ClientInfoPtr client, std::list<std::wstring>& tokens) const;
AMCPCommand::ptr_type create_channel_command(
const std::wstring& s,
IO::ClientInfoPtr client,
unsigned int channel_index,
int layer_index,
- std::list<std::wstring>& tokens);
+ std::list<std::wstring>& tokens) const;
const std::vector<channel_context>& channels() const;
CIIProtocolStrategy::CIIProtocolStrategy(
const std::vector<spl::shared_ptr<core::video_channel>>& channels,
- const spl::shared_ptr<core::cg_producer_registry>& cg_registry)
+ const spl::shared_ptr<core::cg_producer_registry>& cg_registry,
+ const spl::shared_ptr<const core::frame_producer_registry>& producer_registry)
: executor_(L"CIIProtocolStrategy")
, pChannel_(channels.at(0))
, channels_(channels)
, cg_registry_(cg_registry)
+ , producer_registry_(producer_registry)
{
}
core::diagnostics::call_context::for_thread().video_channel = 1;
core::diagnostics::call_context::for_thread().layer = 0;
- auto pFP = create_producer(get_dependencies(), filename);
+ auto pFP = get_producer_registry()->create_producer(get_dependencies(), filename);
auto pTransition = create_transition_producer(GetChannel()->video_format_desc().field_mode, pFP, transition);
try
class CIIProtocolStrategy : public IO::IProtocolStrategy
{
public:
- CIIProtocolStrategy(const std::vector<spl::shared_ptr<core::video_channel>>& channels, const spl::shared_ptr<core::cg_producer_registry>& cg_registry);
+ CIIProtocolStrategy(
+ const std::vector<spl::shared_ptr<core::video_channel>>& channels,
+ const spl::shared_ptr<core::cg_producer_registry>& cg_registry,
+ const spl::shared_ptr<const core::frame_producer_registry>& producer_registry);
void Parse(const std::wstring& message, IO::ClientInfoPtr pClientInfo);
std::string GetCodepage() const { return "ISO-8859-1"; } //ISO 8859-1
spl::shared_ptr<core::video_channel> GetChannel() const { return pChannel_; }
spl::shared_ptr<core::cg_producer_registry> get_cg_registry() const { return cg_registry_; }
- core::frame_producer_dependencies get_dependencies() const { return core::frame_producer_dependencies(GetChannel()->frame_factory(), channels_, GetChannel()->video_format_desc()); }
+ spl::shared_ptr<const core::frame_producer_registry> get_producer_registry() const { return producer_registry_; }
+ core::frame_producer_dependencies get_dependencies() const { return core::frame_producer_dependencies(GetChannel()->frame_factory(), channels_, GetChannel()->video_format_desc(), producer_registry_); }
void DisplayMediaFile(const std::wstring& filename);
void DisplayTemplate(const std::wstring& titleName);
std::wstring currentProfile_;
spl::shared_ptr<core::video_channel> pChannel_;
spl::shared_ptr<core::cg_producer_registry> cg_registry_;
+ spl::shared_ptr<const core::frame_producer_registry> producer_registry_;
std::vector<spl::shared_ptr<core::video_channel>> channels_;
};
clk_protocol_strategy_factory::clk_protocol_strategy_factory(
const std::vector<spl::shared_ptr<core::video_channel>>& channels,
- const spl::shared_ptr<core::cg_producer_registry>& cg_registry)
+ const spl::shared_ptr<core::cg_producer_registry>& cg_registry,
+ const spl::shared_ptr<const core::frame_producer_registry>& producer_registry)
{
- add_command_handlers(command_processor_, channels, channels.at(0), cg_registry);
+ add_command_handlers(command_processor_, channels, channels.at(0), cg_registry, producer_registry);
}
IO::protocol_strategy<wchar_t>::ptr clk_protocol_strategy_factory::create(
public:
clk_protocol_strategy_factory(
const std::vector<spl::shared_ptr<core::video_channel>>& channels,
- const spl::shared_ptr<core::cg_producer_registry>& cg_registry);
+ const spl::shared_ptr<core::cg_producer_registry>& cg_registry,
+ const spl::shared_ptr<const core::frame_producer_registry>& producer_registry);
virtual IO::protocol_strategy<wchar_t>::ptr create(
const IO::client_connection<wchar_t>::ptr& client_connection);
\r
class command_context\r
{\r
- bool clock_loaded_ = false;\r
- std::vector<spl::shared_ptr<core::video_channel>> channels_;\r
- spl::shared_ptr<core::video_channel> channel_;\r
- spl::shared_ptr<core::cg_producer_registry> cg_registry_;\r
+ bool clock_loaded_ = false;\r
+ std::vector<spl::shared_ptr<core::video_channel>> channels_;\r
+ spl::shared_ptr<core::video_channel> channel_;\r
+ spl::shared_ptr<core::cg_producer_registry> cg_registry_;\r
+ spl::shared_ptr<const core::frame_producer_registry> producer_registry_;\r
public:\r
command_context(\r
const std::vector<spl::shared_ptr<core::video_channel>>& channels,\r
const spl::shared_ptr<core::video_channel>& channel,\r
- const spl::shared_ptr<core::cg_producer_registry>& cg_registry)\r
+ const spl::shared_ptr<core::cg_producer_registry>& cg_registry,\r
+ const spl::shared_ptr<const core::frame_producer_registry>& producer_registry)\r
: channels_(channels)\r
, channel_(channel)\r
, cg_registry_(cg_registry)\r
+ , producer_registry_(producer_registry)\r
{\r
}\r
\r
{\r
if (!clock_loaded_) \r
{\r
- core::frame_producer_dependencies dependencies(channel_->frame_factory(), channels_, channel_->video_format_desc());\r
+ core::frame_producer_dependencies dependencies(channel_->frame_factory(), channels_, channel_->video_format_desc(), producer_registry_);\r
cg_registry_->get_or_create_proxy(channel_, dependencies, core::cg_proxy::DEFAULT_LAYER, L"hawrysklocka/clock")->add(\r
- 0, L"hawrysklocka/clock", true, L"", data);\r
+ 0, L"hawrysklocka/clock", true, L"", data);\r
clock_loaded_ = true;\r
}\r
else\r
clk_command_processor& processor,\r
const std::vector<spl::shared_ptr<core::video_channel>>& channels,\r
const spl::shared_ptr<core::video_channel>& channel,\r
- const spl::shared_ptr<core::cg_producer_registry>& cg_registry)\r
+ const spl::shared_ptr<core::cg_producer_registry>& cg_registry,\r
+ const spl::shared_ptr<const core::frame_producer_registry>& producer_registry)\r
{\r
- auto context = spl::make_shared<command_context>(channels, channel, cg_registry);\r
+ auto context = spl::make_shared<command_context>(channels, channel, cg_registry, producer_registry);\r
\r
processor\r
.add_handler(L"DUR", \r
clk_command_processor& processor,\r
const std::vector<spl::shared_ptr<core::video_channel>>& channels,\r
const spl::shared_ptr<core::video_channel>& channel,\r
- const spl::shared_ptr<core::cg_producer_registry>& cg_registry);\r
+ const spl::shared_ptr<core::cg_producer_registry>& cg_registry,\r
+ const spl::shared_ptr<const core::frame_producer_registry>& producer_registry);\r
\r
}}}\r
add_executable(casparcg ${SOURCES} ${HEADERS} ${OS_SPECIFIC_SOURCES})
add_precompiled_header(casparcg stdafx.h FORCEINCLUDE)
+add_executable(generate_docs generate_docs.cpp included_modules.h)
+target_link_libraries(generate_docs
+ protocol
+
+ "${CASPARCG_MODULE_PROJECTS}"
+
+ reroute
+)
+
+
include_directories(..)
include_directories(${BOOST_INCLUDE_PATH})
include_directories(${RXCPP_INCLUDE_PATH})
--- /dev/null
+/*
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
+*
+* This file is part of CasparCG (www.casparcg.com).
+*
+* CasparCG is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* CasparCG is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
+*
+* Author: Helge Norberg, helge.norberg@svt.se
+*/
+
+#include "included_modules.h"
+
+#include <common/env.h>
+#include <common/log.h>
+
+#include <core/producer/media_info/in_memory_media_info_repository.h>
+#include <core/help/help_repository.h>
+#include <core/help/help_sink.h>
+#include <core/help/util.h>
+
+#include <protocol/amcp/amcp_command_repository.h>
+#include <protocol/amcp/AMCPCommandsImpl.h>
+
+#include <boost/filesystem/fstream.hpp>
+
+#include <iostream>
+#include <sstream>
+
+using namespace caspar;
+
+static const int WIDTH = 150;
+
+class mediawiki_paragraph_builder : public core::paragraph_builder
+{
+ std::wostringstream out_;
+ std::wostream& commit_to_;
+public:
+ mediawiki_paragraph_builder(std::wostream& out)
+ : commit_to_(out)
+ {
+ }
+
+ ~mediawiki_paragraph_builder()
+ {
+ commit_to_ << core::wordwrap(out_.str(), WIDTH) << std::endl;
+ }
+
+ spl::shared_ptr<paragraph_builder> text(std::wstring text) override
+ {
+ out_ << std::move(text);
+ return shared_from_this();
+ };
+
+ spl::shared_ptr<paragraph_builder> code(std::wstring text) override
+ {
+ out_ << L"<code>" << std::move(text) << L"</code>";
+ return shared_from_this();
+ };
+
+ spl::shared_ptr<paragraph_builder> see(std::wstring item) override
+ {
+ out_ << L"[[#" << item << L"|" << item << L"]]";
+ return shared_from_this();
+ };
+
+ spl::shared_ptr<paragraph_builder> url(std::wstring url, std::wstring name) override
+ {
+ out_ << L"[" << std::move(url) << L" " << std::move(name) << L"]";
+ return shared_from_this();
+ };
+};
+
+class mediawiki_definition_list_builder : public core::definition_list_builder
+{
+ std::wostream& out_;
+public:
+ mediawiki_definition_list_builder(std::wostream& out)
+ : out_(out)
+ {
+ }
+
+ ~mediawiki_definition_list_builder()
+ {
+ out_ << L"\n" << std::endl;
+ }
+
+ spl::shared_ptr<definition_list_builder> item(std::wstring term, std::wstring description) override
+ {
+ out_ << L"; <code>" << term << L"</code>\n";
+ out_ << L": " << description << L"\n";
+
+ return shared_from_this();
+ };
+};
+
+class mediawiki_help_sink : public core::help_sink
+{
+ std::wostream& out_;
+public:
+ mediawiki_help_sink(std::wostream& out)
+ : out_(out)
+ {
+ }
+
+ void start_section(std::wstring title)
+ {
+ out_ << L"=" << title << L"=\n" << std::endl;
+ }
+
+ void syntax(const std::wstring& syntax) override
+ {
+ out_ << L"Syntax:\n";
+ out_ << core::indent(core::wordwrap(syntax, WIDTH - 1), L" ") << std::endl;
+ }
+
+ spl::shared_ptr<core::paragraph_builder> para() override
+ {
+ return spl::make_shared<mediawiki_paragraph_builder>(out_);
+ }
+
+ spl::shared_ptr<core::definition_list_builder> definitions() override
+ {
+ return spl::make_shared<mediawiki_definition_list_builder>(out_);
+ }
+
+ void example(const std::wstring& code, const std::wstring& caption) override
+ {
+ out_ << core::indent(core::wordwrap(code, WIDTH - 1), L" ");
+
+ if (!caption.empty())
+ out_ << core::wordwrap(L"..." + caption, WIDTH - 1);
+
+ out_ << std::endl;
+ }
+private:
+ void begin_item(const std::wstring& name) override
+ {
+ out_ << L"==" << name << L"==\n" << std::endl;
+ }
+};
+
+void generate_amcp_commands_help(const core::help_repository& help_repo)
+{
+ boost::filesystem::wofstream file(L"amcp_commands_help.wiki");
+ mediawiki_help_sink sink(file);
+
+ auto print_section = [&](std::wstring title)
+ {
+ sink.start_section(title);
+ help_repo.help({ L"AMCP", title }, sink);
+ };
+
+ print_section(L"Basic Commands");
+ print_section(L"Data Commands");
+ print_section(L"Template Commands");
+ print_section(L"Mixer Commands");
+ print_section(L"Thumbnail Commands");
+ print_section(L"Query Commands");
+ file.flush();
+}
+
+int main(int argc, char** argv)
+{
+ //env::configure(L"casparcg.config");
+ //log::set_log_level(L"info");
+
+ spl::shared_ptr<core::system_info_provider_repository> system_info_provider_repo;
+ spl::shared_ptr<core::cg_producer_registry> cg_registry;
+ auto media_info_repo = core::create_in_memory_media_info_repository();
+ spl::shared_ptr<core::help_repository> help_repo;
+ spl::shared_ptr<core::frame_producer_registry> producer_registry;
+ std::promise<bool> shutdown_server_now;
+ protocol::amcp::amcp_command_repository repo(
+ { },
+ nullptr,
+ media_info_repo,
+ system_info_provider_repo,
+ cg_registry,
+ help_repo,
+ producer_registry,
+ shutdown_server_now);
+
+ protocol::amcp::register_commands(repo);
+
+ core::module_dependencies dependencies(system_info_provider_repo, cg_registry, media_info_repo, producer_registry);
+ initialize_modules(dependencies);
+
+ generate_amcp_commands_help(*help_repo);
+
+ uninitialize_modules();
+
+ return 0;
+}
boost::thread initial_media_info_thread_;
spl::shared_ptr<system_info_provider_repository> system_info_provider_repo_;
spl::shared_ptr<core::cg_producer_registry> cg_registry_;
+ spl::shared_ptr<core::frame_producer_registry> producer_registry_;
tbb::atomic<bool> running_;
std::shared_ptr<thumbnail_generator> thumbnail_generator_;
std::promise<bool>& shutdown_server_now_;
diag_subject_->attach_parent(monitor_subject_);
module_dependencies dependencies(
- system_info_provider_repo_,
- cg_registry_,
- media_info_repo_);
+ system_info_provider_repo_,
+ cg_registry_,
+ media_info_repo_,
+ producer_registry_);
initialize_modules(dependencies);
- core::text::init();
+ core::text::init(dependencies);
core::scene::init(dependencies);
}
pt.get(L"configuration.thumbnails.generate-delay-millis", 2000),
&image::write_cropped_png,
media_info_repo_,
+ producer_registry_,
pt.get(L"configuration.thumbnails.mipmap", true)));
CASPAR_LOG(info) << L"Initialized thumbnail generator.";
system_info_provider_repo_,
cg_registry_,
help_repo_,
+ producer_registry_,
shutdown_server_now_);
amcp::register_commands(*amcp_command_repo_);
if(boost::iequals(name, L"AMCP"))
return wrap_legacy_protocol("\r\n", spl::make_shared<amcp::AMCPProtocolStrategy>(spl::make_shared_ptr(amcp_command_repo_)));
else if(boost::iequals(name, L"CII"))
- return wrap_legacy_protocol("\r\n", spl::make_shared<cii::CIIProtocolStrategy>(channels_, cg_registry_));
+ return wrap_legacy_protocol("\r\n", spl::make_shared<cii::CIIProtocolStrategy>(channels_, cg_registry_, producer_registry_));
else if(boost::iequals(name, L"CLOCK"))
return spl::make_shared<to_unicode_adapter_factory>(
"ISO-8859-1",
- spl::make_shared<CLK::clk_protocol_strategy_factory>(channels_, cg_registry_));
+ spl::make_shared<CLK::clk_protocol_strategy_factory>(channels_, cg_registry_, producer_registry_));
CASPAR_THROW_EXCEPTION(caspar_exception() << arg_name_info(L"name") << arg_value_info(name) << msg_info(L"Invalid protocol"));
}