Commit 6ff6c63c authored by Nicolas Carion's avatar Nicolas Carion

Trace more functions

parent 49e9aae5
......@@ -51,6 +51,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <kimagecache.h>
#include "kdenlive_debug.h"
#include "logger.hpp"
#include <KLocalizedString>
#include <KMessageBox>
#include <QApplication>
......@@ -61,6 +62,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QtConcurrent>
#include <utility>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wfloat-equal"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wpedantic"
#include <rttr/registration>
#pragma GCC diagnostic pop
RTTR_REGISTRATION
{
using namespace rttr;
registration::class_<ProjectClip>("ProjectClip");
}
ProjectClip::ProjectClip(const QString &id, const QIcon &thumb, std::shared_ptr<ProjectItemModel> model, std::shared_ptr<Mlt::Producer> producer)
: AbstractProjectItem(AbstractProjectItem::ClipItem, id, model)
, ClipController(id, producer)
......@@ -550,7 +565,7 @@ std::shared_ptr<Mlt::Producer> ProjectClip::getTimelineProducer(int clipId, Play
// We need to get an audio producer, if none exists
if (m_clipType == ClipType::Color || m_clipType == ClipType::Image || m_clipType == ClipType::Text) {
int duration = m_masterProducer->time_to_frames(m_masterProducer->get("kdenlive:duration"));
return std::shared_ptr<Mlt::Producer>(m_masterProducer->cut(-1, duration > 0 ? duration: -1));
return std::shared_ptr<Mlt::Producer>(m_masterProducer->cut(-1, duration > 0 ? duration : -1));
}
if (m_videoProducers.count(clipId) == 0) {
m_videoProducers[clipId] = cloneProducer(&pCore->getCurrentProfile()->profile(), true);
......
......@@ -22,6 +22,27 @@
#include <QColor>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wfloat-equal"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wpedantic"
#include <rttr/registration>
#pragma GCC diagnostic pop
RTTR_REGISTRATION
{
using namespace rttr;
// clang-format off
registration::enumeration<GroupType>("GroupType")(
value("Normal", GroupType::Normal),
value("Selection", GroupType::Selection),
value("AVSplit", GroupType::AVSplit),
value("Leaf", GroupType::Leaf)
);
// clang-format on
}
QDebug operator<<(QDebug qd, const ItemInfo &info)
{
qd << "ItemInfo " << &info;
......
......@@ -20,12 +20,21 @@
***************************************************************************/
#include "logger.hpp"
#include "bin/projectitemmodel.h"
#include "timeline2/model/timelinemodel.hpp"
#include <QString>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wfloat-equal"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wpedantic"
#include <rttr/registration>
#pragma GCC diagnostic pop
thread_local bool Logger::is_executing = false;
std::mutex Logger::mut;
......@@ -52,6 +61,8 @@ std::string Logger::get_ptr_name(rttr::variant ptr)
{
if (ptr.can_convert<TimelineModel *>()) {
return "timeline_" + std::to_string(get_id_from_ptr(ptr.convert<TimelineModel *>()));
} else if (ptr.can_convert<ProjectItemModel *>()) {
return "binModel";
} else {
std::cout << "Error: unhandled ptr type " << ptr.get_type().get_name().to_string() << std::endl;
}
......@@ -65,6 +76,20 @@ void Logger::log_res(rttr::variant result)
invoks[result_awaiting].res = std::move(result);
}
void Logger::log_create_producer(const std::string &type, std::vector<rttr::variant> args)
{
std::unique_lock<std::mutex> lk(mut);
for (auto &a : args) {
// this will rewove shared/weak/unique ptrs
if (a.get_type().is_wrapper()) {
a = a.extract_wrapped_value();
}
const std::string class_name = a.get_type().get_name().to_string();
}
constr[type].push_back({type, std::move(args)});
operations.push_back(ConstrId{type, constr[type].size() - 1});
}
namespace {
bool isIthParamARef(const rttr::method &method, size_t i)
{
......@@ -93,12 +118,27 @@ void Logger::print_trace()
ss << "dummy_" << i;
} else if (a.get_type() == rttr::type::get<int>()) {
ss << a.convert<int>();
} else if (a.can_convert<bool>()) {
} else if (a.get_type() == rttr::type::get<bool>()) {
ss << (a.convert<bool>() ? "true" : "false");
} else if (a.get_type().is_enumeration()) {
auto e = a.get_type().get_enumeration();
ss << e.get_name().to_string() << "::" << a.convert<std::string>();
} else if (a.can_convert<QString>()) {
// Not supported in c++ < 14
// ss << std::quoted(a.convert<QString>().toStdString());
ss << "\" "<<a.convert<QString>().toStdString()<<" \"";
ss << std::quoted(a.convert<QString>().toStdString());
} else if (a.can_convert<std::string>()) {
ss << std::quoted(a.convert<std::string>());
} else if (a.can_convert<std::unordered_set<int>>()) {
auto set = a.convert<std::unordered_set<int>>();
ss << "{";
bool beg = true;
for (int s : set) {
if (beg)
beg = false;
else
ss << ", ";
ss << s;
}
ss << "}";
} else if (a.get_type().is_pointer()) {
ss << get_ptr_name(a);
} else {
......@@ -110,8 +150,6 @@ void Logger::print_trace()
};
std::ofstream test_file;
test_file.open("test_case.cpp");
// Not supported on GCC < 5.1
// auto test_file = std::ofstream("test_case.cpp");
test_file << "TEST_CASE(\"Regression\") {" << std::endl;
test_file << "auto binModel = pCore->projectItemModel();" << std::endl;
test_file << "std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr);" << std::endl;
......@@ -161,7 +199,12 @@ void Logger::print_trace()
} else if (id.type == "TrackModel") {
std::string params = process_args(constr[id.type][id.id].second);
test_file << "TrackModel::construct(" << params << ");" << std::endl;
} else if (id.type == "test_producer") {
std::string params = process_args(constr[id.type][id.id].second);
test_file << "createProducer(reg_profile, " << params << ");" << std::endl;
} else if (id.type == "test_producer_sound") {
std::string params = process_args(constr[id.type][id.id].second);
test_file << "createProducerWithSound(reg_profile, " << params << ");" << std::endl;
} else {
std::cout << "Error: unknown constructor " << id.type << std::endl;
}
......
......@@ -45,9 +45,18 @@ public:
* This function returns true if this is a top-level call, meaning that we indeed want to log it. If the function returns false, the caller must not log.
*/
static bool start_logging();
/** @brief This logs the construction of an object of type T, whose new instance is passed. The instance will be kept around in case future calls refer to
* it. The arguments should more or less match the constructor arguments. In general, it's better to call the corresponding macro TRACE_CONSTR */
template <typename T> static void log_constr(T *inst, std::vector<rttr::variant> args);
/** @brief Logs the call to a member function on a given instance of class T. The string contains the method name, and then the vector contains all the
* parameters. In general, the method should be registered in RTTR. It's better to call the corresponding macro TRACE() if appropriate */
template <typename T> static void log(T *inst, std::string str, std::vector<rttr::variant> args);
static void log_create_producer(const std::string &type, std::vector<rttr::variant> args);
/** @brief When the last function logged has a return value, you can log it through this function, by passing the corresponding value. In general, it's
* better to call the macro TRACE_RES */
static void log_res(rttr::variant result);
/// @brief Notify that we are done with our function. Must not be called if start_logging returned false.
......@@ -57,8 +66,9 @@ public:
static void clear();
protected:
template <typename T> static size_t get_id_from_ptr(T *ptr);
/** @brief Look amongst the known instances to get the name of a given pointer */
static std::string get_ptr_name(rttr::variant ptr);
template <typename T> static size_t get_id_from_ptr(T *ptr);
struct InvokId
{
size_t id;
......@@ -98,21 +108,26 @@ protected:
bool m_hasGuard = false;
};
/// See Logger::log_constr. Note that the macro fills in the ptr instance for you.
#define TRACE_CONSTR(ptr, ...) \
LogGuard __guard; \
if (__guard.hasGuard()) { \
Logger::log_constr((ptr), {__VA_ARGS__}); \
}
/// See Logger::log. Note that the macro fills the ptr instance and the method name for you.
#define TRACE(...) \
LogGuard __guard; \
if (__guard.hasGuard()) { \
Logger::log(this, __FUNCTION__, {__VA_ARGS__}); \
}
/// See Logger::log_res
#define TRACE_RES(res) \
if (__guard.hasGuard()) { \
Logger::log_res(res); \
}
/******* Implementations ***********/
template <typename T> void Logger::log_constr(T *inst, std::vector<rttr::variant> args)
{
......
......@@ -64,7 +64,16 @@ RTTR_REGISTRATION
using namespace rttr;
registration::class_<TimelineModel>("TimelineModel")
.method("requestClipMove", select_overload<bool(int, int, int, bool, bool, bool)>(&TimelineModel::requestClipMove))
.method("requestTrackInsertion", select_overload<bool(int, int &, const QString &, bool)>(&TimelineModel::requestTrackInsertion));
.method("requestClipInsertion", select_overload<bool(const QString &, int, int, int &, bool, bool, bool)>(&TimelineModel::requestClipInsertion))
.method("requestItemDeletion", select_overload<bool(int, bool)>(&TimelineModel::requestItemDeletion))
.method("requestGroupMove", select_overload<bool(int, int, int, int, bool, bool)>(&TimelineModel::requestGroupMove))
.method("requestGroupDeletion", select_overload<bool(int, bool)>(&TimelineModel::requestGroupDeletion))
.method("requestItemResize", select_overload<int(int, int, bool, bool, int, bool)>(&TimelineModel::requestItemResize))
.method("requestCompositionMove", select_overload<bool(int, int, int, bool, bool)>(&TimelineModel::requestCompositionMove))
.method("requestClipsGroup", select_overload<int(const std::unordered_set<int> &, bool, GroupType)>(&TimelineModel::requestClipsGroup))
.method("requestClipUngroup", select_overload<bool(int, bool)>(&TimelineModel::requestClipUngroup))
.method("requestTrackInsertion", select_overload<bool(int, int &, const QString &, bool)>(&TimelineModel::requestTrackInsertion))
.method("requestTrackDeletion", select_overload<bool(int)>(&TimelineModel::requestTrackDeletion));
}
int TimelineModel::next_id = 0;
......@@ -585,8 +594,10 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
<< (logUndo ? "true" : "false") << " ); " << std::endl;
#endif
QWriteLocker locker(&m_lock);
TRACE(clipId, trackId, position, updateView, logUndo, invalidateTimeline);
Q_ASSERT(m_allClips.count(clipId) > 0);
if (m_allClips[clipId]->getPosition() == position && getClipTrackId(clipId) == trackId) {
TRACE_RES(true);
return true;
}
if (m_groups->isInGroup(clipId)) {
......@@ -605,6 +616,7 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
if (res && logUndo) {
PUSH_UNDO(undo, redo, i18n("Move clip"));
}
TRACE_RES(res);
return res;
}
......@@ -898,12 +910,14 @@ bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId,
m_logFile << "timeline->requestClipInsertion(" << binClipId.toStdString() << "," << trackId << " ," << position << ", dummy_id );" << std::endl;
#endif
QWriteLocker locker(&m_lock);
TRACE(binClipId, trackId, position, id, logUndo, refreshView, useTargets);
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool result = requestClipInsertion(binClipId, trackId, position, id, logUndo, refreshView, useTargets, undo, redo);
if (result && logUndo) {
PUSH_UNDO(undo, redo, i18n("Insert Clip"));
}
TRACE_RES(result);
return result;
}
......@@ -1026,9 +1040,12 @@ bool TimelineModel::requestItemDeletion(int itemId, bool logUndo)
m_logFile << "timeline->requestItemDeletion(" << itemId << "); " << std::endl;
#endif
QWriteLocker locker(&m_lock);
TRACE(itemId, logUndo);
Q_ASSERT(isClip(itemId) || isComposition(itemId));
if (m_groups->isInGroup(itemId)) {
return requestGroupDeletion(itemId, logUndo);
bool res = requestGroupDeletion(itemId, logUndo);
TRACE_RES(res);
return res;
}
Fun undo = []() { return true; };
Fun redo = []() { return true; };
......@@ -1044,6 +1061,7 @@ bool TimelineModel::requestItemDeletion(int itemId, bool logUndo)
if (res && logUndo) {
PUSH_UNDO(undo, redo, actionLabel);
}
TRACE_RES(res);
return res;
}
......@@ -1233,12 +1251,15 @@ bool TimelineModel::requestFakeGroupMove(int clipId, int groupId, int delta_trac
bool TimelineModel::requestGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView, bool logUndo)
{
QWriteLocker locker(&m_lock);
TRACE(clipId, groupId, delta_track, delta_pos, updateView, logUndo);
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
bool res = requestGroupMove(clipId, groupId, delta_track, delta_pos, updateView, logUndo, undo, redo);
if (res && logUndo) {
PUSH_UNDO(undo, redo, i18n("Move group"));
}
TRACE_RES(res);
return res;
}
......@@ -1370,12 +1391,14 @@ bool TimelineModel::requestGroupDeletion(int clipId, bool logUndo)
m_logFile << "timeline->requestGroupDeletion(" << clipId << " ); " << std::endl;
#endif
QWriteLocker locker(&m_lock);
TRACE(clipId, logUndo);
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool res = requestGroupDeletion(clipId, undo, redo);
if (res && logUndo) {
PUSH_UNDO(undo, redo, i18n("Remove group"));
}
TRACE_RES(res);
return res;
}
......@@ -1443,8 +1466,12 @@ int TimelineModel::requestItemResize(int itemId, int size, bool right, bool logU
qDebug() << "---------------------\n---------------------\nRESIZE W/UNDO CALLED\n++++++++++++++++\n++++";
}
QWriteLocker locker(&m_lock);
TRACE(itemId, size, right, logUndo, snapDistance, allowSingleResize);
Q_ASSERT(isClip(itemId) || isComposition(itemId));
if (size <= 0) return -1;
if (size <= 0) {
TRACE_RES(-1);
return -1;
}
int in = getItemPosition(itemId);
int out = in + getItemPlaytime(itemId);
if (snapDistance > 0) {
......@@ -1496,6 +1523,7 @@ int TimelineModel::requestItemResize(int itemId, int size, bool right, bool logU
if (!result) {
bool undone = undo();
Q_ASSERT(undone);
TRACE_RES(-1);
return -1;
}
if (result && logUndo) {
......@@ -1505,7 +1533,9 @@ int TimelineModel::requestItemResize(int itemId, int size, bool right, bool logU
PUSH_UNDO(undo, redo, i18n("Resize composition"));
}
}
return result ? size : -1;
int res = result ? size : -1;
TRACE_RES(res);
return res;
}
bool TimelineModel::requestItemResize(int itemId, int size, bool right, bool logUndo, Fun &undo, Fun &redo, bool blockUndo)
......@@ -1542,6 +1572,7 @@ bool TimelineModel::requestItemResize(int itemId, int size, bool right, bool log
int TimelineModel::requestClipsGroup(const std::unordered_set<int> &ids, bool logUndo, GroupType type)
{
QWriteLocker locker(&m_lock);
TRACE(ids, logUndo, type);
Fun undo = []() { return true; };
Fun redo = []() { return true; };
if (m_temporarySelectionGroup > -1) {
......@@ -1558,6 +1589,7 @@ int TimelineModel::requestClipsGroup(const std::unordered_set<int> &ids, bool lo
if (result > -1 && logUndo && type != GroupType::Selection) {
PUSH_UNDO(undo, redo, i18n("Group clips"));
}
TRACE_RES(result);
return result;
}
......@@ -1607,6 +1639,7 @@ bool TimelineModel::requestClipUngroup(int id, bool logUndo)
m_logFile << "timeline->requestClipUngroup(" << id << " ); " << std::endl;
#endif
QWriteLocker locker(&m_lock);
TRACE(id, logUndo);
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool result = true;
......@@ -1622,6 +1655,7 @@ bool TimelineModel::requestClipUngroup(int id, bool logUndo)
if (result && logUndo) {
PUSH_UNDO(undo, redo, i18n("Ungroup clips"));
}
TRACE_RES(result);
return result;
}
......@@ -1678,6 +1712,7 @@ bool TimelineModel::requestTrackDeletion(int trackId)
m_logFile << "timeline->requestTrackDeletion(" << trackId << "); " << std::endl;
#endif
QWriteLocker locker(&m_lock);
TRACE(trackId);
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool result = requestTrackDeletion(trackId, undo, redo);
......@@ -1690,6 +1725,7 @@ bool TimelineModel::requestTrackDeletion(int trackId)
}
PUSH_UNDO(undo, redo, i18n("Delete Track"));
}
TRACE_RES(result);
return result;
}
......
......@@ -7,7 +7,6 @@ Mlt::Profile profile_model;
TEST_CASE("Basic creation/deletion of a track", "[TrackModel]")
{
Logger::clear();
auto binModel = pCore->projectItemModel();
std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr);
std::shared_ptr<MarkerListModel> guideModel = std::make_shared<MarkerListModel>(undoStack);
......
#include "test_utils.hpp"
#include "logger.hpp"
QString createProducer(Mlt::Profile &prof, std::string color, std::shared_ptr<ProjectItemModel> binModel, int length, bool limited)
{
Logger::log_create_producer("test_producer", {color, binModel, length, limited});
std::shared_ptr<Mlt::Producer> producer = std::make_shared<Mlt::Producer>(prof, "color", color.c_str());
producer->set("length", length);
producer->set("out", length - 1);
......@@ -22,6 +24,7 @@ QString createProducer(Mlt::Profile &prof, std::string color, std::shared_ptr<Pr
QString createProducerWithSound(Mlt::Profile &prof, std::shared_ptr<ProjectItemModel> binModel)
{
Logger::log_create_producer("test_producer_sound", {binModel});
// std::shared_ptr<Mlt::Producer> producer = std::make_shared<Mlt::Producer>(prof,
// QFileInfo("../tests/small.mkv").absoluteFilePath().toStdString().c_str());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment