From e9a8b9f64d2b3ccf4887e8b75a19d1e291c249c7 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Tue, 8 Apr 2008 23:01:32 +0100 Subject: [PATCH 001/245] Revert "Lumiera renaming -- source code" This reverts commit e737b9ef1ba938ca2cdd7372fb18c0cac0dd74b9. --- src/backend/mediaaccessfacade.cpp | 4 +- src/backend/mediaaccessfacade.hpp | 2 +- src/{lumiera.h => cinelerra.h} | 12 +- src/common/appconfig.cpp | 10 +- src/common/appconfig.hpp | 8 +- src/common/error.cpp | 38 ++-- src/common/error.hpp | 84 ++++----- src/common/factory.hpp | 8 +- src/common/multithread.hpp | 12 +- src/common/singleton.hpp | 6 +- src/common/singletonfactory.hpp | 8 +- src/common/singletonpolicies.hpp | 14 +- src/common/singletonpreconfigure.hpp | 18 +- src/common/test/mockinjector.hpp | 8 +- src/common/test/suite.cpp | 6 +- src/common/time.cpp | 4 +- src/common/time.hpp | 8 +- src/common/typelist.hpp | 10 +- src/common/visitor.cpp | 4 +- src/common/visitor.hpp | 10 +- src/common/visitordispatcher.hpp | 8 +- src/common/visitorpolicies.hpp | 12 +- src/lib/condition.c | 12 +- src/lib/condition.h | 86 ++++----- src/lib/error.c | 32 ++-- src/lib/error.h | 38 ++-- src/lib/framerate.c | 4 +- src/lib/framerate.h | 42 ++--- src/lib/locking.h | 14 +- src/lib/mutex.c | 10 +- src/lib/mutex.h | 90 +++++----- src/lib/plugin.c | 164 +++++++++--------- src/lib/plugin.h | 74 ++++---- src/lib/references.c | 70 ++++---- src/lib/references.h | 52 +++--- src/lib/rwlock.c | 62 +++---- src/lib/rwlock.h | 60 +++---- src/lib/time.c | 6 +- src/lib/time.h | 66 +++---- src/main.cpp | 4 +- src/nobugcfg.h | 2 +- src/plugin/helloplugin.c | 4 +- src/pre.hpp | 8 +- src/proc/asset.cpp | 2 +- src/proc/asset.hpp | 4 +- src/proc/asset/db.hpp | 4 +- src/proc/asset/media.cpp | 22 +-- src/proc/asset/media.hpp | 8 +- src/proc/asset/meta.hpp | 2 +- src/proc/asset/proc.hpp | 2 +- src/proc/asset/struct.hpp | 2 +- src/proc/asset/unknown.cpp | 16 +- src/proc/asset/unknown.hpp | 6 +- src/proc/assetmanager.cpp | 30 ++-- src/proc/assetmanager.hpp | 12 +- src/proc/engine/codecadapter.hpp | 2 +- src/proc/engine/pluginadapter.hpp | 2 +- src/proc/engine/processor.hpp | 6 +- src/proc/mobject/builder/buildertool.hpp | 8 +- src/proc/mobject/mobject.hpp | 6 +- src/proc/mobject/placement.hpp | 2 +- src/proc/mobject/session.hpp | 2 +- src/proc/mobject/session/locatingpin.hpp | 4 +- src/proc/mobject/session/segment.hpp | 4 +- src/proc/mobject/session/session.cpp | 2 +- src/proc/mobject/session/sessionimpl.cpp | 2 +- src/proc/mobject/session/sessionimpl.hpp | 2 +- src/tool/hello.c | 4 +- tests/10errorhandling.tests | 4 +- tests/50components.tests | 20 +-- tests/54builder.tests | 2 +- tests/components/backend/mediaaccessmock.cpp | 2 +- tests/components/backend/mediaaccessmock.hpp | 2 +- tests/components/common/appconfigtest.cpp | 6 +- .../components/common/exceptionerrortest.cpp | 38 ++-- .../components/common/factoryspecialtest.cpp | 4 +- tests/components/common/factorytest.cpp | 6 +- tests/components/common/singletontest.cpp | 10 +- .../common/singletontestmocktest.cpp | 8 +- tests/components/common/testtargetobj.hpp | 8 +- tests/components/common/typelisttest.cpp | 4 +- .../components/common/visitingtoolconcept.cpp | 8 +- .../common/visitingtoolextendedtest.cpp | 4 +- tests/components/common/visitingtooltest.cpp | 4 +- tests/components/helloworldtest.cpp | 4 +- tests/components/mainsuite.cpp | 2 +- .../components/proc/asset/createassettest.cpp | 18 +- .../proc/asset/mediastructurequerytest.cpp | 2 +- .../mobject/controller/rendersegmenttest.cpp | 2 +- .../proc/mobject/placementbasictest.cpp | 2 +- .../proc/mobject/session/addcliptest.cpp | 2 +- .../proc/mobject/session/testclip.cpp | 4 +- tests/error/errortest.c | 16 +- tests/library/test-llist.c | 2 +- tests/library/test-references.c | 10 +- tests/locking/condition.c | 8 +- tests/locking/mutex.c | 8 +- tests/locking/test-condition.c | 10 +- tests/locking/test-locking.c | 2 +- tests/plugin/example_plugin.c | 16 +- tests/plugin/example_plugin.cpp | 16 +- tests/plugin/hello_interface.h | 8 +- tests/plugin/plugin_main.c | 34 ++-- tests/time/test-time.c | 86 ++++----- 104 files changed, 866 insertions(+), 866 deletions(-) rename src/{lumiera.h => cinelerra.h} (90%) diff --git a/src/backend/mediaaccessfacade.cpp b/src/backend/mediaaccessfacade.cpp index ad52698b8..bd12068f9 100644 --- a/src/backend/mediaaccessfacade.cpp +++ b/src/backend/mediaaccessfacade.cpp @@ -26,13 +26,13 @@ #include "common/util.hpp" using util::isnil; -using lumiera::error::Invalid; +using cinelerra::error::Invalid; namespace backend_interface { /** storage for the SingletonFactory - * (actually a lumiera::test::MockInjector) */ + * (actually a cinelerra::test::MockInjector) */ Singleton MediaAccessFacade::instance; diff --git a/src/backend/mediaaccessfacade.hpp b/src/backend/mediaaccessfacade.hpp index 63741b02e..15579d491 100644 --- a/src/backend/mediaaccessfacade.hpp +++ b/src/backend/mediaaccessfacade.hpp @@ -59,7 +59,7 @@ namespace backend_interface * information from this file, NULL if the * file is not acessible. */ - virtual FileHandle queryFile (const char* name) throw(lumiera::error::Invalid); + virtual FileHandle queryFile (const char* name) throw(cinelerra::error::Invalid); /** request for information about the n-th channel * of the file refered by FileHandle. diff --git a/src/lumiera.h b/src/cinelerra.h similarity index 90% rename from src/lumiera.h rename to src/cinelerra.h index 12b1578b9..30264a904 100644 --- a/src/lumiera.h +++ b/src/cinelerra.h @@ -1,5 +1,5 @@ /* - LUMIERA.h - global definitions and common types + CINELERRA.h - global definitions and common types Copyright (C) Lumiera.org @@ -22,8 +22,8 @@ */ -#ifndef LUMIERA_H -#define LUMIERA_H +#ifndef CINELERRA_H +#define CINELERRA_H @@ -54,13 +54,13 @@ extern "C" { #include "common/error.hpp" -namespace lumiera +namespace cinelerra { /* additional global configuration goes here... */ -} // namespace lumiera +} // namespace cinelerra #endif /* ===================== (End) C++-Part ================= */ -#endif /*LUMIERA_H*/ +#endif /*CINELERRA_H*/ diff --git a/src/common/appconfig.cpp b/src/common/appconfig.cpp index 612376022..fdf16cf40 100644 --- a/src/common/appconfig.cpp +++ b/src/common/appconfig.cpp @@ -34,7 +34,7 @@ using util::isnil; -namespace lumiera +namespace cinelerra { /** This internal pointer to the single instance is deliberately @@ -52,7 +52,7 @@ namespace lumiera /** perform initialization on first access. * A call is placed in static initialization code - * included in lumiera.h; thus it will happen + * included in cinelerra.h; thus it will happen * probably very early. */ Appconfig::Appconfig() @@ -65,7 +65,7 @@ namespace lumiera INFO(config, "Basic application configuration triggered."); // install our own handler for undeclared exceptions - std::set_unexpected (lumiera::error::lumiera_unexpectedException); + std::set_unexpected (cinelerra::error::cinelerra_unexpectedException); (*configParam_)["version"] = STRINGIFY (LUMIERA_VERSION); } @@ -89,10 +89,10 @@ namespace lumiera catch (...) { ERROR(config, "error while accessing configuration parameter \"%s\".", key.c_str()); - throw lumiera::error::Fatal (); + throw cinelerra::error::Fatal (); } } -} // namespace lumiera +} // namespace cinelerra diff --git a/src/common/appconfig.hpp b/src/common/appconfig.hpp index 984236755..bbd50df6f 100644 --- a/src/common/appconfig.hpp +++ b/src/common/appconfig.hpp @@ -34,8 +34,8 @@ */ -#ifndef LUMIERA_APPCONFIG_H -#define LUMIERA_APPCONFIG_H +#ifndef CINELERRA_APPCONFIG_H +#define CINELERRA_APPCONFIG_H #include #include @@ -45,7 +45,7 @@ -namespace lumiera +namespace cinelerra { using std::string; using boost::scoped_ptr; @@ -104,5 +104,5 @@ namespace lumiera -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/src/common/error.cpp b/src/common/error.cpp index e708c5d3a..17e18e676 100644 --- a/src/common/error.cpp +++ b/src/common/error.cpp @@ -1,5 +1,5 @@ /* - Error - Lumiera Exception Interface + Error - Cinelerra Exception Interface Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -33,7 +33,7 @@ using util::isnil; using std::exception; -namespace lumiera +namespace cinelerra { namespace error @@ -46,23 +46,23 @@ namespace lumiera */ inline const string default_usermsg (Error* exception_obj) throw() { - return string("Sorry, Lumiera encountered an internal error. (") + return string("Sorry, Cinelerra encountered an internal error. (") + typeid(*exception_obj).name() + ")"; } /* constants to be used as error IDs */ - LUMIERA_ERROR_DEFINE (LOGIC , "internal logic broken"); - LUMIERA_ERROR_DEFINE (FATAL , "floundered"); - LUMIERA_ERROR_DEFINE (CONFIG , "misconfiguration"); - LUMIERA_ERROR_DEFINE (STATE , "unforseen state"); - LUMIERA_ERROR_DEFINE (INVALID , "invalid input or parameters"); - LUMIERA_ERROR_DEFINE (EXTERNAL , "failure in external service"); - LUMIERA_ERROR_DEFINE (ASSERTION, "assertion failure"); + CINELERRA_ERROR_DEFINE (LOGIC , "internal logic broken"); + CINELERRA_ERROR_DEFINE (FATAL , "floundered"); + CINELERRA_ERROR_DEFINE (CONFIG , "misconfiguration"); + CINELERRA_ERROR_DEFINE (STATE , "unforseen state"); + CINELERRA_ERROR_DEFINE (INVALID , "invalid input or parameters"); + CINELERRA_ERROR_DEFINE (EXTERNAL , "failure in external service"); + CINELERRA_ERROR_DEFINE (ASSERTION, "assertion failure"); } // namespace error - LUMIERA_ERROR_DEFINE (EXCEPTION, "generic Lumiera exception"); + CINELERRA_ERROR_DEFINE (EXCEPTION, "generic cinelerra exception"); @@ -75,7 +75,7 @@ namespace lumiera desc_ (description), cause_ ("") { - lumiera_error_set (this->id_); + cinelerra_error_set (this->id_); } @@ -87,7 +87,7 @@ namespace lumiera desc_ (description), cause_ (extractCauseMsg(cause)) { - lumiera_error_set (this->id_); + cinelerra_error_set (this->id_); } @@ -103,7 +103,7 @@ namespace lumiera /** Description of the problem, including the internal char constant - * in accordance to Lumiera's error identification scheme. + * in accordance to cinelerra's error identification scheme. * If a root cause can be obtained, this will be included in the * generated output as well. */ @@ -167,15 +167,15 @@ namespace lumiera namespace error { - void lumiera_unexpectedException () throw() + void cinelerra_unexpectedException () throw() { const char* is_halted - = "### Lumiera halted due to an unexpected Error ###"; + = "### Cinelerra halted due to an unexpected Error ###"; std::cerr << "\n" << is_halted << "\n\n"; ERROR (NOBUG_ON, "%s", is_halted); - if (const char * errorstate = lumiera_error ()) + if (const char * errorstate = cinelerra_error ()) ERROR (NOBUG_ON, "last registered error was....\n%s", errorstate); std::terminate(); @@ -183,7 +183,7 @@ namespace lumiera void assertion_terminate (const string& location) { - throw Fatal (location, LUMIERA_ERROR_ASSERTION) + throw Fatal (location, CINELERRA_ERROR_ASSERTION) .setUsermsg("Program terminated because of violating " "an internal consistency check."); } @@ -191,4 +191,4 @@ namespace lumiera } // namespace error -} // namespace lumiera +} // namespace cinelerra diff --git a/src/common/error.hpp b/src/common/error.hpp index 4ccb8b1d7..15e60f022 100644 --- a/src/common/error.hpp +++ b/src/common/error.hpp @@ -1,5 +1,5 @@ /* - ERROR.hpp - Lumiera Exception Interface + ERROR.hpp - Cinelerra Exception Interface Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,26 +21,26 @@ */ -#ifndef LUMIERA_ERROR_HPP_ -#define LUMIERA_ERROR_HPP_ +#ifndef CINELERRA_ERROR_HPP_ +#define CINELERRA_ERROR_HPP_ #include #include "nobugcfg.h" #include "lib/error.h" -namespace lumiera +namespace cinelerra { using std::string; /** error-ID for unspecified exceptions */ - LUMIERA_ERROR_DECLARE(EXCEPTION); + CINELERRA_ERROR_DECLARE(EXCEPTION); /** * Interface and Baseclass of all Exceptions thrown - * from within Lumiera (C++) code. Common operations + * from within cinelerra (C++) code. Common operations * for getting an diagnostic message and for obtaining * the root cause, i.e. the first exception encountered * in a chain of exceptions. @@ -48,9 +48,9 @@ namespace lumiera class Error : public std::exception { public: - Error (string description="", const char* id=LUMIERA_ERROR_EXCEPTION) throw(); + Error (string description="", const char* id=CINELERRA_ERROR_EXCEPTION) throw(); Error (std::exception& cause, - string description="", const char* id=LUMIERA_ERROR_EXCEPTION) throw(); + string description="", const char* id=CINELERRA_ERROR_EXCEPTION) throw(); Error (const Error&) throw(); virtual ~Error () throw() {}; @@ -58,7 +58,7 @@ namespace lumiera /** yield a diagnostic message characterizing the problem */ virtual const char* what () const throw(); - /** the internal Lumiera-error-ID (was set as C-errorstate in ctor) */ + /** the internal cinelerra-error-ID (was set as C-errorstate in ctor) */ const char* getID () const throw() { return this->id_; } /** extract the message to be displayed for the user */ @@ -80,7 +80,7 @@ namespace lumiera private: - const char* id_; ///< an LUMIERA_ERROR id, which is set as errorstate on construction + const char* id_; ///< an CINELERRA_ERROR id, which is set as errorstate on construction string msg_; ///< friendly message intended for users (to be localized) string desc_; ///< detailed description of the error situation for the developers mutable string what_; ///< buffer for generating the detailed description on demand @@ -105,68 +105,68 @@ namespace lumiera * can be considered a severe design flaw; we can just * add some diagnostics prior to halting. */ - void lumiera_unexpectedException () throw(); + void cinelerra_unexpectedException () throw(); /** throw an error::Fatal indicating "assertion failure" */ void assertion_terminate (const string& location); /* constants to be used as error IDs */ - LUMIERA_ERROR_DECLARE (LOGIC ); ///< contradiction to internal logic assumptions detected - LUMIERA_ERROR_DECLARE (FATAL ); ///< unable to cope with, internal logic floundered - LUMIERA_ERROR_DECLARE (CONFIG ); ///< execution aborted due to misconfiguration - LUMIERA_ERROR_DECLARE (STATE ); ///< unforeseen internal state - LUMIERA_ERROR_DECLARE (INVALID ); ///< invalid input or parameters encountered - LUMIERA_ERROR_DECLARE (EXTERNAL ); ///< failure in external service the application relies on - LUMIERA_ERROR_DECLARE (ASSERTION); ///< assertion failure + CINELERRA_ERROR_DECLARE (LOGIC ); ///< contradiction to internal logic assumptions detected + CINELERRA_ERROR_DECLARE (FATAL ); ///< unable to cope with, internal logic floundered + CINELERRA_ERROR_DECLARE (CONFIG ); ///< execution aborted due to misconfiguration + CINELERRA_ERROR_DECLARE (STATE ); ///< unforeseen internal state + CINELERRA_ERROR_DECLARE (INVALID ); ///< invalid input or parameters encountered + CINELERRA_ERROR_DECLARE (EXTERNAL ); ///< failure in external service the application relies on + CINELERRA_ERROR_DECLARE (ASSERTION); ///< assertion failure /** Macro for creating derived exception classes properly - * integrated into Lumiera's exception hierarchy. Using + * integrated into cinelerra's exception hierarchy. Using * this macro asures that the new class will get the full * set of constructors and behaviour common to all exception * classes, so it should be used when creating an derived * exception type for more then stricly local purposes */ -#define LUMIERA_EXCEPTION_DECLARE(CLASS, PARENT, _ID_) \ - class CLASS : public PARENT \ - { \ - public: \ - CLASS (std::string description="", \ - const char* id=_ID_) throw() \ - : PARENT (description, id) {} \ - \ - CLASS (std::exception& cause, \ - std::string description="", \ - const char* id=_ID_) throw() \ - : PARENT (cause, description, id) {} \ +#define CINELERRA_EXCEPTION_DECLARE(CLASS, PARENT, _ID_) \ + class CLASS : public PARENT \ + { \ + public: \ + CLASS (std::string description="", \ + const char* id=_ID_) throw() \ + : PARENT (description, id) {} \ + \ + CLASS (std::exception& cause, \ + std::string description="", \ + const char* id=_ID_) throw() \ + : PARENT (cause, description, id) {} \ }; - //-------------------------CLASS-----PARENT--ID---------------------- - LUMIERA_EXCEPTION_DECLARE (Logic, Error, LUMIERA_ERROR_LOGIC); - LUMIERA_EXCEPTION_DECLARE (Fatal, Logic, LUMIERA_ERROR_FATAL); - LUMIERA_EXCEPTION_DECLARE (Config, Error, LUMIERA_ERROR_CONFIG); - LUMIERA_EXCEPTION_DECLARE (State, Error, LUMIERA_ERROR_STATE); - LUMIERA_EXCEPTION_DECLARE (Invalid, Error, LUMIERA_ERROR_INVALID); - LUMIERA_EXCEPTION_DECLARE (External, Error, LUMIERA_ERROR_EXTERNAL); + //---------------------------CLASS-----PARENT--ID---------------------- + CINELERRA_EXCEPTION_DECLARE (Logic, Error, CINELERRA_ERROR_LOGIC); + CINELERRA_EXCEPTION_DECLARE (Fatal, Logic, CINELERRA_ERROR_FATAL); + CINELERRA_EXCEPTION_DECLARE (Config, Error, CINELERRA_ERROR_CONFIG); + CINELERRA_EXCEPTION_DECLARE (State, Error, CINELERRA_ERROR_STATE); + CINELERRA_EXCEPTION_DECLARE (Invalid, Error, CINELERRA_ERROR_INVALID); + CINELERRA_EXCEPTION_DECLARE (External, Error, CINELERRA_ERROR_EXTERNAL); } // namespace error -} // namespace lumiera +} // namespace cinelerra /****************************************************** * if NoBug is used, redefine some macros - * to rather throw Lumiera Errors instead of aborting + * to rather throw Cinelerra Errors instead of aborting */ #ifdef NOBUG_ABORT #undef NOBUG_ABORT #define CIN_NOBUG_LOCATION \ std::string (NOBUG_BASENAME(__FILE__)) +":"+ NOBUG_STRINGIZE(__LINE__) + ", function " + __func__ #define NOBUG_ABORT \ - lumiera::error::assertion_terminate (CIN_NOBUG_LOCATION); + cinelerra::error::assertion_terminate (CIN_NOBUG_LOCATION); #endif -#endif // LUMIERA_ERROR_HPP_ +#endif // CINELERRA_ERROR_HPP_ diff --git a/src/common/factory.hpp b/src/common/factory.hpp index 5645cfba6..a4b953b3a 100644 --- a/src/common/factory.hpp +++ b/src/common/factory.hpp @@ -21,14 +21,14 @@ */ -#ifndef LUMIERA_FACTORY_H -#define LUMIERA_FACTORY_H +#ifndef CINELERRA_FACTORY_H +#define CINELERRA_FACTORY_H #include -namespace lumiera +namespace cinelerra { namespace factory { @@ -141,5 +141,5 @@ namespace lumiera using factory::Factory; -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/src/common/multithread.hpp b/src/common/multithread.hpp index 1dbbac519..cc6eca1c6 100644 --- a/src/common/multithread.hpp +++ b/src/common/multithread.hpp @@ -23,21 +23,21 @@ -#ifndef LUMIERA_MULTITHREAD_H -#define LUMIERA_MULTITHREAD_H +#ifndef CINELERRA_MULTITHREAD_H +#define CINELERRA_MULTITHREAD_H #include "nobugcfg.h" -namespace lumiera +namespace cinelerra { /** * Interface/Policy for managing parallelism issues. * Basically everything is forwarded to the corresponding backend functions, - * because managing threads and locking belongs to the Lumiera backend layer. + * because managing threads and locking belongs to the cinelerra backend layer. * - * @todo actually implement this policy using the Lumiera databackend. + * @todo actually implement this policy using the cinelerra databackend. */ struct Thread { @@ -52,5 +52,5 @@ namespace lumiera }; -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/src/common/singleton.hpp b/src/common/singleton.hpp index c5de1474d..9f149214f 100644 --- a/src/common/singleton.hpp +++ b/src/common/singleton.hpp @@ -30,7 +30,7 @@ ** e.g. sometimes we want to include a hook for injecting Test Mock instances. ** ** You'll find the default Policies in singletonfactory.hpp and the default - ** definition of type lumiera::singleton in singletonpreconfigure.hpp + ** definition of type cinelerra::singleton in singletonpreconfigure.hpp ** ** @see SingletonFactory ** @see singleton::StaticCreate @@ -40,8 +40,8 @@ */ -#ifndef LUMIERA_SINGLETON_H -#define LUMIERA_SINGLETON_H +#ifndef CINELERRA_SINGLETON_H +#define CINELERRA_SINGLETON_H #include "common/singletonpolicies.hpp" diff --git a/src/common/singletonfactory.hpp b/src/common/singletonfactory.hpp index 026b6990e..319722fcf 100644 --- a/src/common/singletonfactory.hpp +++ b/src/common/singletonfactory.hpp @@ -31,8 +31,8 @@ This code is heavily inspired by -#ifndef LUMIERA_SINGLETONFACTORY_H -#define LUMIERA_SINGLETONFACTORY_H +#ifndef CINELERRA_SINGLETONFACTORY_H +#define CINELERRA_SINGLETONFACTORY_H #include "common/singletonpolicies.hpp" ///< several Policies usable together with SingletonFactory @@ -43,7 +43,7 @@ This code is heavily inspired by //#include -namespace lumiera +namespace cinelerra { /** @@ -136,5 +136,5 @@ namespace lumiera ///// It seems this would either cost us much of the flexibility or get complicated ///// to a point where we could as well implement our own Depenency Injection Manager. -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/src/common/singletonpolicies.hpp b/src/common/singletonpolicies.hpp index f0b448305..5ae31b939 100644 --- a/src/common/singletonpolicies.hpp +++ b/src/common/singletonpolicies.hpp @@ -31,8 +31,8 @@ This code is heavily inspired by -#ifndef LUMIERA_SINGLETONPOLICIES_H -#define LUMIERA_SINGLETONPOLICIES_H +#ifndef CINELERRA_SINGLETONPOLICIES_H +#define CINELERRA_SINGLETONPOLICIES_H #include "common/multithread.hpp" #include "common/error.hpp" @@ -40,11 +40,11 @@ This code is heavily inspired by #include -namespace lumiera +namespace cinelerra { namespace singleton { - /* === several Policies usable in conjunction with lumiera::Singleton === */ + /* == several Policies usable in conjunction with cinelerra::Singleton == */ /** * Policy placing the Singleton instance into a statically allocated buffer @@ -133,13 +133,13 @@ namespace lumiera /** * Policy for handling multithreaded access to the singleton instance - * @todo actually implement this policy using the Lumiera databackend. + * @todo actually implement this policy using the cinelerra databackend. */ template struct Multithreaded { typedef volatile S VolatileType; - typedef lumiera::Thread::Lock Lock; + typedef cinelerra::Thread::Lock Lock; }; @@ -156,5 +156,5 @@ namespace lumiera } // namespace singleton -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/src/common/singletonpreconfigure.hpp b/src/common/singletonpreconfigure.hpp index e9b12e3d6..9f3cfb8b2 100644 --- a/src/common/singletonpreconfigure.hpp +++ b/src/common/singletonpreconfigure.hpp @@ -31,7 +31,7 @@ ** One reason why one wants special Singleton behaviour is testing: Without ** altering the executable, for running some tests we need to inject a Test Mock ** in place of some service object, so we can verify the behaviour of the code - ** using this service. For this, we mix lumiera::test::MockInjector + ** using this service. For this, we mix cinelerra::test::MockInjector ** into the actual Singleton type. ** ** @note we declare the specialisations into the target namespace @@ -41,13 +41,13 @@ */ -#ifndef LUMIERA_SINGLETONPRECONFIGURE_H -#define LUMIERA_SINGLETONPRECONFIGURE_H +#ifndef CINELERRA_SINGLETONPRECONFIGURE_H +#define CINELERRA_SINGLETONPRECONFIGURE_H #include "common/test/mockinjector.hpp" -namespace lumiera +namespace cinelerra { /** * Default Singleton configuration @@ -67,15 +67,15 @@ namespace lumiera namespace test { class TestSingletonO; - using lumiera::Singleton; + using cinelerra::Singleton; } // namespace test -} // namespace lumiera +} // namespace cinelerra namespace backend_interface { class MediaAccessFacade; - using lumiera::Singleton; + using cinelerra::Singleton; } // namespace backend_interface @@ -87,7 +87,7 @@ namespace backend_interface /* Specialisation Definitions */ /* ************************** */ -namespace lumiera +namespace cinelerra { using test::MockInjector; @@ -104,7 +104,7 @@ namespace lumiera : public MockInjector { }; -} // namespace lumiera +} // namespace cinelerra diff --git a/src/common/test/mockinjector.hpp b/src/common/test/mockinjector.hpp index 4daf78081..28258e91e 100644 --- a/src/common/test/mockinjector.hpp +++ b/src/common/test/mockinjector.hpp @@ -22,8 +22,8 @@ -#ifndef LUMIERA_TEST_MOCKINJECTOR_H -#define LUMIERA_TEST_MOCKINJECTOR_H +#ifndef CINELERRA_TEST_MOCKINJECTOR_H +#define CINELERRA_TEST_MOCKINJECTOR_H #include "common/singletonfactory.hpp" @@ -31,7 +31,7 @@ #include -namespace lumiera +namespace cinelerra { namespace test { @@ -90,5 +90,5 @@ namespace lumiera } // namespace test -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/src/common/test/suite.cpp b/src/common/test/suite.cpp index 897a7d04f..c81c88097 100644 --- a/src/common/test/suite.cpp +++ b/src/common/test/suite.cpp @@ -133,7 +133,7 @@ namespace test TRACE(test, "Test-Suite( groupID=%s )\n", groupID.c_str () ); if (!testcases.getGroup(groupID)) - throw lumiera::error::Invalid (); + throw cinelerra::error::Invalid (); //throw "empty testsuite"; /////////// TODO Errorhandling! } @@ -155,7 +155,7 @@ namespace test { PTestMap tests = testcases.getGroup(groupID_); if (!tests) - throw lumiera::error::Invalid (); ///////// TODO: pass error description + throw cinelerra::error::Invalid (); ///////// TODO: pass error description if (0 < cmdline.size()) { @@ -209,7 +209,7 @@ namespace test } catch (...) { - std::cout << "PLANNED ============= " << lumiera_error() << "\n"; + std::cout << "PLANNED ============= " << cinelerra_error() << "\n"; } std::cout << "END\n"; } diff --git a/src/common/time.cpp b/src/common/time.cpp index a37979c6b..c208fcb46 100644 --- a/src/common/time.cpp +++ b/src/common/time.cpp @@ -25,7 +25,7 @@ #include -namespace lumiera +namespace cinelerra { // TODO: dummy values; should be adjusted when switching to the real time implementation provided by the backend @@ -34,4 +34,4 @@ namespace lumiera const Time Time::MIN = -std::numeric_limits::max(); -} // namespace lumiera +} // namespace cinelerra diff --git a/src/common/time.hpp b/src/common/time.hpp index d065c3f36..c4fc22244 100644 --- a/src/common/time.hpp +++ b/src/common/time.hpp @@ -21,13 +21,13 @@ */ -#ifndef LUMIERA_TIME_H -#define LUMIERA_TIME_H +#ifndef CINELERRA_TIME_H +#define CINELERRA_TIME_H #include -namespace lumiera +namespace cinelerra { @@ -56,5 +56,5 @@ namespace lumiera -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/src/common/typelist.hpp b/src/common/typelist.hpp index f358a605e..6d2720fcb 100644 --- a/src/common/typelist.hpp +++ b/src/common/typelist.hpp @@ -47,19 +47,19 @@ This code is heavily inspired by ** ** Interface for using this facility is the template Types(.....) for up to 20 Type parameters ** - ** @see lumiera::visitor::Applicable usage example + ** @see cinelerra::visitor::Applicable usage example ** @see typelisttest.cpp ** */ -#ifndef LUMIERA_TYPELIST_H -#define LUMIERA_TYPELIST_H +#ifndef CINELERRA_TYPELIST_H +#define CINELERRA_TYPELIST_H -namespace lumiera +namespace cinelerra { namespace typelist { @@ -116,5 +116,5 @@ namespace lumiera } // namespace typelist -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/src/common/visitor.cpp b/src/common/visitor.cpp index 91b195623..f702f809b 100644 --- a/src/common/visitor.cpp +++ b/src/common/visitor.cpp @@ -23,7 +23,7 @@ #include "common/visitor.hpp" -namespace lumiera +namespace cinelerra { namespace visitor { @@ -32,4 +32,4 @@ namespace lumiera } // namespace visitor -} // namespace lumiera +} // namespace cinelerra diff --git a/src/common/visitor.hpp b/src/common/visitor.hpp index 837ddf713..251254a88 100644 --- a/src/common/visitor.hpp +++ b/src/common/visitor.hpp @@ -37,7 +37,7 @@ Credits for many further implementation ideas go to /** @file visitor.hpp ** A library implementation of the Visitor Pattern taylored specifically - ** to Lumiera's needs within the Proc Layer. Visitor enables double dispatch + ** to cinelerra's needs within the Proc Layer. Visitor enables double dispatch ** calls, based both on the concrete type of some target object and the concrete type of ** a tool object being applied to this target. The code carrying out this tool application ** (and thus triggering the double dispatch) need not know any of these concret types and is @@ -73,8 +73,8 @@ Credits for many further implementation ideas go to -#ifndef LUMIERA_VISITOR_H -#define LUMIERA_VISITOR_H +#ifndef CINELERRA_VISITOR_H +#define CINELERRA_VISITOR_H #include "common/visitorpolicies.hpp" #include "common/visitordispatcher.hpp" @@ -82,7 +82,7 @@ Credits for many further implementation ideas go to #include "common/typelist.hpp" -namespace lumiera +namespace cinelerra { namespace visitor { @@ -229,5 +229,5 @@ namespace lumiera } // namespace visitor -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/src/common/visitordispatcher.hpp b/src/common/visitordispatcher.hpp index dcc28391b..0be12b2df 100644 --- a/src/common/visitordispatcher.hpp +++ b/src/common/visitordispatcher.hpp @@ -22,8 +22,8 @@ -#ifndef LUMIERA_VISITORDISPATCHER_H -#define LUMIERA_VISITORDISPATCHER_H +#ifndef CINELERRA_VISITORDISPATCHER_H +#define CINELERRA_VISITORDISPATCHER_H #include "common/error.hpp" #include "common/util.hpp" @@ -33,7 +33,7 @@ #include -namespace lumiera +namespace cinelerra { namespace visitor { @@ -211,5 +211,5 @@ namespace lumiera } // namespace visitor -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/src/common/visitorpolicies.hpp b/src/common/visitorpolicies.hpp index e59a2f5b2..6b9f353a5 100644 --- a/src/common/visitorpolicies.hpp +++ b/src/common/visitorpolicies.hpp @@ -22,20 +22,20 @@ /** @file visitorpolicies.hpp - ** Policies usable for configuring the lumiera::visitor::Tool for different kinds of error handling. + ** Policies usable for configuring the cinelerra::visitor::Tool for different kinds of error handling. ** @see buildertool.hpp for another flavor (calling and catch-all-function) ** */ -#ifndef LUMIERA_VISITORPOLICIES_H -#define LUMIERA_VISITORPOLICIES_H +#ifndef CINELERRA_VISITORPOLICIES_H +#define CINELERRA_VISITORPOLICIES_H #include "common/error.hpp" -namespace lumiera +namespace cinelerra { namespace visitor { @@ -65,7 +65,7 @@ namespace lumiera RET onUnknown (TAR&) { - throw lumiera::error::Config("unable to decide what tool operation to call"); + throw cinelerra::error::Config("unable to decide what tool operation to call"); } }; @@ -73,5 +73,5 @@ namespace lumiera } // namespace visitor -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/src/lib/condition.c b/src/lib/condition.c index 7427b431d..2b0bc28e8 100644 --- a/src/lib/condition.c +++ b/src/lib/condition.c @@ -30,8 +30,8 @@ * @param self is a pointer to the condition variable to be initialized * @return self as given */ -LumieraCondition -lumiera_condition_init (LumieraCondition self) +CinelerraCondition +cinelerra_condition_init (CinelerraCondition self) { if (self) { @@ -47,15 +47,15 @@ lumiera_condition_init (LumieraCondition self) * @param self is a pointer to the condition variable to be destroyed * @return self as given */ -LumieraCondition -lumiera_condition_destroy (LumieraCondition self) +CinelerraCondition +cinelerra_condition_destroy (CinelerraCondition self) { if (self) { if (pthread_mutex_destroy (&self->mutex)) - LUMIERA_DIE; + CINELERRA_DIE; else if (pthread_cond_destroy (&self->cond)) - LUMIERA_DIE; + CINELERRA_DIE; } return self; } diff --git a/src/lib/condition.h b/src/lib/condition.h index b2fd76c63..73da3685f 100644 --- a/src/lib/condition.h +++ b/src/lib/condition.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef LUMIERA_CONDITION_H -#define LUMIERA_CONDITION_H +#ifndef CINELERRA_CONDITION_H +#define CINELERRA_CONDITION_H #include "lib/locking.h" @@ -33,21 +33,21 @@ * Condition variables. * */ -struct lumiera_condition_struct +struct cinelerra_condition_struct { pthread_cond_t cond; pthread_mutex_t mutex; }; -typedef struct lumiera_condition_struct lumiera_condition; -typedef lumiera_condition* LumieraCondition; +typedef struct cinelerra_condition_struct cinelerra_condition; +typedef cinelerra_condition* CinelerraCondition; -LumieraCondition -lumiera_condition_init (LumieraCondition self); +CinelerraCondition +cinelerra_condition_init (CinelerraCondition self); -LumieraCondition -lumiera_condition_destroy (LumieraCondition self); +CinelerraCondition +cinelerra_condition_destroy (CinelerraCondition self); /** @@ -55,14 +55,14 @@ lumiera_condition_destroy (LumieraCondition self); * @param self condition variable to be signaled, must be given, all errors are fatal */ static inline void -lumiera_condition_signal (LumieraCondition self) +cinelerra_condition_signal (CinelerraCondition self) { REQUIRE (self); if (pthread_mutex_lock (&self->mutex)) - LUMIERA_DIE; + CINELERRA_DIE; pthread_cond_signal (&self->cond); if (pthread_mutex_unlock (&self->mutex)) - LUMIERA_DIE; + CINELERRA_DIE; } /** @@ -70,14 +70,14 @@ lumiera_condition_signal (LumieraCondition self) * @param self condition variable to be signaled, must be given, all errors are fatal */ static inline void -lumiera_condition_broadcast (LumieraCondition self) +cinelerra_condition_broadcast (CinelerraCondition self) { REQUIRE (self); if (pthread_mutex_lock (&self->mutex)) - LUMIERA_DIE; + CINELERRA_DIE; pthread_cond_broadcast (&self->cond); if (pthread_mutex_unlock (&self->mutex)) - LUMIERA_DIE; + CINELERRA_DIE; } @@ -87,44 +87,44 @@ lumiera_condition_broadcast (LumieraCondition self) /** * conditionacquirer used to manage the state of a condition variable. */ -struct lumiera_conditionacquirer_struct +struct cinelerra_conditionacquirer_struct { - LumieraCondition cond; - enum lumiera_lockstate state; + CinelerraCondition cond; + enum cinelerra_lockstate state; }; -typedef struct lumiera_conditionacquirer_struct lumiera_conditionacquirer; -typedef struct lumiera_conditionacquirer_struct* LumieraConditionacquirer; +typedef struct cinelerra_conditionacquirer_struct cinelerra_conditionacquirer; +typedef struct cinelerra_conditionacquirer_struct* CinelerraConditionacquirer; /* helper function for nobug */ static inline void -lumiera_conditionacquirer_ensureunlocked (LumieraConditionacquirer self) +cinelerra_conditionacquirer_ensureunlocked (CinelerraConditionacquirer self) { - ENSURE (self->state == LUMIERA_UNLOCKED, "forgot to unlock the condition mutex"); + ENSURE (self->state == CINELERRA_UNLOCKED, "forgot to unlock the condition mutex"); } /* override with a macro to use the cleanup checker */ -#define lumiera_conditionacquirer \ -lumiera_conditionacquirer NOBUG_CLEANUP(lumiera_conditionacquirer_ensureunlocked) +#define cinelerra_conditionacquirer \ +cinelerra_conditionacquirer NOBUG_CLEANUP(cinelerra_conditionacquirer_ensureunlocked) /** * initialize a conditionacquirer state * @param self conditionacquirer to be initialized, must be an automatic variable * @param cond associated condition variable - * @param state initial state of the mutex, either LUMIERA_LOCKED or LUMIERA_UNLOCKED + * @param state initial state of the mutex, either CINELERRA_LOCKED or CINELERRA_UNLOCKED * @return self as given * errors are fatal */ -static inline LumieraConditionacquirer -lumiera_conditionacquirer_init (LumieraConditionacquirer self, LumieraCondition cond, enum lumiera_lockstate state) +static inline CinelerraConditionacquirer +cinelerra_conditionacquirer_init (CinelerraConditionacquirer self, CinelerraCondition cond, enum cinelerra_lockstate state) { REQUIRE (self); REQUIRE (cond); self->cond = cond; self->state = state; - if (state == LUMIERA_LOCKED) + if (state == CINELERRA_LOCKED) if (pthread_mutex_lock (&cond->mutex)) - LUMIERA_DIE; + CINELERRA_DIE; return self; } @@ -135,15 +135,15 @@ lumiera_conditionacquirer_init (LumieraConditionacquirer self, LumieraCondition * @param self conditionacquirer associated with a condition variable */ static inline void -lumiera_conditionacquirer_lock (LumieraConditionacquirer self) +cinelerra_conditionacquirer_lock (CinelerraConditionacquirer self) { REQUIRE (self); - REQUIRE (self->state == LUMIERA_UNLOCKED, "mutex already locked"); + REQUIRE (self->state == CINELERRA_UNLOCKED, "mutex already locked"); if (pthread_mutex_lock (&self->cond->mutex)) - LUMIERA_DIE; + CINELERRA_DIE; - self->state = LUMIERA_LOCKED; + self->state = CINELERRA_LOCKED; } @@ -153,10 +153,10 @@ lumiera_conditionacquirer_lock (LumieraConditionacquirer self) * @param self conditionacquirer associated with a condition variable */ static inline void -lumiera_conditionacquirer_wait (LumieraConditionacquirer self) +cinelerra_conditionacquirer_wait (CinelerraConditionacquirer self) { REQUIRE (self); - REQUIRE (self->state == LUMIERA_LOCKED, "mutex must be locked"); + REQUIRE (self->state == CINELERRA_LOCKED, "mutex must be locked"); pthread_cond_wait (&self->cond->cond, &self->cond->mutex); } @@ -167,13 +167,13 @@ lumiera_conditionacquirer_wait (LumieraConditionacquirer self) * @param self conditionacquirer associated with a condition variable */ static inline int -lumiera_conditionacquirer_unlock (LumieraConditionacquirer self) +cinelerra_conditionacquirer_unlock (CinelerraConditionacquirer self) { REQUIRE (self); - REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked"); + REQUIRE (self->state == CINELERRA_LOCKED, "mutex was not locked"); if (pthread_mutex_unlock (&self->cond->mutex)) - LUMIERA_DIE; - self->state = LUMIERA_UNLOCKED; + CINELERRA_DIE; + self->state = CINELERRA_UNLOCKED; } @@ -182,10 +182,10 @@ lumiera_conditionacquirer_unlock (LumieraConditionacquirer self) * @param self conditionacquirer associated with the condition variable to be signaled */ static inline void -lumiera_conditionacquirer_signal (LumieraConditionacquirer self) +cinelerra_conditionacquirer_signal (CinelerraConditionacquirer self) { REQUIRE (self); - REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked"); + REQUIRE (self->state == CINELERRA_LOCKED, "mutex was not locked"); pthread_cond_signal (&self->cond->cond); } @@ -195,10 +195,10 @@ lumiera_conditionacquirer_signal (LumieraConditionacquirer self) * @param self conditionacquirer associated with the condition variable to be signaled */ static inline int -lumiera_conditionacquirer_broadcast (LumieraConditionacquirer self) +cinelerra_conditionacquirer_broadcast (CinelerraConditionacquirer self) { REQUIRE (self); - REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked"); + REQUIRE (self->state == CINELERRA_LOCKED, "mutex was not locked"); pthread_cond_broadcast (&self->cond->cond); } diff --git a/src/lib/error.c b/src/lib/error.c index 81e24bad8..df881013b 100644 --- a/src/lib/error.c +++ b/src/lib/error.c @@ -1,5 +1,5 @@ /* - error.c - Lumiera Error handling + error.c - Cinelerra Error handling Copyright (C) Lumiera.org 2008, Christian Thaeter @@ -24,41 +24,41 @@ #include "lib/error.h" /** - * @file C Error handling in Lumiera. + * @file C Error handling in Cinelerra. */ /* predefined errors */ -LUMIERA_ERROR_DEFINE (ERRNO, "errno"); +CINELERRA_ERROR_DEFINE (ERRNO, "errno"); /* Thread local storage */ -static pthread_key_t lumiera_error_tls; -static pthread_once_t lumiera_error_initialized = PTHREAD_ONCE_INIT; +static pthread_key_t cinelerra_error_tls; +static pthread_once_t cinelerra_error_initialized = PTHREAD_ONCE_INIT; static void -lumiera_error_tls_init (void) +cinelerra_error_tls_init (void) { - pthread_key_create (&lumiera_error_tls, NULL); + pthread_key_create (&cinelerra_error_tls, NULL); } /** * Set error state for the current thread. * If the error state of the current thread was cleared, then set it, else preserve the old state. - * @param nerr name of the error with 'LUMIERA_ERROR_' prefix (example: LUMIERA_ERROR_NO_MEMORY) + * @param nerr name of the error with 'CINELERRA_ERROR_' prefix (example: CINELERRA_ERROR_NO_MEMORY) * @return old state, that is NULL for success, when the state was cleared and a pointer to a pending * error when the error state was already set */ const char* -lumiera_error_set (const char * nerr) +cinelerra_error_set (const char * nerr) { - pthread_once (&lumiera_error_initialized, lumiera_error_tls_init); + pthread_once (&cinelerra_error_initialized, cinelerra_error_tls_init); - const char* err = pthread_getspecific (lumiera_error_tls); + const char* err = pthread_getspecific (cinelerra_error_tls); if (!err) - pthread_setspecific (lumiera_error_tls, nerr); + pthread_setspecific (cinelerra_error_tls, nerr); return err; } @@ -71,12 +71,12 @@ lumiera_error_set (const char * nerr) * @return pointer to any pending error of this thread, NULL if no error is pending */ const char* -lumiera_error () +cinelerra_error () { - pthread_once (&lumiera_error_initialized, lumiera_error_tls_init); + pthread_once (&cinelerra_error_initialized, cinelerra_error_tls_init); - const char* err = pthread_getspecific (lumiera_error_tls); + const char* err = pthread_getspecific (cinelerra_error_tls); if (err) - pthread_setspecific (lumiera_error_tls, NULL); + pthread_setspecific (cinelerra_error_tls, NULL); return err; } diff --git a/src/lib/error.h b/src/lib/error.h index 24c73f0a5..322487de1 100644 --- a/src/lib/error.h +++ b/src/lib/error.h @@ -1,5 +1,5 @@ /* - error.h - Lumiera Error handling + error.h - Cinelerra Error handling Copyright (C) Lumiera.org 2008, Christian Thaeter @@ -18,8 +18,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef LUMIERA_ERROR_H -#define LUMIERA_ERROR_H +#ifndef CINELERRA_ERROR_H +#define CINELERRA_ERROR_H #ifdef __cplusplus extern "C" { @@ -31,7 +31,7 @@ extern "C" { #include /** - * @file C Error handling in Lumiera, header. + * @file C Error handling in Cinelerra, header. */ @@ -39,46 +39,46 @@ extern "C" { * Abort unconditionally with a 'Fatal Error!' message. * This macro is used whenever the program end up in a invalid state from which no runtime recovery is possible */ -#define LUMIERA_DIE do { NOBUG_ERROR(NOBUG_ON, "Fatal Error!"); abort(); } while(0) +#define CINELERRA_DIE do { NOBUG_ERROR(NOBUG_ON, "Fatal Error!"); abort(); } while(0) /** * Forward declare an error constant. * This macro eases the error declaration in header files - * @param err name of the error without the 'LUMIERA_ERROR_' prefix (example: NO_MEMORY) + * @param err name of the error without the 'CINELERRA_ERROR_' prefix (example: NO_MEMORY) */ -#define LUMIERA_ERROR_DECLARE(err) \ -extern const char* LUMIERA_ERROR_##err +#define CINELERRA_ERROR_DECLARE(err) \ +extern const char* CINELERRA_ERROR_##err /** * Definition and initialization of an error constant. * This macro eases the error definition in implementation files - * @param err name of the error without the 'LUMIERA_ERROR_' prefix (example: NO_MEMORY) + * @param err name of the error without the 'CINELERRA_ERROR_' prefix (example: NO_MEMORY) * @param msg message describing the error in plain english (example: "memory allocation failed") */ -#define LUMIERA_ERROR_DEFINE(err, msg) \ -const char* LUMIERA_ERROR_##err = "LUMIERA_ERROR_" #err ":" msg +#define CINELERRA_ERROR_DEFINE(err, msg) \ +const char* CINELERRA_ERROR_##err = "CINELERRA_ERROR_" #err ":" msg /** Helper macro to raise an error for the current thread. * This macro eases setting an error. It adds NoBug logging support to the low level error handling. * @param flag NoBug flag describing the subsystem where the error was raised - * @param err name of the error without the 'LUMIERA_ERROR_' prefix (example: NO_MEMORY) + * @param err name of the error without the 'CINELERRA_ERROR_' prefix (example: NO_MEMORY) */ -#define LUMIERA_ERROR_SET(flag, err) \ -(({ERROR (flag, "%s", strchr(LUMIERA_ERROR_##err, ':')+1);}), \ -lumiera_error_set(LUMIERA_ERROR_##err)) +#define CINELERRA_ERROR_SET(flag, err) \ +(({ERROR (flag, "%s", strchr(CINELERRA_ERROR_##err, ':')+1);}), \ +cinelerra_error_set(CINELERRA_ERROR_##err)) const char* -lumiera_error_set (const char * err); +cinelerra_error_set (const char * err); const char* -lumiera_error (); +cinelerra_error (); /* predefined errors */ -LUMIERA_ERROR_DECLARE (ERRNO); +CINELERRA_ERROR_DECLARE (ERRNO); #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* LUMIERA_ERROR_H */ +#endif /* CINELERRA_ERROR_H */ diff --git a/src/lib/framerate.c b/src/lib/framerate.c index d8a2fa830..717bab4bb 100644 --- a/src/lib/framerate.c +++ b/src/lib/framerate.c @@ -26,5 +26,5 @@ */ -LUMIERA_ERROR_DEFINE(FRAMERATE_ILLEGAL_TIME, "invalid time given"); -LUMIERA_ERROR_DEFINE(FRAMERATE_ILLEGAL_FRAME, "invalid frame given"); +CINELERRA_ERROR_DEFINE(FRAMERATE_ILLEGAL_TIME, "invalid time given"); +CINELERRA_ERROR_DEFINE(FRAMERATE_ILLEGAL_FRAME, "invalid frame given"); diff --git a/src/lib/framerate.h b/src/lib/framerate.h index 6b050c86e..c7c9d2adc 100644 --- a/src/lib/framerate.h +++ b/src/lib/framerate.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef LUMIERA_FRAMERATE_H -#define LUMIERA_FRAMERATE_H +#ifndef CINELERRA_FRAMERATE_H +#define CINELERRA_FRAMERATE_H #include @@ -36,37 +36,37 @@ * framerates are defined as a rational number * for example NTSC with 30000/1001fps */ -struct lumiera_framerate_struct +struct cinelerra_framerate_struct { unsigned n; //numerator unsigned d; //denominator }; -typedef struct lumiera_framerate_struct lumiera_framerate; -typedef lumiera_framerate* LumieraFramerate; +typedef struct cinelerra_framerate_struct cinelerra_framerate; +typedef cinelerra_framerate* CinelerraFramerate; -typedef signed long lumiera_framepos; +typedef signed long cinelerra_framepos; -LUMIERA_ERROR_DECLARE(FRAMERATE_ILLEGAL_TIME); -LUMIERA_ERROR_DECLARE(FRAMERATE_ILLEGAL_FRAME); +CINELERRA_ERROR_DECLARE(FRAMERATE_ILLEGAL_TIME); +CINELERRA_ERROR_DECLARE(FRAMERATE_ILLEGAL_FRAME); -#define LUMIERA_FRAMEPOS_ERROR LONG_MIN +#define CINELERRA_FRAMEPOS_ERROR LONG_MIN /** * Get the frame number of a given time at a given frame rate. * frame indexing starts with 1 * @param framerate is a pointer to the framerate used, defined as rational number. Must be given. - * @param time is a pointer to a lumiera_time which shall be converted. - * @return frame at the given time or LUMIERA_FRAMEPOS_ERROR on error. + * @param time is a pointer to a cinelerra_time which shall be converted. + * @return frame at the given time or CINELERRA_FRAMEPOS_ERROR on error. */ -static inline lumiera_framepos -lumiera_framerate_frame_get_time (const LumieraFramerate framerate, LumieraTime time) +static inline cinelerra_framepos +cinelerra_framerate_frame_get_time (const CinelerraFramerate framerate, CinelerraTime time) { REQUIRE (framerate); if (!time || time->tv_sec == (time_t)-1) { - lumiera_error_set(LUMIERA_ERROR_FRAMERATE_ILLEGAL_TIME); - return LUMIERA_FRAMEPOS_ERROR; + cinelerra_error_set(CINELERRA_ERROR_FRAMERATE_ILLEGAL_TIME); + return CINELERRA_FRAMEPOS_ERROR; } /* we add a magic microsecond for rounding, because of integer truncation frames may be calculated at most 1us earlier, @@ -79,21 +79,21 @@ lumiera_framerate_frame_get_time (const LumieraFramerate framerate, LumieraTime * Get the start time for a frame. * frame indexing starts with 1 * @param framerate is a pointer to the framerate used, defined as rational number. Must be given. - * @param time is a pointer to a lumiera_time which shall take the result. + * @param time is a pointer to a cinelerra_time which shall take the result. * @param frame frame number to be converted to time. This frame number must be greater than 0. * @return the pointer given in time or NULL on error (or when it was given as time). */ -static inline LumieraTime -lumiera_framerate_time_get_time_frame (const LumieraFramerate framerate, - LumieraTime time, - lumiera_framepos frame) +static inline CinelerraTime +cinelerra_framerate_time_get_time_frame (const CinelerraFramerate framerate, + CinelerraTime time, + cinelerra_framepos frame) { REQUIRE (framerate); if (time) { if (frame < 1) { - lumiera_error_set(LUMIERA_ERROR_FRAMERATE_ILLEGAL_FRAME); + cinelerra_error_set(CINELERRA_ERROR_FRAMERATE_ILLEGAL_FRAME); return NULL; } diff --git a/src/lib/locking.h b/src/lib/locking.h index 01ad8bb29..2cf7f3700 100644 --- a/src/lib/locking.h +++ b/src/lib/locking.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef LUMIERA_LOCKING_H -#define LUMIERA_LOCKING_H +#ifndef CINELERRA_LOCKING_H +#define CINELERRA_LOCKING_H #include #include @@ -37,12 +37,12 @@ * * */ -enum lumiera_lockstate +enum cinelerra_lockstate { - LUMIERA_UNLOCKED, - LUMIERA_LOCKED, - LUMIERA_RDLOCKED, - LUMIERA_WRLOCKED + CINELERRA_UNLOCKED, + CINELERRA_LOCKED, + CINELERRA_RDLOCKED, + CINELERRA_WRLOCKED }; #endif diff --git a/src/lib/mutex.c b/src/lib/mutex.c index a08d89e51..b644c00ca 100644 --- a/src/lib/mutex.c +++ b/src/lib/mutex.c @@ -31,8 +31,8 @@ * @param self is a pointer to the mutex to be initialized * @return self as given */ -LumieraMutex -lumiera_mutex_init (LumieraMutex self) +CinelerraMutex +cinelerra_mutex_init (CinelerraMutex self) { if (self) { @@ -46,13 +46,13 @@ lumiera_mutex_init (LumieraMutex self) * @param self is a pointer to the mutex to be destroyed * @return self as given */ -LumieraMutex -lumiera_mutex_destroy (LumieraMutex self) +CinelerraMutex +cinelerra_mutex_destroy (CinelerraMutex self) { if (self) { if (pthread_mutex_destroy (&self->mutex)) - LUMIERA_DIE; + CINELERRA_DIE; } return self; } diff --git a/src/lib/mutex.h b/src/lib/mutex.h index ced7118e2..4dc4bac92 100644 --- a/src/lib/mutex.h +++ b/src/lib/mutex.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef LUMIERA_MUTEX_H -#define LUMIERA_MUTEX_H +#ifndef CINELERRA_MUTEX_H +#define CINELERRA_MUTEX_H #include "lib/locking.h" @@ -33,58 +33,58 @@ * Mutex. * */ -struct lumiera_mutex_struct +struct cinelerra_mutex_struct { pthread_mutex_t mutex; }; -typedef struct lumiera_mutex_struct lumiera_mutex; -typedef lumiera_mutex* LumieraMutex; +typedef struct cinelerra_mutex_struct cinelerra_mutex; +typedef cinelerra_mutex* CinelerraMutex; -LumieraMutex -lumiera_mutex_init (LumieraMutex self); +CinelerraMutex +cinelerra_mutex_init (CinelerraMutex self); -LumieraMutex -lumiera_mutex_destroy (LumieraMutex self); +CinelerraMutex +cinelerra_mutex_destroy (CinelerraMutex self); /** * mutexacquirer used to manage the state of a mutex variable. */ -struct lumiera_mutexacquirer_struct +struct cinelerra_mutexacquirer_struct { - LumieraMutex mutex; - enum lumiera_lockstate state; + CinelerraMutex mutex; + enum cinelerra_lockstate state; }; -typedef struct lumiera_mutexacquirer_struct lumiera_mutexacquirer; -typedef struct lumiera_mutexacquirer_struct* LumieraMutexacquirer; +typedef struct cinelerra_mutexacquirer_struct cinelerra_mutexacquirer; +typedef struct cinelerra_mutexacquirer_struct* CinelerraMutexacquirer; /* helper function for nobug */ static inline void -lumiera_mutexacquirer_ensureunlocked (LumieraMutexacquirer self) +cinelerra_mutexacquirer_ensureunlocked (CinelerraMutexacquirer self) { - ENSURE (self->state == LUMIERA_UNLOCKED, "forgot to unlock mutex"); + ENSURE (self->state == CINELERRA_UNLOCKED, "forgot to unlock mutex"); } /* override with a macro to use the cleanup checker */ -#define lumiera_mutexacquirer \ -lumiera_mutexacquirer NOBUG_CLEANUP(lumiera_mutexacquirer_ensureunlocked) +#define cinelerra_mutexacquirer \ +cinelerra_mutexacquirer NOBUG_CLEANUP(cinelerra_mutexacquirer_ensureunlocked) /** * initialize a mutexacquirer state without mutex. * @param self mutexacquirer to be initialized, must be an automatic variable * @return self as given - * This initialization is used when lumiera_mutexacquirer_try_mutex shall be used later + * This initialization is used when cinelerra_mutexacquirer_try_mutex shall be used later */ -static inline LumieraMutexacquirer -lumiera_mutexacquirer_init (LumieraMutexacquirer self) +static inline CinelerraMutexacquirer +cinelerra_mutexacquirer_init (CinelerraMutexacquirer self) { REQUIRE (self); self->mutex = NULL; - self->state = LUMIERA_UNLOCKED; + self->state = CINELERRA_UNLOCKED; return self; } @@ -93,20 +93,20 @@ lumiera_mutexacquirer_init (LumieraMutexacquirer self) * initialize a mutexacquirer state * @param self mutexacquirer to be initialized, must be an automatic variable * @param mutex associated mutex - * @param state initial state of the mutex, either LUMIERA_LOCKED or LUMIERA_UNLOCKED + * @param state initial state of the mutex, either CINELERRA_LOCKED or CINELERRA_UNLOCKED * @return self as given * errors are fatal */ -static inline LumieraMutexacquirer -lumiera_mutexacquirer_init_mutex (LumieraMutexacquirer self, LumieraMutex mutex, enum lumiera_lockstate state) +static inline CinelerraMutexacquirer +cinelerra_mutexacquirer_init_mutex (CinelerraMutexacquirer self, CinelerraMutex mutex, enum cinelerra_lockstate state) { REQUIRE (self); REQUIRE (mutex); self->mutex = mutex; self->state = state; - if (state == LUMIERA_LOCKED) + if (state == CINELERRA_LOCKED) if (pthread_mutex_lock (&mutex->mutex)) - LUMIERA_DIE; + CINELERRA_DIE; return self; } @@ -118,25 +118,25 @@ lumiera_mutexacquirer_init_mutex (LumieraMutexacquirer self, LumieraMutex mutex, * @param self mutexacquirer associated with a mutex variable */ static inline void -lumiera_mutexacquirer_lock (LumieraMutexacquirer self) +cinelerra_mutexacquirer_lock (CinelerraMutexacquirer self) { REQUIRE (self); - REQUIRE (self->state == LUMIERA_UNLOCKED, "mutex already locked"); + REQUIRE (self->state == CINELERRA_UNLOCKED, "mutex already locked"); if (pthread_mutex_lock (&self->mutex->mutex)) - LUMIERA_DIE; + CINELERRA_DIE; - self->state = LUMIERA_LOCKED; + self->state = CINELERRA_LOCKED; } /** * get the state of a lock. * @param self mutexacquirer associated with a mutex variable - * @return LUMIERA_LOCKED when the mutex is locked by this thead + * @return CINELERRA_LOCKED when the mutex is locked by this thead */ -static inline enum lumiera_lockstate -lumiera_mutexacquirer_state (LumieraMutexacquirer self) +static inline enum cinelerra_lockstate +cinelerra_mutexacquirer_state (CinelerraMutexacquirer self) { REQUIRE (self); return self->state; @@ -148,23 +148,23 @@ lumiera_mutexacquirer_state (LumieraMutexacquirer self) * must not already be locked * @param self mutexacquirer associated with a mutex variable * @param mutex pointer to a mutex which should be tried - * @return LUMIERA_LOCKED when the mutex got locked + * @return CINELERRA_LOCKED when the mutex got locked */ -static inline enum lumiera_lockstate -lumiera_mutexacquirer_try_mutex (LumieraMutexacquirer self, LumieraMutex mutex) +static inline enum cinelerra_lockstate +cinelerra_mutexacquirer_try_mutex (CinelerraMutexacquirer self, CinelerraMutex mutex) { REQUIRE (self); - REQUIRE (self->state == LUMIERA_UNLOCKED, "mutex already locked"); + REQUIRE (self->state == CINELERRA_UNLOCKED, "mutex already locked"); self->mutex=mutex; switch (pthread_mutex_trylock (&self->mutex->mutex)) { case 0: - return self->state = LUMIERA_LOCKED; + return self->state = CINELERRA_LOCKED; case EBUSY: - return LUMIERA_UNLOCKED; + return CINELERRA_UNLOCKED; default: - LUMIERA_DIE; + CINELERRA_DIE; } } @@ -175,13 +175,13 @@ lumiera_mutexacquirer_try_mutex (LumieraMutexacquirer self, LumieraMutex mutex) * @param self mutexacquirer associated with a mutex variable */ static inline void -lumiera_mutexacquirer_unlock (LumieraMutexacquirer self) +cinelerra_mutexacquirer_unlock (CinelerraMutexacquirer self) { REQUIRE (self); - REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked"); + REQUIRE (self->state == CINELERRA_LOCKED, "mutex was not locked"); if (pthread_mutex_unlock (&self->mutex->mutex)) - LUMIERA_DIE; - self->state = LUMIERA_UNLOCKED; + CINELERRA_DIE; + self->state = CINELERRA_UNLOCKED; } #endif diff --git a/src/lib/plugin.c b/src/lib/plugin.c index 87939533d..f819f4a6a 100644 --- a/src/lib/plugin.c +++ b/src/lib/plugin.c @@ -1,5 +1,5 @@ /* - plugin.c - Lumiera Plugin loader + plugin.c - Cinelerra Plugin loader Copyright (C) Lumiera.org 2008, Christian Thaeter @@ -34,48 +34,48 @@ /* TODO should be set by the build system to the actual plugin path */ -#define LUMIERA_PLUGIN_PATH "~/.lumiera/plugins:/usr/local/lib/lumiera/plugins:.libs" +#define CINELERRA_PLUGIN_PATH "~/.cinelerra3/plugins:/usr/local/lib/cinelerra3/plugins:.libs" -NOBUG_DEFINE_FLAG (lumiera_plugin); +NOBUG_DEFINE_FLAG (cinelerra_plugin); /* errors */ -LUMIERA_ERROR_DEFINE(PLUGIN_DLOPEN, "Could not open plugin"); -LUMIERA_ERROR_DEFINE(PLUGIN_HOOK, "Hook function failed"); -LUMIERA_ERROR_DEFINE(PLUGIN_NFILE, "No such plugin"); -LUMIERA_ERROR_DEFINE(PLUGIN_NIFACE, "No such interface"); -LUMIERA_ERROR_DEFINE(PLUGIN_REVISION, "Interface revision too old"); +CINELERRA_ERROR_DEFINE(PLUGIN_DLOPEN, "Could not open plugin"); +CINELERRA_ERROR_DEFINE(PLUGIN_HOOK, "Hook function failed"); +CINELERRA_ERROR_DEFINE(PLUGIN_NFILE, "No such plugin"); +CINELERRA_ERROR_DEFINE(PLUGIN_NIFACE, "No such interface"); +CINELERRA_ERROR_DEFINE(PLUGIN_REVISION, "Interface revision too old"); /* supported (planned) plugin types and their file extensions */ -enum lumiera_plugin_type +enum cinelerra_plugin_type { - LUMIERA_PLUGIN_NULL, - LUMIERA_PLUGIN_DYNLIB, - LUMIERA_PLUGIN_CSOURCE + CINELERRA_PLUGIN_NULL, + CINELERRA_PLUGIN_DYNLIB, + CINELERRA_PLUGIN_CSOURCE }; static const struct { const char* const ext; - enum lumiera_plugin_type type; -} lumiera_plugin_extensions [] = + enum cinelerra_plugin_type type; +} cinelerra_plugin_extensions [] = { - {"so", LUMIERA_PLUGIN_DYNLIB}, - {"o", LUMIERA_PLUGIN_DYNLIB}, - {"c", LUMIERA_PLUGIN_CSOURCE}, + {"so", CINELERRA_PLUGIN_DYNLIB}, + {"o", CINELERRA_PLUGIN_DYNLIB}, + {"c", CINELERRA_PLUGIN_CSOURCE}, /* extend here */ - {NULL, LUMIERA_PLUGIN_NULL} + {NULL, CINELERRA_PLUGIN_NULL} }; -struct lumiera_plugin +struct cinelerra_plugin { /* short name as queried ("effects/audio/normalize") used for sorting/finding */ const char* name; - /* long names as looked up ("/usr/local/lib/lumiera/plugins/effects/audio/normalize.so") */ + /* long names as looked up ("/usr/local/lib/cinelerra3/plugins/effects/audio/normalize.so") */ const char* pathname; /* use count for all interfaces of this plugin */ @@ -85,7 +85,7 @@ struct lumiera_plugin time_t last; /* kind of plugin */ - enum lumiera_plugin_type type; + enum cinelerra_plugin_type type; /* dlopen handle */ void* handle; @@ -93,19 +93,19 @@ struct lumiera_plugin /* global plugin registry */ -void* lumiera_plugin_registry = NULL; +void* cinelerra_plugin_registry = NULL; /* plugin operations are protected by one big mutex */ -pthread_mutex_t lumiera_plugin_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t cinelerra_plugin_mutex = PTHREAD_MUTEX_INITIALIZER; /** * the compare function for the registry tree. - * Compares the names of two struct lumiera_plugin. + * Compares the names of two struct cinelerra_plugin. * @return 0 if a and b are equal, just like strcmp. */ static int -lumiera_plugin_name_cmp (const void* a, const void* b) +cinelerra_plugin_name_cmp (const void* a, const void* b) { - return strcmp (((struct lumiera_plugin*) a)->name, ((struct lumiera_plugin*) b)->name); + return strcmp (((struct cinelerra_plugin*) a)->name, ((struct cinelerra_plugin*) b)->name); } /** @@ -113,21 +113,21 @@ lumiera_plugin_name_cmp (const void* a, const void* b) * always succeeds or aborts */ void -lumiera_init_plugin (void) +cinelerra_init_plugin (void) { - NOBUG_INIT_FLAG (lumiera_plugin); + NOBUG_INIT_FLAG (cinelerra_plugin); } /** * Find and set pathname for the plugin. * Searches through given path for given plugin, trying to find the file's location in the filesystem. * If found, self->pathname will be set to the found plugin file. - * @param self The lumiera_plugin to open look for. + * @param self The cinelerra_plugin to open look for. * @param path The path to search trough (paths seperated by ":") * @return 0 on success. -1 on error, or if plugin not found in path. */ int -lumiera_plugin_lookup (struct lumiera_plugin* self, const char* path) +cinelerra_plugin_lookup (struct cinelerra_plugin* self, const char* path) { if (!path) return -1; @@ -146,22 +146,22 @@ lumiera_plugin_lookup (struct lumiera_plugin* self, const char* path) for (char* tok = strtok_r (tpath, ":", &tmp); tok; tok = strtok_r (NULL, ":", &tmp)) { /*for each extension*/ - for (int i = 0; lumiera_plugin_extensions[i].ext; ++i) + for (int i = 0; cinelerra_plugin_extensions[i].ext; ++i) { /* path/name.extension */ - int r = snprintf(pathname, 1024, "%s/%s.%s", tok, self->name, lumiera_plugin_extensions[i].ext); + int r = snprintf(pathname, 1024, "%s/%s.%s", tok, self->name, cinelerra_plugin_extensions[i].ext); if (r >= 1024) return -1; /*TODO error handling, name too long*/ - TRACE (lumiera_plugin, "trying %s", pathname); + TRACE (cinelerra_plugin, "trying %s", pathname); if (!access(pathname, R_OK)) { /* got it */ - TRACE (lumiera_plugin, "found %s", pathname); + TRACE (cinelerra_plugin, "found %s", pathname); self->pathname = strdup (pathname); - if (!self->pathname) LUMIERA_DIE; - self->type = lumiera_plugin_extensions[i].type; + if (!self->pathname) CINELERRA_DIE; + self->type = cinelerra_plugin_extensions[i].type; return 0; } } @@ -181,44 +181,44 @@ lumiera_plugin_lookup (struct lumiera_plugin* self, const char* path) * @return handle to the interface or NULL in case of a error. The application shall cast this handle to * the actual interface type. */ -struct lumiera_interface* -lumiera_interface_open (const char* name, const char* interface, size_t min_revision) +struct cinelerra_interface* +cinelerra_interface_open (const char* name, const char* interface, size_t min_revision) { - //REQUIRE (min_revision > sizeof(struct lumiera_interface), "try to use an empty interface eh?"); + //REQUIRE (min_revision > sizeof(struct cinelerra_interface), "try to use an empty interface eh?"); REQUIRE (interface, "interface name must be given"); - pthread_mutex_lock (&lumiera_plugin_mutex); + pthread_mutex_lock (&cinelerra_plugin_mutex); - struct lumiera_plugin plugin; - struct lumiera_plugin** found; + struct cinelerra_plugin plugin; + struct cinelerra_plugin** found; plugin.name = name; /* for searching */ - found = tsearch (&plugin, &lumiera_plugin_registry, lumiera_plugin_name_cmp); - if (!found) LUMIERA_DIE; + found = tsearch (&plugin, &cinelerra_plugin_registry, cinelerra_plugin_name_cmp); + if (!found) CINELERRA_DIE; if (*found == &plugin) { - NOTICE (lumiera_plugin, "new plugin"); + NOTICE (cinelerra_plugin, "new plugin"); /* now really create new item */ - *found = malloc (sizeof (struct lumiera_plugin)); - if (!*found) LUMIERA_DIE; + *found = malloc (sizeof (struct cinelerra_plugin)); + if (!*found) CINELERRA_DIE; if (name) /* NULL is main app, no lookup needed */ { - /*lookup for $LUMIERA_PLUGIN_PATH*/ + /*lookup for $CINELERRA_PLUGIN_PATH*/ (*found)->name = strdup (name); - if (!(*found)->name) LUMIERA_DIE; + if (!(*found)->name) CINELERRA_DIE; - if (!!lumiera_plugin_lookup (*found, getenv("LUMIERA_PLUGIN_PATH")) -#ifdef LUMIERA_PLUGIN_PATH - /* else lookup for -DLUMIERA_PLUGIN_PATH */ - && !!lumiera_plugin_lookup (*found, LUMIERA_PLUGIN_PATH) + if (!!cinelerra_plugin_lookup (*found, getenv("CINELERRA_PLUGIN_PATH")) +#ifdef CINELERRA_PLUGIN_PATH + /* else lookup for -DCINELERRA_PLUGIN_PATH */ + && !!cinelerra_plugin_lookup (*found, CINELERRA_PLUGIN_PATH) #endif ) { - LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_NFILE); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_NFILE); goto elookup; } } @@ -233,46 +233,46 @@ lumiera_interface_open (const char* name, const char* interface, size_t min_revi PLANNED("if .so like then dlopen; else if .c like tcc compile"); TODO("factor dlopen and dlsym out"); - TRACE(lumiera_plugin, "trying to open %s", (*found)->pathname); + TRACE(cinelerra_plugin, "trying to open %s", (*found)->pathname); (*found)->handle = dlopen ((*found)->pathname, RTLD_LAZY|RTLD_LOCAL); if (!(*found)->handle) { - ERROR (lumiera_plugin, "dlopen failed: %s", dlerror()); - LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_DLOPEN); + ERROR (cinelerra_plugin, "dlopen failed: %s", dlerror()); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_DLOPEN); goto edlopen; } - /* if the plugin defines a 'lumiera_plugin_init' function, we call it, must return 0 on success */ - int (*init)(void) = dlsym((*found)->handle, "lumiera_plugin_init"); + /* if the plugin defines a 'cinelerra_plugin_init' function, we call it, must return 0 on success */ + int (*init)(void) = dlsym((*found)->handle, "cinelerra_plugin_init"); if (init && init()) { - //ERROR (lumiera_plugin, "lumiera_plugin_init failed: %s: %s", name, interface); - LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_HOOK); + //ERROR (cinelerra_plugin, "cinelerra_plugin_init failed: %s: %s", name, interface); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_HOOK); goto einit; } } /* we have the plugin, now get the interface descriptor */ - struct lumiera_interface* ret; + struct cinelerra_interface* ret; dlerror(); ret = dlsym ((*found)->handle, interface); const char *dlerr = dlerror(); - TRACE(lumiera_plugin, "%s", dlerr); - TODO ("need some way to tell 'interface not provided by plugin', maybe lumiera_plugin_error()?"); + TRACE(cinelerra_plugin, "%s", dlerr); + TODO ("need some way to tell 'interface not provided by plugin', maybe cinelerra_plugin_error()?"); if (dlerr) { - //ERROR (lumiera_plugin, "plugin %s doesnt provide interface %s", name, interface); - LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_NIFACE); + //ERROR (cinelerra_plugin, "plugin %s doesnt provide interface %s", name, interface); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_NIFACE); goto edlsym; } /* is the interface older than required? */ if (ret->size < min_revision) { - ERROR (lumiera_plugin, "plugin %s provides older interface %s revision than required", name, interface); - LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_REVISION); + ERROR (cinelerra_plugin, "plugin %s provides older interface %s revision than required", name, interface); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_REVISION); goto erevision; } @@ -281,8 +281,8 @@ lumiera_interface_open (const char* name, const char* interface, size_t min_revi /* if the interface provides a 'open' function, call it now, must return 0 on success */ if (ret->open && ret->open()) { - ERROR (lumiera_plugin, "open hook indicated an error"); - LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_HOOK); + ERROR (cinelerra_plugin, "open hook indicated an error"); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_HOOK); goto eopen; } @@ -290,7 +290,7 @@ lumiera_interface_open (const char* name, const char* interface, size_t min_revi (*found)->last = time (NULL); ret->use_count++; - pthread_mutex_unlock (&lumiera_plugin_mutex); + pthread_mutex_unlock (&cinelerra_plugin_mutex); return ret; /* Error cleanup */ @@ -304,8 +304,8 @@ lumiera_interface_open (const char* name, const char* interface, size_t min_revi free ((char*)(*found)->name); free (*found); *found = &plugin; - tdelete (&plugin, &lumiera_plugin_registry, lumiera_plugin_name_cmp); - pthread_mutex_unlock (&lumiera_plugin_mutex); + tdelete (&plugin, &cinelerra_plugin_registry, cinelerra_plugin_name_cmp); + pthread_mutex_unlock (&cinelerra_plugin_mutex); return NULL; } @@ -315,17 +315,17 @@ lumiera_interface_open (const char* name, const char* interface, size_t min_revi * @param ptr interface to be closed */ void -lumiera_interface_close (void* ptr) +cinelerra_interface_close (void* ptr) { - TRACE (lumiera_plugin, "%p", ptr); + TRACE (cinelerra_plugin, "%p", ptr); if(!ptr) return; - struct lumiera_interface* self = (struct lumiera_interface*) ptr; + struct cinelerra_interface* self = (struct cinelerra_interface*) ptr; - pthread_mutex_lock (&lumiera_plugin_mutex); + pthread_mutex_lock (&cinelerra_plugin_mutex); - struct lumiera_plugin* plugin = self->plugin; + struct cinelerra_plugin* plugin = self->plugin; plugin->use_count--; self->use_count--; @@ -339,16 +339,16 @@ lumiera_interface_close (void* ptr) { TODO ("we dont want to close here, instead store time of recent use and make a expire run, already planned in my head"); - /* if the plugin defines a 'lumiera_plugin_destroy' function, we call it */ - int (*destroy)(void) = dlsym(plugin->handle, "lumiera_plugin_destroy"); + /* if the plugin defines a 'cinelerra_plugin_destroy' function, we call it */ + int (*destroy)(void) = dlsym(plugin->handle, "cinelerra_plugin_destroy"); if (destroy) destroy(); /* and now cleanup */ - tdelete (plugin, &lumiera_plugin_registry, lumiera_plugin_name_cmp); + tdelete (plugin, &cinelerra_plugin_registry, cinelerra_plugin_name_cmp); free ((char*)plugin->name); dlclose(plugin->handle); free (plugin); } - pthread_mutex_unlock (&lumiera_plugin_mutex); + pthread_mutex_unlock (&cinelerra_plugin_mutex); } diff --git a/src/lib/plugin.h b/src/lib/plugin.h index f8916ae96..45a22bf29 100644 --- a/src/lib/plugin.h +++ b/src/lib/plugin.h @@ -18,8 +18,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef LUMIERA_PLUGIN_H -#define LUMIERA_PLUGIN_H +#ifndef CINELERRA_PLUGIN_H +#define CINELERRA_PLUGIN_H #ifdef __cplusplus extern "C" { @@ -37,55 +37,55 @@ extern "C" { */ -NOBUG_DECLARE_FLAG (lumiera_plugin); +NOBUG_DECLARE_FLAG (cinelerra_plugin); /* tool macros*/ -#define LUMIERA_INTERFACE_TYPE(name, version) struct lumiera_interface_##name##_##version -#define LUMIERA_INTERFACE_CAST(name, version) (LUMIERA_INTERFACE_TYPE(name, version)*) +#define CINELERRA_INTERFACE_TYPE(name, version) struct cinelerra_interface_##name##_##version +#define CINELERRA_INTERFACE_CAST(name, version) (CINELERRA_INTERFACE_TYPE(name, version)*) /* Interface definition */ -#define LUMIERA_INTERFACE(name, version, ...) \ -LUMIERA_INTERFACE_TYPE(name, version) \ +#define CINELERRA_INTERFACE(name, version, ...) \ +CINELERRA_INTERFACE_TYPE(name, version) \ { \ - struct lumiera_interface interface_header_; \ + struct cinelerra_interface interface_header_; \ __VA_ARGS__ \ } -#define LUMIERA_INTERFACE_PROTO(ret, name, params) ret (*name) params; +#define CINELERRA_INTERFACE_PROTO(ret, name, params) ret (*name) params; /* Interface instantiation */ -#define LUMIERA_INTERFACE_IMPLEMENT(iname, version, name, open, close, ...) \ -LUMIERA_INTERFACE_TYPE(iname, version) name##_##version = \ -{ \ - { \ - version, \ - sizeof(LUMIERA_INTERFACE_TYPE(iname, version)), \ - NULL, \ - 0, \ - open, \ - close \ - }, \ - __VA_ARGS__ \ +#define CINELERRA_INTERFACE_IMPLEMENT(iname, version, name, open, close, ...) \ +CINELERRA_INTERFACE_TYPE(iname, version) name##_##version = \ +{ \ + { \ + version, \ + sizeof(CINELERRA_INTERFACE_TYPE(iname, version)), \ + NULL, \ + 0, \ + open, \ + close \ + }, \ + __VA_ARGS__ \ } /* internally used */ -struct lumiera_plugin; +struct cinelerra_plugin; /** * This is the header for any interface exported by plugins. * Real interfaces append their functions at the end. There are few standard functions on each Interface * Every function is required to be implemnted. */ -struct lumiera_interface +struct cinelerra_interface { /// interface version number unsigned version; /// size of the full structure is used to determine the revision (adding a new function increments the size) size_t size; /// back reference to plugin - struct lumiera_plugin* plugin; + struct cinelerra_plugin* plugin; /// incremented for each user of this interface and decremented when closed unsigned use_count; @@ -96,15 +96,15 @@ struct lumiera_interface }; void -lumiera_init_plugin (void); +cinelerra_init_plugin (void); -struct lumiera_interface* -lumiera_interface_open (const char* plugin, const char* name, size_t min_revision); +struct cinelerra_interface* +cinelerra_interface_open (const char* plugin, const char* name, size_t min_revision); void -lumiera_interface_close (void* self); +cinelerra_interface_close (void* self); /** * Tries to unload a plugin. @@ -113,24 +113,24 @@ lumiera_interface_close (void* self); * @return 0 on success, else the number if users which keeping the plugin loaded */ int -lumiera_plugin_unload (const char* plugin); +cinelerra_plugin_unload (const char* plugin); /** * Tries to unload plugins which are not in use. - * Calls lumiera_plugin_unload() for each Plugin which is not used for more than age seconds. + * Calls cinelerra_plugin_unload() for each Plugin which is not used for more than age seconds. * This function might be infrequently called by the scheduler to remove things which are not needed. * @param age timeout in seconds when to unload plugins */ void -lumiera_plugin_expire (time_t age); +cinelerra_plugin_expire (time_t age); -LUMIERA_ERROR_DECLARE(PLUGIN_DLOPEN); -LUMIERA_ERROR_DECLARE(PLUGIN_HOOK); -LUMIERA_ERROR_DECLARE(PLUGIN_NFILE); -LUMIERA_ERROR_DECLARE(PLUGIN_NIFACE); -LUMIERA_ERROR_DECLARE(PLUGIN_REVISION); +CINELERRA_ERROR_DECLARE(PLUGIN_DLOPEN); +CINELERRA_ERROR_DECLARE(PLUGIN_HOOK); +CINELERRA_ERROR_DECLARE(PLUGIN_NFILE); +CINELERRA_ERROR_DECLARE(PLUGIN_NIFACE); +CINELERRA_ERROR_DECLARE(PLUGIN_REVISION); #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* LUMIERA_PLUGIN_H */ +#endif /* CINELERRA_PLUGIN_H */ diff --git a/src/lib/references.c b/src/lib/references.c index ad4f9562f..a4c5eb247 100644 --- a/src/lib/references.c +++ b/src/lib/references.c @@ -40,17 +40,17 @@ * @param dtor destructor function which will be called on obj when the last strong reference gets deleted * @return self as given */ -LumieraReference -lumiera_reference_strong_init_once (LumieraReference self, void* obj, void (*dtor)(void*)) +CinelerraReference +cinelerra_reference_strong_init_once (CinelerraReference self, void* obj, void (*dtor)(void*)) { - LumieraReftarget target = malloc (sizeof(lumiera_reftarget)); - if (!target) LUMIERA_DIE; + CinelerraReftarget target = malloc (sizeof(cinelerra_reftarget)); + if (!target) CINELERRA_DIE; target->object = obj; target->dtor = dtor; target->strong_cnt = 1; target->weak_cnt = 0; - lumiera_mutex_init (&target->lock); + cinelerra_mutex_init (&target->lock); self->object = obj; self->target = target; @@ -66,16 +66,16 @@ lumiera_reference_strong_init_once (LumieraReference self, void* obj, void (*dto * @return self as given * destroying a reference is not thread safe as far as 2 threads try to concurrently destroy it! */ -LumieraReference -lumiera_reference_destroy (LumieraReference self) +CinelerraReference +cinelerra_reference_destroy (CinelerraReference self) { - LumieraReftarget target = self->target; + CinelerraReftarget target = self->target; /* defensive, lets detect errors if anything still tries to use this reference */ self->target = NULL; - lumiera_mutexacquirer lock; - lumiera_mutexacquirer_init_mutex (&lock, &target->lock, LUMIERA_LOCKED); + cinelerra_mutexacquirer lock; + cinelerra_mutexacquirer_init_mutex (&lock, &target->lock, CINELERRA_LOCKED); if (self->object) { @@ -89,8 +89,8 @@ lumiera_reference_destroy (LumieraReference self) if (!target->weak_cnt) { /* no weak refs either, destroy it */ - lumiera_mutexacquirer_unlock (&lock); - lumiera_mutex_destroy (&target->lock); + cinelerra_mutexacquirer_unlock (&lock); + cinelerra_mutex_destroy (&target->lock); free (target); return self; } @@ -102,13 +102,13 @@ lumiera_reference_destroy (LumieraReference self) if (!--target->weak_cnt && !target->strong_cnt) { /* was last weak reference, and no strong refs left */ - lumiera_mutexacquirer_unlock (&lock); - lumiera_mutex_destroy (&target->lock); + cinelerra_mutexacquirer_unlock (&lock); + cinelerra_mutex_destroy (&target->lock); free (target); return self; } } - lumiera_mutexacquirer_unlock (&lock); + cinelerra_mutexacquirer_unlock (&lock); return self; } @@ -118,11 +118,11 @@ lumiera_reference_destroy (LumieraReference self) * @return self as strong reference (always for strong references) or NULL if source is an invalidated weak reference, * in the later case the reference is constructed as weak reference barely to allow it be destroyed */ -LumieraReference -lumiera_reference_strong_init (LumieraReference self, LumieraReference source) +CinelerraReference +cinelerra_reference_strong_init (CinelerraReference self, CinelerraReference source) { - lumiera_mutexacquirer lock; - lumiera_mutexacquirer_init_mutex (&lock, &source->target->lock, LUMIERA_LOCKED); + cinelerra_mutexacquirer lock; + cinelerra_mutexacquirer_init_mutex (&lock, &source->target->lock, CINELERRA_LOCKED); self->object = source->target->object; self->target = source->target; @@ -136,7 +136,7 @@ lumiera_reference_strong_init (LumieraReference self, LumieraReference source) ++self->target->weak_cnt; self = NULL; } - lumiera_mutexacquirer_unlock (&lock); + cinelerra_mutexacquirer_unlock (&lock); return self; } @@ -145,11 +145,11 @@ lumiera_reference_strong_init (LumieraReference self, LumieraReference source) * @param source reference to copy * @return self (always for strong references) or NULL if self is an invalidated weak reference */ -LumieraReference -lumiera_reference_weak_init (LumieraReference self, LumieraReference source) +CinelerraReference +cinelerra_reference_weak_init (CinelerraReference self, CinelerraReference source) { - lumiera_mutexacquirer lock; - lumiera_mutexacquirer_init_mutex (&lock, &source->target->lock, LUMIERA_LOCKED); + cinelerra_mutexacquirer lock; + cinelerra_mutexacquirer_init_mutex (&lock, &source->target->lock, CINELERRA_LOCKED); self->object = NULL; self->target = source->target; @@ -159,7 +159,7 @@ lumiera_reference_weak_init (LumieraReference self, LumieraReference source) /* already invalidated */ self = NULL; - lumiera_mutexacquirer_unlock (&lock); + cinelerra_mutexacquirer_unlock (&lock); return self; } @@ -169,14 +169,14 @@ lumiera_reference_weak_init (LumieraReference self, LumieraReference source) * do nothing if the referene is already weak * @return self or NULL if the final strong reference got removed, */ -LumieraReference -lumiera_reference_weaken (restrict LumieraReference self) +CinelerraReference +cinelerra_reference_weaken (restrict CinelerraReference self) { /* is this a strong reference? */ if (self->object) { - lumiera_mutexacquirer lock; - lumiera_mutexacquirer_init_mutex (&lock, &self->target->lock, LUMIERA_LOCKED); + cinelerra_mutexacquirer lock; + cinelerra_mutexacquirer_init_mutex (&lock, &self->target->lock, CINELERRA_LOCKED); self->object = NULL; ++self->target->weak_cnt; @@ -187,7 +187,7 @@ lumiera_reference_weaken (restrict LumieraReference self) self->target->object = NULL; self = NULL; } - lumiera_mutexacquirer_unlock (&lock); + cinelerra_mutexacquirer_unlock (&lock); } return self; } @@ -198,14 +198,14 @@ lumiera_reference_weaken (restrict LumieraReference self) * only references of object which are not already destroyed can be strengthened * @return self when successful, NULL when the object was already destroyed, 'self' stays a dead weak reference in that case */ -LumieraReference -lumiera_reference_strengthen (LumieraReference self) +CinelerraReference +cinelerra_reference_strengthen (CinelerraReference self) { /* is this a weak reference? */ if (!self->object) { - lumiera_mutexacquirer lock; - lumiera_mutexacquirer_init_mutex (&lock, &self->target->lock, LUMIERA_LOCKED); + cinelerra_mutexacquirer lock; + cinelerra_mutexacquirer_init_mutex (&lock, &self->target->lock, CINELERRA_LOCKED); if (self->target->object) { @@ -215,7 +215,7 @@ lumiera_reference_strengthen (LumieraReference self) } else self = NULL; - lumiera_mutexacquirer_unlock (&lock); + cinelerra_mutexacquirer_unlock (&lock); } return self; } diff --git a/src/lib/references.h b/src/lib/references.h index 3e00457e7..a7de3f7f0 100644 --- a/src/lib/references.h +++ b/src/lib/references.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef LUMIERA_REFERENCES_H -#define LUMIERA_REFERENCES_H +#ifndef CINELERRA_REFERENCES_H +#define CINELERRA_REFERENCES_H #include @@ -29,77 +29,77 @@ */ -typedef struct lumiera_reference_struct lumiera_reference; -typedef lumiera_reference* LumieraReference; +typedef struct cinelerra_reference_struct cinelerra_reference; +typedef cinelerra_reference* CinelerraReference; #include "lib/error.h" #include "lib/mutex.h" /* Implementation detail */ -struct lumiera_reftarget_struct +struct cinelerra_reftarget_struct { void* object; void (*dtor)(void*); unsigned strong_cnt; /*when strong becomes 0 obj is destroyed, if weak is 0 destroy target too*/ unsigned weak_cnt; /*when weak becomes 0 and !obj and lock strong is 0, destroy target */ - lumiera_mutex lock; + cinelerra_mutex lock; }; -typedef struct lumiera_reftarget_struct lumiera_reftarget; -typedef lumiera_reftarget* LumieraReftarget; +typedef struct cinelerra_reftarget_struct cinelerra_reftarget; +typedef cinelerra_reftarget* CinelerraReftarget; /** * A reference pointing to some other object */ -struct lumiera_reference_struct +struct cinelerra_reference_struct { void* object; /*set for strong, NULL for weak*/ - LumieraReftarget target; + CinelerraReftarget target; }; -#define lumiera_reference \ -lumiera_reference NOBUG_CLEANUP(lumiera_reference_ensuredestroyed) +#define cinelerra_reference \ +cinelerra_reference NOBUG_CLEANUP(cinelerra_reference_ensuredestroyed) /* helper function for nobug */ static inline void -lumiera_reference_ensuredestroyed (LumieraReference self) +cinelerra_reference_ensuredestroyed (CinelerraReference self) { ENSURE (!self->target, "forgot to destroy reference"); } -LumieraReference -lumiera_reference_strong_init_once (LumieraReference self, void* obj, void (*dtor)(void*)); +CinelerraReference +cinelerra_reference_strong_init_once (CinelerraReference self, void* obj, void (*dtor)(void*)); -LumieraReference -lumiera_reference_destroy (LumieraReference self); +CinelerraReference +cinelerra_reference_destroy (CinelerraReference self); /** * Get object from a strong reference. * @return pointer to object, NULL if applied to a weak reference */ static inline void* -lumiera_reference_get (LumieraReference self) +cinelerra_reference_get (CinelerraReference self) { ENSURE (self->target, "illegal reference (not initialized or already destroyed?)"); return self->object; } -LumieraReference -lumiera_reference_strong_init (LumieraReference self, LumieraReference source); +CinelerraReference +cinelerra_reference_strong_init (CinelerraReference self, CinelerraReference source); -LumieraReference -lumiera_reference_weak_init (LumieraReference self, LumieraReference source); +CinelerraReference +cinelerra_reference_weak_init (CinelerraReference self, CinelerraReference source); -LumieraReference -lumiera_reference_weaken (restrict LumieraReference self); +CinelerraReference +cinelerra_reference_weaken (restrict CinelerraReference self); -LumieraReference -lumiera_reference_strengthen (LumieraReference self); +CinelerraReference +cinelerra_reference_strengthen (CinelerraReference self); #endif diff --git a/src/lib/rwlock.c b/src/lib/rwlock.c index c7ee3a37d..d60223e3c 100644 --- a/src/lib/rwlock.c +++ b/src/lib/rwlock.c @@ -23,8 +23,8 @@ #include #include "lib/rwlock.h" -LUMIERA_ERROR_DEFINE(RWLOCK_AGAIN, "maximum number of readlocks exceed"); -LUMIERA_ERROR_DEFINE(RWLOCK_DEADLOCK, "deadlock detected"); +CINELERRA_ERROR_DEFINE(RWLOCK_AGAIN, "maximum number of readlocks exceed"); +CINELERRA_ERROR_DEFINE(RWLOCK_DEADLOCK, "deadlock detected"); /** * @file Read/write locks. @@ -36,8 +36,8 @@ LUMIERA_ERROR_DEFINE(RWLOCK_DEADLOCK, "deadlock detected"); * @param self is a pointer to the rwlock to be initialized * @return self as given */ -LumieraRWLock -lumiera_rwlock_init (LumieraRWLock self) +CinelerraRWLock +cinelerra_rwlock_init (CinelerraRWLock self) { if (self) { @@ -51,13 +51,13 @@ lumiera_rwlock_init (LumieraRWLock self) * @param self is a pointer to the rwlock to be initialized * @return self on success or NULL at error */ -LumieraRWLock -lumiera_rwlock_destroy (LumieraRWLock self) +CinelerraRWLock +cinelerra_rwlock_destroy (CinelerraRWLock self) { if (self) { if (pthread_rwlock_destroy (&self->rwlock)) - LUMIERA_DIE; + CINELERRA_DIE; } return self; } @@ -69,44 +69,44 @@ lumiera_rwlock_destroy (LumieraRWLock self) * initialize a rwlockacquirer state * @param self rwlockacquirer to be initialized, must be an automatic variable * @param rwlock associated rwlock - * @param state initial state of the mutex, either LUMIERA_RDLOCKED, LUMIERA_WRLOCKED or LUMIERA_UNLOCKED + * @param state initial state of the mutex, either CINELERRA_RDLOCKED, CINELERRA_WRLOCKED or CINELERRA_UNLOCKED * @return self as given or NULL on error */ -LumieraRWLockacquirer -lumiera_rwlockacquirer_init (LumieraRWLockacquirer self, LumieraRWLock rwlock, enum lumiera_lockstate state) +CinelerraRWLockacquirer +cinelerra_rwlockacquirer_init (CinelerraRWLockacquirer self, CinelerraRWLock rwlock, enum cinelerra_lockstate state) { REQUIRE (self); REQUIRE (rwlock); - REQUIRE (state != LUMIERA_LOCKED, "illegal state for rwlock"); + REQUIRE (state != CINELERRA_LOCKED, "illegal state for rwlock"); self->rwlock = rwlock; self->state = state; switch (state) { - case LUMIERA_RDLOCKED: + case CINELERRA_RDLOCKED: switch (pthread_rwlock_rdlock (&rwlock->rwlock)) { case 0: break; case EAGAIN: - lumiera_error_set (LUMIERA_ERROR_RWLOCK_AGAIN); + cinelerra_error_set (CINELERRA_ERROR_RWLOCK_AGAIN); return NULL; case EDEADLK: - lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); + cinelerra_error_set (CINELERRA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - LUMIERA_DIE; + CINELERRA_DIE; } - case LUMIERA_WRLOCKED: + case CINELERRA_WRLOCKED: switch (pthread_rwlock_wrlock (&rwlock->rwlock)) { case 0: break; case EDEADLK: - lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); + cinelerra_error_set (CINELERRA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - LUMIERA_DIE; + CINELERRA_DIE; } default: break; @@ -121,27 +121,27 @@ lumiera_rwlockacquirer_init (LumieraRWLockacquirer self, LumieraRWLock rwlock, e * @param self rwlockacquirer associated with a rwlock * @return self as given or NULL on error */ -LumieraRWLockacquirer -lumiera_rwlockacquirer_rdlock (LumieraRWLockacquirer self) +CinelerraRWLockacquirer +cinelerra_rwlockacquirer_rdlock (CinelerraRWLockacquirer self) { REQUIRE (self); - REQUIRE (self->state == LUMIERA_UNLOCKED, "rwlock already locked"); + REQUIRE (self->state == CINELERRA_UNLOCKED, "rwlock already locked"); switch (pthread_rwlock_rdlock (&self->rwlock->rwlock)) { case 0: break; case EAGAIN: - lumiera_error_set (LUMIERA_ERROR_RWLOCK_AGAIN); + cinelerra_error_set (CINELERRA_ERROR_RWLOCK_AGAIN); return NULL; case EDEADLK: - lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); + cinelerra_error_set (CINELERRA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - LUMIERA_DIE; + CINELERRA_DIE; } - self->state = LUMIERA_RDLOCKED; + self->state = CINELERRA_RDLOCKED; return self; } @@ -152,24 +152,24 @@ lumiera_rwlockacquirer_rdlock (LumieraRWLockacquirer self) * @param self rwlockacquirer associated with a rwlock * @return self as given or NULL on error */ -LumieraRWLockacquirer -lumiera_rwlockacquirer_wrlock (LumieraRWLockacquirer self) +CinelerraRWLockacquirer +cinelerra_rwlockacquirer_wrlock (CinelerraRWLockacquirer self) { REQUIRE (self); - REQUIRE (self->state == LUMIERA_UNLOCKED, "rwlock already locked"); + REQUIRE (self->state == CINELERRA_UNLOCKED, "rwlock already locked"); switch (pthread_rwlock_wrlock (&self->rwlock->rwlock)) { case 0: break; case EDEADLK: - lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); + cinelerra_error_set (CINELERRA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - LUMIERA_DIE; + CINELERRA_DIE; } - self->state = LUMIERA_WRLOCKED; + self->state = CINELERRA_WRLOCKED; return self; } diff --git a/src/lib/rwlock.h b/src/lib/rwlock.h index 922a05e7b..266887e24 100644 --- a/src/lib/rwlock.h +++ b/src/lib/rwlock.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef LUMIERA_RWLOCK_H -#define LUMIERA_RWLOCK_H +#ifndef CINELERRA_RWLOCK_H +#define CINELERRA_RWLOCK_H #ifndef _GNU_SOURCE #error "This header must be included with _GNU_SOURCE or _POSIX_C_SOURCE >= 200112L defined" @@ -31,8 +31,8 @@ #include "lib/locking.h" -LUMIERA_ERROR_DECLARE(RWLOCK_AGAIN); -LUMIERA_ERROR_DECLARE(RWLOCK_DEADLOCK); +CINELERRA_ERROR_DECLARE(RWLOCK_AGAIN); +CINELERRA_ERROR_DECLARE(RWLOCK_DEADLOCK); /** * @file Read/write locks, header. @@ -43,20 +43,20 @@ LUMIERA_ERROR_DECLARE(RWLOCK_DEADLOCK); * RWLock. * */ -struct lumiera_rwlock_struct +struct cinelerra_rwlock_struct { pthread_rwlock_t rwlock; }; -typedef struct lumiera_rwlock_struct lumiera_rwlock; -typedef lumiera_rwlock* LumieraRWLock; +typedef struct cinelerra_rwlock_struct cinelerra_rwlock; +typedef cinelerra_rwlock* CinelerraRWLock; -LumieraRWLock -lumiera_rwlock_init (LumieraRWLock self); +CinelerraRWLock +cinelerra_rwlock_init (CinelerraRWLock self); -LumieraRWLock -lumiera_rwlock_destroy (LumieraRWLock self); +CinelerraRWLock +cinelerra_rwlock_destroy (CinelerraRWLock self); @@ -64,35 +64,35 @@ lumiera_rwlock_destroy (LumieraRWLock self); /** * rwlockacquirer used to manage the state of a rwlock variable. */ -struct lumiera_rwlockacquirer_struct +struct cinelerra_rwlockacquirer_struct { - LumieraRWLock rwlock; - enum lumiera_lockstate state; + CinelerraRWLock rwlock; + enum cinelerra_lockstate state; }; -typedef struct lumiera_rwlockacquirer_struct lumiera_rwlockacquirer; -typedef struct lumiera_rwlockacquirer_struct* LumieraRWLockacquirer; +typedef struct cinelerra_rwlockacquirer_struct cinelerra_rwlockacquirer; +typedef struct cinelerra_rwlockacquirer_struct* CinelerraRWLockacquirer; /* helper function for nobug */ static inline void -lumiera_rwlockacquirer_ensureunlocked (LumieraRWLockacquirer self) +cinelerra_rwlockacquirer_ensureunlocked (CinelerraRWLockacquirer self) { - ENSURE (self->state == LUMIERA_UNLOCKED, "forgot to unlock the rwlock mutex"); + ENSURE (self->state == CINELERRA_UNLOCKED, "forgot to unlock the rwlock mutex"); } /* override with a macro to use the cleanup checker */ -#define lumiera_rwlockacquirer \ -lumiera_rwlockacquirer NOBUG_CLEANUP(lumiera_rwlockacquirer_ensureunlocked) +#define cinelerra_rwlockacquirer \ +cinelerra_rwlockacquirer NOBUG_CLEANUP(cinelerra_rwlockacquirer_ensureunlocked) -LumieraRWLockacquirer -lumiera_rwlockacquirer_init (LumieraRWLockacquirer self, LumieraRWLock rwlock, enum lumiera_lockstate state); +CinelerraRWLockacquirer +cinelerra_rwlockacquirer_init (CinelerraRWLockacquirer self, CinelerraRWLock rwlock, enum cinelerra_lockstate state); -LumieraRWLockacquirer -lumiera_rwlockacquirer_rdlock (LumieraRWLockacquirer self); +CinelerraRWLockacquirer +cinelerra_rwlockacquirer_rdlock (CinelerraRWLockacquirer self); -LumieraRWLockacquirer -lumiera_rwlockacquirer_wrlock (LumieraRWLockacquirer self); +CinelerraRWLockacquirer +cinelerra_rwlockacquirer_wrlock (CinelerraRWLockacquirer self); /** @@ -101,13 +101,13 @@ lumiera_rwlockacquirer_wrlock (LumieraRWLockacquirer self); * @param self rwlockacquirer associated with a rwlock variable */ static inline void -lumiera_rwlockacquirer_unlock (LumieraRWLockacquirer self) +cinelerra_rwlockacquirer_unlock (CinelerraRWLockacquirer self) { REQUIRE (self); - REQUIRE (self->state != LUMIERA_UNLOCKED, "rwlock was not locked"); + REQUIRE (self->state != CINELERRA_UNLOCKED, "rwlock was not locked"); if (pthread_rwlock_unlock (&self->rwlock->rwlock)) - LUMIERA_DIE; - self->state = LUMIERA_UNLOCKED; + CINELERRA_DIE; + self->state = CINELERRA_UNLOCKED; } diff --git a/src/lib/time.c b/src/lib/time.c index 83bfd9797..4566e44b5 100644 --- a/src/lib/time.c +++ b/src/lib/time.c @@ -21,6 +21,6 @@ #include "lib/error.h" -LUMIERA_ERROR_DEFINE(TIME_OVERFLOW, "Time overflow"); -LUMIERA_ERROR_DEFINE(TIME_UNDERFLOW, "Time underflow"); -LUMIERA_ERROR_DEFINE(TIME_NEGATIVE, "Time negative"); +CINELERRA_ERROR_DEFINE(TIME_OVERFLOW, "Time overflow"); +CINELERRA_ERROR_DEFINE(TIME_UNDERFLOW, "Time underflow"); +CINELERRA_ERROR_DEFINE(TIME_NEGATIVE, "Time negative"); diff --git a/src/lib/time.h b/src/lib/time.h index 26b698742..d4c05b71c 100644 --- a/src/lib/time.h +++ b/src/lib/time.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef LUMIERA_TIME_H -#define LUMIERA_TIME_H +#ifndef CINELERRA_TIME_H +#define CINELERRA_TIME_H #include #include @@ -35,31 +35,31 @@ timehandling is a delicate business, be careful of precision errors accumulating - lumiera_time is starting from zero, never becomes negative. + cinelerra_time is starting from zero, never becomes negative. TODO explain how to use time */ /* over or underflow (tried to make a movie which has negative length? or more than some hundreds days?) */ -LUMIERA_ERROR_DECLARE(TIME_OVERFLOW); -LUMIERA_ERROR_DECLARE(TIME_UNDERFLOW); -LUMIERA_ERROR_DECLARE(TIME_NEGATIVE); +CINELERRA_ERROR_DECLARE(TIME_OVERFLOW); +CINELERRA_ERROR_DECLARE(TIME_UNDERFLOW); +CINELERRA_ERROR_DECLARE(TIME_NEGATIVE); /* Note: we measure time starting from zero, time never becomes negative (I didnt checked if the time types are signed) */ -typedef struct timeval lumiera_time; -typedef lumiera_time* LumieraTime; +typedef struct timeval cinelerra_time; +typedef cinelerra_time* CinelerraTime; /** * normalize time after operations. * used internally */ static inline void -lumiera_time_normalize (LumieraTime time) +cinelerra_time_normalize (CinelerraTime time) { REQUIRE (time); if (time->tv_usec >= 1000000) @@ -75,8 +75,8 @@ lumiera_time_normalize (LumieraTime time) * @param time Time to clear * @return time as given */ -static inline LumieraTime -lumiera_time_clear (LumieraTime time) +static inline CinelerraTime +cinelerra_time_clear (CinelerraTime time) { if(time) { @@ -91,14 +91,14 @@ lumiera_time_clear (LumieraTime time) * @param time Time to put current time into. * @return time as given */ -static inline LumieraTime -lumiera_time_current (LumieraTime time) +static inline CinelerraTime +cinelerra_time_current (CinelerraTime time) { if (time) { /* gettime should never ever fail in a correct program */ if (gettimeofday (time, NULL)) - LUMIERA_DIE; + CINELERRA_DIE; } return time; } @@ -110,8 +110,8 @@ lumiera_time_current (LumieraTime time) * @return time as given upon success, NULL if double time given was negative or given time didn't point * anywhere */ -static inline LumieraTime -lumiera_time_set_double (LumieraTime time, double fp) +static inline CinelerraTime +cinelerra_time_set_double (CinelerraTime time, double fp) { if (time) { @@ -125,7 +125,7 @@ lumiera_time_set_double (LumieraTime time, double fp) { time->tv_sec = (time_t)-1; time->tv_usec = (suseconds_t)-1; - lumiera_error_set(LUMIERA_ERROR_TIME_NEGATIVE); + cinelerra_error_set(CINELERRA_ERROR_TIME_NEGATIVE); } } return NULL; @@ -138,14 +138,14 @@ lumiera_time_set_double (LumieraTime time, double fp) * @param usec Microseconds to set * @param Time as given */ -static inline LumieraTime -lumiera_time_init (LumieraTime time, time_t sec, suseconds_t usec) +static inline CinelerraTime +cinelerra_time_init (CinelerraTime time, time_t sec, suseconds_t usec) { if (time) { time->tv_sec = sec; time->tv_usec = usec; - lumiera_time_normalize (time); + cinelerra_time_normalize (time); } return time; } @@ -156,7 +156,7 @@ lumiera_time_init (LumieraTime time, time_t sec, suseconds_t usec) * @return Seconds elapsed, -1 on error */ static inline time_t -lumiera_time_sec (LumieraTime time) +cinelerra_time_sec (CinelerraTime time) { if (time) return time->tv_sec; @@ -170,7 +170,7 @@ lumiera_time_sec (LumieraTime time) * @return Microseconds elapsed, -1 on error */ static inline suseconds_t -lumiera_time_usec (LumieraTime time) +cinelerra_time_usec (CinelerraTime time) { if (time) return time->tv_usec; @@ -184,7 +184,7 @@ lumiera_time_usec (LumieraTime time) * @return Floating point representation of time. NAN on error. */ static inline double -lumiera_time_double_get (LumieraTime time) +cinelerra_time_double_get (CinelerraTime time) { if (time) { @@ -204,8 +204,8 @@ lumiera_time_double_get (LumieraTime time) * @param src Time-source to copy from * @return dest as given */ -static inline LumieraTime -lumiera_time_copy (LumieraTime dest, const LumieraTime src) +static inline CinelerraTime +cinelerra_time_copy (CinelerraTime dest, const CinelerraTime src) { if (dest && src) { @@ -221,8 +221,8 @@ lumiera_time_copy (LumieraTime dest, const LumieraTime src) * @param src Time to add to dest * @return dest as given, or NULL on overflow. */ -static inline LumieraTime -lumiera_time_add (LumieraTime dest, const LumieraTime src) +static inline CinelerraTime +cinelerra_time_add (CinelerraTime dest, const CinelerraTime src) { if (dest && src) { @@ -231,11 +231,11 @@ lumiera_time_add (LumieraTime dest, const LumieraTime src) dest->tv_sec += src->tv_sec; dest->tv_usec += src->tv_usec; - lumiera_time_normalize (dest); + cinelerra_time_normalize (dest); if (dest->tv_sec < t) { - lumiera_error_set (LUMIERA_ERROR_TIME_OVERFLOW); + cinelerra_error_set (CINELERRA_ERROR_TIME_OVERFLOW); return NULL; } } @@ -248,8 +248,8 @@ lumiera_time_add (LumieraTime dest, const LumieraTime src) * @param src Time to subtract from dest * @return dest as given, or NULL on underflow. */ -static inline LumieraTime -lumiera_time_sub (LumieraTime dest, const LumieraTime src) +static inline CinelerraTime +cinelerra_time_sub (CinelerraTime dest, const CinelerraTime src) { if (dest && src) { @@ -264,11 +264,11 @@ lumiera_time_sub (LumieraTime dest, const LumieraTime src) dest->tv_usec += 1000000 - src->tv_usec; } - lumiera_time_normalize (dest); + cinelerra_time_normalize (dest); if (dest->tv_sec > t) { - lumiera_error_set (LUMIERA_ERROR_TIME_UNDERFLOW); + cinelerra_error_set (CINELERRA_ERROR_TIME_UNDERFLOW); return NULL; } } diff --git a/src/main.cpp b/src/main.cpp index 398cdc3df..8d564ed87 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,11 +23,11 @@ #include -#include "lumiera.h" +#include "cinelerra.h" using std::cout; using std::endl; -using lumiera::Appconfig; +using cinelerra::Appconfig; int main (int argc, char* argv[]) diff --git a/src/nobugcfg.h b/src/nobugcfg.h index 916f28663..2cd719a87 100644 --- a/src/nobugcfg.h +++ b/src/nobugcfg.h @@ -27,7 +27,7 @@ ** The idea is that configuration and some globally used flag ** declarations are to be kept in one central location. Normally, ** this header will be included by appconfig.hpp, which in turn gets - ** included by lumiera.h + ** included by cinelerra.h ** @par Besides the usual guarded declarations, this header contains ** one section with the corresponding definitions. This section ** is to be called by appconfig.cpp only, which deals with application diff --git a/src/plugin/helloplugin.c b/src/plugin/helloplugin.c index d75f55f94..62a033f4e 100644 --- a/src/plugin/helloplugin.c +++ b/src/plugin/helloplugin.c @@ -1,12 +1,12 @@ /* * hello.c - demonstrates how to build a standalone tool (C source) - * integrated into the SCons based build system of Lumiera + * integrated into the SCons based build system of Cinelerra */ #include int main(int argc, char* argv[]) { - printf("hello lumiera world"); + printf("hello cinelerra world"); return 0; } diff --git a/src/pre.hpp b/src/pre.hpp index 19717c2bb..8c504c368 100644 --- a/src/pre.hpp +++ b/src/pre.hpp @@ -33,8 +33,8 @@ ** @see mobject.hpp usage example */ -#ifndef LUMIERA_PRE_HPP -#define LUMIERA_PRE_HPP +#ifndef CINELERRA_PRE_HPP +#define CINELERRA_PRE_HPP #include #include @@ -44,8 +44,8 @@ #include #include -#include "lumiera.h" +#include "cinelerra.h" -#endif /*LUMIERA_PRE_HPP*/ +#endif /*CINELERRA_PRE_HPP*/ diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp index 99fd50670..d97c2fd9e 100644 --- a/src/proc/asset.cpp +++ b/src/proc/asset.cpp @@ -111,7 +111,7 @@ namespace asset /**change the enablement status of this asset. */ bool - Asset::enable (bool on) throw(lumiera::error::State) + Asset::enable (bool on) throw(cinelerra::error::State) { if (on == this->enabled) return true; diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp index 0387e85ba..cec77bec4 100644 --- a/src/proc/asset.hpp +++ b/src/proc/asset.hpp @@ -155,7 +155,7 @@ namespace asset /** origin or authorship id. * Can be a project abbreviation, a package id or just the authors nickname or UID. * This allows for the compnent name to be more generic (e.g. "blur"). - * Default for all assets provided by the core Lumiera codebase is "lumi". + * Default for all assets provided by the core cinelerra-3 codebase is "cin3". */ const string org; @@ -284,7 +284,7 @@ namespace asset * @return \c false if the state could not be changed * due to parent objects being disabled */ - bool enable (bool on=true) throw(lumiera::error::State); + bool enable (bool on=true) throw(cinelerra::error::State); }; diff --git a/src/proc/asset/db.hpp b/src/proc/asset/db.hpp index af31df9a3..9f33b01af 100644 --- a/src/proc/asset/db.hpp +++ b/src/proc/asset/db.hpp @@ -87,7 +87,7 @@ namespace asset DB () : table() { } ~DB () {clear();} - friend class lumiera::singleton::StaticCreate; + friend class cinelerra::singleton::StaticCreate; public: @@ -125,7 +125,7 @@ namespace asset table.clear(); } - catch (lumiera::Error& EX) + catch (cinelerra::Error& EX) { WARN (oper, "Problems while clearing Asset registry: %s", EX.what()); } diff --git a/src/proc/asset/media.cpp b/src/proc/asset/media.cpp index 60a1ecd19..1610e822e 100644 --- a/src/proc/asset/media.cpp +++ b/src/proc/asset/media.cpp @@ -116,7 +116,7 @@ namespace asset } - lumiera::Time + cinelerra::Time Media::getLength() const { return len_; @@ -177,7 +177,7 @@ namespace asset MediaFactory::PType MediaFactory::operator() (const string& file, const Category& cat) { - Asset::Ident key(extractName(file), cat, "lumi", 1); + Asset::Ident key(extractName(file), cat, "cin3", 1); return operator() (key, file); } @@ -220,21 +220,21 @@ namespace asset * but rather part or a multichannel (compound) media */ shared_ptr - MediaFactory::operator() (asset::Media& mediaref) throw(lumiera::error::Invalid) + MediaFactory::operator() (asset::Media& mediaref) throw(cinelerra::error::Invalid) { if (mediaref.checkCompound()) - throw lumiera::error::Invalid (str(format("Attempt to create a asset::Clip from the media %s, " - "which is not toplevel but rather part or a compound " - "(multichannel) media. Found parent Media %s.") - % string(mediaref) - % string(*mediaref.checkCompound())) - ,LUMIERA_ERROR_PART_OF_COMPOUND - ); + throw cinelerra::error::Invalid (str(format("Attempt to create a asset::Clip from the media %s, " + "which is not toplevel but rather part or a compound " + "(multichannel) media. Found parent Media %s.") + % string(mediaref) + % string(*mediaref.checkCompound())) + ,CINELERRA_ERROR_PART_OF_COMPOUND + ); asset::Clip* pC = new asset::Clip (mediaref); return AssetManager::instance().getPtr (*pC); } - LUMIERA_ERROR_DEFINE (PART_OF_COMPOUND, "part of compound used as toplevel element"); + CINELERRA_ERROR_DEFINE (PART_OF_COMPOUND, "part of compound used as toplevel element"); diff --git a/src/proc/asset/media.hpp b/src/proc/asset/media.hpp index ce43d6231..67c6a31ca 100644 --- a/src/proc/asset/media.hpp +++ b/src/proc/asset/media.hpp @@ -50,7 +50,7 @@ namespace asset class MediaFactory; class ProcPatt; - using lumiera::Time; + using cinelerra::Time; template<> @@ -137,7 +137,7 @@ namespace asset /** * Factory specialized for creating Media Asset objects. */ - class MediaFactory : public lumiera::Factory + class MediaFactory : public cinelerra::Factory { public: typedef shared_ptr PType; @@ -151,11 +151,11 @@ namespace asset PType operator() (const char* file, asset::Kind); shared_ptr - operator() (asset::Media& mediaref) throw(lumiera::error::Invalid); + operator() (asset::Media& mediaref) throw(cinelerra::error::Invalid); }; - LUMIERA_ERROR_DECLARE (PART_OF_COMPOUND); + CINELERRA_ERROR_DECLARE (PART_OF_COMPOUND); diff --git a/src/proc/asset/meta.hpp b/src/proc/asset/meta.hpp index 89500c226..e995f53a3 100644 --- a/src/proc/asset/meta.hpp +++ b/src/proc/asset/meta.hpp @@ -90,7 +90,7 @@ namespace asset /** * Factory specialized for createing Metadata Asset objects. */ - class MetaFactory : public lumiera::Factory + class MetaFactory : public cinelerra::Factory { public: typedef shared_ptr PType; diff --git a/src/proc/asset/proc.hpp b/src/proc/asset/proc.hpp index b98fa8014..229f66fcd 100644 --- a/src/proc/asset/proc.hpp +++ b/src/proc/asset/proc.hpp @@ -89,7 +89,7 @@ namespace asset /** * Factory specialized for createing Processor Asset objects. */ - class ProcFactory : public lumiera::Factory + class ProcFactory : public cinelerra::Factory { public: typedef shared_ptr PType; diff --git a/src/proc/asset/struct.hpp b/src/proc/asset/struct.hpp index 96dd63001..24cc5c053 100644 --- a/src/proc/asset/struct.hpp +++ b/src/proc/asset/struct.hpp @@ -91,7 +91,7 @@ namespace asset /** * Factory specialized for createing Structural Asset objects. */ - class StructFactory : public lumiera::Factory + class StructFactory : public cinelerra::Factory { public: typedef shared_ptr PType; diff --git a/src/proc/asset/unknown.cpp b/src/proc/asset/unknown.cpp index b47a60113..25d91936c 100644 --- a/src/proc/asset/unknown.cpp +++ b/src/proc/asset/unknown.cpp @@ -48,19 +48,19 @@ namespace asset * try to access the "real" media it stands for. */ Media::PMedia - Unknown::getOrg() throw(lumiera::error::Invalid) + Unknown::getOrg() throw(cinelerra::error::Invalid) { UNIMPLEMENTED ("how to get at the original media from a »Unknown« placeholder"); if (1==0) - throw lumiera::error::Invalid (str(format("Unable to locate original media " - "for ID=%s, filename=\"%s\".") - % string(this->ident) - % string(this->getFilename())) - ,LUMIERA_ERROR_ORIG_NOT_FOUND - ); + throw cinelerra::error::Invalid (str(format("Unable to locate original media " + "for ID=%s, filename=\"%s\".") + % string(this->ident) + % string(this->getFilename())) + ,CINELERRA_ERROR_ORIG_NOT_FOUND + ); } - LUMIERA_ERROR_DEFINE (ORIG_NOT_FOUND, "Media refered by placeholder not found"); + CINELERRA_ERROR_DEFINE (ORIG_NOT_FOUND, "Media refered by placeholder not found"); diff --git a/src/proc/asset/unknown.hpp b/src/proc/asset/unknown.hpp index bcd0bda9f..aa9cd6ec3 100644 --- a/src/proc/asset/unknown.hpp +++ b/src/proc/asset/unknown.hpp @@ -32,7 +32,7 @@ namespace asset { - const lumiera::Time DUMMY_TIME (25); ///< @todo solve konfig management + const cinelerra::Time DUMMY_TIME (25); ///< @todo solve konfig management /** * Placeholder Asset for unknown or unavailable media source. @@ -47,11 +47,11 @@ namespace asset friend class MediaFactory; public: - virtual Media::PMedia getOrg() throw(lumiera::error::Invalid); + virtual Media::PMedia getOrg() throw(cinelerra::error::Invalid); }; - LUMIERA_ERROR_DECLARE (ORIG_NOT_FOUND); + CINELERRA_ERROR_DECLARE (ORIG_NOT_FOUND); diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp index 68843444a..bc6f42ecd 100644 --- a/src/proc/assetmanager.cpp +++ b/src/proc/assetmanager.cpp @@ -38,8 +38,8 @@ using boost::format; using boost::bind; using util::for_each; -using lumiera::Singleton; -using lumiera::Thread; +using cinelerra::Singleton; +using cinelerra::Thread; namespace asset @@ -49,23 +49,23 @@ namespace asset * AssetManager error responses, caused by querying * invalid Asset IDs from the internal DB. */ - class IDErr : public lumiera::error::Invalid + class IDErr : public cinelerra::error::Invalid { public: IDErr (const char* eID, format fmt) - : lumiera::error::Invalid(fmt.str(),eID) {} + : cinelerra::error::Invalid(fmt.str(),eID) {} }; // ------pre-defined-common-error-cases--------------- // - LUMIERA_ERROR_DEFINE (UNKNOWN_ASSET_ID, "non-registered Asset ID"); - LUMIERA_ERROR_DEFINE (WRONG_ASSET_KIND, "wrong Asset kind, unable to cast"); + CINELERRA_ERROR_DEFINE (UNKNOWN_ASSET_ID, "non-registered Asset ID"); + CINELERRA_ERROR_DEFINE (WRONG_ASSET_KIND, "wrong Asset kind, unable to cast"); class UnknownID : public IDErr { public: - UnknownID (ID aID) : IDErr (LUMIERA_ERROR_UNKNOWN_ASSET_ID, + UnknownID (ID aID) : IDErr (CINELERRA_ERROR_UNKNOWN_ASSET_ID, format("Query for Asset with ID=%d, which up to now " "hasn't been created or encountered.") % aID) {} }; @@ -73,7 +73,7 @@ namespace asset class WrongKind : public IDErr { public: - WrongKind (Asset::Ident idi) : IDErr (LUMIERA_ERROR_WRONG_ASSET_KIND, + WrongKind (Asset::Ident idi) : IDErr (CINELERRA_ERROR_WRONG_ASSET_KIND, format("Request for Asset(%s), specifying an Asset kind, " "that doesn't match the actual type (and can't be " "casted either).") % string(idi)) {} @@ -110,7 +110,7 @@ namespace asset template ID AssetManager::reg (KIND* obj, const Asset::Ident& idi) - throw(lumiera::error::Invalid) + throw(cinelerra::error::Invalid) { typedef shared_ptr PType; AssetManager& _aMang (AssetManager::instance()); @@ -133,7 +133,7 @@ namespace asset template shared_ptr AssetManager::getAsset (const ID& id) - throw(lumiera::error::Invalid) + throw(cinelerra::error::Invalid) { if (shared_ptr obj = registry.get (id)) return obj; @@ -243,11 +243,11 @@ namespace asset template ID AssetManager::reg (Asset* obj, const Asset::Ident& idi); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template shared_ptr AssetManager::getAsset (const ID& id) throw(cinelerra::error::Invalid); + template shared_ptr AssetManager::getAsset (const ID& id) throw(cinelerra::error::Invalid); + template shared_ptr AssetManager::getAsset (const ID& id) throw(cinelerra::error::Invalid); + template shared_ptr AssetManager::getAsset (const ID& id) throw(cinelerra::error::Invalid); + template shared_ptr AssetManager::getAsset (const ID& id) throw(cinelerra::error::Invalid); template shared_ptr AssetManager::getPtr (const Asset& asset); template shared_ptr AssetManager::getPtr (const Media& asset); diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp index b2362db00..d1b20e025 100644 --- a/src/proc/assetmanager.hpp +++ b/src/proc/assetmanager.hpp @@ -66,7 +66,7 @@ namespace asset public: - static lumiera::Singleton instance; + static cinelerra::Singleton instance; /** provide the unique ID for given Asset::Ident tuple */ static ID getID (const Asset::Ident&); @@ -77,7 +77,7 @@ namespace asset /** find and return corresponging object */ template - shared_ptr getAsset (const ID& id) throw(lumiera::error::Invalid); + shared_ptr getAsset (const ID& id) throw(cinelerra::error::Invalid); /** @return true if the given id is registered in the internal asset DB */ @@ -101,7 +101,7 @@ namespace asset */ template static ID reg (KIND* obj, const Asset::Ident& idi) - throw(lumiera::error::Invalid); + throw(cinelerra::error::Invalid); /** deleter function used by the Asset smart pointers to delete Asset objects */ static void destroy (Asset* aa) { delete aa; } @@ -110,13 +110,13 @@ namespace asset AssetManager (); - friend class lumiera::singleton::StaticCreate; + friend class cinelerra::singleton::StaticCreate; }; - LUMIERA_ERROR_DECLARE (UNKNOWN_ASSET_ID); ///< use of a non-registered Asset ID. - LUMIERA_ERROR_DECLARE (WRONG_ASSET_KIND); ///< Asset ID of wrong Asset kind, unable to cast. + CINELERRA_ERROR_DECLARE (UNKNOWN_ASSET_ID); ///< use of a non-registered Asset ID. + CINELERRA_ERROR_DECLARE (WRONG_ASSET_KIND); ///< Asset ID of wrong Asset kind, unable to cast. } // namespace asset diff --git a/src/proc/engine/codecadapter.hpp b/src/proc/engine/codecadapter.hpp index 724763eaa..5b4991177 100644 --- a/src/proc/engine/codecadapter.hpp +++ b/src/proc/engine/codecadapter.hpp @@ -38,7 +38,7 @@ namespace engine * process thus is integrated into the framework * of the Renderengine, while the actual implementation * can be delegated to an external library accessed - * through Lumiera's data backend. + * through Cinelerra's datat backend. */ class CodecAdapter : public Trafo {}; diff --git a/src/proc/engine/pluginadapter.hpp b/src/proc/engine/pluginadapter.hpp index b771f1fbc..b080b99ed 100644 --- a/src/proc/engine/pluginadapter.hpp +++ b/src/proc/engine/pluginadapter.hpp @@ -35,7 +35,7 @@ namespace engine /** * Adapter used to integrate an effects processor in the render pipeline. * Effects processors are typically defined in a separate library and - * will be loaded at runtime using Lumiera's plugin interface. + * will be loaded at runtime using Cinelerra's plugin interface. */ class PluginAdapter : public Trafo { diff --git a/src/proc/engine/processor.hpp b/src/proc/engine/processor.hpp index 6b7317886..70ec33f6c 100644 --- a/src/proc/engine/processor.hpp +++ b/src/proc/engine/processor.hpp @@ -24,7 +24,7 @@ #ifndef ENGINE_PROCESSOR_H #define ENGINE_PROCESSOR_H -#include "lumiera.h" +#include "cinelerra.h" #include "proc/stateproxy.hpp" @@ -40,10 +40,10 @@ namespace engine ExitNode * output; /** begin of the timerange covered by this processor */ - lumiera::Time start; + cinelerra::Time start; /**end (exclusive) of the timerange */ - lumiera::Time end; + cinelerra::Time end; }; diff --git a/src/proc/mobject/builder/buildertool.hpp b/src/proc/mobject/builder/buildertool.hpp index 0985567d1..c4700bc0a 100644 --- a/src/proc/mobject/builder/buildertool.hpp +++ b/src/proc/mobject/builder/buildertool.hpp @@ -59,7 +59,7 @@ namespace mobject * an instantiation of the "Applicable" template parametrized with all * concrete Buildable classes, for which it wants calls to be dispatched. */ - typedef lumiera::visitor::Tool BuilderTool; + typedef cinelerra::visitor::Tool BuilderTool; template @@ -67,11 +67,11 @@ namespace mobject class TYPELIST // list of all concrete Buildables to be treated > class Applicable - : public lumiera::visitor::Applicable + : public cinelerra::visitor::Applicable { } ; - using lumiera::typelist::Types; // convienience for the users of "Applicable" + using cinelerra::typelist::Types; // convienience for the users of "Applicable" } // namespace mobject::builder @@ -80,7 +80,7 @@ namespace mobject /** * Marker Interface for classes Visitable by Builder tools. */ - class Buildable : public lumiera::visitor::Visitable + class Buildable : public cinelerra::visitor::Visitable { }; } // namespace mobject diff --git a/src/proc/mobject/mobject.hpp b/src/proc/mobject/mobject.hpp index 3d0222a3d..b7c139f93 100644 --- a/src/proc/mobject/mobject.hpp +++ b/src/proc/mobject/mobject.hpp @@ -29,7 +29,7 @@ #include #include -#include "lumiera.h" +#include "cinelerra.h" #include "proc/mobject/builder/buildertool.hpp" #include "proc/mobject/placement.hpp" #include "proc/asset.hpp" // TODO finally not needed? @@ -55,13 +55,13 @@ namespace mobject /** * MObject is the interface class for all "Media Objects". * All the contents and elements that can be placed and - * manipulated and finally rendered within Lumiera's EDL + * manipulated and finally rendered within Cinelerra's EDL * are MObjects. */ class MObject : public Buildable { protected: - typedef lumiera::Time Time; + typedef cinelerra::Time Time; // TODO: how to represent time intervals best? Time length; diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index 3e941b7d5..71c654308 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -86,7 +86,7 @@ namespace mobject class Placement : protected shared_ptr { protected: - typedef lumiera::Time Time; + typedef cinelerra::Time Time; typedef session::Track* Track; diff --git a/src/proc/mobject/session.hpp b/src/proc/mobject/session.hpp index 1dafb2e87..48473d298 100644 --- a/src/proc/mobject/session.hpp +++ b/src/proc/mobject/session.hpp @@ -57,7 +57,7 @@ namespace mobject /** * The (current) Session holds all the user * visible content to be edited and manipulated - * within the Lumiera Application. From a users + * within the Cinelerra Application. From a users * perspective, it is a collection of Media Objects * (--> MObject) placed (--> Placement) onto virtual * Tracks. diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp index c42d5bc3d..dfc7f8696 100644 --- a/src/proc/mobject/session/locatingpin.hpp +++ b/src/proc/mobject/session/locatingpin.hpp @@ -42,7 +42,7 @@ #define MOBJECT_SESSION_LOCATINGPIN_H -#include "lumiera.h" +#include "cinelerra.h" #include #include @@ -79,7 +79,7 @@ namespace mobject class LocatingPin { protected: - typedef lumiera::Time Time; + typedef cinelerra::Time Time; typedef session::Track* Track; typedef std::pair SolutionData; //TODO (ichthyo consideres better passing of solution by subclass) struct LocatingSolution; diff --git a/src/proc/mobject/session/segment.hpp b/src/proc/mobject/session/segment.hpp index 0b8a6025b..46b5929d4 100644 --- a/src/proc/mobject/session/segment.hpp +++ b/src/proc/mobject/session/segment.hpp @@ -26,7 +26,7 @@ #include -#include "lumiera.h" +#include "cinelerra.h" #include "proc/mobject/explicitplacement.hpp" @@ -49,7 +49,7 @@ namespace mobject class Segment { protected: - typedef lumiera::Time Time; + typedef cinelerra::Time Time; /** begin of this timeline segment. */ Time start; diff --git a/src/proc/mobject/session/session.cpp b/src/proc/mobject/session/session.cpp index ea6a559d9..2e81d752e 100644 --- a/src/proc/mobject/session/session.cpp +++ b/src/proc/mobject/session/session.cpp @@ -37,7 +37,7 @@ #include "common/singleton.hpp" -using lumiera::Singleton; +using cinelerra::Singleton; using mobject::session::SessManager; using mobject::session::SessManagerImpl; diff --git a/src/proc/mobject/session/sessionimpl.cpp b/src/proc/mobject/session/sessionimpl.cpp index 15e940843..e0cab87cc 100644 --- a/src/proc/mobject/session/sessionimpl.cpp +++ b/src/proc/mobject/session/sessionimpl.cpp @@ -60,7 +60,7 @@ namespace mobject catch (...) { focusEDL_ = 0; - throw lumiera::error::Fatal ("unexpected exception while clearing EDLs"); + throw cinelerra::error::Fatal ("unexpected exception while clearing EDLs"); } } diff --git a/src/proc/mobject/session/sessionimpl.hpp b/src/proc/mobject/session/sessionimpl.hpp index 2c396f95c..d145c4fe5 100644 --- a/src/proc/mobject/session/sessionimpl.hpp +++ b/src/proc/mobject/session/sessionimpl.hpp @@ -90,7 +90,7 @@ namespace mobject boost::scoped_ptr pImpl_; SessManagerImpl() throw(); - friend class lumiera::singleton::StaticCreate; + friend class cinelerra::singleton::StaticCreate; public: virtual void clear () ; diff --git a/src/tool/hello.c b/src/tool/hello.c index d75f55f94..62a033f4e 100644 --- a/src/tool/hello.c +++ b/src/tool/hello.c @@ -1,12 +1,12 @@ /* * hello.c - demonstrates how to build a standalone tool (C source) - * integrated into the SCons based build system of Lumiera + * integrated into the SCons based build system of Cinelerra */ #include int main(int argc, char* argv[]) { - printf("hello lumiera world"); + printf("hello cinelerra world"); return 0; } diff --git a/tests/10errorhandling.tests b/tests/10errorhandling.tests index f2e4e9dfc..2492869c5 100644 --- a/tests/10errorhandling.tests +++ b/tests/10errorhandling.tests @@ -15,12 +15,12 @@ return: 0 END TEST "query error" get < #include -using lumiera::error::Invalid; +using cinelerra::error::Invalid; using util::for_each; using util::isnil; using std::cout; diff --git a/tests/components/backend/mediaaccessmock.hpp b/tests/components/backend/mediaaccessmock.hpp index 06eedad5c..e11d0a67a 100644 --- a/tests/components/backend/mediaaccessmock.hpp +++ b/tests/components/backend/mediaaccessmock.hpp @@ -41,7 +41,7 @@ namespace backend_interface class MediaAccessMock : public MediaAccessFacade { public: - FileHandle queryFile (const char* name) throw(lumiera::error::Invalid); + FileHandle queryFile (const char* name) throw(cinelerra::error::Invalid); ChanDesc queryChannel (FileHandle, uint chanNo) throw(); }; diff --git a/tests/components/common/appconfigtest.cpp b/tests/components/common/appconfigtest.cpp index 6cab57de8..d65e29402 100644 --- a/tests/components/common/appconfigtest.cpp +++ b/tests/components/common/appconfigtest.cpp @@ -33,7 +33,7 @@ using std::cout; -namespace lumiera +namespace cinelerra { namespace test { @@ -46,10 +46,10 @@ namespace lumiera testAccess("version"); } - /** @test accessing a value from lumiera::Appconfig */ + /** @test accessing a value from cinelerra::Appconfig */ void testAccess (const string& key) { - string ver = lumiera::Appconfig::get(key); + string ver = cinelerra::Appconfig::get(key); ASSERT ( !util::isnil(ver)); } }; diff --git a/tests/components/common/exceptionerrortest.cpp b/tests/components/common/exceptionerrortest.cpp index 75a13d0ee..987c77d19 100644 --- a/tests/components/common/exceptionerrortest.cpp +++ b/tests/components/common/exceptionerrortest.cpp @@ -42,7 +42,7 @@ using std::cout; -namespace lumiera +namespace cinelerra { namespace test { @@ -50,11 +50,11 @@ namespace lumiera /** local specific error-constant for use in the * construcor of the nested SpecificError class. */ - LUMIERA_ERROR_DEFINE(LIFE_AND_UNIVERSE, "and everything?"); - LUMIERA_ERROR_DEFINE(DERIVED, "convoluted exception"); + CINELERRA_ERROR_DEFINE(LIFE_AND_UNIVERSE, "and everything?"); + CINELERRA_ERROR_DEFINE(DERIVED, "convoluted exception"); /** declare a specific Error class with parent class error::external */ - LUMIERA_EXCEPTION_DECLARE (DerivedError, error::External, LUMIERA_ERROR_DERIVED); + CINELERRA_EXCEPTION_DECLARE (DerivedError, error::External, CINELERRA_ERROR_DERIVED); /********************************************************** @@ -134,29 +134,29 @@ namespace lumiera } - /** @test by constructing an lumiera::Error object, - * the corresponding lumiera_error state is set automatically + /** @test by constructing an cinelerra::Error object, + * the corresponding cinelerra_error state is set automatically */ void checkErrorIntegration() { - lumiera_error (); - ASSERT (!lumiera_error ()); + cinelerra_error (); + ASSERT (!cinelerra_error ()); Error err1; - Error err2("boo",LUMIERA_ERROR_DERIVED); - ASSERT (err1.getID () == lumiera_error ()); // (we didn't clear the first one!) + Error err2("boo",CINELERRA_ERROR_DERIVED); + ASSERT (err1.getID () == cinelerra_error ()); // (we didn't clear the first one!) - Error err3("boooo",LUMIERA_ERROR_DERIVED); - ASSERT (err3.getID () == lumiera_error ()); + Error err3("boooo",CINELERRA_ERROR_DERIVED); + ASSERT (err3.getID () == cinelerra_error ()); SpecificError err4; - ASSERT (err4.getID () == LUMIERA_ERROR_LIFE_AND_UNIVERSE); - ASSERT (err4.getID () == lumiera_error ()); + ASSERT (err4.getID () == CINELERRA_ERROR_LIFE_AND_UNIVERSE); + ASSERT (err4.getID () == cinelerra_error ()); - ASSERT (!lumiera_error ()); + ASSERT (!cinelerra_error ()); } - /** @test the chaining of lumiera::Exception objects + /** @test the chaining of cinelerra::Exception objects * and the retrieval of the original root cause. */ void checkRootCauseChaining() @@ -186,7 +186,7 @@ namespace lumiera * gets installed and invoked, which gives additional diagnostics.*/ void terminateUnknown () throw() { - lumiera::Appconfig::instance(); + cinelerra::Appconfig::instance(); // will cause initialisation of Appconfig, throw Error("You'll never get me, won't you?"); @@ -201,7 +201,7 @@ namespace lumiera { int value; public: - SpecificError () : Invalid("don't panic",LUMIERA_ERROR_LIFE_AND_UNIVERSE), value(42) {} + SpecificError () : Invalid("don't panic",CINELERRA_ERROR_LIFE_AND_UNIVERSE), value(42) {} int revealIt () { return value; } }; @@ -220,7 +220,7 @@ namespace lumiera catch (SpecificError& e) { cout << "caught: " << e.what() << "..the answer is: " << e.revealIt() << "\n"; } catch (error::Logic& e) { cout << "caught error::Logic: " << e.what() << "\n"; } catch (error::Invalid&e) { cout << "caught error::Invalid: " << e.what() << "\n"; } - catch (Error& e) { cout << "caught lumiera::Error: " << e.what() << "\n"; } + catch (Error& e) { cout << "caught cinelerra::Error: " << e.what() << "\n"; } catch (runtime_error& e) { cout << "caught std::runtime_error: " << e.what() << "\n"; } catch (exception& e) { cout << "caught std::exception: " << e.what() << "\n"; } catch (...) { cout << "caught an unknown exception\n"; } diff --git a/tests/components/common/factoryspecialtest.cpp b/tests/components/common/factoryspecialtest.cpp index ecf293cd9..de9eeee8b 100644 --- a/tests/components/common/factoryspecialtest.cpp +++ b/tests/components/common/factoryspecialtest.cpp @@ -38,7 +38,7 @@ using std::string; using std::cout; -namespace lumiera +namespace cinelerra { namespace test { @@ -323,4 +323,4 @@ namespace lumiera } // namespace test -} // namespace lumiera +} // namespace cinelerra diff --git a/tests/components/common/factorytest.cpp b/tests/components/common/factorytest.cpp index 6c96a337c..875266fce 100644 --- a/tests/components/common/factorytest.cpp +++ b/tests/components/common/factorytest.cpp @@ -36,7 +36,7 @@ using std::string; using std::cout; -namespace lumiera +namespace cinelerra { namespace test { @@ -100,7 +100,7 @@ namespace lumiera * further shared-ptrs, invoke a member function and * finally, when leaving the scope, our TargetObj * will be destroyed automatically. - * @see lumiera::Factory + * @see cinelerra::Factory */ class Factory_test : public Test { @@ -125,4 +125,4 @@ namespace lumiera } // namespace test -} // namespace lumiera +} // namespace cinelerra diff --git a/tests/components/common/singletontest.cpp b/tests/components/common/singletontest.cpp index b531d7e9c..558d7e674 100644 --- a/tests/components/common/singletontest.cpp +++ b/tests/components/common/singletontest.cpp @@ -38,7 +38,7 @@ using std::string; using std::cout; -namespace lumiera +namespace cinelerra { namespace test { @@ -72,9 +72,9 @@ namespace lumiera /******************************************************************* * @test implement a Singleton class using our Singleton Template. * Expected results: no memory leaks. - * @see lumiera::Singleton - * @see lumiera::singleton::StaticCreate - * @see lumiera::singleton::HeapCreate + * @see cinelerra::Singleton + * @see cinelerra::singleton::StaticCreate + * @see cinelerra::singleton::HeapCreate */ class Singleton_test : public Test { @@ -136,4 +136,4 @@ namespace lumiera } // namespace test -} // namespace lumiera +} // namespace cinelerra diff --git a/tests/components/common/singletontestmocktest.cpp b/tests/components/common/singletontestmocktest.cpp index ea5e1d70e..b90b1a73c 100644 --- a/tests/components/common/singletontestmocktest.cpp +++ b/tests/components/common/singletontestmocktest.cpp @@ -37,7 +37,7 @@ using std::string; using std::cout; -namespace lumiera +namespace cinelerra { namespace test { @@ -108,8 +108,8 @@ namespace lumiera * @test inject a Mock object into the Singleton Factory, * to be returned and used in place of the original object. * Expected results: Mock(s) called, no memory leaks. - * @see lumiera::Singleton - * @see lumiera::singleton::Static + * @see cinelerra::Singleton + * @see cinelerra::singleton::Static */ class SingletonTestMock_test : public Test { @@ -214,4 +214,4 @@ namespace lumiera } // namespace test -} // namespace lumiera +} // namespace cinelerra diff --git a/tests/components/common/testtargetobj.hpp b/tests/components/common/testtargetobj.hpp index 28ac5890d..8a0728b95 100644 --- a/tests/components/common/testtargetobj.hpp +++ b/tests/components/common/testtargetobj.hpp @@ -21,8 +21,8 @@ */ -#ifndef LUMIERA_TEST_TESTTARGETOBJ_H -#define LUMIERA_TEST_TESTTARGETOBJ_H +#ifndef CINELERRA_TEST_TESTTARGETOBJ_H +#define CINELERRA_TEST_TESTTARGETOBJ_H #include "common/test/run.hpp" @@ -41,7 +41,7 @@ using std::string; using std::cout; -namespace lumiera +namespace cinelerra { namespace test { @@ -107,5 +107,5 @@ namespace lumiera } // namespace test -} // namespace lumiera +} // namespace cinelerra #endif diff --git a/tests/components/common/typelisttest.cpp b/tests/components/common/typelisttest.cpp index 42159d96c..1a2e383e8 100644 --- a/tests/components/common/typelisttest.cpp +++ b/tests/components/common/typelisttest.cpp @@ -30,7 +30,7 @@ using std::string; using std::cout; -namespace lumiera +namespace cinelerra { namespace typelist { @@ -97,4 +97,4 @@ namespace lumiera } // namespace typelist -} // namespace lumiera +} // namespace cinelerra diff --git a/tests/components/common/visitingtoolconcept.cpp b/tests/components/common/visitingtoolconcept.cpp index f2189ed09..16578b6be 100644 --- a/tests/components/common/visitingtoolconcept.cpp +++ b/tests/components/common/visitingtoolconcept.cpp @@ -24,7 +24,7 @@ /** @file visitingtoolconept.cpp ** While laying the foundations for EDL and Builder, Ichthyo came accross ** the necessity to create a custom implementation of the Visitor Pattern - ** optimally suited for Lumiera's needs. This implementation file was + ** optimally suited for Cinelerra's needs. This implementation file was ** used for the draft and is self-contained. The final solution was then ** extracted as library implementation to visitor.hpp ** @@ -60,13 +60,13 @@ #include #include -using lumiera::Singleton; +using cinelerra::Singleton; using boost::format; using std::string; using std::cout; -namespace lumiera +namespace cinelerra { namespace visitor_concept_draft { @@ -459,4 +459,4 @@ namespace lumiera } // namespace visitor_concept_draft -} // namespace lumiera +} // namespace cinelerra diff --git a/tests/components/common/visitingtoolextendedtest.cpp b/tests/components/common/visitingtoolextendedtest.cpp index d29c60b26..a25ebd95a 100644 --- a/tests/components/common/visitingtoolextendedtest.cpp +++ b/tests/components/common/visitingtoolextendedtest.cpp @@ -32,7 +32,7 @@ using std::string; using std::cout; -namespace lumiera +namespace cinelerra { namespace visitor { @@ -226,4 +226,4 @@ namespace lumiera } // namespace visitor -} // namespace lumiera +} // namespace cinelerra diff --git a/tests/components/common/visitingtooltest.cpp b/tests/components/common/visitingtooltest.cpp index 0263d9c88..10edf233d 100644 --- a/tests/components/common/visitingtooltest.cpp +++ b/tests/components/common/visitingtooltest.cpp @@ -32,7 +32,7 @@ using std::string; using std::cout; -namespace lumiera +namespace cinelerra { namespace visitor { @@ -159,4 +159,4 @@ namespace lumiera } // namespace visitor -} // namespace lumiera +} // namespace cinelerra diff --git a/tests/components/helloworldtest.cpp b/tests/components/helloworldtest.cpp index d0c289986..8398f19ad 100644 --- a/tests/components/helloworldtest.cpp +++ b/tests/components/helloworldtest.cpp @@ -31,7 +31,7 @@ using util::isnil; using boost::lexical_cast; -namespace lumiera +namespace cinelerra { namespace test { @@ -65,4 +65,4 @@ namespace lumiera } // namespace test -} // namespace lumiera +} // namespace cinelerra diff --git a/tests/components/mainsuite.cpp b/tests/components/mainsuite.cpp index aa500cdbe..924a982e3 100644 --- a/tests/components/mainsuite.cpp +++ b/tests/components/mainsuite.cpp @@ -1,5 +1,5 @@ /* - mainsuite.cpp - "the" Lumiera self test suite + mainsuite.cpp - "the" cinelerra3 self test suite Copyright (C) Lumiera.org 2008, Christian Thaeter diff --git a/tests/components/proc/asset/createassettest.cpp b/tests/components/proc/asset/createassettest.cpp index d9302fc7c..fa28d4472 100644 --- a/tests/components/proc/asset/createassettest.cpp +++ b/tests/components/proc/asset/createassettest.cpp @@ -100,14 +100,14 @@ namespace asset aMang.getAsset (ID(mm1->getID())); NOTREACHED; } - catch (lumiera::error::Invalid& xxx) {ASSERT (xxx.getID()==LUMIERA_ERROR_WRONG_ASSET_KIND);} + catch (cinelerra::error::Invalid& xxx) {ASSERT (xxx.getID()==CINELERRA_ERROR_WRONG_ASSET_KIND);} try { // try accessing nonexistant ID aMang.getAsset (ID (1234567890)); NOTREACHED; } - catch (lumiera::error::Invalid& xxx) {ASSERT (xxx.getID()==LUMIERA_ERROR_UNKNOWN_ASSET_ID);} - lumiera_error (); // reset errorflag + catch (cinelerra::error::Invalid& xxx) {ASSERT (xxx.getID()==CINELERRA_ERROR_UNKNOWN_ASSET_ID);} + cinelerra_error (); // reset errorflag // checking the Ident-Fields @@ -121,8 +121,8 @@ namespace asset ASSERT (mm3->ident.category == Category (VIDEO )); ASSERT (mm1->ident.org == "ichthyo"); - ASSERT (mm2->ident.org == "lumi"); - ASSERT (mm3->ident.org == "lumi"); + ASSERT (mm2->ident.org == "cin3"); + ASSERT (mm3->ident.org == "cin3"); ASSERT (mm1->ident.version == 5); ASSERT (mm2->ident.version == 1); @@ -159,19 +159,19 @@ namespace asset ASSERT (key2.name == "testfile2"); // name filled in automatically candi = asset::Media::create(string("testfile3.wav"), Category(AUDIO)); - ASSERT ( checkProperties (candi, Asset::Ident("testfile3", Category(AUDIO), "lumi", 1) + ASSERT ( checkProperties (candi, Asset::Ident("testfile3", Category(AUDIO), "cin3", 1) , "testfile3.wav")); candi = asset::Media::create("some/path/testfile4.wav", Category(AUDIO)); - ASSERT ( checkProperties (candi, Asset::Ident("testfile4", Category(AUDIO), "lumi", 1) + ASSERT ( checkProperties (candi, Asset::Ident("testfile4", Category(AUDIO), "cin3", 1) , "some/path/testfile4.wav")); candi = asset::Media::create("", Category(AUDIO,"sub/bin")); - ASSERT ( checkProperties (candi, Asset::Ident("nil", Category(AUDIO,"sub/bin"), "lumi", 1) + ASSERT ( checkProperties (candi, Asset::Ident("nil", Category(AUDIO,"sub/bin"), "cin3", 1) , "")); candi = asset::Media::create("", AUDIO); - ASSERT ( checkProperties (candi, Asset::Ident("nil", Category(AUDIO), "lumi", 1) + ASSERT ( checkProperties (candi, Asset::Ident("nil", Category(AUDIO), "cin3", 1) , "")); } diff --git a/tests/components/proc/asset/mediastructurequerytest.cpp b/tests/components/proc/asset/mediastructurequerytest.cpp index 7cbfcd847..866178fd4 100644 --- a/tests/components/proc/asset/mediastructurequerytest.cpp +++ b/tests/components/proc/asset/mediastructurequerytest.cpp @@ -44,7 +44,7 @@ namespace asset /*********************************************************************** * This test documents the Interface used by MediaFactory when loading - * media files for querying Lumiera's backend layer for information + * media files for querying cinelerra's backend layer for information * on how the media file is structured. */ class MediaStructureQuery_test : public Test diff --git a/tests/components/proc/mobject/controller/rendersegmenttest.cpp b/tests/components/proc/mobject/controller/rendersegmenttest.cpp index a56c76480..fac5568aa 100644 --- a/tests/components/proc/mobject/controller/rendersegmenttest.cpp +++ b/tests/components/proc/mobject/controller/rendersegmenttest.cpp @@ -46,7 +46,7 @@ namespace mobject /******************************************************************* * @test create a render process from a given segment of the EDL. * Basically this includes cooperation of all parts of the - * Lumiera Proc Layer. For a prepared test-EDL we invoke the + * Cinelerra Proc Layer. For a prepared test-EDL we invoke the * controller to create a render process. This includes building * the render pipeline. Finally, we analyze all the created * Structures. diff --git a/tests/components/proc/mobject/placementbasictest.cpp b/tests/components/proc/mobject/placementbasictest.cpp index e3e237252..16b6a80d0 100644 --- a/tests/components/proc/mobject/placementbasictest.cpp +++ b/tests/components/proc/mobject/placementbasictest.cpp @@ -35,7 +35,7 @@ #include //using boost::format; -using lumiera::Time; +using cinelerra::Time; using util::contains; using std::string; using std::cout; diff --git a/tests/components/proc/mobject/session/addcliptest.cpp b/tests/components/proc/mobject/session/addcliptest.cpp index 3cb981270..ffb794e95 100644 --- a/tests/components/proc/mobject/session/addcliptest.cpp +++ b/tests/components/proc/mobject/session/addcliptest.cpp @@ -32,7 +32,7 @@ #include //using boost::format; -using lumiera::Time; +using cinelerra::Time; using util::contains; using std::string; using std::cout; diff --git a/tests/components/proc/mobject/session/testclip.cpp b/tests/components/proc/mobject/session/testclip.cpp index ea17dd19d..ce659e708 100644 --- a/tests/components/proc/mobject/session/testclip.cpp +++ b/tests/components/proc/mobject/session/testclip.cpp @@ -44,7 +44,7 @@ namespace mobject asset::Media & createTestMedia () { - // install Mock-Interface to Lumiera backend + // install Mock-Interface to cinelerra backend MAF::instance.injectSubclass (new MediaAccessMock); PM media = asset::Media::create("test-2", VIDEO); // query magic filename MAF::instance.injectSubclass (0); // remove Mock-Interface @@ -70,7 +70,7 @@ namespace mobject { } }; - lumiera::Singleton testbed_1; // invoke ctor when creating first TestClip... + cinelerra::Singleton testbed_1; // invoke ctor when creating first TestClip... diff --git a/tests/error/errortest.c b/tests/error/errortest.c index d367c0742..0fd95b600 100644 --- a/tests/error/errortest.c +++ b/tests/error/errortest.c @@ -25,7 +25,7 @@ #include "lib/error.h" -LUMIERA_ERROR_DEFINE(TEST, "test error"); +CINELERRA_ERROR_DEFINE(TEST, "test error"); int main (int argc, char** argv) @@ -35,31 +35,31 @@ main (int argc, char** argv) if (!strcmp(argv[1], "set")) { - lumiera_error_set (LUMIERA_ERROR_TEST); + cinelerra_error_set (CINELERRA_ERROR_TEST); } if (!strcmp(argv[1], "get_no")) { const char* err; - err = lumiera_error (); + err = cinelerra_error (); printf ("%p\n", err); } if (!strcmp(argv[1], "get")) { - lumiera_error_set (LUMIERA_ERROR_TEST); + cinelerra_error_set (CINELERRA_ERROR_TEST); const char* err; - err = lumiera_error (); + err = cinelerra_error (); printf ("%s\n", err); } if (!strcmp(argv[1], "get2")) { - lumiera_error_set (LUMIERA_ERROR_TEST); + cinelerra_error_set (CINELERRA_ERROR_TEST); const char* err; - err = lumiera_error (); + err = cinelerra_error (); printf ("%s\n", err); - err = lumiera_error (); + err = cinelerra_error (); printf ("%p\n", err); } diff --git a/tests/library/test-llist.c b/tests/library/test-llist.c index bfaf99c65..bf6c5aed5 100644 --- a/tests/library/test-llist.c +++ b/tests/library/test-llist.c @@ -26,7 +26,7 @@ #include "lib/framerate.h" -LUMIERA_ERROR_DEFINE(TEST, "test error"); +CINELERRA_ERROR_DEFINE(TEST, "test error"); int main (int argc, char** argv) diff --git a/tests/library/test-references.c b/tests/library/test-references.c index c1509c341..f56c7c9d7 100644 --- a/tests/library/test-references.c +++ b/tests/library/test-references.c @@ -25,7 +25,7 @@ #include "lib/references.h" -LUMIERA_ERROR_DEFINE(TEST, "test error"); +CINELERRA_ERROR_DEFINE(TEST, "test error"); struct example @@ -55,16 +55,16 @@ main (int argc, char** argv) struct example test; test.foo = 123; - lumiera_reference hold; + cinelerra_reference hold; - lumiera_reference_strong_init_once (&hold, &test, example_dtor); + cinelerra_reference_strong_init_once (&hold, &test, example_dtor); - struct example* r = lumiera_reference_get (&hold); + struct example* r = cinelerra_reference_get (&hold); printf ("got: %d\n", r->foo); - lumiera_reference_destroy (&hold); + cinelerra_reference_destroy (&hold); } else if (!strcmp(argv[1], "nodeinsert")) { diff --git a/tests/locking/condition.c b/tests/locking/condition.c index 7d79e9a7e..6483ac0a9 100644 --- a/tests/locking/condition.c +++ b/tests/locking/condition.c @@ -40,10 +40,10 @@ signaling_thread() int conditionforgotunlock () { - lumiera_condition c; - lumiera_condition_init (&c); + cinelerra_condition c; + cinelerra_condition_init (&c); - lumiera_conditionacquirer l; - lumiera_conditionacquirer_init (&l, &c, LUMIERA_LOCKED); + cinelerra_conditionacquirer l; + cinelerra_conditionacquirer_init (&l, &c, CINELERRA_LOCKED); return 0; } diff --git a/tests/locking/mutex.c b/tests/locking/mutex.c index f4f8c18f6..ed6a050eb 100644 --- a/tests/locking/mutex.c +++ b/tests/locking/mutex.c @@ -23,10 +23,10 @@ int mutexforgotunlock() { - lumiera_mutex m; - lumiera_mutex_init (&m); + cinelerra_mutex m; + cinelerra_mutex_init (&m); - lumiera_mutexacquirer l; - lumiera_mutexacquirer_init_mutex (&l, &m, LUMIERA_LOCKED); + cinelerra_mutexacquirer l; + cinelerra_mutexacquirer_init_mutex (&l, &m, CINELERRA_LOCKED); return 0; } diff --git a/tests/locking/test-condition.c b/tests/locking/test-condition.c index 1e3ca1bf7..cc8e5ae14 100644 --- a/tests/locking/test-condition.c +++ b/tests/locking/test-condition.c @@ -24,7 +24,7 @@ #include "lib/condition.h" -LUMIERA_ERROR_DEFINE(TEST, "test error"); +CINELERRA_ERROR_DEFINE(TEST, "test error"); #if 0 waiting_thread() @@ -52,11 +52,11 @@ main (int argc, char** argv) if (!strcmp(argv[1], "conditionforgotunlock")) { - lumiera_condition c; - lumiera_condition_init (&c); + cinelerra_condition c; + cinelerra_condition_init (&c); - lumiera_conditionlock NOBUG_CLEANUP(lumiera_conditionlock_ensureunlocked) l; - lumiera_conditionlock_init (&l, &c, LUMIERA_LOCKED); + cinelerra_conditionlock NOBUG_CLEANUP(cinelerra_conditionlock_ensureunlocked) l; + cinelerra_conditionlock_init (&l, &c, CINELERRA_LOCKED); } else return 1; diff --git a/tests/locking/test-locking.c b/tests/locking/test-locking.c index 1b54d152e..46455764b 100644 --- a/tests/locking/test-locking.c +++ b/tests/locking/test-locking.c @@ -24,7 +24,7 @@ #include "lib/error.h" -LUMIERA_ERROR_DEFINE(TEST, "test error"); +CINELERRA_ERROR_DEFINE(TEST, "test error"); int conditionforgotunlock (); int mutexforgotunlock (); diff --git a/tests/plugin/example_plugin.c b/tests/plugin/example_plugin.c index 7540aa35d..ebb71ae8a 100644 --- a/tests/plugin/example_plugin.c +++ b/tests/plugin/example_plugin.c @@ -34,12 +34,12 @@ void bye(const char* m) printf("Bye %s\n", m); } -LUMIERA_INTERFACE_IMPLEMENT(hello, 1, german, myopen, myclose, - hallo, - tschuess - ); +CINELERRA_INTERFACE_IMPLEMENT(hello, 1, german, myopen, myclose, + hallo, + tschuess + ); -LUMIERA_INTERFACE_IMPLEMENT(hello, 1, english, myopen, myclose, - hello, - bye - ); +CINELERRA_INTERFACE_IMPLEMENT(hello, 1, english, myopen, myclose, + hello, + bye + ); diff --git a/tests/plugin/example_plugin.cpp b/tests/plugin/example_plugin.cpp index aba34b44a..b608887d8 100644 --- a/tests/plugin/example_plugin.cpp +++ b/tests/plugin/example_plugin.cpp @@ -50,12 +50,12 @@ public: }; -LUMIERA_INTERFACE_IMPLEMENT(hello, 1, german, example_plugin_de::myopen, example_plugin_de::myclose, - example_plugin_de::hello, - example_plugin_de::bye - ); +CINELERRA_INTERFACE_IMPLEMENT(hello, 1, german, example_plugin_de::myopen, example_plugin_de::myclose, + example_plugin_de::hello, + example_plugin_de::bye + ); -LUMIERA_INTERFACE_IMPLEMENT(hello, 1, english, example_plugin_en::myopen, example_plugin_en::myclose, - example_plugin_en::hello, - example_plugin_en::bye - ); +CINELERRA_INTERFACE_IMPLEMENT(hello, 1, english, example_plugin_en::myopen, example_plugin_en::myclose, + example_plugin_en::hello, + example_plugin_en::bye + ); diff --git a/tests/plugin/hello_interface.h b/tests/plugin/hello_interface.h index d5cf99ea5..ccec270ed 100644 --- a/tests/plugin/hello_interface.h +++ b/tests/plugin/hello_interface.h @@ -1,6 +1,6 @@ #include "lib/plugin.h" -LUMIERA_INTERFACE(hello, 1, - LUMIERA_INTERFACE_PROTO(void, hello, (void)) - LUMIERA_INTERFACE_PROTO(void, goodbye, (const char*)) - ); +CINELERRA_INTERFACE(hello, 1, + CINELERRA_INTERFACE_PROTO(void, hello, (void)) + CINELERRA_INTERFACE_PROTO(void, goodbye, (const char*)) + ); diff --git a/tests/plugin/plugin_main.c b/tests/plugin/plugin_main.c index 2efe32471..e691438b3 100644 --- a/tests/plugin/plugin_main.c +++ b/tests/plugin/plugin_main.c @@ -12,7 +12,7 @@ main(int argc, char** argv) if (argc < 2) return -1; - lumiera_init_plugin (); + cinelerra_init_plugin (); /* we have a plugin 'hello_1' which provides us 2 hello interfaces, one for english and one for german output, open both try them, close them. @@ -22,47 +22,47 @@ main(int argc, char** argv) if( !strcmp(argv[1],"C")) { - LUMIERA_INTERFACE_TYPE(hello, 1)* hello_de = - (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin", "german_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); + CINELERRA_INTERFACE_TYPE(hello, 1)* hello_de = + (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin", "german_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); - if (!hello_de) LUMIERA_DIE; + if (!hello_de) CINELERRA_DIE; hello_de->hello(); hello_de->goodbye(argv[1]); - LUMIERA_INTERFACE_TYPE(hello, 1)* hello_en = - (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin", "english_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); + CINELERRA_INTERFACE_TYPE(hello, 1)* hello_en = + (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin", "english_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); - if (!hello_en) LUMIERA_DIE; + if (!hello_en) CINELERRA_DIE; hello_en->hello(); hello_en->goodbye(argv[1]); - lumiera_interface_close (hello_en); - lumiera_interface_close (hello_de); + cinelerra_interface_close (hello_en); + cinelerra_interface_close (hello_de); } if( !strcmp(argv[1],"C++")) { /* same again for a plugin written in C++ */ - LUMIERA_INTERFACE_TYPE(hello, 1)* hello_de = - (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin_cpp", "german_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); + CINELERRA_INTERFACE_TYPE(hello, 1)* hello_de = + (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin_cpp", "german_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); - if (!hello_de) LUMIERA_DIE; + if (!hello_de) CINELERRA_DIE; hello_de->hello(); hello_de->goodbye(argv[1]); - LUMIERA_INTERFACE_TYPE(hello, 1)* hello_en = - (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin_cpp", "english_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); + CINELERRA_INTERFACE_TYPE(hello, 1)* hello_en = + (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin_cpp", "english_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); - if (!hello_en) LUMIERA_DIE; + if (!hello_en) CINELERRA_DIE; hello_en->hello(); hello_en->goodbye(argv[1]); - lumiera_interface_close (hello_en); - lumiera_interface_close (hello_de); + cinelerra_interface_close (hello_en); + cinelerra_interface_close (hello_de); } return 0; diff --git a/tests/time/test-time.c b/tests/time/test-time.c index e9d8d0550..01dd107ef 100644 --- a/tests/time/test-time.c +++ b/tests/time/test-time.c @@ -26,7 +26,7 @@ #include "lib/framerate.h" -LUMIERA_ERROR_DEFINE(TEST, "test error"); +CINELERRA_ERROR_DEFINE(TEST, "test error"); int main (int argc, char** argv) @@ -38,106 +38,106 @@ main (int argc, char** argv) if (!strcmp(argv[1], "init")) { - lumiera_time time; + cinelerra_time time; - lumiera_time_init (&time, atol (argv[2]), atol(argv[3])); + cinelerra_time_init (&time, atol (argv[2]), atol(argv[3])); - printf ("%lu %lu\n", (long)lumiera_time_sec (&time), (long)lumiera_time_usec (&time)); + printf ("%lu %lu\n", (long)cinelerra_time_sec (&time), (long)cinelerra_time_usec (&time)); } if (!strcmp(argv[1], "todouble")) { - lumiera_time time; + cinelerra_time time; - lumiera_time_init (&time, atol (argv[2]), atol(argv[3])); + cinelerra_time_init (&time, atol (argv[2]), atol(argv[3])); - printf ("%g\n", lumiera_time_double_get (&time)); + printf ("%g\n", cinelerra_time_double_get (&time)); } if (!strcmp(argv[1], "todoublenull")) { - printf ("%g\n", lumiera_time_double_get (NULL)); + printf ("%g\n", cinelerra_time_double_get (NULL)); } if (!strcmp(argv[1], "fromdouble")) { - lumiera_time time; + cinelerra_time time; - lumiera_time_set_double (&time, atof (argv[2])); + cinelerra_time_set_double (&time, atof (argv[2])); - printf ("%lu %lu\n", (long)lumiera_time_sec (&time), (long)lumiera_time_usec (&time)); + printf ("%lu %lu\n", (long)cinelerra_time_sec (&time), (long)cinelerra_time_usec (&time)); } if (!strcmp(argv[1], "currenttime")) { - lumiera_time time; + cinelerra_time time; - lumiera_time_current (&time); + cinelerra_time_current (&time); - printf ("%lu %lu\n", (long)lumiera_time_sec (&time), (long)lumiera_time_usec (&time)); + printf ("%lu %lu\n", (long)cinelerra_time_sec (&time), (long)cinelerra_time_usec (&time)); } if (!strcmp(argv[1], "add")) { - lumiera_time time1, time2; + cinelerra_time time1, time2; - lumiera_time_init (&time1, 0, atol (argv[2])); - lumiera_time_init (&time2, 0, atol (argv[3])); - lumiera_time_add (&time1, &time2); + cinelerra_time_init (&time1, 0, atol (argv[2])); + cinelerra_time_init (&time2, 0, atol (argv[3])); + cinelerra_time_add (&time1, &time2); - printf ("%lu %lu\n", (long)lumiera_time_sec (&time1), (long)lumiera_time_usec (&time1)); + printf ("%lu %lu\n", (long)cinelerra_time_sec (&time1), (long)cinelerra_time_usec (&time1)); } if (!strcmp(argv[1], "sub")) { - lumiera_time time1, time2; + cinelerra_time time1, time2; - lumiera_time_init (&time1, 0, atol (argv[2])); - lumiera_time_init (&time2, 0, atol (argv[3])); - lumiera_time_sub (&time1, &time2); + cinelerra_time_init (&time1, 0, atol (argv[2])); + cinelerra_time_init (&time2, 0, atol (argv[3])); + cinelerra_time_sub (&time1, &time2); - printf ("%lu %lu\n", (long)lumiera_time_sec (&time1), (long)lumiera_time_usec (&time1)); + printf ("%lu %lu\n", (long)cinelerra_time_sec (&time1), (long)cinelerra_time_usec (&time1)); } if (!strcmp(argv[1], "ntscframefromtime")) { - lumiera_framerate ntsc = {30000, 1001}; - lumiera_time time; + cinelerra_framerate ntsc = {30000, 1001}; + cinelerra_time time; - lumiera_time_init (&time, atol (argv[2]), atol (argv[3])); + cinelerra_time_init (&time, atol (argv[2]), atol (argv[3])); - printf ("%lu\n", (long)lumiera_framerate_frame_get_time (&ntsc, &time)); + printf ("%lu\n", (long)cinelerra_framerate_frame_get_time (&ntsc, &time)); } if (!strcmp(argv[1], "ntscframestart")) { - lumiera_framerate ntsc = {30000, 1001}; - lumiera_time time; + cinelerra_framerate ntsc = {30000, 1001}; + cinelerra_time time; - if(lumiera_framerate_time_get_time_frame (&ntsc, &time, atol (argv[2]))) - printf ("%lu %lu\n", (long)lumiera_time_sec(&time), (long)lumiera_time_usec(&time)); + if(cinelerra_framerate_time_get_time_frame (&ntsc, &time, atol (argv[2]))) + printf ("%lu %lu\n", (long)cinelerra_time_sec(&time), (long)cinelerra_time_usec(&time)); } if (!strcmp(argv[1], "ntscframecheck")) { - lumiera_framerate ntsc = {30000, 1001}; - lumiera_time time1; - lumiera_time time2; - lumiera_framepos frame; + cinelerra_framerate ntsc = {30000, 1001}; + cinelerra_time time1; + cinelerra_time time2; + cinelerra_framepos frame; - lumiera_framepos frame1; - lumiera_framepos frame2; + cinelerra_framepos frame1; + cinelerra_framepos frame2; frame = atol (argv[2]); - if (lumiera_framerate_time_get_time_frame (&ntsc, &time1, frame)) + if (cinelerra_framerate_time_get_time_frame (&ntsc, &time1, frame)) { - printf("frame %lu ", frame1 = lumiera_framerate_frame_get_time (&ntsc, &time1)); + printf("frame %lu ", frame1 = cinelerra_framerate_frame_get_time (&ntsc, &time1)); - lumiera_time_init (&time2, 0, 1); - lumiera_time_sub (&time1, &time2); - printf("%lu\n", frame2 = lumiera_framerate_frame_get_time (&ntsc, &time1)); + cinelerra_time_init (&time2, 0, 1); + cinelerra_time_sub (&time1, &time2); + printf("%lu\n", frame2 = cinelerra_framerate_frame_get_time (&ntsc, &time1)); ENSURE (frame1 == frame2+1); } From 7721b6f5b1a9edf3181852c0eeec18df5dc3e18a Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Tue, 8 Apr 2008 23:21:05 +0100 Subject: [PATCH 002/245] Created initial UI base --- gui/AUTHORS | 0 gui/COPYING | 1 + gui/ChangeLog | 0 gui/INSTALL | 1 + gui/Makefile.am | 24 ++++++ gui/NEWS | 0 gui/README | 0 gui/TODO.tasks | 6 ++ gui/autogen.sh | 159 ++++++++++++++++++++++++++++++++++++++ gui/config.h | 77 ++++++++++++++++++ gui/configure.ac | 44 +++++++++++ gui/gtk-lumiera.anjuta | 44 +++++++++++ gui/po/ChangeLog | 0 gui/po/LINGUAS | 2 + gui/po/POTFILES.in | 3 + gui/src/Makefile.am | 27 +++++++ gui/src/gtk-lumiera.glade | 27 +++++++ gui/src/main.cpp | 62 +++++++++++++++ 18 files changed, 477 insertions(+) create mode 100644 gui/AUTHORS create mode 120000 gui/COPYING create mode 100644 gui/ChangeLog create mode 120000 gui/INSTALL create mode 100644 gui/Makefile.am create mode 100644 gui/NEWS create mode 100644 gui/README create mode 100644 gui/TODO.tasks create mode 100755 gui/autogen.sh create mode 100644 gui/config.h create mode 100644 gui/configure.ac create mode 100644 gui/gtk-lumiera.anjuta create mode 100644 gui/po/ChangeLog create mode 100644 gui/po/LINGUAS create mode 100644 gui/po/POTFILES.in create mode 100644 gui/src/Makefile.am create mode 100644 gui/src/gtk-lumiera.glade create mode 100644 gui/src/main.cpp diff --git a/gui/AUTHORS b/gui/AUTHORS new file mode 100644 index 000000000..e69de29bb diff --git a/gui/COPYING b/gui/COPYING new file mode 120000 index 000000000..0b6cbf81b --- /dev/null +++ b/gui/COPYING @@ -0,0 +1 @@ +/usr/share/automake-1.10/COPYING \ No newline at end of file diff --git a/gui/ChangeLog b/gui/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/gui/INSTALL b/gui/INSTALL new file mode 120000 index 000000000..5bb6e7b7e --- /dev/null +++ b/gui/INSTALL @@ -0,0 +1 @@ +/usr/share/automake-1.10/INSTALL \ No newline at end of file diff --git a/gui/Makefile.am b/gui/Makefile.am new file mode 100644 index 000000000..329e83f38 --- /dev/null +++ b/gui/Makefile.am @@ -0,0 +1,24 @@ +## Process this file with automake to produce Makefile.in +## Created by Anjuta + +SUBDIRS = src po + +gtk_lumieradocdir = ${prefix}/doc/gtk-lumiera +gtk_lumieradoc_DATA = \ + README\ + COPYING\ + AUTHORS\ + ChangeLog\ + INSTALL\ + NEWS + +EXTRA_DIST = $(gtk_lumieradoc_DATA) + +# Copy all the spec files. Of cource, only one is actually used. +dist-hook: + for specfile in *.spec; do \ + if test -f $$specfile; then \ + cp -p $$specfile $(distdir); \ + fi \ + done + diff --git a/gui/NEWS b/gui/NEWS new file mode 100644 index 000000000..e69de29bb diff --git a/gui/README b/gui/README new file mode 100644 index 000000000..e69de29bb diff --git a/gui/TODO.tasks b/gui/TODO.tasks new file mode 100644 index 000000000..d1fa282d9 --- /dev/null +++ b/gui/TODO.tasks @@ -0,0 +1,6 @@ + + + + + + diff --git a/gui/autogen.sh b/gui/autogen.sh new file mode 100755 index 000000000..9ab346a30 --- /dev/null +++ b/gui/autogen.sh @@ -0,0 +1,159 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +DIE=0 + +if [ -n "$GNOME2_DIR" ]; then + ACLOCAL_FLAGS="-I $GNOME2_DIR/share/aclocal $ACLOCAL_FLAGS" + LD_LIBRARY_PATH="$GNOME2_DIR/lib:$LD_LIBRARY_PATH" + PATH="$GNOME2_DIR/bin:$PATH" + export PATH + export LD_LIBRARY_PATH +fi + +(test -f $srcdir/configure.ac) || { + echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" + echo " top-level package directory" + exit 1 +} + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`autoconf' installed." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +(grep "^IT_PROG_INTLTOOL" $srcdir/configure.ac >/dev/null) && { + (intltoolize --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`intltool' installed." + echo "You can get it from:" + echo " ftp://ftp.gnome.org/pub/GNOME/" + DIE=1 + } +} + +(grep "^AM_PROG_XML_I18N_TOOLS" $srcdir/configure.ac >/dev/null) && { + (xml-i18n-toolize --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`xml-i18n-toolize' installed." + echo "You can get it from:" + echo " ftp://ftp.gnome.org/pub/GNOME/" + DIE=1 + } +} + +(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && { + (libtool --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`libtool' installed." + echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/" + DIE=1 + } +} + +(grep "^AM_GLIB_GNU_GETTEXT" $srcdir/configure.ac >/dev/null) && { + (grep "sed.*POTFILES" $srcdir/configure.ac) > /dev/null || \ + (glib-gettextize --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`glib' installed." + echo "You can get it from: ftp://ftp.gtk.org/pub/gtk" + DIE=1 + } +} + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`automake' installed." + echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/" + DIE=1 + NO_AUTOMAKE=yes +} + + +# if no automake, don't bother testing for aclocal +test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: Missing \`aclocal'. The version of \`automake'" + echo "installed doesn't appear recent enough." + echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +if test -z "$*"; then + echo "**Warning**: I am going to run \`configure' with no arguments." + echo "If you wish to pass any to it, please specify them on the" + echo \`$0\'" command line." + echo +fi + +case $CC in +xlc ) + am_opt=--include-deps;; +esac + +for coin in `find $srcdir -path $srcdir/CVS -prune -o -name configure.ac -print` +do + dr=`dirname $coin` + if test -f $dr/NO-AUTO-GEN; then + echo skipping $dr -- flagged as no auto-gen + else + echo processing $dr + ( cd $dr + + aclocalinclude="$ACLOCAL_FLAGS" + + if grep "^AM_GLIB_GNU_GETTEXT" configure.ac >/dev/null; then + echo "Creating $dr/aclocal.m4 ..." + test -r $dr/aclocal.m4 || touch $dr/aclocal.m4 + echo "Running glib-gettextize... Ignore non-fatal messages." + echo "no" | glib-gettextize --force --copy + echo "Making $dr/aclocal.m4 writable ..." + test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4 + fi + if grep "^IT_PROG_INTLTOOL" configure.ac >/dev/null; then + echo "Running intltoolize..." + intltoolize --copy --force --automake + fi + if grep "^AM_PROG_XML_I18N_TOOLS" configure.ac >/dev/null; then + echo "Running xml-i18n-toolize..." + xml-i18n-toolize --copy --force --automake + fi + if grep "^AM_PROG_LIBTOOL" configure.ac >/dev/null; then + if test -z "$NO_LIBTOOLIZE" ; then + echo "Running libtoolize..." + libtoolize --force --copy + fi + fi + echo "Running aclocal $aclocalinclude ..." + aclocal $aclocalinclude + if grep "^AM_CONFIG_HEADER" configure.ac >/dev/null; then + echo "Running autoheader..." + autoheader + fi + echo "Running automake --gnu $am_opt ..." + automake --add-missing --gnu $am_opt + echo "Running autoconf ..." + autoconf + ) + fi +done + +conf_flags="--enable-maintainer-mode" + +if test x$NOCONFIGURE = x; then + echo Running $srcdir/configure $conf_flags "$@" ... + $srcdir/configure $conf_flags "$@" \ + && echo Now type \`make\' to compile. || exit 1 +else + echo Skipping configure process. +fi diff --git a/gui/config.h b/gui/config.h new file mode 100644 index 000000000..7b9564f69 --- /dev/null +++ b/gui/config.h @@ -0,0 +1,77 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* always defined to indicate that i18n is enabled */ +#define ENABLE_NLS 1 + +/* GETTEXT package name */ +#define GETTEXT_PACKAGE "gtk-lumiera" + +/* Define to 1 if you have the `bind_textdomain_codeset' function. */ +#define HAVE_BIND_TEXTDOMAIN_CODESET 1 + +/* Define to 1 if you have the `dcgettext' function. */ +#define HAVE_DCGETTEXT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#define HAVE_GETTEXT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if your file defines LC_MESSAGES. */ +#define HAVE_LC_MESSAGES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Name of package */ +#define PACKAGE "gtk-lumiera" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "gtk-lumiera" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "gtk-lumiera 0.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "gtk-lumiera" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.1" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.1" diff --git a/gui/configure.ac b/gui/configure.ac new file mode 100644 index 000000000..9eef896f8 --- /dev/null +++ b/gui/configure.ac @@ -0,0 +1,44 @@ +dnl Process this file with autoconf to produce a configure script. +dnl Created by Anjuta application wizard. + +AC_INIT(gtk-lumiera, 0.1) + +AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) +AM_CONFIG_HEADER(config.h) +AM_MAINTAINER_MODE + +AC_ISC_POSIX +AC_PROG_CXX +AM_PROG_CC_STDC +AC_HEADER_STDC + + + + +dnl *************************************************************************** +dnl Internatinalization +dnl *************************************************************************** +GETTEXT_PACKAGE=gtk-lumiera +AC_SUBST(GETTEXT_PACKAGE) +AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name]) +AM_GLIB_GNU_GETTEXT +IT_PROG_INTLTOOL([0.35.0]) + + + +AM_PROG_LIBTOOL + + + +PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 libglademm-2.4 >= 2.6 ]) +AC_SUBST(GTK_LUMIERA_CFLAGS) +AC_SUBST(GTK_LUMIERA_LIBS) + + + + +AC_OUTPUT([ +Makefile +src/Makefile +po/Makefile.in +]) diff --git a/gui/gtk-lumiera.anjuta b/gui/gtk-lumiera.anjuta new file mode 100644 index 000000000..8b9268a44 --- /dev/null +++ b/gui/gtk-lumiera.anjuta @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/gui/po/ChangeLog b/gui/po/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/gui/po/LINGUAS b/gui/po/LINGUAS new file mode 100644 index 000000000..bc8cbb0fe --- /dev/null +++ b/gui/po/LINGUAS @@ -0,0 +1,2 @@ +# please keep this list sorted alphabetically +# diff --git a/gui/po/POTFILES.in b/gui/po/POTFILES.in new file mode 100644 index 000000000..a0b3c552e --- /dev/null +++ b/gui/po/POTFILES.in @@ -0,0 +1,3 @@ +# List of source files containing translatable strings. + +src/main.c diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am new file mode 100644 index 000000000..7ae61d803 --- /dev/null +++ b/gui/src/Makefile.am @@ -0,0 +1,27 @@ +## Process this file with automake to produce Makefile.in + +## Created by Anjuta + +gladedir = $(datadir)/gtk-lumiera/glade +glade_DATA = gtk-lumiera.glade + +INCLUDES = \ + -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ + -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \ + -DPACKAGE_DATA_DIR=\""$(datadir)"\" \ + $(GTK_LUMIERA_CFLAGS) + +AM_CFLAGS =\ + -Wall\ + -g + +bin_PROGRAMS = gtk-lumiera + +gtk_lumiera_SOURCES = \ + main.cpp + +gtk_lumiera_LDFLAGS = + +gtk_lumiera_LDADD = $(GTK_LUMIERA_LIBS) + +EXTRA_DIST = $(glade_DATA) diff --git a/gui/src/gtk-lumiera.glade b/gui/src/gtk-lumiera.glade new file mode 100644 index 000000000..8db3bef2c --- /dev/null +++ b/gui/src/gtk-lumiera.glade @@ -0,0 +1,27 @@ + + + + + + + True + Hello World! + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + 500 + 400 + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + + + + + + + diff --git a/gui/src/main.cpp b/gui/src/main.cpp new file mode 100644 index 000000000..bb69eb3d9 --- /dev/null +++ b/gui/src/main.cpp @@ -0,0 +1,62 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * main.cc + * Copyright (C) Joel Holdsworth 2008 + * + * main.cc is free software. + * + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * main.cc 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 main.cc. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + + +#ifdef ENABLE_NLS +# include +#endif + + +/* For testing propose use the local (not installed) glade file */ +/* #define GLADE_FILE PACKAGE_DATA_DIR"/gtk-lumiera/glade/gtk-lumiera.glade" */ +#define GLADE_FILE "gtk-lumiera.glade" + +int +main (int argc, char *argv[]) +{ + Gtk::Main kit(argc, argv); + + //Load the Glade file and instiate its widgets: + Glib::RefPtr refXml; + try + { + refXml = Gnome::Glade::Xml::create(GLADE_FILE); + } + catch(const Gnome::Glade::XmlError& ex) + { + std::cerr << ex.what() << std::endl; + return 1; + } + Gtk::Window* main_win = 0; + refXml->get_widget("main_window", main_win); + if (main_win) + { + kit.run(*main_win); + } + return 0; +} From 69a06cdc2d89bd39ef23057fba3f5de51ee241b4 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Tue, 8 Apr 2008 23:27:21 +0100 Subject: [PATCH 003/245] Revert "Revert "Lumiera renaming -- source code"" This reverts commit e9a8b9f64d2b3ccf4887e8b75a19d1e291c249c7. --- src/backend/mediaaccessfacade.cpp | 4 +- src/backend/mediaaccessfacade.hpp | 2 +- src/common/appconfig.cpp | 10 +- src/common/appconfig.hpp | 8 +- src/common/error.cpp | 38 ++-- src/common/error.hpp | 84 ++++----- src/common/factory.hpp | 8 +- src/common/multithread.hpp | 12 +- src/common/singleton.hpp | 6 +- src/common/singletonfactory.hpp | 8 +- src/common/singletonpolicies.hpp | 14 +- src/common/singletonpreconfigure.hpp | 18 +- src/common/test/mockinjector.hpp | 8 +- src/common/test/suite.cpp | 6 +- src/common/time.cpp | 4 +- src/common/time.hpp | 8 +- src/common/typelist.hpp | 10 +- src/common/visitor.cpp | 4 +- src/common/visitor.hpp | 10 +- src/common/visitordispatcher.hpp | 8 +- src/common/visitorpolicies.hpp | 12 +- src/lib/condition.c | 12 +- src/lib/condition.h | 86 ++++----- src/lib/error.c | 32 ++-- src/lib/error.h | 38 ++-- src/lib/framerate.c | 4 +- src/lib/framerate.h | 42 ++--- src/lib/locking.h | 14 +- src/lib/mutex.c | 10 +- src/lib/mutex.h | 90 +++++----- src/lib/plugin.c | 164 +++++++++--------- src/lib/plugin.h | 74 ++++---- src/lib/references.c | 70 ++++---- src/lib/references.h | 52 +++--- src/lib/rwlock.c | 62 +++---- src/lib/rwlock.h | 60 +++---- src/lib/time.c | 6 +- src/lib/time.h | 66 +++---- src/{cinelerra.h => lumiera.h} | 12 +- src/main.cpp | 4 +- src/nobugcfg.h | 2 +- src/plugin/helloplugin.c | 4 +- src/pre.hpp | 8 +- src/proc/asset.cpp | 2 +- src/proc/asset.hpp | 4 +- src/proc/asset/db.hpp | 4 +- src/proc/asset/media.cpp | 22 +-- src/proc/asset/media.hpp | 8 +- src/proc/asset/meta.hpp | 2 +- src/proc/asset/proc.hpp | 2 +- src/proc/asset/struct.hpp | 2 +- src/proc/asset/unknown.cpp | 16 +- src/proc/asset/unknown.hpp | 6 +- src/proc/assetmanager.cpp | 30 ++-- src/proc/assetmanager.hpp | 12 +- src/proc/engine/codecadapter.hpp | 2 +- src/proc/engine/pluginadapter.hpp | 2 +- src/proc/engine/processor.hpp | 6 +- src/proc/mobject/builder/buildertool.hpp | 8 +- src/proc/mobject/mobject.hpp | 6 +- src/proc/mobject/placement.hpp | 2 +- src/proc/mobject/session.hpp | 2 +- src/proc/mobject/session/locatingpin.hpp | 4 +- src/proc/mobject/session/segment.hpp | 4 +- src/proc/mobject/session/session.cpp | 2 +- src/proc/mobject/session/sessionimpl.cpp | 2 +- src/proc/mobject/session/sessionimpl.hpp | 2 +- src/tool/hello.c | 4 +- tests/10errorhandling.tests | 4 +- tests/50components.tests | 20 +-- tests/54builder.tests | 2 +- tests/components/backend/mediaaccessmock.cpp | 2 +- tests/components/backend/mediaaccessmock.hpp | 2 +- tests/components/common/appconfigtest.cpp | 6 +- .../components/common/exceptionerrortest.cpp | 38 ++-- .../components/common/factoryspecialtest.cpp | 4 +- tests/components/common/factorytest.cpp | 6 +- tests/components/common/singletontest.cpp | 10 +- .../common/singletontestmocktest.cpp | 8 +- tests/components/common/testtargetobj.hpp | 8 +- tests/components/common/typelisttest.cpp | 4 +- .../components/common/visitingtoolconcept.cpp | 8 +- .../common/visitingtoolextendedtest.cpp | 4 +- tests/components/common/visitingtooltest.cpp | 4 +- tests/components/helloworldtest.cpp | 4 +- tests/components/mainsuite.cpp | 2 +- .../components/proc/asset/createassettest.cpp | 18 +- .../proc/asset/mediastructurequerytest.cpp | 2 +- .../mobject/controller/rendersegmenttest.cpp | 2 +- .../proc/mobject/placementbasictest.cpp | 2 +- .../proc/mobject/session/addcliptest.cpp | 2 +- .../proc/mobject/session/testclip.cpp | 4 +- tests/error/errortest.c | 16 +- tests/library/test-llist.c | 2 +- tests/library/test-references.c | 10 +- tests/locking/condition.c | 8 +- tests/locking/mutex.c | 8 +- tests/locking/test-condition.c | 10 +- tests/locking/test-locking.c | 2 +- tests/plugin/example_plugin.c | 16 +- tests/plugin/example_plugin.cpp | 16 +- tests/plugin/hello_interface.h | 8 +- tests/plugin/plugin_main.c | 34 ++-- tests/time/test-time.c | 86 ++++----- 104 files changed, 866 insertions(+), 866 deletions(-) rename src/{cinelerra.h => lumiera.h} (90%) diff --git a/src/backend/mediaaccessfacade.cpp b/src/backend/mediaaccessfacade.cpp index bd12068f9..ad52698b8 100644 --- a/src/backend/mediaaccessfacade.cpp +++ b/src/backend/mediaaccessfacade.cpp @@ -26,13 +26,13 @@ #include "common/util.hpp" using util::isnil; -using cinelerra::error::Invalid; +using lumiera::error::Invalid; namespace backend_interface { /** storage for the SingletonFactory - * (actually a cinelerra::test::MockInjector) */ + * (actually a lumiera::test::MockInjector) */ Singleton MediaAccessFacade::instance; diff --git a/src/backend/mediaaccessfacade.hpp b/src/backend/mediaaccessfacade.hpp index 15579d491..63741b02e 100644 --- a/src/backend/mediaaccessfacade.hpp +++ b/src/backend/mediaaccessfacade.hpp @@ -59,7 +59,7 @@ namespace backend_interface * information from this file, NULL if the * file is not acessible. */ - virtual FileHandle queryFile (const char* name) throw(cinelerra::error::Invalid); + virtual FileHandle queryFile (const char* name) throw(lumiera::error::Invalid); /** request for information about the n-th channel * of the file refered by FileHandle. diff --git a/src/common/appconfig.cpp b/src/common/appconfig.cpp index fdf16cf40..612376022 100644 --- a/src/common/appconfig.cpp +++ b/src/common/appconfig.cpp @@ -34,7 +34,7 @@ using util::isnil; -namespace cinelerra +namespace lumiera { /** This internal pointer to the single instance is deliberately @@ -52,7 +52,7 @@ namespace cinelerra /** perform initialization on first access. * A call is placed in static initialization code - * included in cinelerra.h; thus it will happen + * included in lumiera.h; thus it will happen * probably very early. */ Appconfig::Appconfig() @@ -65,7 +65,7 @@ namespace cinelerra INFO(config, "Basic application configuration triggered."); // install our own handler for undeclared exceptions - std::set_unexpected (cinelerra::error::cinelerra_unexpectedException); + std::set_unexpected (lumiera::error::lumiera_unexpectedException); (*configParam_)["version"] = STRINGIFY (LUMIERA_VERSION); } @@ -89,10 +89,10 @@ namespace cinelerra catch (...) { ERROR(config, "error while accessing configuration parameter \"%s\".", key.c_str()); - throw cinelerra::error::Fatal (); + throw lumiera::error::Fatal (); } } -} // namespace cinelerra +} // namespace lumiera diff --git a/src/common/appconfig.hpp b/src/common/appconfig.hpp index bbd50df6f..984236755 100644 --- a/src/common/appconfig.hpp +++ b/src/common/appconfig.hpp @@ -34,8 +34,8 @@ */ -#ifndef CINELERRA_APPCONFIG_H -#define CINELERRA_APPCONFIG_H +#ifndef LUMIERA_APPCONFIG_H +#define LUMIERA_APPCONFIG_H #include #include @@ -45,7 +45,7 @@ -namespace cinelerra +namespace lumiera { using std::string; using boost::scoped_ptr; @@ -104,5 +104,5 @@ namespace cinelerra -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/src/common/error.cpp b/src/common/error.cpp index 17e18e676..e708c5d3a 100644 --- a/src/common/error.cpp +++ b/src/common/error.cpp @@ -1,5 +1,5 @@ /* - Error - Cinelerra Exception Interface + Error - Lumiera Exception Interface Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -33,7 +33,7 @@ using util::isnil; using std::exception; -namespace cinelerra +namespace lumiera { namespace error @@ -46,23 +46,23 @@ namespace cinelerra */ inline const string default_usermsg (Error* exception_obj) throw() { - return string("Sorry, Cinelerra encountered an internal error. (") + return string("Sorry, Lumiera encountered an internal error. (") + typeid(*exception_obj).name() + ")"; } /* constants to be used as error IDs */ - CINELERRA_ERROR_DEFINE (LOGIC , "internal logic broken"); - CINELERRA_ERROR_DEFINE (FATAL , "floundered"); - CINELERRA_ERROR_DEFINE (CONFIG , "misconfiguration"); - CINELERRA_ERROR_DEFINE (STATE , "unforseen state"); - CINELERRA_ERROR_DEFINE (INVALID , "invalid input or parameters"); - CINELERRA_ERROR_DEFINE (EXTERNAL , "failure in external service"); - CINELERRA_ERROR_DEFINE (ASSERTION, "assertion failure"); + LUMIERA_ERROR_DEFINE (LOGIC , "internal logic broken"); + LUMIERA_ERROR_DEFINE (FATAL , "floundered"); + LUMIERA_ERROR_DEFINE (CONFIG , "misconfiguration"); + LUMIERA_ERROR_DEFINE (STATE , "unforseen state"); + LUMIERA_ERROR_DEFINE (INVALID , "invalid input or parameters"); + LUMIERA_ERROR_DEFINE (EXTERNAL , "failure in external service"); + LUMIERA_ERROR_DEFINE (ASSERTION, "assertion failure"); } // namespace error - CINELERRA_ERROR_DEFINE (EXCEPTION, "generic cinelerra exception"); + LUMIERA_ERROR_DEFINE (EXCEPTION, "generic Lumiera exception"); @@ -75,7 +75,7 @@ namespace cinelerra desc_ (description), cause_ ("") { - cinelerra_error_set (this->id_); + lumiera_error_set (this->id_); } @@ -87,7 +87,7 @@ namespace cinelerra desc_ (description), cause_ (extractCauseMsg(cause)) { - cinelerra_error_set (this->id_); + lumiera_error_set (this->id_); } @@ -103,7 +103,7 @@ namespace cinelerra /** Description of the problem, including the internal char constant - * in accordance to cinelerra's error identification scheme. + * in accordance to Lumiera's error identification scheme. * If a root cause can be obtained, this will be included in the * generated output as well. */ @@ -167,15 +167,15 @@ namespace cinelerra namespace error { - void cinelerra_unexpectedException () throw() + void lumiera_unexpectedException () throw() { const char* is_halted - = "### Cinelerra halted due to an unexpected Error ###"; + = "### Lumiera halted due to an unexpected Error ###"; std::cerr << "\n" << is_halted << "\n\n"; ERROR (NOBUG_ON, "%s", is_halted); - if (const char * errorstate = cinelerra_error ()) + if (const char * errorstate = lumiera_error ()) ERROR (NOBUG_ON, "last registered error was....\n%s", errorstate); std::terminate(); @@ -183,7 +183,7 @@ namespace cinelerra void assertion_terminate (const string& location) { - throw Fatal (location, CINELERRA_ERROR_ASSERTION) + throw Fatal (location, LUMIERA_ERROR_ASSERTION) .setUsermsg("Program terminated because of violating " "an internal consistency check."); } @@ -191,4 +191,4 @@ namespace cinelerra } // namespace error -} // namespace cinelerra +} // namespace lumiera diff --git a/src/common/error.hpp b/src/common/error.hpp index 15e60f022..4ccb8b1d7 100644 --- a/src/common/error.hpp +++ b/src/common/error.hpp @@ -1,5 +1,5 @@ /* - ERROR.hpp - Cinelerra Exception Interface + ERROR.hpp - Lumiera Exception Interface Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,26 +21,26 @@ */ -#ifndef CINELERRA_ERROR_HPP_ -#define CINELERRA_ERROR_HPP_ +#ifndef LUMIERA_ERROR_HPP_ +#define LUMIERA_ERROR_HPP_ #include #include "nobugcfg.h" #include "lib/error.h" -namespace cinelerra +namespace lumiera { using std::string; /** error-ID for unspecified exceptions */ - CINELERRA_ERROR_DECLARE(EXCEPTION); + LUMIERA_ERROR_DECLARE(EXCEPTION); /** * Interface and Baseclass of all Exceptions thrown - * from within cinelerra (C++) code. Common operations + * from within Lumiera (C++) code. Common operations * for getting an diagnostic message and for obtaining * the root cause, i.e. the first exception encountered * in a chain of exceptions. @@ -48,9 +48,9 @@ namespace cinelerra class Error : public std::exception { public: - Error (string description="", const char* id=CINELERRA_ERROR_EXCEPTION) throw(); + Error (string description="", const char* id=LUMIERA_ERROR_EXCEPTION) throw(); Error (std::exception& cause, - string description="", const char* id=CINELERRA_ERROR_EXCEPTION) throw(); + string description="", const char* id=LUMIERA_ERROR_EXCEPTION) throw(); Error (const Error&) throw(); virtual ~Error () throw() {}; @@ -58,7 +58,7 @@ namespace cinelerra /** yield a diagnostic message characterizing the problem */ virtual const char* what () const throw(); - /** the internal cinelerra-error-ID (was set as C-errorstate in ctor) */ + /** the internal Lumiera-error-ID (was set as C-errorstate in ctor) */ const char* getID () const throw() { return this->id_; } /** extract the message to be displayed for the user */ @@ -80,7 +80,7 @@ namespace cinelerra private: - const char* id_; ///< an CINELERRA_ERROR id, which is set as errorstate on construction + const char* id_; ///< an LUMIERA_ERROR id, which is set as errorstate on construction string msg_; ///< friendly message intended for users (to be localized) string desc_; ///< detailed description of the error situation for the developers mutable string what_; ///< buffer for generating the detailed description on demand @@ -105,68 +105,68 @@ namespace cinelerra * can be considered a severe design flaw; we can just * add some diagnostics prior to halting. */ - void cinelerra_unexpectedException () throw(); + void lumiera_unexpectedException () throw(); /** throw an error::Fatal indicating "assertion failure" */ void assertion_terminate (const string& location); /* constants to be used as error IDs */ - CINELERRA_ERROR_DECLARE (LOGIC ); ///< contradiction to internal logic assumptions detected - CINELERRA_ERROR_DECLARE (FATAL ); ///< unable to cope with, internal logic floundered - CINELERRA_ERROR_DECLARE (CONFIG ); ///< execution aborted due to misconfiguration - CINELERRA_ERROR_DECLARE (STATE ); ///< unforeseen internal state - CINELERRA_ERROR_DECLARE (INVALID ); ///< invalid input or parameters encountered - CINELERRA_ERROR_DECLARE (EXTERNAL ); ///< failure in external service the application relies on - CINELERRA_ERROR_DECLARE (ASSERTION); ///< assertion failure + LUMIERA_ERROR_DECLARE (LOGIC ); ///< contradiction to internal logic assumptions detected + LUMIERA_ERROR_DECLARE (FATAL ); ///< unable to cope with, internal logic floundered + LUMIERA_ERROR_DECLARE (CONFIG ); ///< execution aborted due to misconfiguration + LUMIERA_ERROR_DECLARE (STATE ); ///< unforeseen internal state + LUMIERA_ERROR_DECLARE (INVALID ); ///< invalid input or parameters encountered + LUMIERA_ERROR_DECLARE (EXTERNAL ); ///< failure in external service the application relies on + LUMIERA_ERROR_DECLARE (ASSERTION); ///< assertion failure /** Macro for creating derived exception classes properly - * integrated into cinelerra's exception hierarchy. Using + * integrated into Lumiera's exception hierarchy. Using * this macro asures that the new class will get the full * set of constructors and behaviour common to all exception * classes, so it should be used when creating an derived * exception type for more then stricly local purposes */ -#define CINELERRA_EXCEPTION_DECLARE(CLASS, PARENT, _ID_) \ - class CLASS : public PARENT \ - { \ - public: \ - CLASS (std::string description="", \ - const char* id=_ID_) throw() \ - : PARENT (description, id) {} \ - \ - CLASS (std::exception& cause, \ - std::string description="", \ - const char* id=_ID_) throw() \ - : PARENT (cause, description, id) {} \ +#define LUMIERA_EXCEPTION_DECLARE(CLASS, PARENT, _ID_) \ + class CLASS : public PARENT \ + { \ + public: \ + CLASS (std::string description="", \ + const char* id=_ID_) throw() \ + : PARENT (description, id) {} \ + \ + CLASS (std::exception& cause, \ + std::string description="", \ + const char* id=_ID_) throw() \ + : PARENT (cause, description, id) {} \ }; - //---------------------------CLASS-----PARENT--ID---------------------- - CINELERRA_EXCEPTION_DECLARE (Logic, Error, CINELERRA_ERROR_LOGIC); - CINELERRA_EXCEPTION_DECLARE (Fatal, Logic, CINELERRA_ERROR_FATAL); - CINELERRA_EXCEPTION_DECLARE (Config, Error, CINELERRA_ERROR_CONFIG); - CINELERRA_EXCEPTION_DECLARE (State, Error, CINELERRA_ERROR_STATE); - CINELERRA_EXCEPTION_DECLARE (Invalid, Error, CINELERRA_ERROR_INVALID); - CINELERRA_EXCEPTION_DECLARE (External, Error, CINELERRA_ERROR_EXTERNAL); + //-------------------------CLASS-----PARENT--ID---------------------- + LUMIERA_EXCEPTION_DECLARE (Logic, Error, LUMIERA_ERROR_LOGIC); + LUMIERA_EXCEPTION_DECLARE (Fatal, Logic, LUMIERA_ERROR_FATAL); + LUMIERA_EXCEPTION_DECLARE (Config, Error, LUMIERA_ERROR_CONFIG); + LUMIERA_EXCEPTION_DECLARE (State, Error, LUMIERA_ERROR_STATE); + LUMIERA_EXCEPTION_DECLARE (Invalid, Error, LUMIERA_ERROR_INVALID); + LUMIERA_EXCEPTION_DECLARE (External, Error, LUMIERA_ERROR_EXTERNAL); } // namespace error -} // namespace cinelerra +} // namespace lumiera /****************************************************** * if NoBug is used, redefine some macros - * to rather throw Cinelerra Errors instead of aborting + * to rather throw Lumiera Errors instead of aborting */ #ifdef NOBUG_ABORT #undef NOBUG_ABORT #define CIN_NOBUG_LOCATION \ std::string (NOBUG_BASENAME(__FILE__)) +":"+ NOBUG_STRINGIZE(__LINE__) + ", function " + __func__ #define NOBUG_ABORT \ - cinelerra::error::assertion_terminate (CIN_NOBUG_LOCATION); + lumiera::error::assertion_terminate (CIN_NOBUG_LOCATION); #endif -#endif // CINELERRA_ERROR_HPP_ +#endif // LUMIERA_ERROR_HPP_ diff --git a/src/common/factory.hpp b/src/common/factory.hpp index a4b953b3a..5645cfba6 100644 --- a/src/common/factory.hpp +++ b/src/common/factory.hpp @@ -21,14 +21,14 @@ */ -#ifndef CINELERRA_FACTORY_H -#define CINELERRA_FACTORY_H +#ifndef LUMIERA_FACTORY_H +#define LUMIERA_FACTORY_H #include -namespace cinelerra +namespace lumiera { namespace factory { @@ -141,5 +141,5 @@ namespace cinelerra using factory::Factory; -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/src/common/multithread.hpp b/src/common/multithread.hpp index cc6eca1c6..1dbbac519 100644 --- a/src/common/multithread.hpp +++ b/src/common/multithread.hpp @@ -23,21 +23,21 @@ -#ifndef CINELERRA_MULTITHREAD_H -#define CINELERRA_MULTITHREAD_H +#ifndef LUMIERA_MULTITHREAD_H +#define LUMIERA_MULTITHREAD_H #include "nobugcfg.h" -namespace cinelerra +namespace lumiera { /** * Interface/Policy for managing parallelism issues. * Basically everything is forwarded to the corresponding backend functions, - * because managing threads and locking belongs to the cinelerra backend layer. + * because managing threads and locking belongs to the Lumiera backend layer. * - * @todo actually implement this policy using the cinelerra databackend. + * @todo actually implement this policy using the Lumiera databackend. */ struct Thread { @@ -52,5 +52,5 @@ namespace cinelerra }; -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/src/common/singleton.hpp b/src/common/singleton.hpp index 9f149214f..c5de1474d 100644 --- a/src/common/singleton.hpp +++ b/src/common/singleton.hpp @@ -30,7 +30,7 @@ ** e.g. sometimes we want to include a hook for injecting Test Mock instances. ** ** You'll find the default Policies in singletonfactory.hpp and the default - ** definition of type cinelerra::singleton in singletonpreconfigure.hpp + ** definition of type lumiera::singleton in singletonpreconfigure.hpp ** ** @see SingletonFactory ** @see singleton::StaticCreate @@ -40,8 +40,8 @@ */ -#ifndef CINELERRA_SINGLETON_H -#define CINELERRA_SINGLETON_H +#ifndef LUMIERA_SINGLETON_H +#define LUMIERA_SINGLETON_H #include "common/singletonpolicies.hpp" diff --git a/src/common/singletonfactory.hpp b/src/common/singletonfactory.hpp index 319722fcf..026b6990e 100644 --- a/src/common/singletonfactory.hpp +++ b/src/common/singletonfactory.hpp @@ -31,8 +31,8 @@ This code is heavily inspired by -#ifndef CINELERRA_SINGLETONFACTORY_H -#define CINELERRA_SINGLETONFACTORY_H +#ifndef LUMIERA_SINGLETONFACTORY_H +#define LUMIERA_SINGLETONFACTORY_H #include "common/singletonpolicies.hpp" ///< several Policies usable together with SingletonFactory @@ -43,7 +43,7 @@ This code is heavily inspired by //#include -namespace cinelerra +namespace lumiera { /** @@ -136,5 +136,5 @@ namespace cinelerra ///// It seems this would either cost us much of the flexibility or get complicated ///// to a point where we could as well implement our own Depenency Injection Manager. -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/src/common/singletonpolicies.hpp b/src/common/singletonpolicies.hpp index 5ae31b939..f0b448305 100644 --- a/src/common/singletonpolicies.hpp +++ b/src/common/singletonpolicies.hpp @@ -31,8 +31,8 @@ This code is heavily inspired by -#ifndef CINELERRA_SINGLETONPOLICIES_H -#define CINELERRA_SINGLETONPOLICIES_H +#ifndef LUMIERA_SINGLETONPOLICIES_H +#define LUMIERA_SINGLETONPOLICIES_H #include "common/multithread.hpp" #include "common/error.hpp" @@ -40,11 +40,11 @@ This code is heavily inspired by #include -namespace cinelerra +namespace lumiera { namespace singleton { - /* == several Policies usable in conjunction with cinelerra::Singleton == */ + /* === several Policies usable in conjunction with lumiera::Singleton === */ /** * Policy placing the Singleton instance into a statically allocated buffer @@ -133,13 +133,13 @@ namespace cinelerra /** * Policy for handling multithreaded access to the singleton instance - * @todo actually implement this policy using the cinelerra databackend. + * @todo actually implement this policy using the Lumiera databackend. */ template struct Multithreaded { typedef volatile S VolatileType; - typedef cinelerra::Thread::Lock Lock; + typedef lumiera::Thread::Lock Lock; }; @@ -156,5 +156,5 @@ namespace cinelerra } // namespace singleton -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/src/common/singletonpreconfigure.hpp b/src/common/singletonpreconfigure.hpp index 9f3cfb8b2..e9b12e3d6 100644 --- a/src/common/singletonpreconfigure.hpp +++ b/src/common/singletonpreconfigure.hpp @@ -31,7 +31,7 @@ ** One reason why one wants special Singleton behaviour is testing: Without ** altering the executable, for running some tests we need to inject a Test Mock ** in place of some service object, so we can verify the behaviour of the code - ** using this service. For this, we mix cinelerra::test::MockInjector + ** using this service. For this, we mix lumiera::test::MockInjector ** into the actual Singleton type. ** ** @note we declare the specialisations into the target namespace @@ -41,13 +41,13 @@ */ -#ifndef CINELERRA_SINGLETONPRECONFIGURE_H -#define CINELERRA_SINGLETONPRECONFIGURE_H +#ifndef LUMIERA_SINGLETONPRECONFIGURE_H +#define LUMIERA_SINGLETONPRECONFIGURE_H #include "common/test/mockinjector.hpp" -namespace cinelerra +namespace lumiera { /** * Default Singleton configuration @@ -67,15 +67,15 @@ namespace cinelerra namespace test { class TestSingletonO; - using cinelerra::Singleton; + using lumiera::Singleton; } // namespace test -} // namespace cinelerra +} // namespace lumiera namespace backend_interface { class MediaAccessFacade; - using cinelerra::Singleton; + using lumiera::Singleton; } // namespace backend_interface @@ -87,7 +87,7 @@ namespace backend_interface /* Specialisation Definitions */ /* ************************** */ -namespace cinelerra +namespace lumiera { using test::MockInjector; @@ -104,7 +104,7 @@ namespace cinelerra : public MockInjector { }; -} // namespace cinelerra +} // namespace lumiera diff --git a/src/common/test/mockinjector.hpp b/src/common/test/mockinjector.hpp index 28258e91e..4daf78081 100644 --- a/src/common/test/mockinjector.hpp +++ b/src/common/test/mockinjector.hpp @@ -22,8 +22,8 @@ -#ifndef CINELERRA_TEST_MOCKINJECTOR_H -#define CINELERRA_TEST_MOCKINJECTOR_H +#ifndef LUMIERA_TEST_MOCKINJECTOR_H +#define LUMIERA_TEST_MOCKINJECTOR_H #include "common/singletonfactory.hpp" @@ -31,7 +31,7 @@ #include -namespace cinelerra +namespace lumiera { namespace test { @@ -90,5 +90,5 @@ namespace cinelerra } // namespace test -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/src/common/test/suite.cpp b/src/common/test/suite.cpp index c81c88097..897a7d04f 100644 --- a/src/common/test/suite.cpp +++ b/src/common/test/suite.cpp @@ -133,7 +133,7 @@ namespace test TRACE(test, "Test-Suite( groupID=%s )\n", groupID.c_str () ); if (!testcases.getGroup(groupID)) - throw cinelerra::error::Invalid (); + throw lumiera::error::Invalid (); //throw "empty testsuite"; /////////// TODO Errorhandling! } @@ -155,7 +155,7 @@ namespace test { PTestMap tests = testcases.getGroup(groupID_); if (!tests) - throw cinelerra::error::Invalid (); ///////// TODO: pass error description + throw lumiera::error::Invalid (); ///////// TODO: pass error description if (0 < cmdline.size()) { @@ -209,7 +209,7 @@ namespace test } catch (...) { - std::cout << "PLANNED ============= " << cinelerra_error() << "\n"; + std::cout << "PLANNED ============= " << lumiera_error() << "\n"; } std::cout << "END\n"; } diff --git a/src/common/time.cpp b/src/common/time.cpp index c208fcb46..a37979c6b 100644 --- a/src/common/time.cpp +++ b/src/common/time.cpp @@ -25,7 +25,7 @@ #include -namespace cinelerra +namespace lumiera { // TODO: dummy values; should be adjusted when switching to the real time implementation provided by the backend @@ -34,4 +34,4 @@ namespace cinelerra const Time Time::MIN = -std::numeric_limits::max(); -} // namespace cinelerra +} // namespace lumiera diff --git a/src/common/time.hpp b/src/common/time.hpp index c4fc22244..d065c3f36 100644 --- a/src/common/time.hpp +++ b/src/common/time.hpp @@ -21,13 +21,13 @@ */ -#ifndef CINELERRA_TIME_H -#define CINELERRA_TIME_H +#ifndef LUMIERA_TIME_H +#define LUMIERA_TIME_H #include -namespace cinelerra +namespace lumiera { @@ -56,5 +56,5 @@ namespace cinelerra -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/src/common/typelist.hpp b/src/common/typelist.hpp index 6d2720fcb..f358a605e 100644 --- a/src/common/typelist.hpp +++ b/src/common/typelist.hpp @@ -47,19 +47,19 @@ This code is heavily inspired by ** ** Interface for using this facility is the template Types(.....) for up to 20 Type parameters ** - ** @see cinelerra::visitor::Applicable usage example + ** @see lumiera::visitor::Applicable usage example ** @see typelisttest.cpp ** */ -#ifndef CINELERRA_TYPELIST_H -#define CINELERRA_TYPELIST_H +#ifndef LUMIERA_TYPELIST_H +#define LUMIERA_TYPELIST_H -namespace cinelerra +namespace lumiera { namespace typelist { @@ -116,5 +116,5 @@ namespace cinelerra } // namespace typelist -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/src/common/visitor.cpp b/src/common/visitor.cpp index f702f809b..91b195623 100644 --- a/src/common/visitor.cpp +++ b/src/common/visitor.cpp @@ -23,7 +23,7 @@ #include "common/visitor.hpp" -namespace cinelerra +namespace lumiera { namespace visitor { @@ -32,4 +32,4 @@ namespace cinelerra } // namespace visitor -} // namespace cinelerra +} // namespace lumiera diff --git a/src/common/visitor.hpp b/src/common/visitor.hpp index 251254a88..837ddf713 100644 --- a/src/common/visitor.hpp +++ b/src/common/visitor.hpp @@ -37,7 +37,7 @@ Credits for many further implementation ideas go to /** @file visitor.hpp ** A library implementation of the Visitor Pattern taylored specifically - ** to cinelerra's needs within the Proc Layer. Visitor enables double dispatch + ** to Lumiera's needs within the Proc Layer. Visitor enables double dispatch ** calls, based both on the concrete type of some target object and the concrete type of ** a tool object being applied to this target. The code carrying out this tool application ** (and thus triggering the double dispatch) need not know any of these concret types and is @@ -73,8 +73,8 @@ Credits for many further implementation ideas go to -#ifndef CINELERRA_VISITOR_H -#define CINELERRA_VISITOR_H +#ifndef LUMIERA_VISITOR_H +#define LUMIERA_VISITOR_H #include "common/visitorpolicies.hpp" #include "common/visitordispatcher.hpp" @@ -82,7 +82,7 @@ Credits for many further implementation ideas go to #include "common/typelist.hpp" -namespace cinelerra +namespace lumiera { namespace visitor { @@ -229,5 +229,5 @@ namespace cinelerra } // namespace visitor -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/src/common/visitordispatcher.hpp b/src/common/visitordispatcher.hpp index 0be12b2df..dcc28391b 100644 --- a/src/common/visitordispatcher.hpp +++ b/src/common/visitordispatcher.hpp @@ -22,8 +22,8 @@ -#ifndef CINELERRA_VISITORDISPATCHER_H -#define CINELERRA_VISITORDISPATCHER_H +#ifndef LUMIERA_VISITORDISPATCHER_H +#define LUMIERA_VISITORDISPATCHER_H #include "common/error.hpp" #include "common/util.hpp" @@ -33,7 +33,7 @@ #include -namespace cinelerra +namespace lumiera { namespace visitor { @@ -211,5 +211,5 @@ namespace cinelerra } // namespace visitor -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/src/common/visitorpolicies.hpp b/src/common/visitorpolicies.hpp index 6b9f353a5..e59a2f5b2 100644 --- a/src/common/visitorpolicies.hpp +++ b/src/common/visitorpolicies.hpp @@ -22,20 +22,20 @@ /** @file visitorpolicies.hpp - ** Policies usable for configuring the cinelerra::visitor::Tool for different kinds of error handling. + ** Policies usable for configuring the lumiera::visitor::Tool for different kinds of error handling. ** @see buildertool.hpp for another flavor (calling and catch-all-function) ** */ -#ifndef CINELERRA_VISITORPOLICIES_H -#define CINELERRA_VISITORPOLICIES_H +#ifndef LUMIERA_VISITORPOLICIES_H +#define LUMIERA_VISITORPOLICIES_H #include "common/error.hpp" -namespace cinelerra +namespace lumiera { namespace visitor { @@ -65,7 +65,7 @@ namespace cinelerra RET onUnknown (TAR&) { - throw cinelerra::error::Config("unable to decide what tool operation to call"); + throw lumiera::error::Config("unable to decide what tool operation to call"); } }; @@ -73,5 +73,5 @@ namespace cinelerra } // namespace visitor -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/src/lib/condition.c b/src/lib/condition.c index 2b0bc28e8..7427b431d 100644 --- a/src/lib/condition.c +++ b/src/lib/condition.c @@ -30,8 +30,8 @@ * @param self is a pointer to the condition variable to be initialized * @return self as given */ -CinelerraCondition -cinelerra_condition_init (CinelerraCondition self) +LumieraCondition +lumiera_condition_init (LumieraCondition self) { if (self) { @@ -47,15 +47,15 @@ cinelerra_condition_init (CinelerraCondition self) * @param self is a pointer to the condition variable to be destroyed * @return self as given */ -CinelerraCondition -cinelerra_condition_destroy (CinelerraCondition self) +LumieraCondition +lumiera_condition_destroy (LumieraCondition self) { if (self) { if (pthread_mutex_destroy (&self->mutex)) - CINELERRA_DIE; + LUMIERA_DIE; else if (pthread_cond_destroy (&self->cond)) - CINELERRA_DIE; + LUMIERA_DIE; } return self; } diff --git a/src/lib/condition.h b/src/lib/condition.h index 73da3685f..b2fd76c63 100644 --- a/src/lib/condition.h +++ b/src/lib/condition.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef CINELERRA_CONDITION_H -#define CINELERRA_CONDITION_H +#ifndef LUMIERA_CONDITION_H +#define LUMIERA_CONDITION_H #include "lib/locking.h" @@ -33,21 +33,21 @@ * Condition variables. * */ -struct cinelerra_condition_struct +struct lumiera_condition_struct { pthread_cond_t cond; pthread_mutex_t mutex; }; -typedef struct cinelerra_condition_struct cinelerra_condition; -typedef cinelerra_condition* CinelerraCondition; +typedef struct lumiera_condition_struct lumiera_condition; +typedef lumiera_condition* LumieraCondition; -CinelerraCondition -cinelerra_condition_init (CinelerraCondition self); +LumieraCondition +lumiera_condition_init (LumieraCondition self); -CinelerraCondition -cinelerra_condition_destroy (CinelerraCondition self); +LumieraCondition +lumiera_condition_destroy (LumieraCondition self); /** @@ -55,14 +55,14 @@ cinelerra_condition_destroy (CinelerraCondition self); * @param self condition variable to be signaled, must be given, all errors are fatal */ static inline void -cinelerra_condition_signal (CinelerraCondition self) +lumiera_condition_signal (LumieraCondition self) { REQUIRE (self); if (pthread_mutex_lock (&self->mutex)) - CINELERRA_DIE; + LUMIERA_DIE; pthread_cond_signal (&self->cond); if (pthread_mutex_unlock (&self->mutex)) - CINELERRA_DIE; + LUMIERA_DIE; } /** @@ -70,14 +70,14 @@ cinelerra_condition_signal (CinelerraCondition self) * @param self condition variable to be signaled, must be given, all errors are fatal */ static inline void -cinelerra_condition_broadcast (CinelerraCondition self) +lumiera_condition_broadcast (LumieraCondition self) { REQUIRE (self); if (pthread_mutex_lock (&self->mutex)) - CINELERRA_DIE; + LUMIERA_DIE; pthread_cond_broadcast (&self->cond); if (pthread_mutex_unlock (&self->mutex)) - CINELERRA_DIE; + LUMIERA_DIE; } @@ -87,44 +87,44 @@ cinelerra_condition_broadcast (CinelerraCondition self) /** * conditionacquirer used to manage the state of a condition variable. */ -struct cinelerra_conditionacquirer_struct +struct lumiera_conditionacquirer_struct { - CinelerraCondition cond; - enum cinelerra_lockstate state; + LumieraCondition cond; + enum lumiera_lockstate state; }; -typedef struct cinelerra_conditionacquirer_struct cinelerra_conditionacquirer; -typedef struct cinelerra_conditionacquirer_struct* CinelerraConditionacquirer; +typedef struct lumiera_conditionacquirer_struct lumiera_conditionacquirer; +typedef struct lumiera_conditionacquirer_struct* LumieraConditionacquirer; /* helper function for nobug */ static inline void -cinelerra_conditionacquirer_ensureunlocked (CinelerraConditionacquirer self) +lumiera_conditionacquirer_ensureunlocked (LumieraConditionacquirer self) { - ENSURE (self->state == CINELERRA_UNLOCKED, "forgot to unlock the condition mutex"); + ENSURE (self->state == LUMIERA_UNLOCKED, "forgot to unlock the condition mutex"); } /* override with a macro to use the cleanup checker */ -#define cinelerra_conditionacquirer \ -cinelerra_conditionacquirer NOBUG_CLEANUP(cinelerra_conditionacquirer_ensureunlocked) +#define lumiera_conditionacquirer \ +lumiera_conditionacquirer NOBUG_CLEANUP(lumiera_conditionacquirer_ensureunlocked) /** * initialize a conditionacquirer state * @param self conditionacquirer to be initialized, must be an automatic variable * @param cond associated condition variable - * @param state initial state of the mutex, either CINELERRA_LOCKED or CINELERRA_UNLOCKED + * @param state initial state of the mutex, either LUMIERA_LOCKED or LUMIERA_UNLOCKED * @return self as given * errors are fatal */ -static inline CinelerraConditionacquirer -cinelerra_conditionacquirer_init (CinelerraConditionacquirer self, CinelerraCondition cond, enum cinelerra_lockstate state) +static inline LumieraConditionacquirer +lumiera_conditionacquirer_init (LumieraConditionacquirer self, LumieraCondition cond, enum lumiera_lockstate state) { REQUIRE (self); REQUIRE (cond); self->cond = cond; self->state = state; - if (state == CINELERRA_LOCKED) + if (state == LUMIERA_LOCKED) if (pthread_mutex_lock (&cond->mutex)) - CINELERRA_DIE; + LUMIERA_DIE; return self; } @@ -135,15 +135,15 @@ cinelerra_conditionacquirer_init (CinelerraConditionacquirer self, CinelerraCond * @param self conditionacquirer associated with a condition variable */ static inline void -cinelerra_conditionacquirer_lock (CinelerraConditionacquirer self) +lumiera_conditionacquirer_lock (LumieraConditionacquirer self) { REQUIRE (self); - REQUIRE (self->state == CINELERRA_UNLOCKED, "mutex already locked"); + REQUIRE (self->state == LUMIERA_UNLOCKED, "mutex already locked"); if (pthread_mutex_lock (&self->cond->mutex)) - CINELERRA_DIE; + LUMIERA_DIE; - self->state = CINELERRA_LOCKED; + self->state = LUMIERA_LOCKED; } @@ -153,10 +153,10 @@ cinelerra_conditionacquirer_lock (CinelerraConditionacquirer self) * @param self conditionacquirer associated with a condition variable */ static inline void -cinelerra_conditionacquirer_wait (CinelerraConditionacquirer self) +lumiera_conditionacquirer_wait (LumieraConditionacquirer self) { REQUIRE (self); - REQUIRE (self->state == CINELERRA_LOCKED, "mutex must be locked"); + REQUIRE (self->state == LUMIERA_LOCKED, "mutex must be locked"); pthread_cond_wait (&self->cond->cond, &self->cond->mutex); } @@ -167,13 +167,13 @@ cinelerra_conditionacquirer_wait (CinelerraConditionacquirer self) * @param self conditionacquirer associated with a condition variable */ static inline int -cinelerra_conditionacquirer_unlock (CinelerraConditionacquirer self) +lumiera_conditionacquirer_unlock (LumieraConditionacquirer self) { REQUIRE (self); - REQUIRE (self->state == CINELERRA_LOCKED, "mutex was not locked"); + REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked"); if (pthread_mutex_unlock (&self->cond->mutex)) - CINELERRA_DIE; - self->state = CINELERRA_UNLOCKED; + LUMIERA_DIE; + self->state = LUMIERA_UNLOCKED; } @@ -182,10 +182,10 @@ cinelerra_conditionacquirer_unlock (CinelerraConditionacquirer self) * @param self conditionacquirer associated with the condition variable to be signaled */ static inline void -cinelerra_conditionacquirer_signal (CinelerraConditionacquirer self) +lumiera_conditionacquirer_signal (LumieraConditionacquirer self) { REQUIRE (self); - REQUIRE (self->state == CINELERRA_LOCKED, "mutex was not locked"); + REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked"); pthread_cond_signal (&self->cond->cond); } @@ -195,10 +195,10 @@ cinelerra_conditionacquirer_signal (CinelerraConditionacquirer self) * @param self conditionacquirer associated with the condition variable to be signaled */ static inline int -cinelerra_conditionacquirer_broadcast (CinelerraConditionacquirer self) +lumiera_conditionacquirer_broadcast (LumieraConditionacquirer self) { REQUIRE (self); - REQUIRE (self->state == CINELERRA_LOCKED, "mutex was not locked"); + REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked"); pthread_cond_broadcast (&self->cond->cond); } diff --git a/src/lib/error.c b/src/lib/error.c index df881013b..81e24bad8 100644 --- a/src/lib/error.c +++ b/src/lib/error.c @@ -1,5 +1,5 @@ /* - error.c - Cinelerra Error handling + error.c - Lumiera Error handling Copyright (C) Lumiera.org 2008, Christian Thaeter @@ -24,41 +24,41 @@ #include "lib/error.h" /** - * @file C Error handling in Cinelerra. + * @file C Error handling in Lumiera. */ /* predefined errors */ -CINELERRA_ERROR_DEFINE (ERRNO, "errno"); +LUMIERA_ERROR_DEFINE (ERRNO, "errno"); /* Thread local storage */ -static pthread_key_t cinelerra_error_tls; -static pthread_once_t cinelerra_error_initialized = PTHREAD_ONCE_INIT; +static pthread_key_t lumiera_error_tls; +static pthread_once_t lumiera_error_initialized = PTHREAD_ONCE_INIT; static void -cinelerra_error_tls_init (void) +lumiera_error_tls_init (void) { - pthread_key_create (&cinelerra_error_tls, NULL); + pthread_key_create (&lumiera_error_tls, NULL); } /** * Set error state for the current thread. * If the error state of the current thread was cleared, then set it, else preserve the old state. - * @param nerr name of the error with 'CINELERRA_ERROR_' prefix (example: CINELERRA_ERROR_NO_MEMORY) + * @param nerr name of the error with 'LUMIERA_ERROR_' prefix (example: LUMIERA_ERROR_NO_MEMORY) * @return old state, that is NULL for success, when the state was cleared and a pointer to a pending * error when the error state was already set */ const char* -cinelerra_error_set (const char * nerr) +lumiera_error_set (const char * nerr) { - pthread_once (&cinelerra_error_initialized, cinelerra_error_tls_init); + pthread_once (&lumiera_error_initialized, lumiera_error_tls_init); - const char* err = pthread_getspecific (cinelerra_error_tls); + const char* err = pthread_getspecific (lumiera_error_tls); if (!err) - pthread_setspecific (cinelerra_error_tls, nerr); + pthread_setspecific (lumiera_error_tls, nerr); return err; } @@ -71,12 +71,12 @@ cinelerra_error_set (const char * nerr) * @return pointer to any pending error of this thread, NULL if no error is pending */ const char* -cinelerra_error () +lumiera_error () { - pthread_once (&cinelerra_error_initialized, cinelerra_error_tls_init); + pthread_once (&lumiera_error_initialized, lumiera_error_tls_init); - const char* err = pthread_getspecific (cinelerra_error_tls); + const char* err = pthread_getspecific (lumiera_error_tls); if (err) - pthread_setspecific (cinelerra_error_tls, NULL); + pthread_setspecific (lumiera_error_tls, NULL); return err; } diff --git a/src/lib/error.h b/src/lib/error.h index 322487de1..24c73f0a5 100644 --- a/src/lib/error.h +++ b/src/lib/error.h @@ -1,5 +1,5 @@ /* - error.h - Cinelerra Error handling + error.h - Lumiera Error handling Copyright (C) Lumiera.org 2008, Christian Thaeter @@ -18,8 +18,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef CINELERRA_ERROR_H -#define CINELERRA_ERROR_H +#ifndef LUMIERA_ERROR_H +#define LUMIERA_ERROR_H #ifdef __cplusplus extern "C" { @@ -31,7 +31,7 @@ extern "C" { #include /** - * @file C Error handling in Cinelerra, header. + * @file C Error handling in Lumiera, header. */ @@ -39,46 +39,46 @@ extern "C" { * Abort unconditionally with a 'Fatal Error!' message. * This macro is used whenever the program end up in a invalid state from which no runtime recovery is possible */ -#define CINELERRA_DIE do { NOBUG_ERROR(NOBUG_ON, "Fatal Error!"); abort(); } while(0) +#define LUMIERA_DIE do { NOBUG_ERROR(NOBUG_ON, "Fatal Error!"); abort(); } while(0) /** * Forward declare an error constant. * This macro eases the error declaration in header files - * @param err name of the error without the 'CINELERRA_ERROR_' prefix (example: NO_MEMORY) + * @param err name of the error without the 'LUMIERA_ERROR_' prefix (example: NO_MEMORY) */ -#define CINELERRA_ERROR_DECLARE(err) \ -extern const char* CINELERRA_ERROR_##err +#define LUMIERA_ERROR_DECLARE(err) \ +extern const char* LUMIERA_ERROR_##err /** * Definition and initialization of an error constant. * This macro eases the error definition in implementation files - * @param err name of the error without the 'CINELERRA_ERROR_' prefix (example: NO_MEMORY) + * @param err name of the error without the 'LUMIERA_ERROR_' prefix (example: NO_MEMORY) * @param msg message describing the error in plain english (example: "memory allocation failed") */ -#define CINELERRA_ERROR_DEFINE(err, msg) \ -const char* CINELERRA_ERROR_##err = "CINELERRA_ERROR_" #err ":" msg +#define LUMIERA_ERROR_DEFINE(err, msg) \ +const char* LUMIERA_ERROR_##err = "LUMIERA_ERROR_" #err ":" msg /** Helper macro to raise an error for the current thread. * This macro eases setting an error. It adds NoBug logging support to the low level error handling. * @param flag NoBug flag describing the subsystem where the error was raised - * @param err name of the error without the 'CINELERRA_ERROR_' prefix (example: NO_MEMORY) + * @param err name of the error without the 'LUMIERA_ERROR_' prefix (example: NO_MEMORY) */ -#define CINELERRA_ERROR_SET(flag, err) \ -(({ERROR (flag, "%s", strchr(CINELERRA_ERROR_##err, ':')+1);}), \ -cinelerra_error_set(CINELERRA_ERROR_##err)) +#define LUMIERA_ERROR_SET(flag, err) \ +(({ERROR (flag, "%s", strchr(LUMIERA_ERROR_##err, ':')+1);}), \ +lumiera_error_set(LUMIERA_ERROR_##err)) const char* -cinelerra_error_set (const char * err); +lumiera_error_set (const char * err); const char* -cinelerra_error (); +lumiera_error (); /* predefined errors */ -CINELERRA_ERROR_DECLARE (ERRNO); +LUMIERA_ERROR_DECLARE (ERRNO); #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* CINELERRA_ERROR_H */ +#endif /* LUMIERA_ERROR_H */ diff --git a/src/lib/framerate.c b/src/lib/framerate.c index 717bab4bb..d8a2fa830 100644 --- a/src/lib/framerate.c +++ b/src/lib/framerate.c @@ -26,5 +26,5 @@ */ -CINELERRA_ERROR_DEFINE(FRAMERATE_ILLEGAL_TIME, "invalid time given"); -CINELERRA_ERROR_DEFINE(FRAMERATE_ILLEGAL_FRAME, "invalid frame given"); +LUMIERA_ERROR_DEFINE(FRAMERATE_ILLEGAL_TIME, "invalid time given"); +LUMIERA_ERROR_DEFINE(FRAMERATE_ILLEGAL_FRAME, "invalid frame given"); diff --git a/src/lib/framerate.h b/src/lib/framerate.h index c7c9d2adc..6b050c86e 100644 --- a/src/lib/framerate.h +++ b/src/lib/framerate.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef CINELERRA_FRAMERATE_H -#define CINELERRA_FRAMERATE_H +#ifndef LUMIERA_FRAMERATE_H +#define LUMIERA_FRAMERATE_H #include @@ -36,37 +36,37 @@ * framerates are defined as a rational number * for example NTSC with 30000/1001fps */ -struct cinelerra_framerate_struct +struct lumiera_framerate_struct { unsigned n; //numerator unsigned d; //denominator }; -typedef struct cinelerra_framerate_struct cinelerra_framerate; -typedef cinelerra_framerate* CinelerraFramerate; +typedef struct lumiera_framerate_struct lumiera_framerate; +typedef lumiera_framerate* LumieraFramerate; -typedef signed long cinelerra_framepos; +typedef signed long lumiera_framepos; -CINELERRA_ERROR_DECLARE(FRAMERATE_ILLEGAL_TIME); -CINELERRA_ERROR_DECLARE(FRAMERATE_ILLEGAL_FRAME); +LUMIERA_ERROR_DECLARE(FRAMERATE_ILLEGAL_TIME); +LUMIERA_ERROR_DECLARE(FRAMERATE_ILLEGAL_FRAME); -#define CINELERRA_FRAMEPOS_ERROR LONG_MIN +#define LUMIERA_FRAMEPOS_ERROR LONG_MIN /** * Get the frame number of a given time at a given frame rate. * frame indexing starts with 1 * @param framerate is a pointer to the framerate used, defined as rational number. Must be given. - * @param time is a pointer to a cinelerra_time which shall be converted. - * @return frame at the given time or CINELERRA_FRAMEPOS_ERROR on error. + * @param time is a pointer to a lumiera_time which shall be converted. + * @return frame at the given time or LUMIERA_FRAMEPOS_ERROR on error. */ -static inline cinelerra_framepos -cinelerra_framerate_frame_get_time (const CinelerraFramerate framerate, CinelerraTime time) +static inline lumiera_framepos +lumiera_framerate_frame_get_time (const LumieraFramerate framerate, LumieraTime time) { REQUIRE (framerate); if (!time || time->tv_sec == (time_t)-1) { - cinelerra_error_set(CINELERRA_ERROR_FRAMERATE_ILLEGAL_TIME); - return CINELERRA_FRAMEPOS_ERROR; + lumiera_error_set(LUMIERA_ERROR_FRAMERATE_ILLEGAL_TIME); + return LUMIERA_FRAMEPOS_ERROR; } /* we add a magic microsecond for rounding, because of integer truncation frames may be calculated at most 1us earlier, @@ -79,21 +79,21 @@ cinelerra_framerate_frame_get_time (const CinelerraFramerate framerate, Cinelerr * Get the start time for a frame. * frame indexing starts with 1 * @param framerate is a pointer to the framerate used, defined as rational number. Must be given. - * @param time is a pointer to a cinelerra_time which shall take the result. + * @param time is a pointer to a lumiera_time which shall take the result. * @param frame frame number to be converted to time. This frame number must be greater than 0. * @return the pointer given in time or NULL on error (or when it was given as time). */ -static inline CinelerraTime -cinelerra_framerate_time_get_time_frame (const CinelerraFramerate framerate, - CinelerraTime time, - cinelerra_framepos frame) +static inline LumieraTime +lumiera_framerate_time_get_time_frame (const LumieraFramerate framerate, + LumieraTime time, + lumiera_framepos frame) { REQUIRE (framerate); if (time) { if (frame < 1) { - cinelerra_error_set(CINELERRA_ERROR_FRAMERATE_ILLEGAL_FRAME); + lumiera_error_set(LUMIERA_ERROR_FRAMERATE_ILLEGAL_FRAME); return NULL; } diff --git a/src/lib/locking.h b/src/lib/locking.h index 2cf7f3700..01ad8bb29 100644 --- a/src/lib/locking.h +++ b/src/lib/locking.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef CINELERRA_LOCKING_H -#define CINELERRA_LOCKING_H +#ifndef LUMIERA_LOCKING_H +#define LUMIERA_LOCKING_H #include #include @@ -37,12 +37,12 @@ * * */ -enum cinelerra_lockstate +enum lumiera_lockstate { - CINELERRA_UNLOCKED, - CINELERRA_LOCKED, - CINELERRA_RDLOCKED, - CINELERRA_WRLOCKED + LUMIERA_UNLOCKED, + LUMIERA_LOCKED, + LUMIERA_RDLOCKED, + LUMIERA_WRLOCKED }; #endif diff --git a/src/lib/mutex.c b/src/lib/mutex.c index b644c00ca..a08d89e51 100644 --- a/src/lib/mutex.c +++ b/src/lib/mutex.c @@ -31,8 +31,8 @@ * @param self is a pointer to the mutex to be initialized * @return self as given */ -CinelerraMutex -cinelerra_mutex_init (CinelerraMutex self) +LumieraMutex +lumiera_mutex_init (LumieraMutex self) { if (self) { @@ -46,13 +46,13 @@ cinelerra_mutex_init (CinelerraMutex self) * @param self is a pointer to the mutex to be destroyed * @return self as given */ -CinelerraMutex -cinelerra_mutex_destroy (CinelerraMutex self) +LumieraMutex +lumiera_mutex_destroy (LumieraMutex self) { if (self) { if (pthread_mutex_destroy (&self->mutex)) - CINELERRA_DIE; + LUMIERA_DIE; } return self; } diff --git a/src/lib/mutex.h b/src/lib/mutex.h index 4dc4bac92..ced7118e2 100644 --- a/src/lib/mutex.h +++ b/src/lib/mutex.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef CINELERRA_MUTEX_H -#define CINELERRA_MUTEX_H +#ifndef LUMIERA_MUTEX_H +#define LUMIERA_MUTEX_H #include "lib/locking.h" @@ -33,58 +33,58 @@ * Mutex. * */ -struct cinelerra_mutex_struct +struct lumiera_mutex_struct { pthread_mutex_t mutex; }; -typedef struct cinelerra_mutex_struct cinelerra_mutex; -typedef cinelerra_mutex* CinelerraMutex; +typedef struct lumiera_mutex_struct lumiera_mutex; +typedef lumiera_mutex* LumieraMutex; -CinelerraMutex -cinelerra_mutex_init (CinelerraMutex self); +LumieraMutex +lumiera_mutex_init (LumieraMutex self); -CinelerraMutex -cinelerra_mutex_destroy (CinelerraMutex self); +LumieraMutex +lumiera_mutex_destroy (LumieraMutex self); /** * mutexacquirer used to manage the state of a mutex variable. */ -struct cinelerra_mutexacquirer_struct +struct lumiera_mutexacquirer_struct { - CinelerraMutex mutex; - enum cinelerra_lockstate state; + LumieraMutex mutex; + enum lumiera_lockstate state; }; -typedef struct cinelerra_mutexacquirer_struct cinelerra_mutexacquirer; -typedef struct cinelerra_mutexacquirer_struct* CinelerraMutexacquirer; +typedef struct lumiera_mutexacquirer_struct lumiera_mutexacquirer; +typedef struct lumiera_mutexacquirer_struct* LumieraMutexacquirer; /* helper function for nobug */ static inline void -cinelerra_mutexacquirer_ensureunlocked (CinelerraMutexacquirer self) +lumiera_mutexacquirer_ensureunlocked (LumieraMutexacquirer self) { - ENSURE (self->state == CINELERRA_UNLOCKED, "forgot to unlock mutex"); + ENSURE (self->state == LUMIERA_UNLOCKED, "forgot to unlock mutex"); } /* override with a macro to use the cleanup checker */ -#define cinelerra_mutexacquirer \ -cinelerra_mutexacquirer NOBUG_CLEANUP(cinelerra_mutexacquirer_ensureunlocked) +#define lumiera_mutexacquirer \ +lumiera_mutexacquirer NOBUG_CLEANUP(lumiera_mutexacquirer_ensureunlocked) /** * initialize a mutexacquirer state without mutex. * @param self mutexacquirer to be initialized, must be an automatic variable * @return self as given - * This initialization is used when cinelerra_mutexacquirer_try_mutex shall be used later + * This initialization is used when lumiera_mutexacquirer_try_mutex shall be used later */ -static inline CinelerraMutexacquirer -cinelerra_mutexacquirer_init (CinelerraMutexacquirer self) +static inline LumieraMutexacquirer +lumiera_mutexacquirer_init (LumieraMutexacquirer self) { REQUIRE (self); self->mutex = NULL; - self->state = CINELERRA_UNLOCKED; + self->state = LUMIERA_UNLOCKED; return self; } @@ -93,20 +93,20 @@ cinelerra_mutexacquirer_init (CinelerraMutexacquirer self) * initialize a mutexacquirer state * @param self mutexacquirer to be initialized, must be an automatic variable * @param mutex associated mutex - * @param state initial state of the mutex, either CINELERRA_LOCKED or CINELERRA_UNLOCKED + * @param state initial state of the mutex, either LUMIERA_LOCKED or LUMIERA_UNLOCKED * @return self as given * errors are fatal */ -static inline CinelerraMutexacquirer -cinelerra_mutexacquirer_init_mutex (CinelerraMutexacquirer self, CinelerraMutex mutex, enum cinelerra_lockstate state) +static inline LumieraMutexacquirer +lumiera_mutexacquirer_init_mutex (LumieraMutexacquirer self, LumieraMutex mutex, enum lumiera_lockstate state) { REQUIRE (self); REQUIRE (mutex); self->mutex = mutex; self->state = state; - if (state == CINELERRA_LOCKED) + if (state == LUMIERA_LOCKED) if (pthread_mutex_lock (&mutex->mutex)) - CINELERRA_DIE; + LUMIERA_DIE; return self; } @@ -118,25 +118,25 @@ cinelerra_mutexacquirer_init_mutex (CinelerraMutexacquirer self, CinelerraMutex * @param self mutexacquirer associated with a mutex variable */ static inline void -cinelerra_mutexacquirer_lock (CinelerraMutexacquirer self) +lumiera_mutexacquirer_lock (LumieraMutexacquirer self) { REQUIRE (self); - REQUIRE (self->state == CINELERRA_UNLOCKED, "mutex already locked"); + REQUIRE (self->state == LUMIERA_UNLOCKED, "mutex already locked"); if (pthread_mutex_lock (&self->mutex->mutex)) - CINELERRA_DIE; + LUMIERA_DIE; - self->state = CINELERRA_LOCKED; + self->state = LUMIERA_LOCKED; } /** * get the state of a lock. * @param self mutexacquirer associated with a mutex variable - * @return CINELERRA_LOCKED when the mutex is locked by this thead + * @return LUMIERA_LOCKED when the mutex is locked by this thead */ -static inline enum cinelerra_lockstate -cinelerra_mutexacquirer_state (CinelerraMutexacquirer self) +static inline enum lumiera_lockstate +lumiera_mutexacquirer_state (LumieraMutexacquirer self) { REQUIRE (self); return self->state; @@ -148,23 +148,23 @@ cinelerra_mutexacquirer_state (CinelerraMutexacquirer self) * must not already be locked * @param self mutexacquirer associated with a mutex variable * @param mutex pointer to a mutex which should be tried - * @return CINELERRA_LOCKED when the mutex got locked + * @return LUMIERA_LOCKED when the mutex got locked */ -static inline enum cinelerra_lockstate -cinelerra_mutexacquirer_try_mutex (CinelerraMutexacquirer self, CinelerraMutex mutex) +static inline enum lumiera_lockstate +lumiera_mutexacquirer_try_mutex (LumieraMutexacquirer self, LumieraMutex mutex) { REQUIRE (self); - REQUIRE (self->state == CINELERRA_UNLOCKED, "mutex already locked"); + REQUIRE (self->state == LUMIERA_UNLOCKED, "mutex already locked"); self->mutex=mutex; switch (pthread_mutex_trylock (&self->mutex->mutex)) { case 0: - return self->state = CINELERRA_LOCKED; + return self->state = LUMIERA_LOCKED; case EBUSY: - return CINELERRA_UNLOCKED; + return LUMIERA_UNLOCKED; default: - CINELERRA_DIE; + LUMIERA_DIE; } } @@ -175,13 +175,13 @@ cinelerra_mutexacquirer_try_mutex (CinelerraMutexacquirer self, CinelerraMutex m * @param self mutexacquirer associated with a mutex variable */ static inline void -cinelerra_mutexacquirer_unlock (CinelerraMutexacquirer self) +lumiera_mutexacquirer_unlock (LumieraMutexacquirer self) { REQUIRE (self); - REQUIRE (self->state == CINELERRA_LOCKED, "mutex was not locked"); + REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked"); if (pthread_mutex_unlock (&self->mutex->mutex)) - CINELERRA_DIE; - self->state = CINELERRA_UNLOCKED; + LUMIERA_DIE; + self->state = LUMIERA_UNLOCKED; } #endif diff --git a/src/lib/plugin.c b/src/lib/plugin.c index f819f4a6a..87939533d 100644 --- a/src/lib/plugin.c +++ b/src/lib/plugin.c @@ -1,5 +1,5 @@ /* - plugin.c - Cinelerra Plugin loader + plugin.c - Lumiera Plugin loader Copyright (C) Lumiera.org 2008, Christian Thaeter @@ -34,48 +34,48 @@ /* TODO should be set by the build system to the actual plugin path */ -#define CINELERRA_PLUGIN_PATH "~/.cinelerra3/plugins:/usr/local/lib/cinelerra3/plugins:.libs" +#define LUMIERA_PLUGIN_PATH "~/.lumiera/plugins:/usr/local/lib/lumiera/plugins:.libs" -NOBUG_DEFINE_FLAG (cinelerra_plugin); +NOBUG_DEFINE_FLAG (lumiera_plugin); /* errors */ -CINELERRA_ERROR_DEFINE(PLUGIN_DLOPEN, "Could not open plugin"); -CINELERRA_ERROR_DEFINE(PLUGIN_HOOK, "Hook function failed"); -CINELERRA_ERROR_DEFINE(PLUGIN_NFILE, "No such plugin"); -CINELERRA_ERROR_DEFINE(PLUGIN_NIFACE, "No such interface"); -CINELERRA_ERROR_DEFINE(PLUGIN_REVISION, "Interface revision too old"); +LUMIERA_ERROR_DEFINE(PLUGIN_DLOPEN, "Could not open plugin"); +LUMIERA_ERROR_DEFINE(PLUGIN_HOOK, "Hook function failed"); +LUMIERA_ERROR_DEFINE(PLUGIN_NFILE, "No such plugin"); +LUMIERA_ERROR_DEFINE(PLUGIN_NIFACE, "No such interface"); +LUMIERA_ERROR_DEFINE(PLUGIN_REVISION, "Interface revision too old"); /* supported (planned) plugin types and their file extensions */ -enum cinelerra_plugin_type +enum lumiera_plugin_type { - CINELERRA_PLUGIN_NULL, - CINELERRA_PLUGIN_DYNLIB, - CINELERRA_PLUGIN_CSOURCE + LUMIERA_PLUGIN_NULL, + LUMIERA_PLUGIN_DYNLIB, + LUMIERA_PLUGIN_CSOURCE }; static const struct { const char* const ext; - enum cinelerra_plugin_type type; -} cinelerra_plugin_extensions [] = + enum lumiera_plugin_type type; +} lumiera_plugin_extensions [] = { - {"so", CINELERRA_PLUGIN_DYNLIB}, - {"o", CINELERRA_PLUGIN_DYNLIB}, - {"c", CINELERRA_PLUGIN_CSOURCE}, + {"so", LUMIERA_PLUGIN_DYNLIB}, + {"o", LUMIERA_PLUGIN_DYNLIB}, + {"c", LUMIERA_PLUGIN_CSOURCE}, /* extend here */ - {NULL, CINELERRA_PLUGIN_NULL} + {NULL, LUMIERA_PLUGIN_NULL} }; -struct cinelerra_plugin +struct lumiera_plugin { /* short name as queried ("effects/audio/normalize") used for sorting/finding */ const char* name; - /* long names as looked up ("/usr/local/lib/cinelerra3/plugins/effects/audio/normalize.so") */ + /* long names as looked up ("/usr/local/lib/lumiera/plugins/effects/audio/normalize.so") */ const char* pathname; /* use count for all interfaces of this plugin */ @@ -85,7 +85,7 @@ struct cinelerra_plugin time_t last; /* kind of plugin */ - enum cinelerra_plugin_type type; + enum lumiera_plugin_type type; /* dlopen handle */ void* handle; @@ -93,19 +93,19 @@ struct cinelerra_plugin /* global plugin registry */ -void* cinelerra_plugin_registry = NULL; +void* lumiera_plugin_registry = NULL; /* plugin operations are protected by one big mutex */ -pthread_mutex_t cinelerra_plugin_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t lumiera_plugin_mutex = PTHREAD_MUTEX_INITIALIZER; /** * the compare function for the registry tree. - * Compares the names of two struct cinelerra_plugin. + * Compares the names of two struct lumiera_plugin. * @return 0 if a and b are equal, just like strcmp. */ static int -cinelerra_plugin_name_cmp (const void* a, const void* b) +lumiera_plugin_name_cmp (const void* a, const void* b) { - return strcmp (((struct cinelerra_plugin*) a)->name, ((struct cinelerra_plugin*) b)->name); + return strcmp (((struct lumiera_plugin*) a)->name, ((struct lumiera_plugin*) b)->name); } /** @@ -113,21 +113,21 @@ cinelerra_plugin_name_cmp (const void* a, const void* b) * always succeeds or aborts */ void -cinelerra_init_plugin (void) +lumiera_init_plugin (void) { - NOBUG_INIT_FLAG (cinelerra_plugin); + NOBUG_INIT_FLAG (lumiera_plugin); } /** * Find and set pathname for the plugin. * Searches through given path for given plugin, trying to find the file's location in the filesystem. * If found, self->pathname will be set to the found plugin file. - * @param self The cinelerra_plugin to open look for. + * @param self The lumiera_plugin to open look for. * @param path The path to search trough (paths seperated by ":") * @return 0 on success. -1 on error, or if plugin not found in path. */ int -cinelerra_plugin_lookup (struct cinelerra_plugin* self, const char* path) +lumiera_plugin_lookup (struct lumiera_plugin* self, const char* path) { if (!path) return -1; @@ -146,22 +146,22 @@ cinelerra_plugin_lookup (struct cinelerra_plugin* self, const char* path) for (char* tok = strtok_r (tpath, ":", &tmp); tok; tok = strtok_r (NULL, ":", &tmp)) { /*for each extension*/ - for (int i = 0; cinelerra_plugin_extensions[i].ext; ++i) + for (int i = 0; lumiera_plugin_extensions[i].ext; ++i) { /* path/name.extension */ - int r = snprintf(pathname, 1024, "%s/%s.%s", tok, self->name, cinelerra_plugin_extensions[i].ext); + int r = snprintf(pathname, 1024, "%s/%s.%s", tok, self->name, lumiera_plugin_extensions[i].ext); if (r >= 1024) return -1; /*TODO error handling, name too long*/ - TRACE (cinelerra_plugin, "trying %s", pathname); + TRACE (lumiera_plugin, "trying %s", pathname); if (!access(pathname, R_OK)) { /* got it */ - TRACE (cinelerra_plugin, "found %s", pathname); + TRACE (lumiera_plugin, "found %s", pathname); self->pathname = strdup (pathname); - if (!self->pathname) CINELERRA_DIE; - self->type = cinelerra_plugin_extensions[i].type; + if (!self->pathname) LUMIERA_DIE; + self->type = lumiera_plugin_extensions[i].type; return 0; } } @@ -181,44 +181,44 @@ cinelerra_plugin_lookup (struct cinelerra_plugin* self, const char* path) * @return handle to the interface or NULL in case of a error. The application shall cast this handle to * the actual interface type. */ -struct cinelerra_interface* -cinelerra_interface_open (const char* name, const char* interface, size_t min_revision) +struct lumiera_interface* +lumiera_interface_open (const char* name, const char* interface, size_t min_revision) { - //REQUIRE (min_revision > sizeof(struct cinelerra_interface), "try to use an empty interface eh?"); + //REQUIRE (min_revision > sizeof(struct lumiera_interface), "try to use an empty interface eh?"); REQUIRE (interface, "interface name must be given"); - pthread_mutex_lock (&cinelerra_plugin_mutex); + pthread_mutex_lock (&lumiera_plugin_mutex); - struct cinelerra_plugin plugin; - struct cinelerra_plugin** found; + struct lumiera_plugin plugin; + struct lumiera_plugin** found; plugin.name = name; /* for searching */ - found = tsearch (&plugin, &cinelerra_plugin_registry, cinelerra_plugin_name_cmp); - if (!found) CINELERRA_DIE; + found = tsearch (&plugin, &lumiera_plugin_registry, lumiera_plugin_name_cmp); + if (!found) LUMIERA_DIE; if (*found == &plugin) { - NOTICE (cinelerra_plugin, "new plugin"); + NOTICE (lumiera_plugin, "new plugin"); /* now really create new item */ - *found = malloc (sizeof (struct cinelerra_plugin)); - if (!*found) CINELERRA_DIE; + *found = malloc (sizeof (struct lumiera_plugin)); + if (!*found) LUMIERA_DIE; if (name) /* NULL is main app, no lookup needed */ { - /*lookup for $CINELERRA_PLUGIN_PATH*/ + /*lookup for $LUMIERA_PLUGIN_PATH*/ (*found)->name = strdup (name); - if (!(*found)->name) CINELERRA_DIE; + if (!(*found)->name) LUMIERA_DIE; - if (!!cinelerra_plugin_lookup (*found, getenv("CINELERRA_PLUGIN_PATH")) -#ifdef CINELERRA_PLUGIN_PATH - /* else lookup for -DCINELERRA_PLUGIN_PATH */ - && !!cinelerra_plugin_lookup (*found, CINELERRA_PLUGIN_PATH) + if (!!lumiera_plugin_lookup (*found, getenv("LUMIERA_PLUGIN_PATH")) +#ifdef LUMIERA_PLUGIN_PATH + /* else lookup for -DLUMIERA_PLUGIN_PATH */ + && !!lumiera_plugin_lookup (*found, LUMIERA_PLUGIN_PATH) #endif ) { - CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_NFILE); + LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_NFILE); goto elookup; } } @@ -233,46 +233,46 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re PLANNED("if .so like then dlopen; else if .c like tcc compile"); TODO("factor dlopen and dlsym out"); - TRACE(cinelerra_plugin, "trying to open %s", (*found)->pathname); + TRACE(lumiera_plugin, "trying to open %s", (*found)->pathname); (*found)->handle = dlopen ((*found)->pathname, RTLD_LAZY|RTLD_LOCAL); if (!(*found)->handle) { - ERROR (cinelerra_plugin, "dlopen failed: %s", dlerror()); - CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_DLOPEN); + ERROR (lumiera_plugin, "dlopen failed: %s", dlerror()); + LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_DLOPEN); goto edlopen; } - /* if the plugin defines a 'cinelerra_plugin_init' function, we call it, must return 0 on success */ - int (*init)(void) = dlsym((*found)->handle, "cinelerra_plugin_init"); + /* if the plugin defines a 'lumiera_plugin_init' function, we call it, must return 0 on success */ + int (*init)(void) = dlsym((*found)->handle, "lumiera_plugin_init"); if (init && init()) { - //ERROR (cinelerra_plugin, "cinelerra_plugin_init failed: %s: %s", name, interface); - CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_HOOK); + //ERROR (lumiera_plugin, "lumiera_plugin_init failed: %s: %s", name, interface); + LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_HOOK); goto einit; } } /* we have the plugin, now get the interface descriptor */ - struct cinelerra_interface* ret; + struct lumiera_interface* ret; dlerror(); ret = dlsym ((*found)->handle, interface); const char *dlerr = dlerror(); - TRACE(cinelerra_plugin, "%s", dlerr); - TODO ("need some way to tell 'interface not provided by plugin', maybe cinelerra_plugin_error()?"); + TRACE(lumiera_plugin, "%s", dlerr); + TODO ("need some way to tell 'interface not provided by plugin', maybe lumiera_plugin_error()?"); if (dlerr) { - //ERROR (cinelerra_plugin, "plugin %s doesnt provide interface %s", name, interface); - CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_NIFACE); + //ERROR (lumiera_plugin, "plugin %s doesnt provide interface %s", name, interface); + LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_NIFACE); goto edlsym; } /* is the interface older than required? */ if (ret->size < min_revision) { - ERROR (cinelerra_plugin, "plugin %s provides older interface %s revision than required", name, interface); - CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_REVISION); + ERROR (lumiera_plugin, "plugin %s provides older interface %s revision than required", name, interface); + LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_REVISION); goto erevision; } @@ -281,8 +281,8 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re /* if the interface provides a 'open' function, call it now, must return 0 on success */ if (ret->open && ret->open()) { - ERROR (cinelerra_plugin, "open hook indicated an error"); - CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_HOOK); + ERROR (lumiera_plugin, "open hook indicated an error"); + LUMIERA_ERROR_SET (lumiera_plugin, PLUGIN_HOOK); goto eopen; } @@ -290,7 +290,7 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re (*found)->last = time (NULL); ret->use_count++; - pthread_mutex_unlock (&cinelerra_plugin_mutex); + pthread_mutex_unlock (&lumiera_plugin_mutex); return ret; /* Error cleanup */ @@ -304,8 +304,8 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re free ((char*)(*found)->name); free (*found); *found = &plugin; - tdelete (&plugin, &cinelerra_plugin_registry, cinelerra_plugin_name_cmp); - pthread_mutex_unlock (&cinelerra_plugin_mutex); + tdelete (&plugin, &lumiera_plugin_registry, lumiera_plugin_name_cmp); + pthread_mutex_unlock (&lumiera_plugin_mutex); return NULL; } @@ -315,17 +315,17 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re * @param ptr interface to be closed */ void -cinelerra_interface_close (void* ptr) +lumiera_interface_close (void* ptr) { - TRACE (cinelerra_plugin, "%p", ptr); + TRACE (lumiera_plugin, "%p", ptr); if(!ptr) return; - struct cinelerra_interface* self = (struct cinelerra_interface*) ptr; + struct lumiera_interface* self = (struct lumiera_interface*) ptr; - pthread_mutex_lock (&cinelerra_plugin_mutex); + pthread_mutex_lock (&lumiera_plugin_mutex); - struct cinelerra_plugin* plugin = self->plugin; + struct lumiera_plugin* plugin = self->plugin; plugin->use_count--; self->use_count--; @@ -339,16 +339,16 @@ cinelerra_interface_close (void* ptr) { TODO ("we dont want to close here, instead store time of recent use and make a expire run, already planned in my head"); - /* if the plugin defines a 'cinelerra_plugin_destroy' function, we call it */ - int (*destroy)(void) = dlsym(plugin->handle, "cinelerra_plugin_destroy"); + /* if the plugin defines a 'lumiera_plugin_destroy' function, we call it */ + int (*destroy)(void) = dlsym(plugin->handle, "lumiera_plugin_destroy"); if (destroy) destroy(); /* and now cleanup */ - tdelete (plugin, &cinelerra_plugin_registry, cinelerra_plugin_name_cmp); + tdelete (plugin, &lumiera_plugin_registry, lumiera_plugin_name_cmp); free ((char*)plugin->name); dlclose(plugin->handle); free (plugin); } - pthread_mutex_unlock (&cinelerra_plugin_mutex); + pthread_mutex_unlock (&lumiera_plugin_mutex); } diff --git a/src/lib/plugin.h b/src/lib/plugin.h index 45a22bf29..f8916ae96 100644 --- a/src/lib/plugin.h +++ b/src/lib/plugin.h @@ -18,8 +18,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef CINELERRA_PLUGIN_H -#define CINELERRA_PLUGIN_H +#ifndef LUMIERA_PLUGIN_H +#define LUMIERA_PLUGIN_H #ifdef __cplusplus extern "C" { @@ -37,55 +37,55 @@ extern "C" { */ -NOBUG_DECLARE_FLAG (cinelerra_plugin); +NOBUG_DECLARE_FLAG (lumiera_plugin); /* tool macros*/ -#define CINELERRA_INTERFACE_TYPE(name, version) struct cinelerra_interface_##name##_##version -#define CINELERRA_INTERFACE_CAST(name, version) (CINELERRA_INTERFACE_TYPE(name, version)*) +#define LUMIERA_INTERFACE_TYPE(name, version) struct lumiera_interface_##name##_##version +#define LUMIERA_INTERFACE_CAST(name, version) (LUMIERA_INTERFACE_TYPE(name, version)*) /* Interface definition */ -#define CINELERRA_INTERFACE(name, version, ...) \ -CINELERRA_INTERFACE_TYPE(name, version) \ +#define LUMIERA_INTERFACE(name, version, ...) \ +LUMIERA_INTERFACE_TYPE(name, version) \ { \ - struct cinelerra_interface interface_header_; \ + struct lumiera_interface interface_header_; \ __VA_ARGS__ \ } -#define CINELERRA_INTERFACE_PROTO(ret, name, params) ret (*name) params; +#define LUMIERA_INTERFACE_PROTO(ret, name, params) ret (*name) params; /* Interface instantiation */ -#define CINELERRA_INTERFACE_IMPLEMENT(iname, version, name, open, close, ...) \ -CINELERRA_INTERFACE_TYPE(iname, version) name##_##version = \ -{ \ - { \ - version, \ - sizeof(CINELERRA_INTERFACE_TYPE(iname, version)), \ - NULL, \ - 0, \ - open, \ - close \ - }, \ - __VA_ARGS__ \ +#define LUMIERA_INTERFACE_IMPLEMENT(iname, version, name, open, close, ...) \ +LUMIERA_INTERFACE_TYPE(iname, version) name##_##version = \ +{ \ + { \ + version, \ + sizeof(LUMIERA_INTERFACE_TYPE(iname, version)), \ + NULL, \ + 0, \ + open, \ + close \ + }, \ + __VA_ARGS__ \ } /* internally used */ -struct cinelerra_plugin; +struct lumiera_plugin; /** * This is the header for any interface exported by plugins. * Real interfaces append their functions at the end. There are few standard functions on each Interface * Every function is required to be implemnted. */ -struct cinelerra_interface +struct lumiera_interface { /// interface version number unsigned version; /// size of the full structure is used to determine the revision (adding a new function increments the size) size_t size; /// back reference to plugin - struct cinelerra_plugin* plugin; + struct lumiera_plugin* plugin; /// incremented for each user of this interface and decremented when closed unsigned use_count; @@ -96,15 +96,15 @@ struct cinelerra_interface }; void -cinelerra_init_plugin (void); +lumiera_init_plugin (void); -struct cinelerra_interface* -cinelerra_interface_open (const char* plugin, const char* name, size_t min_revision); +struct lumiera_interface* +lumiera_interface_open (const char* plugin, const char* name, size_t min_revision); void -cinelerra_interface_close (void* self); +lumiera_interface_close (void* self); /** * Tries to unload a plugin. @@ -113,24 +113,24 @@ cinelerra_interface_close (void* self); * @return 0 on success, else the number if users which keeping the plugin loaded */ int -cinelerra_plugin_unload (const char* plugin); +lumiera_plugin_unload (const char* plugin); /** * Tries to unload plugins which are not in use. - * Calls cinelerra_plugin_unload() for each Plugin which is not used for more than age seconds. + * Calls lumiera_plugin_unload() for each Plugin which is not used for more than age seconds. * This function might be infrequently called by the scheduler to remove things which are not needed. * @param age timeout in seconds when to unload plugins */ void -cinelerra_plugin_expire (time_t age); +lumiera_plugin_expire (time_t age); -CINELERRA_ERROR_DECLARE(PLUGIN_DLOPEN); -CINELERRA_ERROR_DECLARE(PLUGIN_HOOK); -CINELERRA_ERROR_DECLARE(PLUGIN_NFILE); -CINELERRA_ERROR_DECLARE(PLUGIN_NIFACE); -CINELERRA_ERROR_DECLARE(PLUGIN_REVISION); +LUMIERA_ERROR_DECLARE(PLUGIN_DLOPEN); +LUMIERA_ERROR_DECLARE(PLUGIN_HOOK); +LUMIERA_ERROR_DECLARE(PLUGIN_NFILE); +LUMIERA_ERROR_DECLARE(PLUGIN_NIFACE); +LUMIERA_ERROR_DECLARE(PLUGIN_REVISION); #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* CINELERRA_PLUGIN_H */ +#endif /* LUMIERA_PLUGIN_H */ diff --git a/src/lib/references.c b/src/lib/references.c index a4c5eb247..ad4f9562f 100644 --- a/src/lib/references.c +++ b/src/lib/references.c @@ -40,17 +40,17 @@ * @param dtor destructor function which will be called on obj when the last strong reference gets deleted * @return self as given */ -CinelerraReference -cinelerra_reference_strong_init_once (CinelerraReference self, void* obj, void (*dtor)(void*)) +LumieraReference +lumiera_reference_strong_init_once (LumieraReference self, void* obj, void (*dtor)(void*)) { - CinelerraReftarget target = malloc (sizeof(cinelerra_reftarget)); - if (!target) CINELERRA_DIE; + LumieraReftarget target = malloc (sizeof(lumiera_reftarget)); + if (!target) LUMIERA_DIE; target->object = obj; target->dtor = dtor; target->strong_cnt = 1; target->weak_cnt = 0; - cinelerra_mutex_init (&target->lock); + lumiera_mutex_init (&target->lock); self->object = obj; self->target = target; @@ -66,16 +66,16 @@ cinelerra_reference_strong_init_once (CinelerraReference self, void* obj, void ( * @return self as given * destroying a reference is not thread safe as far as 2 threads try to concurrently destroy it! */ -CinelerraReference -cinelerra_reference_destroy (CinelerraReference self) +LumieraReference +lumiera_reference_destroy (LumieraReference self) { - CinelerraReftarget target = self->target; + LumieraReftarget target = self->target; /* defensive, lets detect errors if anything still tries to use this reference */ self->target = NULL; - cinelerra_mutexacquirer lock; - cinelerra_mutexacquirer_init_mutex (&lock, &target->lock, CINELERRA_LOCKED); + lumiera_mutexacquirer lock; + lumiera_mutexacquirer_init_mutex (&lock, &target->lock, LUMIERA_LOCKED); if (self->object) { @@ -89,8 +89,8 @@ cinelerra_reference_destroy (CinelerraReference self) if (!target->weak_cnt) { /* no weak refs either, destroy it */ - cinelerra_mutexacquirer_unlock (&lock); - cinelerra_mutex_destroy (&target->lock); + lumiera_mutexacquirer_unlock (&lock); + lumiera_mutex_destroy (&target->lock); free (target); return self; } @@ -102,13 +102,13 @@ cinelerra_reference_destroy (CinelerraReference self) if (!--target->weak_cnt && !target->strong_cnt) { /* was last weak reference, and no strong refs left */ - cinelerra_mutexacquirer_unlock (&lock); - cinelerra_mutex_destroy (&target->lock); + lumiera_mutexacquirer_unlock (&lock); + lumiera_mutex_destroy (&target->lock); free (target); return self; } } - cinelerra_mutexacquirer_unlock (&lock); + lumiera_mutexacquirer_unlock (&lock); return self; } @@ -118,11 +118,11 @@ cinelerra_reference_destroy (CinelerraReference self) * @return self as strong reference (always for strong references) or NULL if source is an invalidated weak reference, * in the later case the reference is constructed as weak reference barely to allow it be destroyed */ -CinelerraReference -cinelerra_reference_strong_init (CinelerraReference self, CinelerraReference source) +LumieraReference +lumiera_reference_strong_init (LumieraReference self, LumieraReference source) { - cinelerra_mutexacquirer lock; - cinelerra_mutexacquirer_init_mutex (&lock, &source->target->lock, CINELERRA_LOCKED); + lumiera_mutexacquirer lock; + lumiera_mutexacquirer_init_mutex (&lock, &source->target->lock, LUMIERA_LOCKED); self->object = source->target->object; self->target = source->target; @@ -136,7 +136,7 @@ cinelerra_reference_strong_init (CinelerraReference self, CinelerraReference sou ++self->target->weak_cnt; self = NULL; } - cinelerra_mutexacquirer_unlock (&lock); + lumiera_mutexacquirer_unlock (&lock); return self; } @@ -145,11 +145,11 @@ cinelerra_reference_strong_init (CinelerraReference self, CinelerraReference sou * @param source reference to copy * @return self (always for strong references) or NULL if self is an invalidated weak reference */ -CinelerraReference -cinelerra_reference_weak_init (CinelerraReference self, CinelerraReference source) +LumieraReference +lumiera_reference_weak_init (LumieraReference self, LumieraReference source) { - cinelerra_mutexacquirer lock; - cinelerra_mutexacquirer_init_mutex (&lock, &source->target->lock, CINELERRA_LOCKED); + lumiera_mutexacquirer lock; + lumiera_mutexacquirer_init_mutex (&lock, &source->target->lock, LUMIERA_LOCKED); self->object = NULL; self->target = source->target; @@ -159,7 +159,7 @@ cinelerra_reference_weak_init (CinelerraReference self, CinelerraReference sourc /* already invalidated */ self = NULL; - cinelerra_mutexacquirer_unlock (&lock); + lumiera_mutexacquirer_unlock (&lock); return self; } @@ -169,14 +169,14 @@ cinelerra_reference_weak_init (CinelerraReference self, CinelerraReference sourc * do nothing if the referene is already weak * @return self or NULL if the final strong reference got removed, */ -CinelerraReference -cinelerra_reference_weaken (restrict CinelerraReference self) +LumieraReference +lumiera_reference_weaken (restrict LumieraReference self) { /* is this a strong reference? */ if (self->object) { - cinelerra_mutexacquirer lock; - cinelerra_mutexacquirer_init_mutex (&lock, &self->target->lock, CINELERRA_LOCKED); + lumiera_mutexacquirer lock; + lumiera_mutexacquirer_init_mutex (&lock, &self->target->lock, LUMIERA_LOCKED); self->object = NULL; ++self->target->weak_cnt; @@ -187,7 +187,7 @@ cinelerra_reference_weaken (restrict CinelerraReference self) self->target->object = NULL; self = NULL; } - cinelerra_mutexacquirer_unlock (&lock); + lumiera_mutexacquirer_unlock (&lock); } return self; } @@ -198,14 +198,14 @@ cinelerra_reference_weaken (restrict CinelerraReference self) * only references of object which are not already destroyed can be strengthened * @return self when successful, NULL when the object was already destroyed, 'self' stays a dead weak reference in that case */ -CinelerraReference -cinelerra_reference_strengthen (CinelerraReference self) +LumieraReference +lumiera_reference_strengthen (LumieraReference self) { /* is this a weak reference? */ if (!self->object) { - cinelerra_mutexacquirer lock; - cinelerra_mutexacquirer_init_mutex (&lock, &self->target->lock, CINELERRA_LOCKED); + lumiera_mutexacquirer lock; + lumiera_mutexacquirer_init_mutex (&lock, &self->target->lock, LUMIERA_LOCKED); if (self->target->object) { @@ -215,7 +215,7 @@ cinelerra_reference_strengthen (CinelerraReference self) } else self = NULL; - cinelerra_mutexacquirer_unlock (&lock); + lumiera_mutexacquirer_unlock (&lock); } return self; } diff --git a/src/lib/references.h b/src/lib/references.h index a7de3f7f0..3e00457e7 100644 --- a/src/lib/references.h +++ b/src/lib/references.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef CINELERRA_REFERENCES_H -#define CINELERRA_REFERENCES_H +#ifndef LUMIERA_REFERENCES_H +#define LUMIERA_REFERENCES_H #include @@ -29,77 +29,77 @@ */ -typedef struct cinelerra_reference_struct cinelerra_reference; -typedef cinelerra_reference* CinelerraReference; +typedef struct lumiera_reference_struct lumiera_reference; +typedef lumiera_reference* LumieraReference; #include "lib/error.h" #include "lib/mutex.h" /* Implementation detail */ -struct cinelerra_reftarget_struct +struct lumiera_reftarget_struct { void* object; void (*dtor)(void*); unsigned strong_cnt; /*when strong becomes 0 obj is destroyed, if weak is 0 destroy target too*/ unsigned weak_cnt; /*when weak becomes 0 and !obj and lock strong is 0, destroy target */ - cinelerra_mutex lock; + lumiera_mutex lock; }; -typedef struct cinelerra_reftarget_struct cinelerra_reftarget; -typedef cinelerra_reftarget* CinelerraReftarget; +typedef struct lumiera_reftarget_struct lumiera_reftarget; +typedef lumiera_reftarget* LumieraReftarget; /** * A reference pointing to some other object */ -struct cinelerra_reference_struct +struct lumiera_reference_struct { void* object; /*set for strong, NULL for weak*/ - CinelerraReftarget target; + LumieraReftarget target; }; -#define cinelerra_reference \ -cinelerra_reference NOBUG_CLEANUP(cinelerra_reference_ensuredestroyed) +#define lumiera_reference \ +lumiera_reference NOBUG_CLEANUP(lumiera_reference_ensuredestroyed) /* helper function for nobug */ static inline void -cinelerra_reference_ensuredestroyed (CinelerraReference self) +lumiera_reference_ensuredestroyed (LumieraReference self) { ENSURE (!self->target, "forgot to destroy reference"); } -CinelerraReference -cinelerra_reference_strong_init_once (CinelerraReference self, void* obj, void (*dtor)(void*)); +LumieraReference +lumiera_reference_strong_init_once (LumieraReference self, void* obj, void (*dtor)(void*)); -CinelerraReference -cinelerra_reference_destroy (CinelerraReference self); +LumieraReference +lumiera_reference_destroy (LumieraReference self); /** * Get object from a strong reference. * @return pointer to object, NULL if applied to a weak reference */ static inline void* -cinelerra_reference_get (CinelerraReference self) +lumiera_reference_get (LumieraReference self) { ENSURE (self->target, "illegal reference (not initialized or already destroyed?)"); return self->object; } -CinelerraReference -cinelerra_reference_strong_init (CinelerraReference self, CinelerraReference source); +LumieraReference +lumiera_reference_strong_init (LumieraReference self, LumieraReference source); -CinelerraReference -cinelerra_reference_weak_init (CinelerraReference self, CinelerraReference source); +LumieraReference +lumiera_reference_weak_init (LumieraReference self, LumieraReference source); -CinelerraReference -cinelerra_reference_weaken (restrict CinelerraReference self); +LumieraReference +lumiera_reference_weaken (restrict LumieraReference self); -CinelerraReference -cinelerra_reference_strengthen (CinelerraReference self); +LumieraReference +lumiera_reference_strengthen (LumieraReference self); #endif diff --git a/src/lib/rwlock.c b/src/lib/rwlock.c index d60223e3c..c7ee3a37d 100644 --- a/src/lib/rwlock.c +++ b/src/lib/rwlock.c @@ -23,8 +23,8 @@ #include #include "lib/rwlock.h" -CINELERRA_ERROR_DEFINE(RWLOCK_AGAIN, "maximum number of readlocks exceed"); -CINELERRA_ERROR_DEFINE(RWLOCK_DEADLOCK, "deadlock detected"); +LUMIERA_ERROR_DEFINE(RWLOCK_AGAIN, "maximum number of readlocks exceed"); +LUMIERA_ERROR_DEFINE(RWLOCK_DEADLOCK, "deadlock detected"); /** * @file Read/write locks. @@ -36,8 +36,8 @@ CINELERRA_ERROR_DEFINE(RWLOCK_DEADLOCK, "deadlock detected"); * @param self is a pointer to the rwlock to be initialized * @return self as given */ -CinelerraRWLock -cinelerra_rwlock_init (CinelerraRWLock self) +LumieraRWLock +lumiera_rwlock_init (LumieraRWLock self) { if (self) { @@ -51,13 +51,13 @@ cinelerra_rwlock_init (CinelerraRWLock self) * @param self is a pointer to the rwlock to be initialized * @return self on success or NULL at error */ -CinelerraRWLock -cinelerra_rwlock_destroy (CinelerraRWLock self) +LumieraRWLock +lumiera_rwlock_destroy (LumieraRWLock self) { if (self) { if (pthread_rwlock_destroy (&self->rwlock)) - CINELERRA_DIE; + LUMIERA_DIE; } return self; } @@ -69,44 +69,44 @@ cinelerra_rwlock_destroy (CinelerraRWLock self) * initialize a rwlockacquirer state * @param self rwlockacquirer to be initialized, must be an automatic variable * @param rwlock associated rwlock - * @param state initial state of the mutex, either CINELERRA_RDLOCKED, CINELERRA_WRLOCKED or CINELERRA_UNLOCKED + * @param state initial state of the mutex, either LUMIERA_RDLOCKED, LUMIERA_WRLOCKED or LUMIERA_UNLOCKED * @return self as given or NULL on error */ -CinelerraRWLockacquirer -cinelerra_rwlockacquirer_init (CinelerraRWLockacquirer self, CinelerraRWLock rwlock, enum cinelerra_lockstate state) +LumieraRWLockacquirer +lumiera_rwlockacquirer_init (LumieraRWLockacquirer self, LumieraRWLock rwlock, enum lumiera_lockstate state) { REQUIRE (self); REQUIRE (rwlock); - REQUIRE (state != CINELERRA_LOCKED, "illegal state for rwlock"); + REQUIRE (state != LUMIERA_LOCKED, "illegal state for rwlock"); self->rwlock = rwlock; self->state = state; switch (state) { - case CINELERRA_RDLOCKED: + case LUMIERA_RDLOCKED: switch (pthread_rwlock_rdlock (&rwlock->rwlock)) { case 0: break; case EAGAIN: - cinelerra_error_set (CINELERRA_ERROR_RWLOCK_AGAIN); + lumiera_error_set (LUMIERA_ERROR_RWLOCK_AGAIN); return NULL; case EDEADLK: - cinelerra_error_set (CINELERRA_ERROR_RWLOCK_DEADLOCK); + lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - CINELERRA_DIE; + LUMIERA_DIE; } - case CINELERRA_WRLOCKED: + case LUMIERA_WRLOCKED: switch (pthread_rwlock_wrlock (&rwlock->rwlock)) { case 0: break; case EDEADLK: - cinelerra_error_set (CINELERRA_ERROR_RWLOCK_DEADLOCK); + lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - CINELERRA_DIE; + LUMIERA_DIE; } default: break; @@ -121,27 +121,27 @@ cinelerra_rwlockacquirer_init (CinelerraRWLockacquirer self, CinelerraRWLock rwl * @param self rwlockacquirer associated with a rwlock * @return self as given or NULL on error */ -CinelerraRWLockacquirer -cinelerra_rwlockacquirer_rdlock (CinelerraRWLockacquirer self) +LumieraRWLockacquirer +lumiera_rwlockacquirer_rdlock (LumieraRWLockacquirer self) { REQUIRE (self); - REQUIRE (self->state == CINELERRA_UNLOCKED, "rwlock already locked"); + REQUIRE (self->state == LUMIERA_UNLOCKED, "rwlock already locked"); switch (pthread_rwlock_rdlock (&self->rwlock->rwlock)) { case 0: break; case EAGAIN: - cinelerra_error_set (CINELERRA_ERROR_RWLOCK_AGAIN); + lumiera_error_set (LUMIERA_ERROR_RWLOCK_AGAIN); return NULL; case EDEADLK: - cinelerra_error_set (CINELERRA_ERROR_RWLOCK_DEADLOCK); + lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - CINELERRA_DIE; + LUMIERA_DIE; } - self->state = CINELERRA_RDLOCKED; + self->state = LUMIERA_RDLOCKED; return self; } @@ -152,24 +152,24 @@ cinelerra_rwlockacquirer_rdlock (CinelerraRWLockacquirer self) * @param self rwlockacquirer associated with a rwlock * @return self as given or NULL on error */ -CinelerraRWLockacquirer -cinelerra_rwlockacquirer_wrlock (CinelerraRWLockacquirer self) +LumieraRWLockacquirer +lumiera_rwlockacquirer_wrlock (LumieraRWLockacquirer self) { REQUIRE (self); - REQUIRE (self->state == CINELERRA_UNLOCKED, "rwlock already locked"); + REQUIRE (self->state == LUMIERA_UNLOCKED, "rwlock already locked"); switch (pthread_rwlock_wrlock (&self->rwlock->rwlock)) { case 0: break; case EDEADLK: - cinelerra_error_set (CINELERRA_ERROR_RWLOCK_DEADLOCK); + lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - CINELERRA_DIE; + LUMIERA_DIE; } - self->state = CINELERRA_WRLOCKED; + self->state = LUMIERA_WRLOCKED; return self; } diff --git a/src/lib/rwlock.h b/src/lib/rwlock.h index 266887e24..922a05e7b 100644 --- a/src/lib/rwlock.h +++ b/src/lib/rwlock.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef CINELERRA_RWLOCK_H -#define CINELERRA_RWLOCK_H +#ifndef LUMIERA_RWLOCK_H +#define LUMIERA_RWLOCK_H #ifndef _GNU_SOURCE #error "This header must be included with _GNU_SOURCE or _POSIX_C_SOURCE >= 200112L defined" @@ -31,8 +31,8 @@ #include "lib/locking.h" -CINELERRA_ERROR_DECLARE(RWLOCK_AGAIN); -CINELERRA_ERROR_DECLARE(RWLOCK_DEADLOCK); +LUMIERA_ERROR_DECLARE(RWLOCK_AGAIN); +LUMIERA_ERROR_DECLARE(RWLOCK_DEADLOCK); /** * @file Read/write locks, header. @@ -43,20 +43,20 @@ CINELERRA_ERROR_DECLARE(RWLOCK_DEADLOCK); * RWLock. * */ -struct cinelerra_rwlock_struct +struct lumiera_rwlock_struct { pthread_rwlock_t rwlock; }; -typedef struct cinelerra_rwlock_struct cinelerra_rwlock; -typedef cinelerra_rwlock* CinelerraRWLock; +typedef struct lumiera_rwlock_struct lumiera_rwlock; +typedef lumiera_rwlock* LumieraRWLock; -CinelerraRWLock -cinelerra_rwlock_init (CinelerraRWLock self); +LumieraRWLock +lumiera_rwlock_init (LumieraRWLock self); -CinelerraRWLock -cinelerra_rwlock_destroy (CinelerraRWLock self); +LumieraRWLock +lumiera_rwlock_destroy (LumieraRWLock self); @@ -64,35 +64,35 @@ cinelerra_rwlock_destroy (CinelerraRWLock self); /** * rwlockacquirer used to manage the state of a rwlock variable. */ -struct cinelerra_rwlockacquirer_struct +struct lumiera_rwlockacquirer_struct { - CinelerraRWLock rwlock; - enum cinelerra_lockstate state; + LumieraRWLock rwlock; + enum lumiera_lockstate state; }; -typedef struct cinelerra_rwlockacquirer_struct cinelerra_rwlockacquirer; -typedef struct cinelerra_rwlockacquirer_struct* CinelerraRWLockacquirer; +typedef struct lumiera_rwlockacquirer_struct lumiera_rwlockacquirer; +typedef struct lumiera_rwlockacquirer_struct* LumieraRWLockacquirer; /* helper function for nobug */ static inline void -cinelerra_rwlockacquirer_ensureunlocked (CinelerraRWLockacquirer self) +lumiera_rwlockacquirer_ensureunlocked (LumieraRWLockacquirer self) { - ENSURE (self->state == CINELERRA_UNLOCKED, "forgot to unlock the rwlock mutex"); + ENSURE (self->state == LUMIERA_UNLOCKED, "forgot to unlock the rwlock mutex"); } /* override with a macro to use the cleanup checker */ -#define cinelerra_rwlockacquirer \ -cinelerra_rwlockacquirer NOBUG_CLEANUP(cinelerra_rwlockacquirer_ensureunlocked) +#define lumiera_rwlockacquirer \ +lumiera_rwlockacquirer NOBUG_CLEANUP(lumiera_rwlockacquirer_ensureunlocked) -CinelerraRWLockacquirer -cinelerra_rwlockacquirer_init (CinelerraRWLockacquirer self, CinelerraRWLock rwlock, enum cinelerra_lockstate state); +LumieraRWLockacquirer +lumiera_rwlockacquirer_init (LumieraRWLockacquirer self, LumieraRWLock rwlock, enum lumiera_lockstate state); -CinelerraRWLockacquirer -cinelerra_rwlockacquirer_rdlock (CinelerraRWLockacquirer self); +LumieraRWLockacquirer +lumiera_rwlockacquirer_rdlock (LumieraRWLockacquirer self); -CinelerraRWLockacquirer -cinelerra_rwlockacquirer_wrlock (CinelerraRWLockacquirer self); +LumieraRWLockacquirer +lumiera_rwlockacquirer_wrlock (LumieraRWLockacquirer self); /** @@ -101,13 +101,13 @@ cinelerra_rwlockacquirer_wrlock (CinelerraRWLockacquirer self); * @param self rwlockacquirer associated with a rwlock variable */ static inline void -cinelerra_rwlockacquirer_unlock (CinelerraRWLockacquirer self) +lumiera_rwlockacquirer_unlock (LumieraRWLockacquirer self) { REQUIRE (self); - REQUIRE (self->state != CINELERRA_UNLOCKED, "rwlock was not locked"); + REQUIRE (self->state != LUMIERA_UNLOCKED, "rwlock was not locked"); if (pthread_rwlock_unlock (&self->rwlock->rwlock)) - CINELERRA_DIE; - self->state = CINELERRA_UNLOCKED; + LUMIERA_DIE; + self->state = LUMIERA_UNLOCKED; } diff --git a/src/lib/time.c b/src/lib/time.c index 4566e44b5..83bfd9797 100644 --- a/src/lib/time.c +++ b/src/lib/time.c @@ -21,6 +21,6 @@ #include "lib/error.h" -CINELERRA_ERROR_DEFINE(TIME_OVERFLOW, "Time overflow"); -CINELERRA_ERROR_DEFINE(TIME_UNDERFLOW, "Time underflow"); -CINELERRA_ERROR_DEFINE(TIME_NEGATIVE, "Time negative"); +LUMIERA_ERROR_DEFINE(TIME_OVERFLOW, "Time overflow"); +LUMIERA_ERROR_DEFINE(TIME_UNDERFLOW, "Time underflow"); +LUMIERA_ERROR_DEFINE(TIME_NEGATIVE, "Time negative"); diff --git a/src/lib/time.h b/src/lib/time.h index d4c05b71c..26b698742 100644 --- a/src/lib/time.h +++ b/src/lib/time.h @@ -19,8 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef CINELERRA_TIME_H -#define CINELERRA_TIME_H +#ifndef LUMIERA_TIME_H +#define LUMIERA_TIME_H #include #include @@ -35,31 +35,31 @@ timehandling is a delicate business, be careful of precision errors accumulating - cinelerra_time is starting from zero, never becomes negative. + lumiera_time is starting from zero, never becomes negative. TODO explain how to use time */ /* over or underflow (tried to make a movie which has negative length? or more than some hundreds days?) */ -CINELERRA_ERROR_DECLARE(TIME_OVERFLOW); -CINELERRA_ERROR_DECLARE(TIME_UNDERFLOW); -CINELERRA_ERROR_DECLARE(TIME_NEGATIVE); +LUMIERA_ERROR_DECLARE(TIME_OVERFLOW); +LUMIERA_ERROR_DECLARE(TIME_UNDERFLOW); +LUMIERA_ERROR_DECLARE(TIME_NEGATIVE); /* Note: we measure time starting from zero, time never becomes negative (I didnt checked if the time types are signed) */ -typedef struct timeval cinelerra_time; -typedef cinelerra_time* CinelerraTime; +typedef struct timeval lumiera_time; +typedef lumiera_time* LumieraTime; /** * normalize time after operations. * used internally */ static inline void -cinelerra_time_normalize (CinelerraTime time) +lumiera_time_normalize (LumieraTime time) { REQUIRE (time); if (time->tv_usec >= 1000000) @@ -75,8 +75,8 @@ cinelerra_time_normalize (CinelerraTime time) * @param time Time to clear * @return time as given */ -static inline CinelerraTime -cinelerra_time_clear (CinelerraTime time) +static inline LumieraTime +lumiera_time_clear (LumieraTime time) { if(time) { @@ -91,14 +91,14 @@ cinelerra_time_clear (CinelerraTime time) * @param time Time to put current time into. * @return time as given */ -static inline CinelerraTime -cinelerra_time_current (CinelerraTime time) +static inline LumieraTime +lumiera_time_current (LumieraTime time) { if (time) { /* gettime should never ever fail in a correct program */ if (gettimeofday (time, NULL)) - CINELERRA_DIE; + LUMIERA_DIE; } return time; } @@ -110,8 +110,8 @@ cinelerra_time_current (CinelerraTime time) * @return time as given upon success, NULL if double time given was negative or given time didn't point * anywhere */ -static inline CinelerraTime -cinelerra_time_set_double (CinelerraTime time, double fp) +static inline LumieraTime +lumiera_time_set_double (LumieraTime time, double fp) { if (time) { @@ -125,7 +125,7 @@ cinelerra_time_set_double (CinelerraTime time, double fp) { time->tv_sec = (time_t)-1; time->tv_usec = (suseconds_t)-1; - cinelerra_error_set(CINELERRA_ERROR_TIME_NEGATIVE); + lumiera_error_set(LUMIERA_ERROR_TIME_NEGATIVE); } } return NULL; @@ -138,14 +138,14 @@ cinelerra_time_set_double (CinelerraTime time, double fp) * @param usec Microseconds to set * @param Time as given */ -static inline CinelerraTime -cinelerra_time_init (CinelerraTime time, time_t sec, suseconds_t usec) +static inline LumieraTime +lumiera_time_init (LumieraTime time, time_t sec, suseconds_t usec) { if (time) { time->tv_sec = sec; time->tv_usec = usec; - cinelerra_time_normalize (time); + lumiera_time_normalize (time); } return time; } @@ -156,7 +156,7 @@ cinelerra_time_init (CinelerraTime time, time_t sec, suseconds_t usec) * @return Seconds elapsed, -1 on error */ static inline time_t -cinelerra_time_sec (CinelerraTime time) +lumiera_time_sec (LumieraTime time) { if (time) return time->tv_sec; @@ -170,7 +170,7 @@ cinelerra_time_sec (CinelerraTime time) * @return Microseconds elapsed, -1 on error */ static inline suseconds_t -cinelerra_time_usec (CinelerraTime time) +lumiera_time_usec (LumieraTime time) { if (time) return time->tv_usec; @@ -184,7 +184,7 @@ cinelerra_time_usec (CinelerraTime time) * @return Floating point representation of time. NAN on error. */ static inline double -cinelerra_time_double_get (CinelerraTime time) +lumiera_time_double_get (LumieraTime time) { if (time) { @@ -204,8 +204,8 @@ cinelerra_time_double_get (CinelerraTime time) * @param src Time-source to copy from * @return dest as given */ -static inline CinelerraTime -cinelerra_time_copy (CinelerraTime dest, const CinelerraTime src) +static inline LumieraTime +lumiera_time_copy (LumieraTime dest, const LumieraTime src) { if (dest && src) { @@ -221,8 +221,8 @@ cinelerra_time_copy (CinelerraTime dest, const CinelerraTime src) * @param src Time to add to dest * @return dest as given, or NULL on overflow. */ -static inline CinelerraTime -cinelerra_time_add (CinelerraTime dest, const CinelerraTime src) +static inline LumieraTime +lumiera_time_add (LumieraTime dest, const LumieraTime src) { if (dest && src) { @@ -231,11 +231,11 @@ cinelerra_time_add (CinelerraTime dest, const CinelerraTime src) dest->tv_sec += src->tv_sec; dest->tv_usec += src->tv_usec; - cinelerra_time_normalize (dest); + lumiera_time_normalize (dest); if (dest->tv_sec < t) { - cinelerra_error_set (CINELERRA_ERROR_TIME_OVERFLOW); + lumiera_error_set (LUMIERA_ERROR_TIME_OVERFLOW); return NULL; } } @@ -248,8 +248,8 @@ cinelerra_time_add (CinelerraTime dest, const CinelerraTime src) * @param src Time to subtract from dest * @return dest as given, or NULL on underflow. */ -static inline CinelerraTime -cinelerra_time_sub (CinelerraTime dest, const CinelerraTime src) +static inline LumieraTime +lumiera_time_sub (LumieraTime dest, const LumieraTime src) { if (dest && src) { @@ -264,11 +264,11 @@ cinelerra_time_sub (CinelerraTime dest, const CinelerraTime src) dest->tv_usec += 1000000 - src->tv_usec; } - cinelerra_time_normalize (dest); + lumiera_time_normalize (dest); if (dest->tv_sec > t) { - cinelerra_error_set (CINELERRA_ERROR_TIME_UNDERFLOW); + lumiera_error_set (LUMIERA_ERROR_TIME_UNDERFLOW); return NULL; } } diff --git a/src/cinelerra.h b/src/lumiera.h similarity index 90% rename from src/cinelerra.h rename to src/lumiera.h index 30264a904..12b1578b9 100644 --- a/src/cinelerra.h +++ b/src/lumiera.h @@ -1,5 +1,5 @@ /* - CINELERRA.h - global definitions and common types + LUMIERA.h - global definitions and common types Copyright (C) Lumiera.org @@ -22,8 +22,8 @@ */ -#ifndef CINELERRA_H -#define CINELERRA_H +#ifndef LUMIERA_H +#define LUMIERA_H @@ -54,13 +54,13 @@ extern "C" { #include "common/error.hpp" -namespace cinelerra +namespace lumiera { /* additional global configuration goes here... */ -} // namespace cinelerra +} // namespace lumiera #endif /* ===================== (End) C++-Part ================= */ -#endif /*CINELERRA_H*/ +#endif /*LUMIERA_H*/ diff --git a/src/main.cpp b/src/main.cpp index 8d564ed87..398cdc3df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,11 +23,11 @@ #include -#include "cinelerra.h" +#include "lumiera.h" using std::cout; using std::endl; -using cinelerra::Appconfig; +using lumiera::Appconfig; int main (int argc, char* argv[]) diff --git a/src/nobugcfg.h b/src/nobugcfg.h index 2cd719a87..916f28663 100644 --- a/src/nobugcfg.h +++ b/src/nobugcfg.h @@ -27,7 +27,7 @@ ** The idea is that configuration and some globally used flag ** declarations are to be kept in one central location. Normally, ** this header will be included by appconfig.hpp, which in turn gets - ** included by cinelerra.h + ** included by lumiera.h ** @par Besides the usual guarded declarations, this header contains ** one section with the corresponding definitions. This section ** is to be called by appconfig.cpp only, which deals with application diff --git a/src/plugin/helloplugin.c b/src/plugin/helloplugin.c index 62a033f4e..d75f55f94 100644 --- a/src/plugin/helloplugin.c +++ b/src/plugin/helloplugin.c @@ -1,12 +1,12 @@ /* * hello.c - demonstrates how to build a standalone tool (C source) - * integrated into the SCons based build system of Cinelerra + * integrated into the SCons based build system of Lumiera */ #include int main(int argc, char* argv[]) { - printf("hello cinelerra world"); + printf("hello lumiera world"); return 0; } diff --git a/src/pre.hpp b/src/pre.hpp index 8c504c368..19717c2bb 100644 --- a/src/pre.hpp +++ b/src/pre.hpp @@ -33,8 +33,8 @@ ** @see mobject.hpp usage example */ -#ifndef CINELERRA_PRE_HPP -#define CINELERRA_PRE_HPP +#ifndef LUMIERA_PRE_HPP +#define LUMIERA_PRE_HPP #include #include @@ -44,8 +44,8 @@ #include #include -#include "cinelerra.h" +#include "lumiera.h" -#endif /*CINELERRA_PRE_HPP*/ +#endif /*LUMIERA_PRE_HPP*/ diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp index d97c2fd9e..99fd50670 100644 --- a/src/proc/asset.cpp +++ b/src/proc/asset.cpp @@ -111,7 +111,7 @@ namespace asset /**change the enablement status of this asset. */ bool - Asset::enable (bool on) throw(cinelerra::error::State) + Asset::enable (bool on) throw(lumiera::error::State) { if (on == this->enabled) return true; diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp index cec77bec4..0387e85ba 100644 --- a/src/proc/asset.hpp +++ b/src/proc/asset.hpp @@ -155,7 +155,7 @@ namespace asset /** origin or authorship id. * Can be a project abbreviation, a package id or just the authors nickname or UID. * This allows for the compnent name to be more generic (e.g. "blur"). - * Default for all assets provided by the core cinelerra-3 codebase is "cin3". + * Default for all assets provided by the core Lumiera codebase is "lumi". */ const string org; @@ -284,7 +284,7 @@ namespace asset * @return \c false if the state could not be changed * due to parent objects being disabled */ - bool enable (bool on=true) throw(cinelerra::error::State); + bool enable (bool on=true) throw(lumiera::error::State); }; diff --git a/src/proc/asset/db.hpp b/src/proc/asset/db.hpp index 9f33b01af..af31df9a3 100644 --- a/src/proc/asset/db.hpp +++ b/src/proc/asset/db.hpp @@ -87,7 +87,7 @@ namespace asset DB () : table() { } ~DB () {clear();} - friend class cinelerra::singleton::StaticCreate; + friend class lumiera::singleton::StaticCreate; public: @@ -125,7 +125,7 @@ namespace asset table.clear(); } - catch (cinelerra::Error& EX) + catch (lumiera::Error& EX) { WARN (oper, "Problems while clearing Asset registry: %s", EX.what()); } diff --git a/src/proc/asset/media.cpp b/src/proc/asset/media.cpp index 1610e822e..60a1ecd19 100644 --- a/src/proc/asset/media.cpp +++ b/src/proc/asset/media.cpp @@ -116,7 +116,7 @@ namespace asset } - cinelerra::Time + lumiera::Time Media::getLength() const { return len_; @@ -177,7 +177,7 @@ namespace asset MediaFactory::PType MediaFactory::operator() (const string& file, const Category& cat) { - Asset::Ident key(extractName(file), cat, "cin3", 1); + Asset::Ident key(extractName(file), cat, "lumi", 1); return operator() (key, file); } @@ -220,21 +220,21 @@ namespace asset * but rather part or a multichannel (compound) media */ shared_ptr - MediaFactory::operator() (asset::Media& mediaref) throw(cinelerra::error::Invalid) + MediaFactory::operator() (asset::Media& mediaref) throw(lumiera::error::Invalid) { if (mediaref.checkCompound()) - throw cinelerra::error::Invalid (str(format("Attempt to create a asset::Clip from the media %s, " - "which is not toplevel but rather part or a compound " - "(multichannel) media. Found parent Media %s.") - % string(mediaref) - % string(*mediaref.checkCompound())) - ,CINELERRA_ERROR_PART_OF_COMPOUND - ); + throw lumiera::error::Invalid (str(format("Attempt to create a asset::Clip from the media %s, " + "which is not toplevel but rather part or a compound " + "(multichannel) media. Found parent Media %s.") + % string(mediaref) + % string(*mediaref.checkCompound())) + ,LUMIERA_ERROR_PART_OF_COMPOUND + ); asset::Clip* pC = new asset::Clip (mediaref); return AssetManager::instance().getPtr (*pC); } - CINELERRA_ERROR_DEFINE (PART_OF_COMPOUND, "part of compound used as toplevel element"); + LUMIERA_ERROR_DEFINE (PART_OF_COMPOUND, "part of compound used as toplevel element"); diff --git a/src/proc/asset/media.hpp b/src/proc/asset/media.hpp index 67c6a31ca..ce43d6231 100644 --- a/src/proc/asset/media.hpp +++ b/src/proc/asset/media.hpp @@ -50,7 +50,7 @@ namespace asset class MediaFactory; class ProcPatt; - using cinelerra::Time; + using lumiera::Time; template<> @@ -137,7 +137,7 @@ namespace asset /** * Factory specialized for creating Media Asset objects. */ - class MediaFactory : public cinelerra::Factory + class MediaFactory : public lumiera::Factory { public: typedef shared_ptr PType; @@ -151,11 +151,11 @@ namespace asset PType operator() (const char* file, asset::Kind); shared_ptr - operator() (asset::Media& mediaref) throw(cinelerra::error::Invalid); + operator() (asset::Media& mediaref) throw(lumiera::error::Invalid); }; - CINELERRA_ERROR_DECLARE (PART_OF_COMPOUND); + LUMIERA_ERROR_DECLARE (PART_OF_COMPOUND); diff --git a/src/proc/asset/meta.hpp b/src/proc/asset/meta.hpp index e995f53a3..89500c226 100644 --- a/src/proc/asset/meta.hpp +++ b/src/proc/asset/meta.hpp @@ -90,7 +90,7 @@ namespace asset /** * Factory specialized for createing Metadata Asset objects. */ - class MetaFactory : public cinelerra::Factory + class MetaFactory : public lumiera::Factory { public: typedef shared_ptr PType; diff --git a/src/proc/asset/proc.hpp b/src/proc/asset/proc.hpp index 229f66fcd..b98fa8014 100644 --- a/src/proc/asset/proc.hpp +++ b/src/proc/asset/proc.hpp @@ -89,7 +89,7 @@ namespace asset /** * Factory specialized for createing Processor Asset objects. */ - class ProcFactory : public cinelerra::Factory + class ProcFactory : public lumiera::Factory { public: typedef shared_ptr PType; diff --git a/src/proc/asset/struct.hpp b/src/proc/asset/struct.hpp index 24cc5c053..96dd63001 100644 --- a/src/proc/asset/struct.hpp +++ b/src/proc/asset/struct.hpp @@ -91,7 +91,7 @@ namespace asset /** * Factory specialized for createing Structural Asset objects. */ - class StructFactory : public cinelerra::Factory + class StructFactory : public lumiera::Factory { public: typedef shared_ptr PType; diff --git a/src/proc/asset/unknown.cpp b/src/proc/asset/unknown.cpp index 25d91936c..b47a60113 100644 --- a/src/proc/asset/unknown.cpp +++ b/src/proc/asset/unknown.cpp @@ -48,19 +48,19 @@ namespace asset * try to access the "real" media it stands for. */ Media::PMedia - Unknown::getOrg() throw(cinelerra::error::Invalid) + Unknown::getOrg() throw(lumiera::error::Invalid) { UNIMPLEMENTED ("how to get at the original media from a »Unknown« placeholder"); if (1==0) - throw cinelerra::error::Invalid (str(format("Unable to locate original media " - "for ID=%s, filename=\"%s\".") - % string(this->ident) - % string(this->getFilename())) - ,CINELERRA_ERROR_ORIG_NOT_FOUND - ); + throw lumiera::error::Invalid (str(format("Unable to locate original media " + "for ID=%s, filename=\"%s\".") + % string(this->ident) + % string(this->getFilename())) + ,LUMIERA_ERROR_ORIG_NOT_FOUND + ); } - CINELERRA_ERROR_DEFINE (ORIG_NOT_FOUND, "Media refered by placeholder not found"); + LUMIERA_ERROR_DEFINE (ORIG_NOT_FOUND, "Media refered by placeholder not found"); diff --git a/src/proc/asset/unknown.hpp b/src/proc/asset/unknown.hpp index aa9cd6ec3..bcd0bda9f 100644 --- a/src/proc/asset/unknown.hpp +++ b/src/proc/asset/unknown.hpp @@ -32,7 +32,7 @@ namespace asset { - const cinelerra::Time DUMMY_TIME (25); ///< @todo solve konfig management + const lumiera::Time DUMMY_TIME (25); ///< @todo solve konfig management /** * Placeholder Asset for unknown or unavailable media source. @@ -47,11 +47,11 @@ namespace asset friend class MediaFactory; public: - virtual Media::PMedia getOrg() throw(cinelerra::error::Invalid); + virtual Media::PMedia getOrg() throw(lumiera::error::Invalid); }; - CINELERRA_ERROR_DECLARE (ORIG_NOT_FOUND); + LUMIERA_ERROR_DECLARE (ORIG_NOT_FOUND); diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp index bc6f42ecd..68843444a 100644 --- a/src/proc/assetmanager.cpp +++ b/src/proc/assetmanager.cpp @@ -38,8 +38,8 @@ using boost::format; using boost::bind; using util::for_each; -using cinelerra::Singleton; -using cinelerra::Thread; +using lumiera::Singleton; +using lumiera::Thread; namespace asset @@ -49,23 +49,23 @@ namespace asset * AssetManager error responses, caused by querying * invalid Asset IDs from the internal DB. */ - class IDErr : public cinelerra::error::Invalid + class IDErr : public lumiera::error::Invalid { public: IDErr (const char* eID, format fmt) - : cinelerra::error::Invalid(fmt.str(),eID) {} + : lumiera::error::Invalid(fmt.str(),eID) {} }; // ------pre-defined-common-error-cases--------------- // - CINELERRA_ERROR_DEFINE (UNKNOWN_ASSET_ID, "non-registered Asset ID"); - CINELERRA_ERROR_DEFINE (WRONG_ASSET_KIND, "wrong Asset kind, unable to cast"); + LUMIERA_ERROR_DEFINE (UNKNOWN_ASSET_ID, "non-registered Asset ID"); + LUMIERA_ERROR_DEFINE (WRONG_ASSET_KIND, "wrong Asset kind, unable to cast"); class UnknownID : public IDErr { public: - UnknownID (ID aID) : IDErr (CINELERRA_ERROR_UNKNOWN_ASSET_ID, + UnknownID (ID aID) : IDErr (LUMIERA_ERROR_UNKNOWN_ASSET_ID, format("Query for Asset with ID=%d, which up to now " "hasn't been created or encountered.") % aID) {} }; @@ -73,7 +73,7 @@ namespace asset class WrongKind : public IDErr { public: - WrongKind (Asset::Ident idi) : IDErr (CINELERRA_ERROR_WRONG_ASSET_KIND, + WrongKind (Asset::Ident idi) : IDErr (LUMIERA_ERROR_WRONG_ASSET_KIND, format("Request for Asset(%s), specifying an Asset kind, " "that doesn't match the actual type (and can't be " "casted either).") % string(idi)) {} @@ -110,7 +110,7 @@ namespace asset template ID AssetManager::reg (KIND* obj, const Asset::Ident& idi) - throw(cinelerra::error::Invalid) + throw(lumiera::error::Invalid) { typedef shared_ptr PType; AssetManager& _aMang (AssetManager::instance()); @@ -133,7 +133,7 @@ namespace asset template shared_ptr AssetManager::getAsset (const ID& id) - throw(cinelerra::error::Invalid) + throw(lumiera::error::Invalid) { if (shared_ptr obj = registry.get (id)) return obj; @@ -243,11 +243,11 @@ namespace asset template ID AssetManager::reg (Asset* obj, const Asset::Ident& idi); - template shared_ptr AssetManager::getAsset (const ID& id) throw(cinelerra::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(cinelerra::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(cinelerra::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(cinelerra::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(cinelerra::error::Invalid); + template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); template shared_ptr AssetManager::getPtr (const Asset& asset); template shared_ptr AssetManager::getPtr (const Media& asset); diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp index d1b20e025..b2362db00 100644 --- a/src/proc/assetmanager.hpp +++ b/src/proc/assetmanager.hpp @@ -66,7 +66,7 @@ namespace asset public: - static cinelerra::Singleton instance; + static lumiera::Singleton instance; /** provide the unique ID for given Asset::Ident tuple */ static ID getID (const Asset::Ident&); @@ -77,7 +77,7 @@ namespace asset /** find and return corresponging object */ template - shared_ptr getAsset (const ID& id) throw(cinelerra::error::Invalid); + shared_ptr getAsset (const ID& id) throw(lumiera::error::Invalid); /** @return true if the given id is registered in the internal asset DB */ @@ -101,7 +101,7 @@ namespace asset */ template static ID reg (KIND* obj, const Asset::Ident& idi) - throw(cinelerra::error::Invalid); + throw(lumiera::error::Invalid); /** deleter function used by the Asset smart pointers to delete Asset objects */ static void destroy (Asset* aa) { delete aa; } @@ -110,13 +110,13 @@ namespace asset AssetManager (); - friend class cinelerra::singleton::StaticCreate; + friend class lumiera::singleton::StaticCreate; }; - CINELERRA_ERROR_DECLARE (UNKNOWN_ASSET_ID); ///< use of a non-registered Asset ID. - CINELERRA_ERROR_DECLARE (WRONG_ASSET_KIND); ///< Asset ID of wrong Asset kind, unable to cast. + LUMIERA_ERROR_DECLARE (UNKNOWN_ASSET_ID); ///< use of a non-registered Asset ID. + LUMIERA_ERROR_DECLARE (WRONG_ASSET_KIND); ///< Asset ID of wrong Asset kind, unable to cast. } // namespace asset diff --git a/src/proc/engine/codecadapter.hpp b/src/proc/engine/codecadapter.hpp index 5b4991177..724763eaa 100644 --- a/src/proc/engine/codecadapter.hpp +++ b/src/proc/engine/codecadapter.hpp @@ -38,7 +38,7 @@ namespace engine * process thus is integrated into the framework * of the Renderengine, while the actual implementation * can be delegated to an external library accessed - * through Cinelerra's datat backend. + * through Lumiera's data backend. */ class CodecAdapter : public Trafo {}; diff --git a/src/proc/engine/pluginadapter.hpp b/src/proc/engine/pluginadapter.hpp index b080b99ed..b771f1fbc 100644 --- a/src/proc/engine/pluginadapter.hpp +++ b/src/proc/engine/pluginadapter.hpp @@ -35,7 +35,7 @@ namespace engine /** * Adapter used to integrate an effects processor in the render pipeline. * Effects processors are typically defined in a separate library and - * will be loaded at runtime using Cinelerra's plugin interface. + * will be loaded at runtime using Lumiera's plugin interface. */ class PluginAdapter : public Trafo { diff --git a/src/proc/engine/processor.hpp b/src/proc/engine/processor.hpp index 70ec33f6c..6b7317886 100644 --- a/src/proc/engine/processor.hpp +++ b/src/proc/engine/processor.hpp @@ -24,7 +24,7 @@ #ifndef ENGINE_PROCESSOR_H #define ENGINE_PROCESSOR_H -#include "cinelerra.h" +#include "lumiera.h" #include "proc/stateproxy.hpp" @@ -40,10 +40,10 @@ namespace engine ExitNode * output; /** begin of the timerange covered by this processor */ - cinelerra::Time start; + lumiera::Time start; /**end (exclusive) of the timerange */ - cinelerra::Time end; + lumiera::Time end; }; diff --git a/src/proc/mobject/builder/buildertool.hpp b/src/proc/mobject/builder/buildertool.hpp index c4700bc0a..0985567d1 100644 --- a/src/proc/mobject/builder/buildertool.hpp +++ b/src/proc/mobject/builder/buildertool.hpp @@ -59,7 +59,7 @@ namespace mobject * an instantiation of the "Applicable" template parametrized with all * concrete Buildable classes, for which it wants calls to be dispatched. */ - typedef cinelerra::visitor::Tool BuilderTool; + typedef lumiera::visitor::Tool BuilderTool; template @@ -67,11 +67,11 @@ namespace mobject class TYPELIST // list of all concrete Buildables to be treated > class Applicable - : public cinelerra::visitor::Applicable + : public lumiera::visitor::Applicable { } ; - using cinelerra::typelist::Types; // convienience for the users of "Applicable" + using lumiera::typelist::Types; // convienience for the users of "Applicable" } // namespace mobject::builder @@ -80,7 +80,7 @@ namespace mobject /** * Marker Interface for classes Visitable by Builder tools. */ - class Buildable : public cinelerra::visitor::Visitable + class Buildable : public lumiera::visitor::Visitable { }; } // namespace mobject diff --git a/src/proc/mobject/mobject.hpp b/src/proc/mobject/mobject.hpp index b7c139f93..3d0222a3d 100644 --- a/src/proc/mobject/mobject.hpp +++ b/src/proc/mobject/mobject.hpp @@ -29,7 +29,7 @@ #include #include -#include "cinelerra.h" +#include "lumiera.h" #include "proc/mobject/builder/buildertool.hpp" #include "proc/mobject/placement.hpp" #include "proc/asset.hpp" // TODO finally not needed? @@ -55,13 +55,13 @@ namespace mobject /** * MObject is the interface class for all "Media Objects". * All the contents and elements that can be placed and - * manipulated and finally rendered within Cinelerra's EDL + * manipulated and finally rendered within Lumiera's EDL * are MObjects. */ class MObject : public Buildable { protected: - typedef cinelerra::Time Time; + typedef lumiera::Time Time; // TODO: how to represent time intervals best? Time length; diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index 71c654308..3e941b7d5 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -86,7 +86,7 @@ namespace mobject class Placement : protected shared_ptr { protected: - typedef cinelerra::Time Time; + typedef lumiera::Time Time; typedef session::Track* Track; diff --git a/src/proc/mobject/session.hpp b/src/proc/mobject/session.hpp index 48473d298..1dafb2e87 100644 --- a/src/proc/mobject/session.hpp +++ b/src/proc/mobject/session.hpp @@ -57,7 +57,7 @@ namespace mobject /** * The (current) Session holds all the user * visible content to be edited and manipulated - * within the Cinelerra Application. From a users + * within the Lumiera Application. From a users * perspective, it is a collection of Media Objects * (--> MObject) placed (--> Placement) onto virtual * Tracks. diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp index dfc7f8696..c42d5bc3d 100644 --- a/src/proc/mobject/session/locatingpin.hpp +++ b/src/proc/mobject/session/locatingpin.hpp @@ -42,7 +42,7 @@ #define MOBJECT_SESSION_LOCATINGPIN_H -#include "cinelerra.h" +#include "lumiera.h" #include #include @@ -79,7 +79,7 @@ namespace mobject class LocatingPin { protected: - typedef cinelerra::Time Time; + typedef lumiera::Time Time; typedef session::Track* Track; typedef std::pair SolutionData; //TODO (ichthyo consideres better passing of solution by subclass) struct LocatingSolution; diff --git a/src/proc/mobject/session/segment.hpp b/src/proc/mobject/session/segment.hpp index 46b5929d4..0b8a6025b 100644 --- a/src/proc/mobject/session/segment.hpp +++ b/src/proc/mobject/session/segment.hpp @@ -26,7 +26,7 @@ #include -#include "cinelerra.h" +#include "lumiera.h" #include "proc/mobject/explicitplacement.hpp" @@ -49,7 +49,7 @@ namespace mobject class Segment { protected: - typedef cinelerra::Time Time; + typedef lumiera::Time Time; /** begin of this timeline segment. */ Time start; diff --git a/src/proc/mobject/session/session.cpp b/src/proc/mobject/session/session.cpp index 2e81d752e..ea6a559d9 100644 --- a/src/proc/mobject/session/session.cpp +++ b/src/proc/mobject/session/session.cpp @@ -37,7 +37,7 @@ #include "common/singleton.hpp" -using cinelerra::Singleton; +using lumiera::Singleton; using mobject::session::SessManager; using mobject::session::SessManagerImpl; diff --git a/src/proc/mobject/session/sessionimpl.cpp b/src/proc/mobject/session/sessionimpl.cpp index e0cab87cc..15e940843 100644 --- a/src/proc/mobject/session/sessionimpl.cpp +++ b/src/proc/mobject/session/sessionimpl.cpp @@ -60,7 +60,7 @@ namespace mobject catch (...) { focusEDL_ = 0; - throw cinelerra::error::Fatal ("unexpected exception while clearing EDLs"); + throw lumiera::error::Fatal ("unexpected exception while clearing EDLs"); } } diff --git a/src/proc/mobject/session/sessionimpl.hpp b/src/proc/mobject/session/sessionimpl.hpp index d145c4fe5..2c396f95c 100644 --- a/src/proc/mobject/session/sessionimpl.hpp +++ b/src/proc/mobject/session/sessionimpl.hpp @@ -90,7 +90,7 @@ namespace mobject boost::scoped_ptr pImpl_; SessManagerImpl() throw(); - friend class cinelerra::singleton::StaticCreate; + friend class lumiera::singleton::StaticCreate; public: virtual void clear () ; diff --git a/src/tool/hello.c b/src/tool/hello.c index 62a033f4e..d75f55f94 100644 --- a/src/tool/hello.c +++ b/src/tool/hello.c @@ -1,12 +1,12 @@ /* * hello.c - demonstrates how to build a standalone tool (C source) - * integrated into the SCons based build system of Cinelerra + * integrated into the SCons based build system of Lumiera */ #include int main(int argc, char* argv[]) { - printf("hello cinelerra world"); + printf("hello lumiera world"); return 0; } diff --git a/tests/10errorhandling.tests b/tests/10errorhandling.tests index 2492869c5..f2e4e9dfc 100644 --- a/tests/10errorhandling.tests +++ b/tests/10errorhandling.tests @@ -15,12 +15,12 @@ return: 0 END TEST "query error" get < #include -using cinelerra::error::Invalid; +using lumiera::error::Invalid; using util::for_each; using util::isnil; using std::cout; diff --git a/tests/components/backend/mediaaccessmock.hpp b/tests/components/backend/mediaaccessmock.hpp index e11d0a67a..06eedad5c 100644 --- a/tests/components/backend/mediaaccessmock.hpp +++ b/tests/components/backend/mediaaccessmock.hpp @@ -41,7 +41,7 @@ namespace backend_interface class MediaAccessMock : public MediaAccessFacade { public: - FileHandle queryFile (const char* name) throw(cinelerra::error::Invalid); + FileHandle queryFile (const char* name) throw(lumiera::error::Invalid); ChanDesc queryChannel (FileHandle, uint chanNo) throw(); }; diff --git a/tests/components/common/appconfigtest.cpp b/tests/components/common/appconfigtest.cpp index d65e29402..6cab57de8 100644 --- a/tests/components/common/appconfigtest.cpp +++ b/tests/components/common/appconfigtest.cpp @@ -33,7 +33,7 @@ using std::cout; -namespace cinelerra +namespace lumiera { namespace test { @@ -46,10 +46,10 @@ namespace cinelerra testAccess("version"); } - /** @test accessing a value from cinelerra::Appconfig */ + /** @test accessing a value from lumiera::Appconfig */ void testAccess (const string& key) { - string ver = cinelerra::Appconfig::get(key); + string ver = lumiera::Appconfig::get(key); ASSERT ( !util::isnil(ver)); } }; diff --git a/tests/components/common/exceptionerrortest.cpp b/tests/components/common/exceptionerrortest.cpp index 987c77d19..75a13d0ee 100644 --- a/tests/components/common/exceptionerrortest.cpp +++ b/tests/components/common/exceptionerrortest.cpp @@ -42,7 +42,7 @@ using std::cout; -namespace cinelerra +namespace lumiera { namespace test { @@ -50,11 +50,11 @@ namespace cinelerra /** local specific error-constant for use in the * construcor of the nested SpecificError class. */ - CINELERRA_ERROR_DEFINE(LIFE_AND_UNIVERSE, "and everything?"); - CINELERRA_ERROR_DEFINE(DERIVED, "convoluted exception"); + LUMIERA_ERROR_DEFINE(LIFE_AND_UNIVERSE, "and everything?"); + LUMIERA_ERROR_DEFINE(DERIVED, "convoluted exception"); /** declare a specific Error class with parent class error::external */ - CINELERRA_EXCEPTION_DECLARE (DerivedError, error::External, CINELERRA_ERROR_DERIVED); + LUMIERA_EXCEPTION_DECLARE (DerivedError, error::External, LUMIERA_ERROR_DERIVED); /********************************************************** @@ -134,29 +134,29 @@ namespace cinelerra } - /** @test by constructing an cinelerra::Error object, - * the corresponding cinelerra_error state is set automatically + /** @test by constructing an lumiera::Error object, + * the corresponding lumiera_error state is set automatically */ void checkErrorIntegration() { - cinelerra_error (); - ASSERT (!cinelerra_error ()); + lumiera_error (); + ASSERT (!lumiera_error ()); Error err1; - Error err2("boo",CINELERRA_ERROR_DERIVED); - ASSERT (err1.getID () == cinelerra_error ()); // (we didn't clear the first one!) + Error err2("boo",LUMIERA_ERROR_DERIVED); + ASSERT (err1.getID () == lumiera_error ()); // (we didn't clear the first one!) - Error err3("boooo",CINELERRA_ERROR_DERIVED); - ASSERT (err3.getID () == cinelerra_error ()); + Error err3("boooo",LUMIERA_ERROR_DERIVED); + ASSERT (err3.getID () == lumiera_error ()); SpecificError err4; - ASSERT (err4.getID () == CINELERRA_ERROR_LIFE_AND_UNIVERSE); - ASSERT (err4.getID () == cinelerra_error ()); + ASSERT (err4.getID () == LUMIERA_ERROR_LIFE_AND_UNIVERSE); + ASSERT (err4.getID () == lumiera_error ()); - ASSERT (!cinelerra_error ()); + ASSERT (!lumiera_error ()); } - /** @test the chaining of cinelerra::Exception objects + /** @test the chaining of lumiera::Exception objects * and the retrieval of the original root cause. */ void checkRootCauseChaining() @@ -186,7 +186,7 @@ namespace cinelerra * gets installed and invoked, which gives additional diagnostics.*/ void terminateUnknown () throw() { - cinelerra::Appconfig::instance(); + lumiera::Appconfig::instance(); // will cause initialisation of Appconfig, throw Error("You'll never get me, won't you?"); @@ -201,7 +201,7 @@ namespace cinelerra { int value; public: - SpecificError () : Invalid("don't panic",CINELERRA_ERROR_LIFE_AND_UNIVERSE), value(42) {} + SpecificError () : Invalid("don't panic",LUMIERA_ERROR_LIFE_AND_UNIVERSE), value(42) {} int revealIt () { return value; } }; @@ -220,7 +220,7 @@ namespace cinelerra catch (SpecificError& e) { cout << "caught: " << e.what() << "..the answer is: " << e.revealIt() << "\n"; } catch (error::Logic& e) { cout << "caught error::Logic: " << e.what() << "\n"; } catch (error::Invalid&e) { cout << "caught error::Invalid: " << e.what() << "\n"; } - catch (Error& e) { cout << "caught cinelerra::Error: " << e.what() << "\n"; } + catch (Error& e) { cout << "caught lumiera::Error: " << e.what() << "\n"; } catch (runtime_error& e) { cout << "caught std::runtime_error: " << e.what() << "\n"; } catch (exception& e) { cout << "caught std::exception: " << e.what() << "\n"; } catch (...) { cout << "caught an unknown exception\n"; } diff --git a/tests/components/common/factoryspecialtest.cpp b/tests/components/common/factoryspecialtest.cpp index de9eeee8b..ecf293cd9 100644 --- a/tests/components/common/factoryspecialtest.cpp +++ b/tests/components/common/factoryspecialtest.cpp @@ -38,7 +38,7 @@ using std::string; using std::cout; -namespace cinelerra +namespace lumiera { namespace test { @@ -323,4 +323,4 @@ namespace cinelerra } // namespace test -} // namespace cinelerra +} // namespace lumiera diff --git a/tests/components/common/factorytest.cpp b/tests/components/common/factorytest.cpp index 875266fce..6c96a337c 100644 --- a/tests/components/common/factorytest.cpp +++ b/tests/components/common/factorytest.cpp @@ -36,7 +36,7 @@ using std::string; using std::cout; -namespace cinelerra +namespace lumiera { namespace test { @@ -100,7 +100,7 @@ namespace cinelerra * further shared-ptrs, invoke a member function and * finally, when leaving the scope, our TargetObj * will be destroyed automatically. - * @see cinelerra::Factory + * @see lumiera::Factory */ class Factory_test : public Test { @@ -125,4 +125,4 @@ namespace cinelerra } // namespace test -} // namespace cinelerra +} // namespace lumiera diff --git a/tests/components/common/singletontest.cpp b/tests/components/common/singletontest.cpp index 558d7e674..b531d7e9c 100644 --- a/tests/components/common/singletontest.cpp +++ b/tests/components/common/singletontest.cpp @@ -38,7 +38,7 @@ using std::string; using std::cout; -namespace cinelerra +namespace lumiera { namespace test { @@ -72,9 +72,9 @@ namespace cinelerra /******************************************************************* * @test implement a Singleton class using our Singleton Template. * Expected results: no memory leaks. - * @see cinelerra::Singleton - * @see cinelerra::singleton::StaticCreate - * @see cinelerra::singleton::HeapCreate + * @see lumiera::Singleton + * @see lumiera::singleton::StaticCreate + * @see lumiera::singleton::HeapCreate */ class Singleton_test : public Test { @@ -136,4 +136,4 @@ namespace cinelerra } // namespace test -} // namespace cinelerra +} // namespace lumiera diff --git a/tests/components/common/singletontestmocktest.cpp b/tests/components/common/singletontestmocktest.cpp index b90b1a73c..ea5e1d70e 100644 --- a/tests/components/common/singletontestmocktest.cpp +++ b/tests/components/common/singletontestmocktest.cpp @@ -37,7 +37,7 @@ using std::string; using std::cout; -namespace cinelerra +namespace lumiera { namespace test { @@ -108,8 +108,8 @@ namespace cinelerra * @test inject a Mock object into the Singleton Factory, * to be returned and used in place of the original object. * Expected results: Mock(s) called, no memory leaks. - * @see cinelerra::Singleton - * @see cinelerra::singleton::Static + * @see lumiera::Singleton + * @see lumiera::singleton::Static */ class SingletonTestMock_test : public Test { @@ -214,4 +214,4 @@ namespace cinelerra } // namespace test -} // namespace cinelerra +} // namespace lumiera diff --git a/tests/components/common/testtargetobj.hpp b/tests/components/common/testtargetobj.hpp index 8a0728b95..28ac5890d 100644 --- a/tests/components/common/testtargetobj.hpp +++ b/tests/components/common/testtargetobj.hpp @@ -21,8 +21,8 @@ */ -#ifndef CINELERRA_TEST_TESTTARGETOBJ_H -#define CINELERRA_TEST_TESTTARGETOBJ_H +#ifndef LUMIERA_TEST_TESTTARGETOBJ_H +#define LUMIERA_TEST_TESTTARGETOBJ_H #include "common/test/run.hpp" @@ -41,7 +41,7 @@ using std::string; using std::cout; -namespace cinelerra +namespace lumiera { namespace test { @@ -107,5 +107,5 @@ namespace cinelerra } // namespace test -} // namespace cinelerra +} // namespace lumiera #endif diff --git a/tests/components/common/typelisttest.cpp b/tests/components/common/typelisttest.cpp index 1a2e383e8..42159d96c 100644 --- a/tests/components/common/typelisttest.cpp +++ b/tests/components/common/typelisttest.cpp @@ -30,7 +30,7 @@ using std::string; using std::cout; -namespace cinelerra +namespace lumiera { namespace typelist { @@ -97,4 +97,4 @@ namespace cinelerra } // namespace typelist -} // namespace cinelerra +} // namespace lumiera diff --git a/tests/components/common/visitingtoolconcept.cpp b/tests/components/common/visitingtoolconcept.cpp index 16578b6be..f2189ed09 100644 --- a/tests/components/common/visitingtoolconcept.cpp +++ b/tests/components/common/visitingtoolconcept.cpp @@ -24,7 +24,7 @@ /** @file visitingtoolconept.cpp ** While laying the foundations for EDL and Builder, Ichthyo came accross ** the necessity to create a custom implementation of the Visitor Pattern - ** optimally suited for Cinelerra's needs. This implementation file was + ** optimally suited for Lumiera's needs. This implementation file was ** used for the draft and is self-contained. The final solution was then ** extracted as library implementation to visitor.hpp ** @@ -60,13 +60,13 @@ #include #include -using cinelerra::Singleton; +using lumiera::Singleton; using boost::format; using std::string; using std::cout; -namespace cinelerra +namespace lumiera { namespace visitor_concept_draft { @@ -459,4 +459,4 @@ namespace cinelerra } // namespace visitor_concept_draft -} // namespace cinelerra +} // namespace lumiera diff --git a/tests/components/common/visitingtoolextendedtest.cpp b/tests/components/common/visitingtoolextendedtest.cpp index a25ebd95a..d29c60b26 100644 --- a/tests/components/common/visitingtoolextendedtest.cpp +++ b/tests/components/common/visitingtoolextendedtest.cpp @@ -32,7 +32,7 @@ using std::string; using std::cout; -namespace cinelerra +namespace lumiera { namespace visitor { @@ -226,4 +226,4 @@ namespace cinelerra } // namespace visitor -} // namespace cinelerra +} // namespace lumiera diff --git a/tests/components/common/visitingtooltest.cpp b/tests/components/common/visitingtooltest.cpp index 10edf233d..0263d9c88 100644 --- a/tests/components/common/visitingtooltest.cpp +++ b/tests/components/common/visitingtooltest.cpp @@ -32,7 +32,7 @@ using std::string; using std::cout; -namespace cinelerra +namespace lumiera { namespace visitor { @@ -159,4 +159,4 @@ namespace cinelerra } // namespace visitor -} // namespace cinelerra +} // namespace lumiera diff --git a/tests/components/helloworldtest.cpp b/tests/components/helloworldtest.cpp index 8398f19ad..d0c289986 100644 --- a/tests/components/helloworldtest.cpp +++ b/tests/components/helloworldtest.cpp @@ -31,7 +31,7 @@ using util::isnil; using boost::lexical_cast; -namespace cinelerra +namespace lumiera { namespace test { @@ -65,4 +65,4 @@ namespace cinelerra } // namespace test -} // namespace cinelerra +} // namespace lumiera diff --git a/tests/components/mainsuite.cpp b/tests/components/mainsuite.cpp index 924a982e3..aa500cdbe 100644 --- a/tests/components/mainsuite.cpp +++ b/tests/components/mainsuite.cpp @@ -1,5 +1,5 @@ /* - mainsuite.cpp - "the" cinelerra3 self test suite + mainsuite.cpp - "the" Lumiera self test suite Copyright (C) Lumiera.org 2008, Christian Thaeter diff --git a/tests/components/proc/asset/createassettest.cpp b/tests/components/proc/asset/createassettest.cpp index fa28d4472..d9302fc7c 100644 --- a/tests/components/proc/asset/createassettest.cpp +++ b/tests/components/proc/asset/createassettest.cpp @@ -100,14 +100,14 @@ namespace asset aMang.getAsset (ID(mm1->getID())); NOTREACHED; } - catch (cinelerra::error::Invalid& xxx) {ASSERT (xxx.getID()==CINELERRA_ERROR_WRONG_ASSET_KIND);} + catch (lumiera::error::Invalid& xxx) {ASSERT (xxx.getID()==LUMIERA_ERROR_WRONG_ASSET_KIND);} try { // try accessing nonexistant ID aMang.getAsset (ID (1234567890)); NOTREACHED; } - catch (cinelerra::error::Invalid& xxx) {ASSERT (xxx.getID()==CINELERRA_ERROR_UNKNOWN_ASSET_ID);} - cinelerra_error (); // reset errorflag + catch (lumiera::error::Invalid& xxx) {ASSERT (xxx.getID()==LUMIERA_ERROR_UNKNOWN_ASSET_ID);} + lumiera_error (); // reset errorflag // checking the Ident-Fields @@ -121,8 +121,8 @@ namespace asset ASSERT (mm3->ident.category == Category (VIDEO )); ASSERT (mm1->ident.org == "ichthyo"); - ASSERT (mm2->ident.org == "cin3"); - ASSERT (mm3->ident.org == "cin3"); + ASSERT (mm2->ident.org == "lumi"); + ASSERT (mm3->ident.org == "lumi"); ASSERT (mm1->ident.version == 5); ASSERT (mm2->ident.version == 1); @@ -159,19 +159,19 @@ namespace asset ASSERT (key2.name == "testfile2"); // name filled in automatically candi = asset::Media::create(string("testfile3.wav"), Category(AUDIO)); - ASSERT ( checkProperties (candi, Asset::Ident("testfile3", Category(AUDIO), "cin3", 1) + ASSERT ( checkProperties (candi, Asset::Ident("testfile3", Category(AUDIO), "lumi", 1) , "testfile3.wav")); candi = asset::Media::create("some/path/testfile4.wav", Category(AUDIO)); - ASSERT ( checkProperties (candi, Asset::Ident("testfile4", Category(AUDIO), "cin3", 1) + ASSERT ( checkProperties (candi, Asset::Ident("testfile4", Category(AUDIO), "lumi", 1) , "some/path/testfile4.wav")); candi = asset::Media::create("", Category(AUDIO,"sub/bin")); - ASSERT ( checkProperties (candi, Asset::Ident("nil", Category(AUDIO,"sub/bin"), "cin3", 1) + ASSERT ( checkProperties (candi, Asset::Ident("nil", Category(AUDIO,"sub/bin"), "lumi", 1) , "")); candi = asset::Media::create("", AUDIO); - ASSERT ( checkProperties (candi, Asset::Ident("nil", Category(AUDIO), "cin3", 1) + ASSERT ( checkProperties (candi, Asset::Ident("nil", Category(AUDIO), "lumi", 1) , "")); } diff --git a/tests/components/proc/asset/mediastructurequerytest.cpp b/tests/components/proc/asset/mediastructurequerytest.cpp index 866178fd4..7cbfcd847 100644 --- a/tests/components/proc/asset/mediastructurequerytest.cpp +++ b/tests/components/proc/asset/mediastructurequerytest.cpp @@ -44,7 +44,7 @@ namespace asset /*********************************************************************** * This test documents the Interface used by MediaFactory when loading - * media files for querying cinelerra's backend layer for information + * media files for querying Lumiera's backend layer for information * on how the media file is structured. */ class MediaStructureQuery_test : public Test diff --git a/tests/components/proc/mobject/controller/rendersegmenttest.cpp b/tests/components/proc/mobject/controller/rendersegmenttest.cpp index fac5568aa..a56c76480 100644 --- a/tests/components/proc/mobject/controller/rendersegmenttest.cpp +++ b/tests/components/proc/mobject/controller/rendersegmenttest.cpp @@ -46,7 +46,7 @@ namespace mobject /******************************************************************* * @test create a render process from a given segment of the EDL. * Basically this includes cooperation of all parts of the - * Cinelerra Proc Layer. For a prepared test-EDL we invoke the + * Lumiera Proc Layer. For a prepared test-EDL we invoke the * controller to create a render process. This includes building * the render pipeline. Finally, we analyze all the created * Structures. diff --git a/tests/components/proc/mobject/placementbasictest.cpp b/tests/components/proc/mobject/placementbasictest.cpp index 16b6a80d0..e3e237252 100644 --- a/tests/components/proc/mobject/placementbasictest.cpp +++ b/tests/components/proc/mobject/placementbasictest.cpp @@ -35,7 +35,7 @@ #include //using boost::format; -using cinelerra::Time; +using lumiera::Time; using util::contains; using std::string; using std::cout; diff --git a/tests/components/proc/mobject/session/addcliptest.cpp b/tests/components/proc/mobject/session/addcliptest.cpp index ffb794e95..3cb981270 100644 --- a/tests/components/proc/mobject/session/addcliptest.cpp +++ b/tests/components/proc/mobject/session/addcliptest.cpp @@ -32,7 +32,7 @@ #include //using boost::format; -using cinelerra::Time; +using lumiera::Time; using util::contains; using std::string; using std::cout; diff --git a/tests/components/proc/mobject/session/testclip.cpp b/tests/components/proc/mobject/session/testclip.cpp index ce659e708..ea17dd19d 100644 --- a/tests/components/proc/mobject/session/testclip.cpp +++ b/tests/components/proc/mobject/session/testclip.cpp @@ -44,7 +44,7 @@ namespace mobject asset::Media & createTestMedia () { - // install Mock-Interface to cinelerra backend + // install Mock-Interface to Lumiera backend MAF::instance.injectSubclass (new MediaAccessMock); PM media = asset::Media::create("test-2", VIDEO); // query magic filename MAF::instance.injectSubclass (0); // remove Mock-Interface @@ -70,7 +70,7 @@ namespace mobject { } }; - cinelerra::Singleton testbed_1; // invoke ctor when creating first TestClip... + lumiera::Singleton testbed_1; // invoke ctor when creating first TestClip... diff --git a/tests/error/errortest.c b/tests/error/errortest.c index 0fd95b600..d367c0742 100644 --- a/tests/error/errortest.c +++ b/tests/error/errortest.c @@ -25,7 +25,7 @@ #include "lib/error.h" -CINELERRA_ERROR_DEFINE(TEST, "test error"); +LUMIERA_ERROR_DEFINE(TEST, "test error"); int main (int argc, char** argv) @@ -35,31 +35,31 @@ main (int argc, char** argv) if (!strcmp(argv[1], "set")) { - cinelerra_error_set (CINELERRA_ERROR_TEST); + lumiera_error_set (LUMIERA_ERROR_TEST); } if (!strcmp(argv[1], "get_no")) { const char* err; - err = cinelerra_error (); + err = lumiera_error (); printf ("%p\n", err); } if (!strcmp(argv[1], "get")) { - cinelerra_error_set (CINELERRA_ERROR_TEST); + lumiera_error_set (LUMIERA_ERROR_TEST); const char* err; - err = cinelerra_error (); + err = lumiera_error (); printf ("%s\n", err); } if (!strcmp(argv[1], "get2")) { - cinelerra_error_set (CINELERRA_ERROR_TEST); + lumiera_error_set (LUMIERA_ERROR_TEST); const char* err; - err = cinelerra_error (); + err = lumiera_error (); printf ("%s\n", err); - err = cinelerra_error (); + err = lumiera_error (); printf ("%p\n", err); } diff --git a/tests/library/test-llist.c b/tests/library/test-llist.c index bf6c5aed5..bfaf99c65 100644 --- a/tests/library/test-llist.c +++ b/tests/library/test-llist.c @@ -26,7 +26,7 @@ #include "lib/framerate.h" -CINELERRA_ERROR_DEFINE(TEST, "test error"); +LUMIERA_ERROR_DEFINE(TEST, "test error"); int main (int argc, char** argv) diff --git a/tests/library/test-references.c b/tests/library/test-references.c index f56c7c9d7..c1509c341 100644 --- a/tests/library/test-references.c +++ b/tests/library/test-references.c @@ -25,7 +25,7 @@ #include "lib/references.h" -CINELERRA_ERROR_DEFINE(TEST, "test error"); +LUMIERA_ERROR_DEFINE(TEST, "test error"); struct example @@ -55,16 +55,16 @@ main (int argc, char** argv) struct example test; test.foo = 123; - cinelerra_reference hold; + lumiera_reference hold; - cinelerra_reference_strong_init_once (&hold, &test, example_dtor); + lumiera_reference_strong_init_once (&hold, &test, example_dtor); - struct example* r = cinelerra_reference_get (&hold); + struct example* r = lumiera_reference_get (&hold); printf ("got: %d\n", r->foo); - cinelerra_reference_destroy (&hold); + lumiera_reference_destroy (&hold); } else if (!strcmp(argv[1], "nodeinsert")) { diff --git a/tests/locking/condition.c b/tests/locking/condition.c index 6483ac0a9..7d79e9a7e 100644 --- a/tests/locking/condition.c +++ b/tests/locking/condition.c @@ -40,10 +40,10 @@ signaling_thread() int conditionforgotunlock () { - cinelerra_condition c; - cinelerra_condition_init (&c); + lumiera_condition c; + lumiera_condition_init (&c); - cinelerra_conditionacquirer l; - cinelerra_conditionacquirer_init (&l, &c, CINELERRA_LOCKED); + lumiera_conditionacquirer l; + lumiera_conditionacquirer_init (&l, &c, LUMIERA_LOCKED); return 0; } diff --git a/tests/locking/mutex.c b/tests/locking/mutex.c index ed6a050eb..f4f8c18f6 100644 --- a/tests/locking/mutex.c +++ b/tests/locking/mutex.c @@ -23,10 +23,10 @@ int mutexforgotunlock() { - cinelerra_mutex m; - cinelerra_mutex_init (&m); + lumiera_mutex m; + lumiera_mutex_init (&m); - cinelerra_mutexacquirer l; - cinelerra_mutexacquirer_init_mutex (&l, &m, CINELERRA_LOCKED); + lumiera_mutexacquirer l; + lumiera_mutexacquirer_init_mutex (&l, &m, LUMIERA_LOCKED); return 0; } diff --git a/tests/locking/test-condition.c b/tests/locking/test-condition.c index cc8e5ae14..1e3ca1bf7 100644 --- a/tests/locking/test-condition.c +++ b/tests/locking/test-condition.c @@ -24,7 +24,7 @@ #include "lib/condition.h" -CINELERRA_ERROR_DEFINE(TEST, "test error"); +LUMIERA_ERROR_DEFINE(TEST, "test error"); #if 0 waiting_thread() @@ -52,11 +52,11 @@ main (int argc, char** argv) if (!strcmp(argv[1], "conditionforgotunlock")) { - cinelerra_condition c; - cinelerra_condition_init (&c); + lumiera_condition c; + lumiera_condition_init (&c); - cinelerra_conditionlock NOBUG_CLEANUP(cinelerra_conditionlock_ensureunlocked) l; - cinelerra_conditionlock_init (&l, &c, CINELERRA_LOCKED); + lumiera_conditionlock NOBUG_CLEANUP(lumiera_conditionlock_ensureunlocked) l; + lumiera_conditionlock_init (&l, &c, LUMIERA_LOCKED); } else return 1; diff --git a/tests/locking/test-locking.c b/tests/locking/test-locking.c index 46455764b..1b54d152e 100644 --- a/tests/locking/test-locking.c +++ b/tests/locking/test-locking.c @@ -24,7 +24,7 @@ #include "lib/error.h" -CINELERRA_ERROR_DEFINE(TEST, "test error"); +LUMIERA_ERROR_DEFINE(TEST, "test error"); int conditionforgotunlock (); int mutexforgotunlock (); diff --git a/tests/plugin/example_plugin.c b/tests/plugin/example_plugin.c index ebb71ae8a..7540aa35d 100644 --- a/tests/plugin/example_plugin.c +++ b/tests/plugin/example_plugin.c @@ -34,12 +34,12 @@ void bye(const char* m) printf("Bye %s\n", m); } -CINELERRA_INTERFACE_IMPLEMENT(hello, 1, german, myopen, myclose, - hallo, - tschuess - ); +LUMIERA_INTERFACE_IMPLEMENT(hello, 1, german, myopen, myclose, + hallo, + tschuess + ); -CINELERRA_INTERFACE_IMPLEMENT(hello, 1, english, myopen, myclose, - hello, - bye - ); +LUMIERA_INTERFACE_IMPLEMENT(hello, 1, english, myopen, myclose, + hello, + bye + ); diff --git a/tests/plugin/example_plugin.cpp b/tests/plugin/example_plugin.cpp index b608887d8..aba34b44a 100644 --- a/tests/plugin/example_plugin.cpp +++ b/tests/plugin/example_plugin.cpp @@ -50,12 +50,12 @@ public: }; -CINELERRA_INTERFACE_IMPLEMENT(hello, 1, german, example_plugin_de::myopen, example_plugin_de::myclose, - example_plugin_de::hello, - example_plugin_de::bye - ); +LUMIERA_INTERFACE_IMPLEMENT(hello, 1, german, example_plugin_de::myopen, example_plugin_de::myclose, + example_plugin_de::hello, + example_plugin_de::bye + ); -CINELERRA_INTERFACE_IMPLEMENT(hello, 1, english, example_plugin_en::myopen, example_plugin_en::myclose, - example_plugin_en::hello, - example_plugin_en::bye - ); +LUMIERA_INTERFACE_IMPLEMENT(hello, 1, english, example_plugin_en::myopen, example_plugin_en::myclose, + example_plugin_en::hello, + example_plugin_en::bye + ); diff --git a/tests/plugin/hello_interface.h b/tests/plugin/hello_interface.h index ccec270ed..d5cf99ea5 100644 --- a/tests/plugin/hello_interface.h +++ b/tests/plugin/hello_interface.h @@ -1,6 +1,6 @@ #include "lib/plugin.h" -CINELERRA_INTERFACE(hello, 1, - CINELERRA_INTERFACE_PROTO(void, hello, (void)) - CINELERRA_INTERFACE_PROTO(void, goodbye, (const char*)) - ); +LUMIERA_INTERFACE(hello, 1, + LUMIERA_INTERFACE_PROTO(void, hello, (void)) + LUMIERA_INTERFACE_PROTO(void, goodbye, (const char*)) + ); diff --git a/tests/plugin/plugin_main.c b/tests/plugin/plugin_main.c index e691438b3..2efe32471 100644 --- a/tests/plugin/plugin_main.c +++ b/tests/plugin/plugin_main.c @@ -12,7 +12,7 @@ main(int argc, char** argv) if (argc < 2) return -1; - cinelerra_init_plugin (); + lumiera_init_plugin (); /* we have a plugin 'hello_1' which provides us 2 hello interfaces, one for english and one for german output, open both try them, close them. @@ -22,47 +22,47 @@ main(int argc, char** argv) if( !strcmp(argv[1],"C")) { - CINELERRA_INTERFACE_TYPE(hello, 1)* hello_de = - (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin", "german_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); + LUMIERA_INTERFACE_TYPE(hello, 1)* hello_de = + (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin", "german_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); - if (!hello_de) CINELERRA_DIE; + if (!hello_de) LUMIERA_DIE; hello_de->hello(); hello_de->goodbye(argv[1]); - CINELERRA_INTERFACE_TYPE(hello, 1)* hello_en = - (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin", "english_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); + LUMIERA_INTERFACE_TYPE(hello, 1)* hello_en = + (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin", "english_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); - if (!hello_en) CINELERRA_DIE; + if (!hello_en) LUMIERA_DIE; hello_en->hello(); hello_en->goodbye(argv[1]); - cinelerra_interface_close (hello_en); - cinelerra_interface_close (hello_de); + lumiera_interface_close (hello_en); + lumiera_interface_close (hello_de); } if( !strcmp(argv[1],"C++")) { /* same again for a plugin written in C++ */ - CINELERRA_INTERFACE_TYPE(hello, 1)* hello_de = - (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin_cpp", "german_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); + LUMIERA_INTERFACE_TYPE(hello, 1)* hello_de = + (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin_cpp", "german_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); - if (!hello_de) CINELERRA_DIE; + if (!hello_de) LUMIERA_DIE; hello_de->hello(); hello_de->goodbye(argv[1]); - CINELERRA_INTERFACE_TYPE(hello, 1)* hello_en = - (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin_cpp", "english_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); + LUMIERA_INTERFACE_TYPE(hello, 1)* hello_en = + (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin_cpp", "english_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); - if (!hello_en) CINELERRA_DIE; + if (!hello_en) LUMIERA_DIE; hello_en->hello(); hello_en->goodbye(argv[1]); - cinelerra_interface_close (hello_en); - cinelerra_interface_close (hello_de); + lumiera_interface_close (hello_en); + lumiera_interface_close (hello_de); } return 0; diff --git a/tests/time/test-time.c b/tests/time/test-time.c index 01dd107ef..e9d8d0550 100644 --- a/tests/time/test-time.c +++ b/tests/time/test-time.c @@ -26,7 +26,7 @@ #include "lib/framerate.h" -CINELERRA_ERROR_DEFINE(TEST, "test error"); +LUMIERA_ERROR_DEFINE(TEST, "test error"); int main (int argc, char** argv) @@ -38,106 +38,106 @@ main (int argc, char** argv) if (!strcmp(argv[1], "init")) { - cinelerra_time time; + lumiera_time time; - cinelerra_time_init (&time, atol (argv[2]), atol(argv[3])); + lumiera_time_init (&time, atol (argv[2]), atol(argv[3])); - printf ("%lu %lu\n", (long)cinelerra_time_sec (&time), (long)cinelerra_time_usec (&time)); + printf ("%lu %lu\n", (long)lumiera_time_sec (&time), (long)lumiera_time_usec (&time)); } if (!strcmp(argv[1], "todouble")) { - cinelerra_time time; + lumiera_time time; - cinelerra_time_init (&time, atol (argv[2]), atol(argv[3])); + lumiera_time_init (&time, atol (argv[2]), atol(argv[3])); - printf ("%g\n", cinelerra_time_double_get (&time)); + printf ("%g\n", lumiera_time_double_get (&time)); } if (!strcmp(argv[1], "todoublenull")) { - printf ("%g\n", cinelerra_time_double_get (NULL)); + printf ("%g\n", lumiera_time_double_get (NULL)); } if (!strcmp(argv[1], "fromdouble")) { - cinelerra_time time; + lumiera_time time; - cinelerra_time_set_double (&time, atof (argv[2])); + lumiera_time_set_double (&time, atof (argv[2])); - printf ("%lu %lu\n", (long)cinelerra_time_sec (&time), (long)cinelerra_time_usec (&time)); + printf ("%lu %lu\n", (long)lumiera_time_sec (&time), (long)lumiera_time_usec (&time)); } if (!strcmp(argv[1], "currenttime")) { - cinelerra_time time; + lumiera_time time; - cinelerra_time_current (&time); + lumiera_time_current (&time); - printf ("%lu %lu\n", (long)cinelerra_time_sec (&time), (long)cinelerra_time_usec (&time)); + printf ("%lu %lu\n", (long)lumiera_time_sec (&time), (long)lumiera_time_usec (&time)); } if (!strcmp(argv[1], "add")) { - cinelerra_time time1, time2; + lumiera_time time1, time2; - cinelerra_time_init (&time1, 0, atol (argv[2])); - cinelerra_time_init (&time2, 0, atol (argv[3])); - cinelerra_time_add (&time1, &time2); + lumiera_time_init (&time1, 0, atol (argv[2])); + lumiera_time_init (&time2, 0, atol (argv[3])); + lumiera_time_add (&time1, &time2); - printf ("%lu %lu\n", (long)cinelerra_time_sec (&time1), (long)cinelerra_time_usec (&time1)); + printf ("%lu %lu\n", (long)lumiera_time_sec (&time1), (long)lumiera_time_usec (&time1)); } if (!strcmp(argv[1], "sub")) { - cinelerra_time time1, time2; + lumiera_time time1, time2; - cinelerra_time_init (&time1, 0, atol (argv[2])); - cinelerra_time_init (&time2, 0, atol (argv[3])); - cinelerra_time_sub (&time1, &time2); + lumiera_time_init (&time1, 0, atol (argv[2])); + lumiera_time_init (&time2, 0, atol (argv[3])); + lumiera_time_sub (&time1, &time2); - printf ("%lu %lu\n", (long)cinelerra_time_sec (&time1), (long)cinelerra_time_usec (&time1)); + printf ("%lu %lu\n", (long)lumiera_time_sec (&time1), (long)lumiera_time_usec (&time1)); } if (!strcmp(argv[1], "ntscframefromtime")) { - cinelerra_framerate ntsc = {30000, 1001}; - cinelerra_time time; + lumiera_framerate ntsc = {30000, 1001}; + lumiera_time time; - cinelerra_time_init (&time, atol (argv[2]), atol (argv[3])); + lumiera_time_init (&time, atol (argv[2]), atol (argv[3])); - printf ("%lu\n", (long)cinelerra_framerate_frame_get_time (&ntsc, &time)); + printf ("%lu\n", (long)lumiera_framerate_frame_get_time (&ntsc, &time)); } if (!strcmp(argv[1], "ntscframestart")) { - cinelerra_framerate ntsc = {30000, 1001}; - cinelerra_time time; + lumiera_framerate ntsc = {30000, 1001}; + lumiera_time time; - if(cinelerra_framerate_time_get_time_frame (&ntsc, &time, atol (argv[2]))) - printf ("%lu %lu\n", (long)cinelerra_time_sec(&time), (long)cinelerra_time_usec(&time)); + if(lumiera_framerate_time_get_time_frame (&ntsc, &time, atol (argv[2]))) + printf ("%lu %lu\n", (long)lumiera_time_sec(&time), (long)lumiera_time_usec(&time)); } if (!strcmp(argv[1], "ntscframecheck")) { - cinelerra_framerate ntsc = {30000, 1001}; - cinelerra_time time1; - cinelerra_time time2; - cinelerra_framepos frame; + lumiera_framerate ntsc = {30000, 1001}; + lumiera_time time1; + lumiera_time time2; + lumiera_framepos frame; - cinelerra_framepos frame1; - cinelerra_framepos frame2; + lumiera_framepos frame1; + lumiera_framepos frame2; frame = atol (argv[2]); - if (cinelerra_framerate_time_get_time_frame (&ntsc, &time1, frame)) + if (lumiera_framerate_time_get_time_frame (&ntsc, &time1, frame)) { - printf("frame %lu ", frame1 = cinelerra_framerate_frame_get_time (&ntsc, &time1)); + printf("frame %lu ", frame1 = lumiera_framerate_frame_get_time (&ntsc, &time1)); - cinelerra_time_init (&time2, 0, 1); - cinelerra_time_sub (&time1, &time2); - printf("%lu\n", frame2 = cinelerra_framerate_frame_get_time (&ntsc, &time1)); + lumiera_time_init (&time2, 0, 1); + lumiera_time_sub (&time1, &time2); + printf("%lu\n", frame2 = lumiera_framerate_frame_get_time (&ntsc, &time1)); ENSURE (frame1 == frame2+1); } From 912b4993fcca65b2a3666b7f0ac3b8207508beab Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 10 Apr 2008 15:36:21 +0100 Subject: [PATCH 004/245] Created empty UI window --- gui/configure.ac | 2 +- gui/src/Makefile.am | 5 ++++- gui/src/gtk-lumiera.h | 27 +++++++++++++++++++++++++++ gui/src/main-window.cpp | 39 +++++++++++++++++++++++++++++++++++++++ gui/src/main-window.h | 29 +++++++++++++++++++++++++++++ gui/src/main.cpp | 35 +++++++++-------------------------- 6 files changed, 109 insertions(+), 28 deletions(-) create mode 100644 gui/src/gtk-lumiera.h create mode 100644 gui/src/main-window.cpp create mode 100644 gui/src/main-window.h diff --git a/gui/configure.ac b/gui/configure.ac index 9eef896f8..0bc4740c9 100644 --- a/gui/configure.ac +++ b/gui/configure.ac @@ -30,7 +30,7 @@ AM_PROG_LIBTOOL -PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 libglademm-2.4 >= 2.6 ]) +PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 libglademm-2.4 >= 2.6 gdl-1.0 >= 0.2.6]) AC_SUBST(GTK_LUMIERA_CFLAGS) AC_SUBST(GTK_LUMIERA_LIBS) diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index 7ae61d803..a47247986 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -18,7 +18,10 @@ AM_CFLAGS =\ bin_PROGRAMS = gtk-lumiera gtk_lumiera_SOURCES = \ - main.cpp + main.cpp \ + main-window.cpp \ + main-window.h \ + gtk-lumiera.h gtk_lumiera_LDFLAGS = diff --git a/gui/src/gtk-lumiera.h b/gui/src/gtk-lumiera.h new file mode 100644 index 000000000..1b69d5521 --- /dev/null +++ b/gui/src/gtk-lumiera.h @@ -0,0 +1,27 @@ +/* + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA + */ + +#ifdef ENABLE_NLS +# include +# define _(String) gettext (String) +# define gettext_noop(String) String +# define N_(String) gettext_noop (String) +#else +# define _(String) (String) +# define N_(String) String +# define textdomain(Domain) +# define bindtextdomain(Package, Directory) +#endif diff --git a/gui/src/main-window.cpp b/gui/src/main-window.cpp new file mode 100644 index 000000000..e0984f238 --- /dev/null +++ b/gui/src/main-window.cpp @@ -0,0 +1,39 @@ +// main-window.cpp +// Tue Apr 8 23:54:36 2008 +// Copyright 2008 joel +// > + +// This program 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. +// +// This program 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 Library General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA + +#include + +#ifdef ENABLE_NLS +# include +#endif + +#include "gtk-lumiera.h" +#include "main-window.h" + +namespace Lumiera { +namespace UI { + +MainWindow::MainWindow() +{ + set_title(_("Lumiera")); + set_default_size(1024, 768); +} + +} +} diff --git a/gui/src/main-window.h b/gui/src/main-window.h new file mode 100644 index 000000000..8d916eb1f --- /dev/null +++ b/gui/src/main-window.h @@ -0,0 +1,29 @@ +/* + * This program 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. + * + * This program 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA + */ + +#include + +namespace Lumiera { +namespace UI { + +class MainWindow : public Gtk::Window +{ +public: + MainWindow(); +}; + +} +} diff --git a/gui/src/main.cpp b/gui/src/main.cpp index bb69eb3d9..aa3a9f0a3 100644 --- a/gui/src/main.cpp +++ b/gui/src/main.cpp @@ -1,6 +1,6 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* - * main.cc + * main.cpp * Copyright (C) Joel Holdsworth 2008 * * main.cc is free software. @@ -22,41 +22,24 @@ * Boston, MA 02110-1301, USA. */ -#include #include #include - #ifdef ENABLE_NLS # include #endif +#include "main-window.h" -/* For testing propose use the local (not installed) glade file */ -/* #define GLADE_FILE PACKAGE_DATA_DIR"/gtk-lumiera/glade/gtk-lumiera.glade" */ -#define GLADE_FILE "gtk-lumiera.glade" - -int -main (int argc, char *argv[]) +using namespace Lumiera::UI; + +int main (int argc, char *argv[]) { Gtk::Main kit(argc, argv); - //Load the Glade file and instiate its widgets: - Glib::RefPtr refXml; - try - { - refXml = Gnome::Glade::Xml::create(GLADE_FILE); - } - catch(const Gnome::Glade::XmlError& ex) - { - std::cerr << ex.what() << std::endl; - return 1; - } - Gtk::Window* main_win = 0; - refXml->get_widget("main_window", main_win); - if (main_win) - { - kit.run(*main_win); - } + MainWindow main_window; + + kit.run(main_window); + return 0; } From 6f5c701c5735e3bf9d144a1d90574c5d996f8f85 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Fri, 11 Apr 2008 20:28:15 +0100 Subject: [PATCH 005/245] Created workscape namespace --- gui/src/Makefile.am | 16 ++- gui/src/{gtk-lumiera.h => gtk-lumiera.hpp} | 2 + gui/src/main-window.cpp | 39 ------ gui/src/main.cpp | 9 +- gui/src/workspace/actions.cpp | 121 ++++++++++++++++++ gui/src/workspace/actions.hpp | 61 +++++++++ gui/src/workspace/mainwindow.cpp | 121 ++++++++++++++++++ .../mainwindow.hpp} | 26 +++- 8 files changed, 342 insertions(+), 53 deletions(-) rename gui/src/{gtk-lumiera.h => gtk-lumiera.hpp} (96%) delete mode 100644 gui/src/main-window.cpp create mode 100644 gui/src/workspace/actions.cpp create mode 100644 gui/src/workspace/actions.hpp create mode 100644 gui/src/workspace/mainwindow.cpp rename gui/src/{main-window.h => workspace/mainwindow.hpp} (68%) diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index a47247986..a2ef821b3 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -1,7 +1,5 @@ ## Process this file with automake to produce Makefile.in -## Created by Anjuta - gladedir = $(datadir)/gtk-lumiera/glade glade_DATA = gtk-lumiera.glade @@ -17,14 +15,18 @@ AM_CFLAGS =\ bin_PROGRAMS = gtk-lumiera -gtk_lumiera_SOURCES = \ - main.cpp \ - main-window.cpp \ - main-window.h \ - gtk-lumiera.h +gtk_lumiera_SOURCES = \ + main.cpp \ + gtk-lumiera.hpp \ + workspace/actions.cpp \ + workspace/actions.hpp \ + workspace/mainwindow.cpp \ + workspace/mainwindow.hpp gtk_lumiera_LDFLAGS = gtk_lumiera_LDADD = $(GTK_LUMIERA_LIBS) EXTRA_DIST = $(glade_DATA) + + diff --git a/gui/src/gtk-lumiera.h b/gui/src/gtk-lumiera.hpp similarity index 96% rename from gui/src/gtk-lumiera.h rename to gui/src/gtk-lumiera.hpp index 1b69d5521..e8b9eed6a 100644 --- a/gui/src/gtk-lumiera.h +++ b/gui/src/gtk-lumiera.hpp @@ -25,3 +25,5 @@ # define textdomain(Domain) # define bindtextdomain(Package, Directory) #endif + +const gchar* AppTitle = N_("Lumiera"); diff --git a/gui/src/main-window.cpp b/gui/src/main-window.cpp deleted file mode 100644 index e0984f238..000000000 --- a/gui/src/main-window.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// main-window.cpp -// Tue Apr 8 23:54:36 2008 -// Copyright 2008 joel -// > - -// This program 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. -// -// This program 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 Library General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA - -#include - -#ifdef ENABLE_NLS -# include -#endif - -#include "gtk-lumiera.h" -#include "main-window.h" - -namespace Lumiera { -namespace UI { - -MainWindow::MainWindow() -{ - set_title(_("Lumiera")); - set_default_size(1024, 768); -} - -} -} diff --git a/gui/src/main.cpp b/gui/src/main.cpp index aa3a9f0a3..9c9298ebf 100644 --- a/gui/src/main.cpp +++ b/gui/src/main.cpp @@ -29,13 +29,16 @@ # include #endif -#include "main-window.h" +#include "workspace/mainwindow.hpp" -using namespace Lumiera::UI; +using namespace Lumiera::Workspace; +using namespace Gtk; int main (int argc, char *argv[]) { - Gtk::Main kit(argc, argv); + Main kit(argc, argv); + + Glib::set_application_name("UIManager example"); MainWindow main_window; diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp new file mode 100644 index 000000000..1fc1f3a9f --- /dev/null +++ b/gui/src/workspace/actions.cpp @@ -0,0 +1,121 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * gui + * Copyright (C) 2008 <> + * + * gui is free software. + * + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * gui 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 gui. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +#include "actions.hpp" +#include "mainwindow.hpp" + +namespace Lumiera { +namespace Workspace { + +Actions::Actions(MainWindow &main_window) : + _main_window(main_window) +{ + _action_group = Gtk::ActionGroup::create(); + + // File|New sub menu: + _action_group->add(Gtk::Action::create("FileNewStandard", + Gtk::Stock::NEW, "_New", "Create a new file"), + sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); + + _action_group->add(Gtk::Action::create("FileNewFoo", + Gtk::Stock::NEW, "New Foo", "Create a new foo"), + sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); + + _action_group->add(Gtk::Action::create("FileNewGoo", + Gtk::Stock::NEW, "_New Goo", "Create a new goo"), + sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); + + // File menu: + _action_group->add(Gtk::Action::create("FileMenu", "File")); + // Sub-menu. + _action_group->add(Gtk::Action::create("FileNew", Gtk::Stock::NEW)); + _action_group->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), + sigc::mem_fun(*this, &Actions::on_menu_file_quit)); + + // Edit menu: + _action_group->add(Gtk::Action::create("EditMenu", "Edit")); + _action_group->add(Gtk::Action::create("EditCopy", Gtk::Stock::COPY), + sigc::mem_fun(*this, &Actions::on_menu_others)); + _action_group->add(Gtk::Action::create("EditPaste", Gtk::Stock::PASTE), + sigc::mem_fun(*this, &Actions::on_menu_others)); + _action_group->add(Gtk::Action::create("EditSomething", "Something"), + Gtk::AccelKey("S"), + sigc::mem_fun(*this, &Actions::on_menu_others)); + + // Choices menu, to demonstrate Radio items + _action_group->add( Gtk::Action::create("ChoicesMenu", "Choices") ); + Gtk::RadioAction::Group group_userlevel; + m_refChoiceOne = Gtk::RadioAction::create(group_userlevel, "ChoiceOne", "One"); + _action_group->add(m_refChoiceOne, + sigc::mem_fun(*this, &Actions::on_menu_choices_one) ); + m_refChoiceTwo = Gtk::RadioAction::create(group_userlevel, "ChoiceTwo", "Two"); + _action_group->add(m_refChoiceTwo, + sigc::mem_fun(*this, &Actions::on_menu_choices_two) ); + + // Help menu: + _action_group->add( Gtk::Action::create("HelpMenu", "Help") ); + _action_group->add( Gtk::Action::create("HelpAbout", Gtk::Stock::HELP), + sigc::mem_fun(*this, &Actions::on_menu_others) ); +} + +void Actions::on_menu_file_quit() +{ + _main_window.hide(); // Closes the main window to stop the Gtk::Main::run(). +} + +void Actions::on_menu_file_new_generic() +{ + g_message("A File|New menu item was selecteda."); +} + +void Actions::on_menu_others() +{ + g_message("A menu item was selected."); +} + +void Actions::on_menu_choices_one() +{ + Glib::ustring message; + //if(m_refChoiceOne->get_active()) + // message = "Choice 1 was selected."; + //else + message = "Choice 1 was deselected"; + + g_message(message.c_str()); +} + +void Actions::on_menu_choices_two() +{ + Glib::ustring message; + //if(_main_window.m_refChoiceTwo->get_active()) + // message = "Choice 2 was selected."; + //else + message = "Choice 2 was deselected"; + + g_message(message.c_str()); +} + +} // namespace Workspace +} // namespace Lumiera + diff --git a/gui/src/workspace/actions.hpp b/gui/src/workspace/actions.hpp new file mode 100644 index 000000000..787c5a376 --- /dev/null +++ b/gui/src/workspace/actions.hpp @@ -0,0 +1,61 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * gui + * Copyright (C) 2008 <> + * + * gui is free software. + * + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * gui 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 gui. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +#ifndef ACTIONS_H +#define ACTIONS_H + +#include + +namespace Lumiera { +namespace Workspace { + +class MainWindow; + +class Actions +{ +private: + Actions(MainWindow &main_window); + + //----- Event Handlers -----// + void on_menu_file_new_generic(); + void on_menu_file_quit(); + void on_menu_others(); + + void on_menu_choices_one(); + void on_menu_choices_two(); + + //----- Actions -----// + Glib::RefPtr _action_group; + Glib::RefPtr m_refChoiceOne, m_refChoiceTwo; + + // Reference to the main window + MainWindow &_main_window; + + friend class MainWindow; +}; + +} // namespace Workspace +} // namespace Lumiera + +#endif // ACTIONS_H diff --git a/gui/src/workspace/mainwindow.cpp b/gui/src/workspace/mainwindow.cpp new file mode 100644 index 000000000..79eea3a2b --- /dev/null +++ b/gui/src/workspace/mainwindow.cpp @@ -0,0 +1,121 @@ +// main-window.cpp +// Tue Apr 8 23:54:36 2008 +// Copyright 2008 joel +// + +// This program 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. +// +// This program 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 Library General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA + +#include + +#ifdef ENABLE_NLS +# include +#endif + +#include "gtk-lumiera.hpp" +#include "mainwindow.hpp" + +namespace Lumiera { +namespace Workspace { + +MainWindow::MainWindow() + : _actions(*this) +{ + create_ui(); +} + +MainWindow::~MainWindow() +{ +} + +void MainWindow::create_ui() +{ + //----- Configure the Window -----// + set_title(AppTitle); + set_default_size(1024, 768); + + // The UI will be nested within a VBOX + add(_box); + + m_refUIManager = Gtk::UIManager::create(); + m_refUIManager->insert_action_group(_actions._action_group); + + add_accel_group(m_refUIManager->get_accel_group()); + + //Layout the actions in a menubar and toolbar: + Glib::ustring ui_info = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try + { + m_refUIManager->add_ui_from_string(ui_info); + } + catch(const Glib::Error& ex) + { + g_error("building menus failed: "); + return; + } +#else + std::auto_ptr ex; + m_refUIManager->add_ui_from_string(ui_info, ex); + if(ex.get()) + { + g_error("building menus failed: "); + return; + } +#endif //GLIBMM_EXCEPTIONS_ENABLED + + // Get the menubar and toolbar widgets, and add them to a container widget: + Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar"); + if(pMenubar) + _box.pack_start(*pMenubar, Gtk::PACK_SHRINK); + + Gtk::Widget* pToolbar = m_refUIManager->get_widget("/ToolBar") ; + if(pToolbar) + _box.pack_start(*pToolbar, Gtk::PACK_SHRINK); + + show_all_children(); +} + +} // namespace Workspace +} // namespace Lumiera + diff --git a/gui/src/main-window.h b/gui/src/workspace/mainwindow.hpp similarity index 68% rename from gui/src/main-window.h rename to gui/src/workspace/mainwindow.hpp index 8d916eb1f..7beab8783 100644 --- a/gui/src/main-window.h +++ b/gui/src/workspace/mainwindow.hpp @@ -14,16 +14,34 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA */ -#include +#ifndef MAIN_WINDOW_H +#define MAIN_WINDOW_H + +#include +#include "actions.hpp" namespace Lumiera { -namespace UI { +namespace Workspace { class MainWindow : public Gtk::Window { public: MainWindow(); + virtual ~MainWindow(); + +protected: + void create_ui(); + + // Helpers + Actions _actions; + + // Child widgets + Gtk::VBox _box; + + Glib::RefPtr m_refUIManager; }; -} -} +} // namespace Workspace +} // namespace Lumiera + +#endif // MAIN_WINDOW_H From bd0e634a27882642c65775fa297b1600dfd8bc61 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Fri, 11 Apr 2008 22:04:39 +0100 Subject: [PATCH 006/245] Reformatted code to comply with project format guidlines, and added some documentation --- gui/src/gtk-lumiera.hpp | 49 ++++++++---- gui/src/main.cpp | 59 +++++++------- gui/src/workspace/actions.cpp | 129 ++++++++++++++++--------------- gui/src/workspace/actions.hpp | 98 ++++++++++++----------- gui/src/workspace/mainwindow.cpp | 98 +++++++++++------------ gui/src/workspace/mainwindow.hpp | 85 ++++++++++++-------- 6 files changed, 290 insertions(+), 228 deletions(-) diff --git a/gui/src/gtk-lumiera.hpp b/gui/src/gtk-lumiera.hpp index e8b9eed6a..97eb98744 100644 --- a/gui/src/gtk-lumiera.hpp +++ b/gui/src/gtk-lumiera.hpp @@ -1,18 +1,32 @@ /* - * This program 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 2 of the License, or - * (at your option) any later version. - * - * This program 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 Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA + gtk-lumiera.hpp - Application wide global definitions + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file gtk-lumiera.hpp + ** This file contains application wide global definitions + ** user actions. + ** @see main.cpp */ + +#ifndef GTK_LUMIERA_HPP +#define GTK_LUMIERA_HPO #ifdef ENABLE_NLS # include @@ -26,4 +40,11 @@ # define bindtextdomain(Package, Directory) #endif -const gchar* AppTitle = N_("Lumiera"); +/** + * The name of the Lumiera application + */ +static const gchar* AppTitle = N_("Lumiera"); + +#endif + + diff --git a/gui/src/main.cpp b/gui/src/main.cpp index 9c9298ebf..9b191fc1e 100644 --- a/gui/src/main.cpp +++ b/gui/src/main.cpp @@ -1,26 +1,24 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* - * main.cpp - * Copyright (C) Joel Holdsworth 2008 - * - * main.cc is free software. - * - * You may redistribute it and/or modify it under the terms of the - * GNU General Public License, as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * main.cc 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 main.cc. If not, write to: - * The Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301, USA. - */ + Main.cpp - The entry point for the GTK GUI application + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ #include #include @@ -29,20 +27,27 @@ # include #endif +#include "gtk-lumiera.hpp" #include "workspace/mainwindow.hpp" -using namespace Lumiera::Workspace; + +//const gchar* AppTitle +//const gchar AppTitle[] = N_("Lumiera"); + +using namespace lumiera::workspace; using namespace Gtk; -int main (int argc, char *argv[]) -{ + int + main (int argc, char *argv[]) + { Main kit(argc, argv); - Glib::set_application_name("UIManager example"); + Glib::set_application_name(AppTitle); MainWindow main_window; kit.run(main_window); return 0; -} + } + diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp index 1fc1f3a9f..801140ecc 100644 --- a/gui/src/workspace/actions.cpp +++ b/gui/src/workspace/actions.cpp @@ -1,101 +1,105 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* - * gui - * Copyright (C) 2008 <> - * - * gui is free software. - * - * You may redistribute it and/or modify it under the terms of the - * GNU General Public License, as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * gui 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 gui. If not, write to: - * The Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301, USA. - */ + Actions.cpp - Definition of the main workspace window object + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ #include "actions.hpp" #include "mainwindow.hpp" -namespace Lumiera { -namespace Workspace { +namespace lumiera + { +namespace workspace + { -Actions::Actions(MainWindow &main_window) : - _main_window(main_window) -{ - _action_group = Gtk::ActionGroup::create(); + Actions::Actions(MainWindow &main_window) : + mainWindow(main_window) + { + actionGroup = Gtk::ActionGroup::create(); // File|New sub menu: - _action_group->add(Gtk::Action::create("FileNewStandard", + actionGroup->add(Gtk::Action::create("FileNewStandard", Gtk::Stock::NEW, "_New", "Create a new file"), sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); - _action_group->add(Gtk::Action::create("FileNewFoo", + actionGroup->add(Gtk::Action::create("FileNewFoo", Gtk::Stock::NEW, "New Foo", "Create a new foo"), sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); - _action_group->add(Gtk::Action::create("FileNewGoo", + actionGroup->add(Gtk::Action::create("FileNewGoo", Gtk::Stock::NEW, "_New Goo", "Create a new goo"), sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); // File menu: - _action_group->add(Gtk::Action::create("FileMenu", "File")); + actionGroup->add(Gtk::Action::create("FileMenu", "File")); // Sub-menu. - _action_group->add(Gtk::Action::create("FileNew", Gtk::Stock::NEW)); - _action_group->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), + actionGroup->add(Gtk::Action::create("FileNew", Gtk::Stock::NEW)); + actionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), sigc::mem_fun(*this, &Actions::on_menu_file_quit)); // Edit menu: - _action_group->add(Gtk::Action::create("EditMenu", "Edit")); - _action_group->add(Gtk::Action::create("EditCopy", Gtk::Stock::COPY), + actionGroup->add(Gtk::Action::create("EditMenu", "Edit")); + actionGroup->add(Gtk::Action::create("EditCopy", Gtk::Stock::COPY), sigc::mem_fun(*this, &Actions::on_menu_others)); - _action_group->add(Gtk::Action::create("EditPaste", Gtk::Stock::PASTE), + actionGroup->add(Gtk::Action::create("EditPaste", Gtk::Stock::PASTE), sigc::mem_fun(*this, &Actions::on_menu_others)); - _action_group->add(Gtk::Action::create("EditSomething", "Something"), + actionGroup->add(Gtk::Action::create("EditSomething", "Something"), Gtk::AccelKey("S"), sigc::mem_fun(*this, &Actions::on_menu_others)); // Choices menu, to demonstrate Radio items - _action_group->add( Gtk::Action::create("ChoicesMenu", "Choices") ); + actionGroup->add( Gtk::Action::create("ChoicesMenu", "Choices") ); Gtk::RadioAction::Group group_userlevel; m_refChoiceOne = Gtk::RadioAction::create(group_userlevel, "ChoiceOne", "One"); - _action_group->add(m_refChoiceOne, + actionGroup->add(m_refChoiceOne, sigc::mem_fun(*this, &Actions::on_menu_choices_one) ); m_refChoiceTwo = Gtk::RadioAction::create(group_userlevel, "ChoiceTwo", "Two"); - _action_group->add(m_refChoiceTwo, + actionGroup->add(m_refChoiceTwo, sigc::mem_fun(*this, &Actions::on_menu_choices_two) ); // Help menu: - _action_group->add( Gtk::Action::create("HelpMenu", "Help") ); - _action_group->add( Gtk::Action::create("HelpAbout", Gtk::Stock::HELP), + actionGroup->add( Gtk::Action::create("HelpMenu", "Help") ); + actionGroup->add( Gtk::Action::create("HelpAbout", Gtk::Stock::HELP), sigc::mem_fun(*this, &Actions::on_menu_others) ); -} + } -void Actions::on_menu_file_quit() -{ - _main_window.hide(); // Closes the main window to stop the Gtk::Main::run(). -} + void + Actions::on_menu_file_quit() + { + mainWindow.hide(); // Closes the main window to stop the Gtk::Main::run(). + } -void Actions::on_menu_file_new_generic() -{ + void + Actions::on_menu_file_new_generic() + { g_message("A File|New menu item was selecteda."); -} + } -void Actions::on_menu_others() -{ + void + Actions::on_menu_others() + { g_message("A menu item was selected."); -} + } -void Actions::on_menu_choices_one() -{ + void + Actions::on_menu_choices_one() + { Glib::ustring message; //if(m_refChoiceOne->get_active()) // message = "Choice 1 was selected."; @@ -103,10 +107,11 @@ void Actions::on_menu_choices_one() message = "Choice 1 was deselected"; g_message(message.c_str()); -} + } -void Actions::on_menu_choices_two() -{ + void + Actions::on_menu_choices_two() + { Glib::ustring message; //if(_main_window.m_refChoiceTwo->get_active()) // message = "Choice 2 was selected."; @@ -114,8 +119,8 @@ void Actions::on_menu_choices_two() message = "Choice 2 was deselected"; g_message(message.c_str()); -} + } -} // namespace Workspace -} // namespace Lumiera +} // namespace workspace +} // namespace lumiera diff --git a/gui/src/workspace/actions.hpp b/gui/src/workspace/actions.hpp index 787c5a376..ec8abe3bc 100644 --- a/gui/src/workspace/actions.hpp +++ b/gui/src/workspace/actions.hpp @@ -1,61 +1,71 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* - * gui - * Copyright (C) 2008 <> - * - * gui is free software. - * - * You may redistribute it and/or modify it under the terms of the - * GNU General Public License, as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * gui 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 gui. If not, write to: - * The Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301, USA. + ACTIONS.hpp - Definition of a helper class for user actions + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file actions.hpp + ** This file contains the definition of a helper class for the + ** main workspace window object, which registers and handles + ** user actions. + ** @see mainwindow.hpp */ -#ifndef ACTIONS_H -#define ACTIONS_H +#ifndef ACTIONS_HPP +#define ACTIONS_HPP #include -namespace Lumiera { -namespace Workspace { +namespace lumiera { +namespace workspace { class MainWindow; -class Actions -{ -private: - Actions(MainWindow &main_window); + /** + * A helper class which registers and handles + * user action events. + */ + class Actions + { + private: + Actions(MainWindow &main_window); - //----- Event Handlers -----// - void on_menu_file_new_generic(); - void on_menu_file_quit(); - void on_menu_others(); + /** + * A reference to the MainWindow which owns + * this helper */ + MainWindow &mainWindow; - void on_menu_choices_one(); - void on_menu_choices_two(); + /* ===== Event Handlers ===== */ + void on_menu_file_new_generic(); + void on_menu_file_quit(); + void on_menu_others(); - //----- Actions -----// - Glib::RefPtr _action_group; - Glib::RefPtr m_refChoiceOne, m_refChoiceTwo; + void on_menu_choices_one(); + void on_menu_choices_two(); - // Reference to the main window - MainWindow &_main_window; + /* ===== Actions ===== */ + Glib::RefPtr actionGroup; + Glib::RefPtr m_refChoiceOne, m_refChoiceTwo; - friend class MainWindow; -}; + friend class MainWindow; + }; -} // namespace Workspace -} // namespace Lumiera +} // namespace workspace +} // namespace lumiera #endif // ACTIONS_H diff --git a/gui/src/workspace/mainwindow.cpp b/gui/src/workspace/mainwindow.cpp index 79eea3a2b..9ae32ea88 100644 --- a/gui/src/workspace/mainwindow.cpp +++ b/gui/src/workspace/mainwindow.cpp @@ -1,21 +1,24 @@ -// main-window.cpp -// Tue Apr 8 23:54:36 2008 -// Copyright 2008 joel -// - -// This program 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. -// -// This program 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 Library General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA +/* + MainWindow.cpp - Definition of the main workspace window object + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ #include @@ -26,32 +29,33 @@ #include "gtk-lumiera.hpp" #include "mainwindow.hpp" -namespace Lumiera { -namespace Workspace { +namespace lumiera { +namespace workspace { -MainWindow::MainWindow() - : _actions(*this) -{ + MainWindow::MainWindow() + : actions(*this) + { create_ui(); -} + } -MainWindow::~MainWindow() -{ -} + MainWindow::~MainWindow() + { + } -void MainWindow::create_ui() -{ + void + MainWindow::create_ui() + { //----- Configure the Window -----// set_title(AppTitle); set_default_size(1024, 768); // The UI will be nested within a VBOX - add(_box); + add(box); - m_refUIManager = Gtk::UIManager::create(); - m_refUIManager->insert_action_group(_actions._action_group); + uiManager = Gtk::UIManager::create(); + uiManager->insert_action_group(actions.actionGroup); - add_accel_group(m_refUIManager->get_accel_group()); + add_accel_group(uiManager->get_accel_group()); //Layout the actions in a menubar and toolbar: Glib::ustring ui_info = @@ -87,35 +91,33 @@ void MainWindow::create_ui() #ifdef GLIBMM_EXCEPTIONS_ENABLED try { - m_refUIManager->add_ui_from_string(ui_info); + uiManager->add_ui_from_string(ui_info); } catch(const Glib::Error& ex) { - g_error("building menus failed: "); - return; + g_error("building menus failed: "); + return; } #else std::auto_ptr ex; - m_refUIManager->add_ui_from_string(ui_info, ex); + uiManager->add_ui_from_string(ui_info, ex); if(ex.get()) { - g_error("building menus failed: "); - return; + g_error("building menus failed: "); + return; } #endif //GLIBMM_EXCEPTIONS_ENABLED // Get the menubar and toolbar widgets, and add them to a container widget: - Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar"); - if(pMenubar) - _box.pack_start(*pMenubar, Gtk::PACK_SHRINK); + Gtk::Widget* menu_bar = uiManager->get_widget("/MenuBar"); + if(menu_bar) box.pack_start(*menu_bar, Gtk::PACK_SHRINK); - Gtk::Widget* pToolbar = m_refUIManager->get_widget("/ToolBar") ; - if(pToolbar) - _box.pack_start(*pToolbar, Gtk::PACK_SHRINK); + Gtk::Widget* toolbar = uiManager->get_widget("/ToolBar") ; + if(toolbar) box.pack_start(*toolbar, Gtk::PACK_SHRINK); show_all_children(); -} + } -} // namespace Workspace -} // namespace Lumiera +} // namespace workspace +} // namespace lumiera diff --git a/gui/src/workspace/mainwindow.hpp b/gui/src/workspace/mainwindow.hpp index 7beab8783..494393051 100644 --- a/gui/src/workspace/mainwindow.hpp +++ b/gui/src/workspace/mainwindow.hpp @@ -1,17 +1,29 @@ /* - * This program 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. - * - * This program 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 Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA + MainWindow.hpp - Definition of the main workspace window object + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file mainwindow.hpp + ** This file contains the definition of the main workspace window + ** parent, which is the toplevel parent of the whole workspace. + ** + ** @see mainwindow.hpp */ #ifndef MAIN_WINDOW_H @@ -20,28 +32,35 @@ #include #include "actions.hpp" -namespace Lumiera { -namespace Workspace { +namespace lumiera { +namespace workspace { + + /** + * The main lumiera workspace window + */ + class MainWindow : public Gtk::Window + { + public: + MainWindow(); + virtual ~MainWindow(); -class MainWindow : public Gtk::Window -{ -public: - MainWindow(); - virtual ~MainWindow(); - -protected: - void create_ui(); - - // Helpers - Actions _actions; + protected: + void create_ui(); - // Child widgets - Gtk::VBox _box; + /* ===== UI ===== */ + protected: + Gtk::VBox box; + Glib::RefPtr uiManager; + + /* ===== Helpers ===== */ + protected: + /** + * The instantiation of the actions helper class, which + * registers and handles user action events */ + Actions actions; + }; - Glib::RefPtr m_refUIManager; -}; - -} // namespace Workspace -} // namespace Lumiera +} // namespace workspace +} // namespace lumiera #endif // MAIN_WINDOW_H From 6498aef338697f84e67603f30318a1fae16b9229 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 12 Apr 2008 00:23:12 +0100 Subject: [PATCH 007/245] Removed some build files which should not be present --- gui/config.h | 77 ------------------------------------------ gui/gtk-lumiera.anjuta | 44 ------------------------ 2 files changed, 121 deletions(-) delete mode 100644 gui/config.h delete mode 100644 gui/gtk-lumiera.anjuta diff --git a/gui/config.h b/gui/config.h deleted file mode 100644 index 7b9564f69..000000000 --- a/gui/config.h +++ /dev/null @@ -1,77 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* always defined to indicate that i18n is enabled */ -#define ENABLE_NLS 1 - -/* GETTEXT package name */ -#define GETTEXT_PACKAGE "gtk-lumiera" - -/* Define to 1 if you have the `bind_textdomain_codeset' function. */ -#define HAVE_BIND_TEXTDOMAIN_CODESET 1 - -/* Define to 1 if you have the `dcgettext' function. */ -#define HAVE_DCGETTEXT 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define if the GNU gettext() function is already present or preinstalled. */ -#define HAVE_GETTEXT 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define if your file defines LC_MESSAGES. */ -#define HAVE_LC_MESSAGES 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Name of package */ -#define PACKAGE "gtk-lumiera" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "gtk-lumiera" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "gtk-lumiera 0.1" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "gtk-lumiera" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "0.1" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "0.1" diff --git a/gui/gtk-lumiera.anjuta b/gui/gtk-lumiera.anjuta deleted file mode 100644 index 8b9268a44..000000000 --- a/gui/gtk-lumiera.anjuta +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - From 4698998d43a4d81e4091ebe45b154b17ee9c5956 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 12 Apr 2008 17:46:32 +0100 Subject: [PATCH 008/245] Added a placeholder for the Render dialog, and restructured application and namespaces --- gui/src/Makefile.am | 8 +- gui/src/{main.cpp => dialogs/render.cpp} | 43 +++--- gui/src/dialogs/render.hpp | 51 +++++++ gui/src/gtk-lumiera.cpp | 97 ++++++++++++ gui/src/gtk-lumiera.glade | 179 +++++++++++++++++++---- gui/src/gtk-lumiera.hpp | 39 ++++- gui/src/workspace/actions.cpp | 24 ++- gui/src/workspace/actions.hpp | 13 +- gui/src/workspace/mainwindow.cpp | 4 + gui/src/workspace/mainwindow.hpp | 6 +- 10 files changed, 392 insertions(+), 72 deletions(-) rename gui/src/{main.cpp => dialogs/render.cpp} (63%) create mode 100644 gui/src/dialogs/render.hpp create mode 100644 gui/src/gtk-lumiera.cpp diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index a2ef821b3..0cef35d54 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -16,12 +16,14 @@ AM_CFLAGS =\ bin_PROGRAMS = gtk-lumiera gtk_lumiera_SOURCES = \ - main.cpp \ + gtk-lumiera.cpp \ gtk-lumiera.hpp \ workspace/actions.cpp \ workspace/actions.hpp \ - workspace/mainwindow.cpp \ - workspace/mainwindow.hpp + workspace/mainwindow.cpp \ + workspace/mainwindow.hpp \ + dialogs/render.cpp \ + dialogs/render.hpp gtk_lumiera_LDFLAGS = diff --git a/gui/src/main.cpp b/gui/src/dialogs/render.cpp similarity index 63% rename from gui/src/main.cpp rename to gui/src/dialogs/render.cpp index 9b191fc1e..35f83113f 100644 --- a/gui/src/main.cpp +++ b/gui/src/dialogs/render.cpp @@ -1,5 +1,5 @@ /* - Main.cpp - The entry point for the GTK GUI application + render.cpp - Definition of the main workspace window object Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -20,34 +20,25 @@ * *****************************************************/ -#include -#include +#include "../gtk-lumiera.hpp" -#ifdef ENABLE_NLS -# include -#endif - -#include "gtk-lumiera.hpp" -#include "workspace/mainwindow.hpp" +namespace lumiera { +namespace gui { +namespace dialogs { -//const gchar* AppTitle -//const gchar AppTitle[] = N_("Lumiera"); - -using namespace lumiera::workspace; -using namespace Gtk; - - int - main (int argc, char *argv[]) + Render::Render(BaseObjectType* cobject, const Glib::RefPtr& xml) : + Gtk::Dialog(cobject) { - Main kit(argc, argv); - - Glib::set_application_name(AppTitle); - - MainWindow main_window; - - kit.run(main_window); - - return 0; + } + void + Render::init(const Glib::RefPtr& glade_xml, Render*& dialog) + { + glade_xml->get_widget_derived("Render", dialog); + } + +} // namespace dialogs +} // namespace gui +} // namespace lumiera diff --git a/gui/src/dialogs/render.hpp b/gui/src/dialogs/render.hpp new file mode 100644 index 000000000..473699bfa --- /dev/null +++ b/gui/src/dialogs/render.hpp @@ -0,0 +1,51 @@ +/* + render.hpp - Definition of the render output dialog + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file render.hpp + ** This file contains the definition of the render output dialog + ** + */ + +#ifndef RENDER_H +#define RENDER_H + +#include + +namespace lumiera { +namespace gui { +namespace dialogs { + + /** + * The defintion of render output dialog class + */ + class Render : public Gtk::Dialog + { + public: + Render(BaseObjectType* cobject, const Glib::RefPtr& xml); + + static void init(const Glib::RefPtr& glade_xml, Render*& dialog); + }; + +} // namespace dialogs +} // namespace gui +} // namespace lumiera + +#endif // RENDER_H diff --git a/gui/src/gtk-lumiera.cpp b/gui/src/gtk-lumiera.cpp new file mode 100644 index 000000000..146a6de00 --- /dev/null +++ b/gui/src/gtk-lumiera.cpp @@ -0,0 +1,97 @@ +/* + gtk-lumiera.cpp - The entry point for the GTK GUI application + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include +#include + +#ifdef ENABLE_NLS +# include +#endif + +#include "gtk-lumiera.hpp" +#include "workspace/mainwindow.hpp" + +using namespace lumiera::gui; +using namespace lumiera::gui::workspace; +using namespace Gtk; + +GtkLumiera the_application; + + int + main (int argc, char *argv[]) + { + + return the_application.main(argc, argv); + } + + + +namespace lumiera { +namespace gui { + + int + GtkLumiera::main(int argc, char *argv[]) + { + Main kit(argc, argv); + + Glib::set_application_name(AppTitle); + + init_ui(); + + MainWindow main_window; + + kit.run(main_window); + } + + dialogs::Render* + GtkLumiera::get_render_dialog() const + { + g_assert(renderDialog != NULL); + return renderDialog; + } + + void + GtkLumiera::init_ui() + { + try + { + gladeXml = Gnome::Glade::Xml::create("gtk-lumiera.glade"); + } + catch(const Gnome::Glade::XmlError& ex) + { + g_message(ex.what().data()); + return; + } + + dialogs::Render::init(gladeXml, renderDialog); + } + + GtkLumiera& + application() + { + return the_application; + } + +} // namespace gui +} // namespace lumiera + + diff --git a/gui/src/gtk-lumiera.glade b/gui/src/gtk-lumiera.glade index 8db3bef2c..79e9e3d89 100644 --- a/gui/src/gtk-lumiera.glade +++ b/gui/src/gtk-lumiera.glade @@ -1,27 +1,156 @@ - - - + + + - - - True - Hello World! - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - 500 - 400 - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - - - - - - + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + GTK_WIN_POS_CENTER_ON_PARENT + GDK_WINDOW_TYPE_HINT_DIALOG + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 4 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 4 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Output File: + + + False + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-open + True + 0 + + + False + 2 + + + + + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 4 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Container Format: + + + False + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + + + + + False + 1 + + + + + + + + + + + + + + + + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-cancel + True + 0 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-ok + True + 0 + + + 1 + + + + + False + GTK_PACK_END + + + + + diff --git a/gui/src/gtk-lumiera.hpp b/gui/src/gtk-lumiera.hpp index 97eb98744..ebfb2056c 100644 --- a/gui/src/gtk-lumiera.hpp +++ b/gui/src/gtk-lumiera.hpp @@ -27,6 +27,9 @@ #ifndef GTK_LUMIERA_HPP #define GTK_LUMIERA_HPO + +#include +#include "dialogs/render.hpp" #ifdef ENABLE_NLS # include @@ -40,10 +43,38 @@ # define bindtextdomain(Package, Directory) #endif -/** - * The name of the Lumiera application - */ -static const gchar* AppTitle = N_("Lumiera"); +namespace lumiera { +namespace gui { + + /** + * The name of the Lumiera application + */ + static const gchar* AppTitle = N_("Lumiera"); + + class GtkLumiera + { + public: + int main(int argc, char *argv[]); + + public: + dialogs::Render* get_render_dialog() const; + + private: + void init_ui(); + + private: + Glib::RefPtr gladeXml; + + dialogs::Render *renderDialog; + }; + + /** + * Returns a reference to the global application object + */ + GtkLumiera& application(); + +} // namespace gui +} // namespace lumiera #endif diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp index 801140ecc..7a735be96 100644 --- a/gui/src/workspace/actions.cpp +++ b/gui/src/workspace/actions.cpp @@ -20,13 +20,13 @@ * *****************************************************/ +#include "../gtk-lumiera.hpp" #include "actions.hpp" #include "mainwindow.hpp" -namespace lumiera - { -namespace workspace - { +namespace lumiera { +namespace gui { +namespace workspace { Actions::Actions(MainWindow &main_window) : mainWindow(main_window) @@ -50,8 +50,11 @@ namespace workspace actionGroup->add(Gtk::Action::create("FileMenu", "File")); // Sub-menu. actionGroup->add(Gtk::Action::create("FileNew", Gtk::Stock::NEW)); + actionGroup->add(Gtk::Action::create("FileRender", _("Render...")), + Gtk::AccelKey("R"), + sigc::mem_fun(*this, &Actions::on_menu_file_render)); actionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), - sigc::mem_fun(*this, &Actions::on_menu_file_quit)); + sigc::mem_fun(*this, &Actions::on_menu_file_quit)); // Edit menu: actionGroup->add(Gtk::Action::create("EditMenu", "Edit")); @@ -60,8 +63,8 @@ namespace workspace actionGroup->add(Gtk::Action::create("EditPaste", Gtk::Stock::PASTE), sigc::mem_fun(*this, &Actions::on_menu_others)); actionGroup->add(Gtk::Action::create("EditSomething", "Something"), - Gtk::AccelKey("S"), - sigc::mem_fun(*this, &Actions::on_menu_others)); + Gtk::AccelKey("S"), + sigc::mem_fun(*this, &Actions::on_menu_others)); // Choices menu, to demonstrate Radio items actionGroup->add( Gtk::Action::create("ChoicesMenu", "Choices") ); @@ -79,6 +82,12 @@ namespace workspace sigc::mem_fun(*this, &Actions::on_menu_others) ); } + void + Actions::on_menu_file_render() + { + application().get_render_dialog()->run(); + } + void Actions::on_menu_file_quit() { @@ -122,5 +131,6 @@ namespace workspace } } // namespace workspace +} // namespace gui } // namespace lumiera diff --git a/gui/src/workspace/actions.hpp b/gui/src/workspace/actions.hpp index ec8abe3bc..a552be90e 100644 --- a/gui/src/workspace/actions.hpp +++ b/gui/src/workspace/actions.hpp @@ -32,6 +32,7 @@ #include namespace lumiera { +namespace gui { namespace workspace { class MainWindow; @@ -51,12 +52,13 @@ class MainWindow; MainWindow &mainWindow; /* ===== Event Handlers ===== */ - void on_menu_file_new_generic(); - void on_menu_file_quit(); - void on_menu_others(); + void on_menu_file_new_generic(); + void on_menu_file_render(); + void on_menu_file_quit(); + void on_menu_others(); - void on_menu_choices_one(); - void on_menu_choices_two(); + void on_menu_choices_one(); + void on_menu_choices_two(); /* ===== Actions ===== */ Glib::RefPtr actionGroup; @@ -66,6 +68,7 @@ class MainWindow; }; } // namespace workspace +} // namespace gui } // namespace lumiera #endif // ACTIONS_H diff --git a/gui/src/workspace/mainwindow.cpp b/gui/src/workspace/mainwindow.cpp index 9ae32ea88..8b2c13074 100644 --- a/gui/src/workspace/mainwindow.cpp +++ b/gui/src/workspace/mainwindow.cpp @@ -30,6 +30,7 @@ #include "mainwindow.hpp" namespace lumiera { +namespace gui { namespace workspace { MainWindow::MainWindow() @@ -68,6 +69,8 @@ namespace workspace { " " " " " " + " " + " " " " " " " " @@ -119,5 +122,6 @@ namespace workspace { } } // namespace workspace +} // namespace gui } // namespace lumiera diff --git a/gui/src/workspace/mainwindow.hpp b/gui/src/workspace/mainwindow.hpp index 494393051..541646c29 100644 --- a/gui/src/workspace/mainwindow.hpp +++ b/gui/src/workspace/mainwindow.hpp @@ -1,5 +1,5 @@ /* - MainWindow.hpp - Definition of the main workspace window object + mainwindow.hpp - Definition of the main workspace window object Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -23,7 +23,7 @@ ** This file contains the definition of the main workspace window ** parent, which is the toplevel parent of the whole workspace. ** - ** @see mainwindow.hpp + ** @see actions.hpp */ #ifndef MAIN_WINDOW_H @@ -33,6 +33,7 @@ #include "actions.hpp" namespace lumiera { +namespace gui { namespace workspace { /** @@ -61,6 +62,7 @@ namespace workspace { }; } // namespace workspace +} // namespace gui } // namespace lumiera #endif // MAIN_WINDOW_H From 584a33408bda46b0a1a6f2a668cced8bf1ddfc8b Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 12 Apr 2008 21:15:07 +0100 Subject: [PATCH 009/245] Added GDL docking framework, and some placeholder panels --- gui/src/Makefile.am | 12 +++++-- gui/src/panels/assets.cpp | 38 ++++++++++++++++++++ gui/src/panels/assets.hpp | 48 +++++++++++++++++++++++++ gui/src/panels/panel.cpp | 49 +++++++++++++++++++++++++ gui/src/panels/panel.hpp | 59 ++++++++++++++++++++++++++++++ gui/src/panels/timeline.cpp | 38 ++++++++++++++++++++ gui/src/panels/timeline.hpp | 48 +++++++++++++++++++++++++ gui/src/panels/viewer.cpp | 38 ++++++++++++++++++++ gui/src/panels/viewer.hpp | 48 +++++++++++++++++++++++++ gui/src/workspace/mainwindow.cpp | 61 +++++++++++++++++++++++--------- gui/src/workspace/mainwindow.hpp | 29 ++++++++++++--- 11 files changed, 445 insertions(+), 23 deletions(-) create mode 100644 gui/src/panels/assets.cpp create mode 100644 gui/src/panels/assets.hpp create mode 100644 gui/src/panels/panel.cpp create mode 100644 gui/src/panels/panel.hpp create mode 100644 gui/src/panels/timeline.cpp create mode 100644 gui/src/panels/timeline.hpp create mode 100644 gui/src/panels/viewer.cpp create mode 100644 gui/src/panels/viewer.hpp diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index 0cef35d54..0d149d8de 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -16,14 +16,22 @@ AM_CFLAGS =\ bin_PROGRAMS = gtk-lumiera gtk_lumiera_SOURCES = \ - gtk-lumiera.cpp \ + gtk-lumiera.cpp \ gtk-lumiera.hpp \ workspace/actions.cpp \ workspace/actions.hpp \ workspace/mainwindow.cpp \ workspace/mainwindow.hpp \ dialogs/render.cpp \ - dialogs/render.hpp + dialogs/render.hpp \ + panels/panel.cpp \ + panels/panel.hpp \ + panels/timeline.cpp \ + panels/timeline.hpp \ + panels/viewer.cpp \ + panels/viewer.hpp \ + panels/assets.cpp \ + panels/assets.hpp gtk_lumiera_LDFLAGS = diff --git a/gui/src/panels/assets.cpp b/gui/src/panels/assets.cpp new file mode 100644 index 000000000..daaa0f363 --- /dev/null +++ b/gui/src/panels/assets.cpp @@ -0,0 +1,38 @@ +/* + assets.cpp - Implementation of the assets panel + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "assets.hpp" + +namespace lumiera { +namespace gui { +namespace panels { + +Assets::Assets() : + Panel("assets", "Assets"), + placeholder("Placeholder label. Is this supposed to be titled assets\nas in the proc layer? or resources\nas in cinelerra?") + { + pack_start(placeholder); + } + +} // namespace panels +} // namespace gui +} // namespace lumiera diff --git a/gui/src/panels/assets.hpp b/gui/src/panels/assets.hpp new file mode 100644 index 000000000..1a11107d9 --- /dev/null +++ b/gui/src/panels/assets.hpp @@ -0,0 +1,48 @@ +/* + assets.hpp - Definition of the assets panel + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file timeline.hpp + ** This file contains the definition of the assets panel + */ + +#ifndef ASSETS_H +#define ASSETS_H + +#include "panel.hpp" + +namespace lumiera { +namespace gui { +namespace panels { + + class Assets : public Panel + { + public: + Assets(); + + protected: + Gtk::Label placeholder; + }; + +} // namespace panels +} // namespace gui +} // namespace lumiera + +#endif // ASSETS_H diff --git a/gui/src/panels/panel.cpp b/gui/src/panels/panel.cpp new file mode 100644 index 000000000..67ac1fd3f --- /dev/null +++ b/gui/src/panels/panel.cpp @@ -0,0 +1,49 @@ +/* + panel.cpp - Implementation of Panel, the base class for docking panels + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "panel.hpp" + +namespace lumiera { +namespace gui { +namespace panels { + +Panel::Panel(const gchar *name, const gchar *long_name, GdlDockItemBehavior behavior) +{ + dock_item = (GdlDockItem*)gdl_dock_item_new (name, long_name, behavior); + gtk_container_add ((GtkContainer*)dock_item, (GtkWidget*)gobj()); + gtk_widget_show ((GtkWidget*)dock_item); +} + +Panel::~Panel() +{ + +} + +GdlDockItem* Panel::get_dock_item() const +{ + return dock_item; +} + +} // namespace panels +} // namespace gui +} // namespace lumiera + diff --git a/gui/src/panels/panel.hpp b/gui/src/panels/panel.hpp new file mode 100644 index 000000000..fdb7296cf --- /dev/null +++ b/gui/src/panels/panel.hpp @@ -0,0 +1,59 @@ +/* + panel.hpp - Definition of Panel, the base class for docking panels + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file panel.hpp + ** This file contains the definition of Panel; the base class + ** for all docking panels + */ + +#ifndef PANEL_H +#define PANEL_H + +#include +#include + +namespace lumiera { +namespace gui { +namespace panels { + + /** + * The main lumiera workspace window + */ + class Panel : public Gtk::VBox + { + protected: + Panel(const gchar *name, const gchar *long_name, + GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL); + ~Panel(); + + public: + GdlDockItem* get_dock_item() const; + + + protected: + GdlDockItem* dock_item; + }; + +} // namespace panels +} // namespace gui +} // namespace lumiera + +#endif // PANEL_H diff --git a/gui/src/panels/timeline.cpp b/gui/src/panels/timeline.cpp new file mode 100644 index 000000000..1e5086fd7 --- /dev/null +++ b/gui/src/panels/timeline.cpp @@ -0,0 +1,38 @@ +/* + timeline.cpp - Implementation of the timeline panel + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "timeline.hpp" + +namespace lumiera { +namespace gui { +namespace panels { + +Timeline::Timeline() : + Panel("timeline", "Timeline"), + placeholder("Placeholder label. Is Timeline the correct title for this panel?") + { + pack_start(placeholder); + } + +} // namespace panels +} // namespace gui +} // namespace lumiera diff --git a/gui/src/panels/timeline.hpp b/gui/src/panels/timeline.hpp new file mode 100644 index 000000000..54c6afe1e --- /dev/null +++ b/gui/src/panels/timeline.hpp @@ -0,0 +1,48 @@ +/* + timeline.hpp - Definition of the timeline panel + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file timeline.hpp + ** This file contains the definition of the timeline panel + */ + +#ifndef TIMELINE_H +#define TIMELINE_H + +#include "panel.hpp" + +namespace lumiera { +namespace gui { +namespace panels { + + class Timeline : public Panel + { + public: + Timeline(); + + protected: + Gtk::Label placeholder; + }; + +} // namespace panels +} // namespace gui +} // namespace lumiera + +#endif // TIMELINE_H diff --git a/gui/src/panels/viewer.cpp b/gui/src/panels/viewer.cpp new file mode 100644 index 000000000..991bb7457 --- /dev/null +++ b/gui/src/panels/viewer.cpp @@ -0,0 +1,38 @@ +/* + viewer.cpp - Implementation of the viewer panel + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "viewer.hpp" + +namespace lumiera { +namespace gui { +namespace panels { + +Viewer::Viewer() : + Panel("viewer", "Viewer"), + placeholder("Placeholder: XVideo in here!!!") + { + pack_start(placeholder); + } + +} // namespace panels +} // namespace gui +} // namespace lumiera diff --git a/gui/src/panels/viewer.hpp b/gui/src/panels/viewer.hpp new file mode 100644 index 000000000..8090f01c4 --- /dev/null +++ b/gui/src/panels/viewer.hpp @@ -0,0 +1,48 @@ +/* + viewer.hpp - Definition of the viewer panel + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file viewer.hpp + ** This file contains the definition of the viewer panel + */ + +#ifndef VIEWER_H +#define VIEWER_H + +#include "panel.hpp" + +namespace lumiera { +namespace gui { +namespace panels { + + class Viewer : public Panel + { + public: + Viewer(); + + protected: + Gtk::Button placeholder; + }; + +} // namespace panels +} // namespace gui +} // namespace lumiera + +#endif // VIEWER_H diff --git a/gui/src/workspace/mainwindow.cpp b/gui/src/workspace/mainwindow.cpp index 8b2c13074..bbff0aa6d 100644 --- a/gui/src/workspace/mainwindow.cpp +++ b/gui/src/workspace/mainwindow.cpp @@ -26,9 +26,20 @@ # include #endif +#include + +#include +#include +#include +#include +#include +#include + #include "gtk-lumiera.hpp" #include "mainwindow.hpp" +using namespace Gtk; + namespace lumiera { namespace gui { namespace workspace { @@ -51,7 +62,7 @@ namespace workspace { set_default_size(1024, 768); // The UI will be nested within a VBOX - add(box); + add(base_container); uiManager = Gtk::UIManager::create(); uiManager->insert_action_group(actions.actionGroup); @@ -91,34 +102,52 @@ namespace workspace { " " ""; -#ifdef GLIBMM_EXCEPTIONS_ENABLED try { uiManager->add_ui_from_string(ui_info); } catch(const Glib::Error& ex) { - g_error("building menus failed: "); + g_error("building menus failed: %s", ex.what().data()); return; } -#else - std::auto_ptr ex; - uiManager->add_ui_from_string(ui_info, ex); - if(ex.get()) - { - g_error("building menus failed: "); - return; - } -#endif //GLIBMM_EXCEPTIONS_ENABLED // Get the menubar and toolbar widgets, and add them to a container widget: Gtk::Widget* menu_bar = uiManager->get_widget("/MenuBar"); - if(menu_bar) box.pack_start(*menu_bar, Gtk::PACK_SHRINK); - + g_assert(menu_bar); + base_container.pack_start(*menu_bar, Gtk::PACK_SHRINK); + Gtk::Widget* toolbar = uiManager->get_widget("/ToolBar") ; - if(toolbar) box.pack_start(*toolbar, Gtk::PACK_SHRINK); + g_assert(toolbar); + base_container.pack_start(*toolbar, Gtk::PACK_SHRINK); - show_all_children(); + //----- Create the dock -----// + dock = Glib::wrap(gdl_dock_new()); + + layout = gdl_dock_layout_new((GdlDock*)dock->gobj()); + + dockbar = Glib::wrap(gdl_dock_bar_new ((GdlDock*)dock->gobj())); + gdl_dock_bar_set_style((GdlDockBar*)dockbar->gobj(), GDL_DOCK_BAR_TEXT); + + dock_container.pack_start(*dockbar, PACK_SHRINK); + dock_container.pack_end(*dock, PACK_EXPAND_WIDGET); + base_container.pack_start(dock_container, PACK_EXPAND_WIDGET); + + gdl_dock_add_item ((GdlDock*)dock->gobj(), assets.get_dock_item(), GDL_DOCK_LEFT); + gdl_dock_add_item ((GdlDock*)dock->gobj(), viewer.get_dock_item(), GDL_DOCK_RIGHT); + gdl_dock_add_item ((GdlDock*)dock->gobj(), timeline.get_dock_item(), GDL_DOCK_BOTTOM); + + // Manually dock and move around some of the items + gdl_dock_item_dock_to (timeline.get_dock_item(), assets.get_dock_item(), + GDL_DOCK_BOTTOM, -1); + gdl_dock_item_dock_to (viewer.get_dock_item(), assets.get_dock_item(), + GDL_DOCK_RIGHT, -1); + show_all_children(); + + gdl_dock_placeholder_new ("ph1", (GdlDockObject*)dock->gobj(), GDL_DOCK_TOP, FALSE); + gdl_dock_placeholder_new ("ph2", (GdlDockObject*)dock->gobj(), GDL_DOCK_BOTTOM, FALSE); + gdl_dock_placeholder_new ("ph3", (GdlDockObject*)dock->gobj(), GDL_DOCK_LEFT, FALSE); + gdl_dock_placeholder_new ("ph4", (GdlDockObject*)dock->gobj(), GDL_DOCK_RIGHT, FALSE); } } // namespace workspace diff --git a/gui/src/workspace/mainwindow.hpp b/gui/src/workspace/mainwindow.hpp index 541646c29..3913533cc 100644 --- a/gui/src/workspace/mainwindow.hpp +++ b/gui/src/workspace/mainwindow.hpp @@ -26,12 +26,20 @@ ** @see actions.hpp */ -#ifndef MAIN_WINDOW_H -#define MAIN_WINDOW_H +#ifndef MAINWINDOW_H +#define MAINWINDOW_H #include +#include + #include "actions.hpp" +#include "../panels/assets.hpp" +#include "../panels/viewer.hpp" +#include "../panels/timeline.hpp" + +using namespace lumiera::gui::panels; + namespace lumiera { namespace gui { namespace workspace { @@ -42,17 +50,28 @@ namespace workspace { class MainWindow : public Gtk::Window { public: - MainWindow(); - virtual ~MainWindow(); + MainWindow(); + virtual ~MainWindow(); protected: void create_ui(); /* ===== UI ===== */ protected: - Gtk::VBox box; Glib::RefPtr uiManager; + Gtk::VBox base_container; + Gtk::HBox dock_container; + Gtk::Widget *dock; + Gtk::Widget *dockbar; + GdlDockLayout *layout; + + /* ===== Panels ===== */ + protected: + Assets assets; + Viewer viewer; + Timeline timeline; + /* ===== Helpers ===== */ protected: /** From 1c91e56fc5e79b9ff3b3d94efa96504334b77087 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 14 Apr 2008 21:10:56 +0100 Subject: [PATCH 010/245] Corrected the version check for gdl >= v0.7.6 --- gui/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/configure.ac b/gui/configure.ac index 0bc4740c9..170dcc687 100644 --- a/gui/configure.ac +++ b/gui/configure.ac @@ -30,7 +30,7 @@ AM_PROG_LIBTOOL -PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 libglademm-2.4 >= 2.6 gdl-1.0 >= 0.2.6]) +PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 libglademm-2.4 >= 2.6 gdl-1.0 >= 0.7.6]) AC_SUBST(GTK_LUMIERA_CFLAGS) AC_SUBST(GTK_LUMIERA_LIBS) From 368f3595b407b5f85db393eb20f36f7734010630 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 14 Apr 2008 22:51:59 +0100 Subject: [PATCH 011/245] Renamed mainwindow.* -> main-window.*, and added the base of video viewer widget --- gui/src/Makefile.am | 8 +- gui/src/gtk-lumiera.cpp | 2 +- gui/src/panels/timeline.hpp | 4 +- gui/src/panels/viewer.cpp | 7 +- gui/src/panels/viewer.hpp | 5 +- gui/src/widgets/video-display.cpp | 77 +++++++++++++++++++ gui/src/widgets/video-display.hpp | 50 ++++++++++++ gui/src/workspace/actions.cpp | 2 +- .../{mainwindow.cpp => main-window.cpp} | 4 +- .../{mainwindow.hpp => main-window.hpp} | 8 +- 10 files changed, 150 insertions(+), 17 deletions(-) create mode 100644 gui/src/widgets/video-display.cpp create mode 100644 gui/src/widgets/video-display.hpp rename gui/src/workspace/{mainwindow.cpp => main-window.cpp} (97%) rename gui/src/workspace/{mainwindow.hpp => main-window.hpp} (93%) diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index 0d149d8de..eda59746e 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -20,8 +20,8 @@ gtk_lumiera_SOURCES = \ gtk-lumiera.hpp \ workspace/actions.cpp \ workspace/actions.hpp \ - workspace/mainwindow.cpp \ - workspace/mainwindow.hpp \ + workspace/main-window.cpp \ + workspace/main-window.hpp \ dialogs/render.cpp \ dialogs/render.hpp \ panels/panel.cpp \ @@ -31,7 +31,9 @@ gtk_lumiera_SOURCES = \ panels/viewer.cpp \ panels/viewer.hpp \ panels/assets.cpp \ - panels/assets.hpp + panels/assets.hpp \ + widgets/video-display.cpp \ + widgets/video-display.hpp gtk_lumiera_LDFLAGS = diff --git a/gui/src/gtk-lumiera.cpp b/gui/src/gtk-lumiera.cpp index 146a6de00..1a6dfacc5 100644 --- a/gui/src/gtk-lumiera.cpp +++ b/gui/src/gtk-lumiera.cpp @@ -28,7 +28,7 @@ #endif #include "gtk-lumiera.hpp" -#include "workspace/mainwindow.hpp" +#include "workspace/main-window.hpp" using namespace lumiera::gui; using namespace lumiera::gui::workspace; diff --git a/gui/src/panels/timeline.hpp b/gui/src/panels/timeline.hpp index 54c6afe1e..b219b3f55 100644 --- a/gui/src/panels/timeline.hpp +++ b/gui/src/panels/timeline.hpp @@ -23,8 +23,8 @@ ** This file contains the definition of the timeline panel */ -#ifndef TIMELINE_H -#define TIMELINE_H +#ifndef TIMELINE_HPP +#define TIMELINE_HPP #include "panel.hpp" diff --git a/gui/src/panels/viewer.cpp b/gui/src/panels/viewer.cpp index 991bb7457..d10ca7929 100644 --- a/gui/src/panels/viewer.cpp +++ b/gui/src/panels/viewer.cpp @@ -22,15 +22,16 @@ #include "viewer.hpp" +using namespace lumiera::gui::widgets; + namespace lumiera { namespace gui { namespace panels { Viewer::Viewer() : - Panel("viewer", "Viewer"), - placeholder("Placeholder: XVideo in here!!!") + Panel("viewer", "Viewer") { - pack_start(placeholder); + pack_start(display); } } // namespace panels diff --git a/gui/src/panels/viewer.hpp b/gui/src/panels/viewer.hpp index 8090f01c4..5d7038961 100644 --- a/gui/src/panels/viewer.hpp +++ b/gui/src/panels/viewer.hpp @@ -27,6 +27,9 @@ #define VIEWER_H #include "panel.hpp" +#include "../widgets/video-display.hpp" + +using namespace lumiera::gui::widgets; namespace lumiera { namespace gui { @@ -38,7 +41,7 @@ namespace panels { Viewer(); protected: - Gtk::Button placeholder; + VideoDisplay display; }; } // namespace panels diff --git a/gui/src/widgets/video-display.cpp b/gui/src/widgets/video-display.cpp new file mode 100644 index 000000000..4ec1eada5 --- /dev/null +++ b/gui/src/widgets/video-display.cpp @@ -0,0 +1,77 @@ +/* + video-display.cpp - Implementation of the video viewer widget + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include +#include + +#include "video-display.hpp" + +namespace lumiera { +namespace gui { +namespace widgets { + +VideoDisplay::VideoDisplay() + { + set_flags(Gtk::NO_WINDOW); + } + +void +VideoDisplay::on_realize() + { + //Call base class: + Gtk::Widget::on_realize(); + + } + +bool +VideoDisplay::on_expose_event(GdkEventExpose* event) + { + // This is where we draw on the window + Glib::RefPtr window = get_window(); + if(window) + { + double scale_x = 1; + double scale_y = 1; + + Cairo::RefPtr cr = window->create_cairo_context(); + if(event) + { + // clip to the area that needs to be re-exposed so we don't draw any + // more than we need to. + cr->rectangle(event->area.x, event->area.y, + event->area.width, event->area.height); + cr->clip(); + } + + // Paint the background + cr->set_source_rgb(0.0, 0.0, 0.0); + cr->paint(); + } + return true; + } + + + +} // namespace widgets +} // namespace gui +} // namespace lumiera + diff --git a/gui/src/widgets/video-display.hpp b/gui/src/widgets/video-display.hpp new file mode 100644 index 000000000..34fbce81c --- /dev/null +++ b/gui/src/widgets/video-display.hpp @@ -0,0 +1,50 @@ +/* + video-display.hpp - Declaration of the video viewer widget + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file viewer.hpp + ** This file contains the definition of video viewer widget + */ + +#ifndef VIDEO_DISPLAY_HPP +#define VIDEO_DISPLAY_HPP + +#include + +namespace lumiera { +namespace gui { +namespace widgets { + + class VideoDisplay : public Gtk::Widget + { + public: + VideoDisplay(); + + /* ===== Overrides ===== */ + protected: + virtual void on_realize(); + virtual bool on_expose_event(GdkEventExpose* event); + }; + +} // namespace widgets +} // namespace gui +} // namespace lumiera + +#endif // VIDEO_DISPLAY_H diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp index 7a735be96..a6633b4aa 100644 --- a/gui/src/workspace/actions.cpp +++ b/gui/src/workspace/actions.cpp @@ -22,7 +22,7 @@ #include "../gtk-lumiera.hpp" #include "actions.hpp" -#include "mainwindow.hpp" +#include "main-window.hpp" namespace lumiera { namespace gui { diff --git a/gui/src/workspace/mainwindow.cpp b/gui/src/workspace/main-window.cpp similarity index 97% rename from gui/src/workspace/mainwindow.cpp rename to gui/src/workspace/main-window.cpp index bbff0aa6d..d51dd554b 100644 --- a/gui/src/workspace/mainwindow.cpp +++ b/gui/src/workspace/main-window.cpp @@ -1,5 +1,5 @@ /* - MainWindow.cpp - Definition of the main workspace window object + main-window.cpp - Definition of the main workspace window object Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -36,7 +36,7 @@ #include #include "gtk-lumiera.hpp" -#include "mainwindow.hpp" +#include "main-window.hpp" using namespace Gtk; diff --git a/gui/src/workspace/mainwindow.hpp b/gui/src/workspace/main-window.hpp similarity index 93% rename from gui/src/workspace/mainwindow.hpp rename to gui/src/workspace/main-window.hpp index 3913533cc..1b997623a 100644 --- a/gui/src/workspace/mainwindow.hpp +++ b/gui/src/workspace/main-window.hpp @@ -1,5 +1,5 @@ /* - mainwindow.hpp - Definition of the main workspace window object + main-window.hpp - Definition of the main workspace window object Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -26,8 +26,8 @@ ** @see actions.hpp */ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H +#ifndef MAIN_WINDOW_HPP +#define MAIN_WINDOW_HPP #include #include @@ -84,4 +84,4 @@ namespace workspace { } // namespace gui } // namespace lumiera -#endif // MAIN_WINDOW_H +#endif // MAIN_WINDOW_HPP From 26fb2497e66c34bfac9ff95f593da6ada2688649 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 14 Apr 2008 22:57:13 +0100 Subject: [PATCH 012/245] Modified toolbar style from default to icons only --- gui/src/workspace/main-window.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gui/src/workspace/main-window.cpp b/gui/src/workspace/main-window.cpp index d51dd554b..096f28014 100644 --- a/gui/src/workspace/main-window.cpp +++ b/gui/src/workspace/main-window.cpp @@ -61,6 +61,7 @@ namespace workspace { set_title(AppTitle); set_default_size(1024, 768); + //----- Set up the UI Manager -----// // The UI will be nested within a VBOX add(base_container); @@ -112,13 +113,15 @@ namespace workspace { return; } - // Get the menubar and toolbar widgets, and add them to a container widget: + //----- Set up the Menu Bar -----// Gtk::Widget* menu_bar = uiManager->get_widget("/MenuBar"); - g_assert(menu_bar); + g_assert(menu_bar != NULL); base_container.pack_start(*menu_bar, Gtk::PACK_SHRINK); - Gtk::Widget* toolbar = uiManager->get_widget("/ToolBar") ; - g_assert(toolbar); + //----- Set up the Tool Bar -----// + Gtk::Toolbar* toolbar = dynamic_cast(uiManager->get_widget("/ToolBar")); + g_assert(toolbar != NULL); + toolbar->set_toolbar_style(TOOLBAR_ICONS); base_container.pack_start(*toolbar, Gtk::PACK_SHRINK); //----- Create the dock -----// From 8691db867165093a4d34bbe0e9b15cb24df6b9dd Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 14 Apr 2008 23:23:29 +0100 Subject: [PATCH 013/245] Added basic playback controls to the viewer panel --- gui/src/panels/viewer.cpp | 23 +++++++++++++++++++++-- gui/src/panels/viewer.hpp | 11 +++++++++++ gui/src/workspace/main-window.cpp | 3 +-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/gui/src/panels/viewer.cpp b/gui/src/panels/viewer.cpp index d10ca7929..0c64f3d68 100644 --- a/gui/src/panels/viewer.cpp +++ b/gui/src/panels/viewer.cpp @@ -23,15 +23,34 @@ #include "viewer.hpp" using namespace lumiera::gui::widgets; +using namespace Gtk; namespace lumiera { namespace gui { namespace panels { Viewer::Viewer() : - Panel("viewer", "Viewer") + Panel("viewer", "Viewer"), + previousButton(Stock::MEDIA_PREVIOUS), + rewindButton(Stock::MEDIA_REWIND), + playPauseButton(Stock::MEDIA_PLAY), + forwardButton(Stock::MEDIA_FORWARD), + nextButton(Stock::MEDIA_NEXT) { - pack_start(display); + //----- Set up the Tool Bar -----// + // Add the commands + toolBar.append(previousButton); + toolBar.append(rewindButton); + toolBar.append(playPauseButton); + toolBar.append(forwardButton); + toolBar.append(nextButton); + + // Configure the toolbar + toolBar.set_toolbar_style(TOOLBAR_ICONS); + + //----- Pack in the Widgets -----// + pack_start(display, PACK_EXPAND_WIDGET); + pack_start(toolBar, PACK_SHRINK); } } // namespace panels diff --git a/gui/src/panels/viewer.hpp b/gui/src/panels/viewer.hpp index 5d7038961..e6d459ffa 100644 --- a/gui/src/panels/viewer.hpp +++ b/gui/src/panels/viewer.hpp @@ -26,10 +26,13 @@ #ifndef VIEWER_H #define VIEWER_H +#include + #include "panel.hpp" #include "../widgets/video-display.hpp" using namespace lumiera::gui::widgets; +using namespace Gtk; namespace lumiera { namespace gui { @@ -41,7 +44,15 @@ namespace panels { Viewer(); protected: + + ToolButton previousButton; + ToolButton rewindButton; + ToolButton playPauseButton; + ToolButton forwardButton; + ToolButton nextButton; + VideoDisplay display; + Toolbar toolBar; }; } // namespace panels diff --git a/gui/src/workspace/main-window.cpp b/gui/src/workspace/main-window.cpp index 096f28014..3f1868d03 100644 --- a/gui/src/workspace/main-window.cpp +++ b/gui/src/workspace/main-window.cpp @@ -27,7 +27,6 @@ #endif #include - #include #include #include @@ -109,7 +108,7 @@ namespace workspace { } catch(const Glib::Error& ex) { - g_error("building menus failed: %s", ex.what().data()); + g_error("Building menus failed: %s", ex.what().data()); return; } From c7255625ec77b5b9abb0e5d23295e14fb558393a Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Tue, 15 Apr 2008 23:36:15 +0100 Subject: [PATCH 014/245] Restructured dialogs a bit. Dialogs are now centred on the main window when shown --- gui/src/dialogs/render.cpp | 7 ++++--- gui/src/dialogs/render.hpp | 4 +++- gui/src/workspace/actions.cpp | 2 +- gui/src/workspace/main-window.cpp | 17 +++++++++++++++++ gui/src/workspace/main-window.hpp | 12 ++++++++++++ 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/gui/src/dialogs/render.cpp b/gui/src/dialogs/render.cpp index 35f83113f..48423ebb0 100644 --- a/gui/src/dialogs/render.cpp +++ b/gui/src/dialogs/render.cpp @@ -20,13 +20,12 @@ * *****************************************************/ -#include "../gtk-lumiera.hpp" +#include "render.hpp" namespace lumiera { namespace gui { namespace dialogs { - Render::Render(BaseObjectType* cobject, const Glib::RefPtr& xml) : Gtk::Dialog(cobject) { @@ -34,9 +33,11 @@ namespace dialogs { } void - Render::init(const Glib::RefPtr& glade_xml, Render*& dialog) + Render::init(Gtk::Window &parent, + const Glib::RefPtr& glade_xml, Render*& dialog) { glade_xml->get_widget_derived("Render", dialog); + if(dialog != NULL) dialog->set_transient_for(parent); } } // namespace dialogs diff --git a/gui/src/dialogs/render.hpp b/gui/src/dialogs/render.hpp index 473699bfa..d515ece96 100644 --- a/gui/src/dialogs/render.hpp +++ b/gui/src/dialogs/render.hpp @@ -28,6 +28,7 @@ #define RENDER_H #include +#include namespace lumiera { namespace gui { @@ -41,7 +42,8 @@ namespace dialogs { public: Render(BaseObjectType* cobject, const Glib::RefPtr& xml); - static void init(const Glib::RefPtr& glade_xml, Render*& dialog); + static void init(Gtk::Window &parent, + const Glib::RefPtr& glade_xml, Render*& dialog); }; } // namespace dialogs diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp index a6633b4aa..6f644a458 100644 --- a/gui/src/workspace/actions.cpp +++ b/gui/src/workspace/actions.cpp @@ -85,7 +85,7 @@ namespace workspace { void Actions::on_menu_file_render() { - application().get_render_dialog()->run(); + mainWindow.renderDialog->run(); } void diff --git a/gui/src/workspace/main-window.cpp b/gui/src/workspace/main-window.cpp index 3f1868d03..658057bcc 100644 --- a/gui/src/workspace/main-window.cpp +++ b/gui/src/workspace/main-window.cpp @@ -47,6 +47,7 @@ namespace workspace { : actions(*this) { create_ui(); + create_dialogs(); } MainWindow::~MainWindow() @@ -152,6 +153,22 @@ namespace workspace { gdl_dock_placeholder_new ("ph4", (GdlDockObject*)dock->gobj(), GDL_DOCK_RIGHT, FALSE); } + void + MainWindow::create_dialogs() + { + try + { + gladeXml = Gnome::Glade::Xml::create("gtk-lumiera.glade"); + } + catch(const Gnome::Glade::XmlError& ex) + { + g_message(ex.what().data()); + return; + } + + dialogs::Render::init(*this, gladeXml, renderDialog); + } + } // namespace workspace } // namespace gui } // namespace lumiera diff --git a/gui/src/workspace/main-window.hpp b/gui/src/workspace/main-window.hpp index 1b997623a..526f8df6c 100644 --- a/gui/src/workspace/main-window.hpp +++ b/gui/src/workspace/main-window.hpp @@ -31,6 +31,7 @@ #include #include +#include #include "actions.hpp" @@ -38,6 +39,8 @@ #include "../panels/viewer.hpp" #include "../panels/timeline.hpp" +#include "../dialogs/render.hpp" + using namespace lumiera::gui::panels; namespace lumiera { @@ -55,6 +58,7 @@ namespace workspace { protected: void create_ui(); + void create_dialogs(); /* ===== UI ===== */ protected: @@ -71,6 +75,12 @@ namespace workspace { Assets assets; Viewer viewer; Timeline timeline; + + /* ===== Dialogs ===== */ + protected: + Glib::RefPtr gladeXml; + + dialogs::Render *renderDialog; /* ===== Helpers ===== */ protected: @@ -78,6 +88,8 @@ namespace workspace { * The instantiation of the actions helper class, which * registers and handles user action events */ Actions actions; + + friend class Actions; }; } // namespace workspace From 7f487ed3ec04beac389267b8d7f676872143cfa1 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Wed, 16 Apr 2008 18:24:11 +0100 Subject: [PATCH 015/245] Added a Help>About about dialog --- gui/src/gtk-lumiera.cpp | 26 -------- gui/src/gtk-lumiera.glade | 3 +- gui/src/gtk-lumiera.hpp | 46 +++++++++----- gui/src/workspace/actions.cpp | 110 +++++++++++++++++++++------------- gui/src/workspace/actions.hpp | 5 +- 5 files changed, 106 insertions(+), 84 deletions(-) diff --git a/gui/src/gtk-lumiera.cpp b/gui/src/gtk-lumiera.cpp index 1a6dfacc5..4dff269b4 100644 --- a/gui/src/gtk-lumiera.cpp +++ b/gui/src/gtk-lumiera.cpp @@ -39,7 +39,6 @@ GtkLumiera the_application; int main (int argc, char *argv[]) { - return the_application.main(argc, argv); } @@ -54,37 +53,12 @@ namespace gui { Main kit(argc, argv); Glib::set_application_name(AppTitle); - - init_ui(); MainWindow main_window; kit.run(main_window); } - dialogs::Render* - GtkLumiera::get_render_dialog() const - { - g_assert(renderDialog != NULL); - return renderDialog; - } - - void - GtkLumiera::init_ui() - { - try - { - gladeXml = Gnome::Glade::Xml::create("gtk-lumiera.glade"); - } - catch(const Gnome::Glade::XmlError& ex) - { - g_message(ex.what().data()); - return; - } - - dialogs::Render::init(gladeXml, renderDialog); - } - GtkLumiera& application() { diff --git a/gui/src/gtk-lumiera.glade b/gui/src/gtk-lumiera.glade index 79e9e3d89..d0c8a28f4 100644 --- a/gui/src/gtk-lumiera.glade +++ b/gui/src/gtk-lumiera.glade @@ -1,10 +1,11 @@ - + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + False GTK_WIN_POS_CENTER_ON_PARENT GDK_WINDOW_TYPE_HINT_DIALOG False diff --git a/gui/src/gtk-lumiera.hpp b/gui/src/gtk-lumiera.hpp index ebfb2056c..6532d2b42 100644 --- a/gui/src/gtk-lumiera.hpp +++ b/gui/src/gtk-lumiera.hpp @@ -28,9 +28,8 @@ #ifndef GTK_LUMIERA_HPP #define GTK_LUMIERA_HPO -#include -#include "dialogs/render.hpp" - +#include + #ifdef ENABLE_NLS # include # define _(String) gettext (String) @@ -47,25 +46,42 @@ namespace lumiera { namespace gui { /** - * The name of the Lumiera application + * The name of the application */ - static const gchar* AppTitle = N_("Lumiera"); + static const gchar* AppTitle = "Lumiera"; + /** + * The version number of the application + */ + static const gchar* AppVersion = N_("0.1-dev"); + + /** + * The copyright of the application + */ + static const gchar* AppCopyright = N_("© 2008 The Lumiera Team"); + + /** + * The website of the application + */ + static const gchar* AppWebsite = "www.lumiera.org"; + + /** + * An alphabetical list of the application's authors + */ + static const gchar* AppAuthors[] = { + "Joel Holdsworth", + "Christian Thaeter", + "Hermann Vosseler", + ""}; + + /** + * The main application class. + */ class GtkLumiera { public: int main(int argc, char *argv[]); - public: - dialogs::Render* get_render_dialog() const; - - private: - void init_ui(); - - private: - Glib::RefPtr gladeXml; - - dialogs::Render *renderDialog; }; /** diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp index 6f644a458..fc7b70fde 100644 --- a/gui/src/workspace/actions.cpp +++ b/gui/src/workspace/actions.cpp @@ -24,6 +24,9 @@ #include "actions.hpp" #include "main-window.hpp" +using namespace Gtk; +using namespace Glib; + namespace lumiera { namespace gui { namespace workspace { @@ -31,55 +34,55 @@ namespace workspace { Actions::Actions(MainWindow &main_window) : mainWindow(main_window) { - actionGroup = Gtk::ActionGroup::create(); + actionGroup = Gtk::ActionGroup::create(); - // File|New sub menu: - actionGroup->add(Gtk::Action::create("FileNewStandard", - Gtk::Stock::NEW, "_New", "Create a new file"), - sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); + // File|New sub menu: + actionGroup->add(Gtk::Action::create("FileNewStandard", + Gtk::Stock::NEW, "_New", "Create a new file"), + sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); - actionGroup->add(Gtk::Action::create("FileNewFoo", - Gtk::Stock::NEW, "New Foo", "Create a new foo"), - sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); + actionGroup->add(Gtk::Action::create("FileNewFoo", + Gtk::Stock::NEW, "New Foo", "Create a new foo"), + sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); - actionGroup->add(Gtk::Action::create("FileNewGoo", - Gtk::Stock::NEW, "_New Goo", "Create a new goo"), - sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); + actionGroup->add(Gtk::Action::create("FileNewGoo", + Gtk::Stock::NEW, "_New Goo", "Create a new goo"), + sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); - // File menu: - actionGroup->add(Gtk::Action::create("FileMenu", "File")); - // Sub-menu. - actionGroup->add(Gtk::Action::create("FileNew", Gtk::Stock::NEW)); - actionGroup->add(Gtk::Action::create("FileRender", _("Render...")), - Gtk::AccelKey("R"), - sigc::mem_fun(*this, &Actions::on_menu_file_render)); - actionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), - sigc::mem_fun(*this, &Actions::on_menu_file_quit)); + // File menu: + actionGroup->add(Gtk::Action::create("FileMenu", "File")); + // Sub-menu. + actionGroup->add(Gtk::Action::create("FileNew", Gtk::Stock::NEW)); + actionGroup->add(Gtk::Action::create("FileRender", _("Render...")), + Gtk::AccelKey("R"), + sigc::mem_fun(*this, &Actions::on_menu_file_render)); + actionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), + sigc::mem_fun(*this, &Actions::on_menu_file_quit)); - // Edit menu: - actionGroup->add(Gtk::Action::create("EditMenu", "Edit")); - actionGroup->add(Gtk::Action::create("EditCopy", Gtk::Stock::COPY), - sigc::mem_fun(*this, &Actions::on_menu_others)); - actionGroup->add(Gtk::Action::create("EditPaste", Gtk::Stock::PASTE), - sigc::mem_fun(*this, &Actions::on_menu_others)); - actionGroup->add(Gtk::Action::create("EditSomething", "Something"), - Gtk::AccelKey("S"), + // Edit menu: + actionGroup->add(Gtk::Action::create("EditMenu", "Edit")); + actionGroup->add(Gtk::Action::create("EditCopy", Gtk::Stock::COPY), sigc::mem_fun(*this, &Actions::on_menu_others)); + actionGroup->add(Gtk::Action::create("EditPaste", Gtk::Stock::PASTE), + sigc::mem_fun(*this, &Actions::on_menu_others)); + actionGroup->add(Gtk::Action::create("EditSomething", "Something"), + Gtk::AccelKey("S"), + sigc::mem_fun(*this, &Actions::on_menu_others)); - // Choices menu, to demonstrate Radio items - actionGroup->add( Gtk::Action::create("ChoicesMenu", "Choices") ); - Gtk::RadioAction::Group group_userlevel; - m_refChoiceOne = Gtk::RadioAction::create(group_userlevel, "ChoiceOne", "One"); - actionGroup->add(m_refChoiceOne, - sigc::mem_fun(*this, &Actions::on_menu_choices_one) ); - m_refChoiceTwo = Gtk::RadioAction::create(group_userlevel, "ChoiceTwo", "Two"); - actionGroup->add(m_refChoiceTwo, - sigc::mem_fun(*this, &Actions::on_menu_choices_two) ); + // Choices menu, to demonstrate Radio items + actionGroup->add( Gtk::Action::create("ChoicesMenu", "Choices") ); + Gtk::RadioAction::Group group_userlevel; + m_refChoiceOne = Gtk::RadioAction::create(group_userlevel, "ChoiceOne", "One"); + actionGroup->add(m_refChoiceOne, + sigc::mem_fun(*this, &Actions::on_menu_choices_one) ); + m_refChoiceTwo = Gtk::RadioAction::create(group_userlevel, "ChoiceTwo", "Two"); + actionGroup->add(m_refChoiceTwo, + sigc::mem_fun(*this, &Actions::on_menu_choices_two) ); - // Help menu: - actionGroup->add( Gtk::Action::create("HelpMenu", "Help") ); - actionGroup->add( Gtk::Action::create("HelpAbout", Gtk::Stock::HELP), - sigc::mem_fun(*this, &Actions::on_menu_others) ); + // Help menu: + actionGroup->add( Gtk::Action::create("HelpMenu", "Help") ); + actionGroup->add( Gtk::Action::create("HelpAbout", Gtk::Stock::ABOUT), + sigc::mem_fun(*this, &Actions::on_menu_help_about) ); } void @@ -94,6 +97,31 @@ namespace workspace { mainWindow.hide(); // Closes the main window to stop the Gtk::Main::run(). } + void + Actions::on_menu_help_about() + { + // Configure the about dialog + AboutDialog dialog; + + dialog.set_program_name(AppTitle); + dialog.set_version(AppVersion); + //dialog.set_version(Appconfig::get("version")); + dialog.set_copyright(AppCopyright); + dialog.set_website(AppWebsite); + dialog.set_authors(StringArrayHandle(AppAuthors, + sizeof(AppAuthors) / sizeof(gchar*), + OWNERSHIP_NONE)); + + dialog.set_transient_for(mainWindow); + + // Show the about dialog + dialog.run(); + } + + + + //----- Temporary junk + void Actions::on_menu_file_new_generic() { diff --git a/gui/src/workspace/actions.hpp b/gui/src/workspace/actions.hpp index a552be90e..7c8c1d89e 100644 --- a/gui/src/workspace/actions.hpp +++ b/gui/src/workspace/actions.hpp @@ -55,8 +55,11 @@ class MainWindow; void on_menu_file_new_generic(); void on_menu_file_render(); void on_menu_file_quit(); - void on_menu_others(); + void on_menu_help_about(); + + // Temporary Junk + void on_menu_others(); void on_menu_choices_one(); void on_menu_choices_two(); From aa5580057292dbb4718cfca7c76b7f1d1aeed353 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Wed, 16 Apr 2008 19:48:54 +0100 Subject: [PATCH 016/245] Modified menus to remove dummy example code, and add real file items --- gui/src/workspace/actions.cpp | 85 ++++++++----------------------- gui/src/workspace/actions.hpp | 5 +- gui/src/workspace/main-window.cpp | 14 ++--- 3 files changed, 26 insertions(+), 78 deletions(-) diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp index fc7b70fde..e91ab9ff1 100644 --- a/gui/src/workspace/actions.cpp +++ b/gui/src/workspace/actions.cpp @@ -36,48 +36,24 @@ namespace workspace { { actionGroup = Gtk::ActionGroup::create(); - // File|New sub menu: - actionGroup->add(Gtk::Action::create("FileNewStandard", - Gtk::Stock::NEW, "_New", "Create a new file"), - sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); - - actionGroup->add(Gtk::Action::create("FileNewFoo", - Gtk::Stock::NEW, "New Foo", "Create a new foo"), - sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); - - actionGroup->add(Gtk::Action::create("FileNewGoo", - Gtk::Stock::NEW, "_New Goo", "Create a new goo"), - sigc::mem_fun(*this, &Actions::on_menu_file_new_generic)); - // File menu: - actionGroup->add(Gtk::Action::create("FileMenu", "File")); - // Sub-menu. - actionGroup->add(Gtk::Action::create("FileNew", Gtk::Stock::NEW)); - actionGroup->add(Gtk::Action::create("FileRender", _("Render...")), + actionGroup->add(Gtk::Action::create("FileMenu", _("File"))); + actionGroup->add(Gtk::Action::create("FileNewProject", Gtk::Stock::NEW, _("_New Project...")), + sigc::mem_fun(*this, &Actions::on_menu_file_new_project)); + actionGroup->add(Gtk::Action::create("FileOpenProject", Gtk::Stock::OPEN, _("_Open Project...")), + sigc::mem_fun(*this, &Actions::on_menu_file_new_project)); + actionGroup->add(Gtk::Action::create("FileRender", _("_Render...")), Gtk::AccelKey("R"), sigc::mem_fun(*this, &Actions::on_menu_file_render)); actionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), sigc::mem_fun(*this, &Actions::on_menu_file_quit)); // Edit menu: - actionGroup->add(Gtk::Action::create("EditMenu", "Edit")); + actionGroup->add(Gtk::Action::create("EditMenu", _("Edit"))); actionGroup->add(Gtk::Action::create("EditCopy", Gtk::Stock::COPY), - sigc::mem_fun(*this, &Actions::on_menu_others)); - actionGroup->add(Gtk::Action::create("EditPaste", Gtk::Stock::PASTE), - sigc::mem_fun(*this, &Actions::on_menu_others)); - actionGroup->add(Gtk::Action::create("EditSomething", "Something"), - Gtk::AccelKey("S"), sigc::mem_fun(*this, &Actions::on_menu_others)); - - // Choices menu, to demonstrate Radio items - actionGroup->add( Gtk::Action::create("ChoicesMenu", "Choices") ); - Gtk::RadioAction::Group group_userlevel; - m_refChoiceOne = Gtk::RadioAction::create(group_userlevel, "ChoiceOne", "One"); - actionGroup->add(m_refChoiceOne, - sigc::mem_fun(*this, &Actions::on_menu_choices_one) ); - m_refChoiceTwo = Gtk::RadioAction::create(group_userlevel, "ChoiceTwo", "Two"); - actionGroup->add(m_refChoiceTwo, - sigc::mem_fun(*this, &Actions::on_menu_choices_two) ); + actionGroup->add(Gtk::Action::create("EditPaste", Gtk::Stock::PASTE), + sigc::mem_fun(*this, &Actions::on_menu_others)); // Help menu: actionGroup->add( Gtk::Action::create("HelpMenu", "Help") ); @@ -85,6 +61,18 @@ namespace workspace { sigc::mem_fun(*this, &Actions::on_menu_help_about) ); } + void + Actions::on_menu_file_new_project() + { + g_message("A File|New menu item was selecteda."); + } + + void + Actions::on_menu_file_open_project() + { + g_message("A File|Open menu item was selecteda."); + } + void Actions::on_menu_file_render() { @@ -121,43 +109,12 @@ namespace workspace { //----- Temporary junk - - void - Actions::on_menu_file_new_generic() - { - g_message("A File|New menu item was selecteda."); - } - void Actions::on_menu_others() { g_message("A menu item was selected."); } - void - Actions::on_menu_choices_one() - { - Glib::ustring message; - //if(m_refChoiceOne->get_active()) - // message = "Choice 1 was selected."; - //else - message = "Choice 1 was deselected"; - - g_message(message.c_str()); - } - - void - Actions::on_menu_choices_two() - { - Glib::ustring message; - //if(_main_window.m_refChoiceTwo->get_active()) - // message = "Choice 2 was selected."; - //else - message = "Choice 2 was deselected"; - - g_message(message.c_str()); - } - } // namespace workspace } // namespace gui } // namespace lumiera diff --git a/gui/src/workspace/actions.hpp b/gui/src/workspace/actions.hpp index 7c8c1d89e..2f24517c9 100644 --- a/gui/src/workspace/actions.hpp +++ b/gui/src/workspace/actions.hpp @@ -52,7 +52,8 @@ class MainWindow; MainWindow &mainWindow; /* ===== Event Handlers ===== */ - void on_menu_file_new_generic(); + void on_menu_file_new_project(); + void on_menu_file_open_project(); void on_menu_file_render(); void on_menu_file_quit(); @@ -60,8 +61,6 @@ class MainWindow; // Temporary Junk void on_menu_others(); - void on_menu_choices_one(); - void on_menu_choices_two(); /* ===== Actions ===== */ Glib::RefPtr actionGroup; diff --git a/gui/src/workspace/main-window.cpp b/gui/src/workspace/main-window.cpp index 658057bcc..1a57934e6 100644 --- a/gui/src/workspace/main-window.cpp +++ b/gui/src/workspace/main-window.cpp @@ -75,11 +75,8 @@ namespace workspace { "" " " " " - " " - " " - " " - " " - " " + " " + " " " " " " " " @@ -88,18 +85,13 @@ namespace workspace { " " " " " " - " " - " " - " " - " " - " " " " " " " " " " " " " " - " " + " " " " ""; From e59d3b6e356cf6fa14e667627968c7ce1c8c6a66 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Wed, 16 Apr 2008 22:50:01 +0100 Subject: [PATCH 017/245] Excised glade, and recreated Render dialog in C++ --- gui/configure.ac | 2 +- gui/src/Makefile.am | 5 +- gui/src/dialogs/render.cpp | 74 ++++++++++++-- gui/src/dialogs/render.hpp | 34 ++++++- gui/src/gtk-lumiera.glade | 157 ------------------------------ gui/src/workspace/actions.cpp | 32 +++--- gui/src/workspace/main-window.cpp | 20 +--- gui/src/workspace/main-window.hpp | 12 +-- 8 files changed, 120 insertions(+), 216 deletions(-) delete mode 100644 gui/src/gtk-lumiera.glade diff --git a/gui/configure.ac b/gui/configure.ac index 170dcc687..a858cf3ce 100644 --- a/gui/configure.ac +++ b/gui/configure.ac @@ -30,7 +30,7 @@ AM_PROG_LIBTOOL -PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 libglademm-2.4 >= 2.6 gdl-1.0 >= 0.7.6]) +PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.7.6]) AC_SUBST(GTK_LUMIERA_CFLAGS) AC_SUBST(GTK_LUMIERA_LIBS) diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index eda59746e..e35cf0494 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -1,8 +1,5 @@ ## Process this file with automake to produce Makefile.in -gladedir = $(datadir)/gtk-lumiera/glade -glade_DATA = gtk-lumiera.glade - INCLUDES = \ -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \ @@ -39,6 +36,6 @@ gtk_lumiera_LDFLAGS = gtk_lumiera_LDADD = $(GTK_LUMIERA_LIBS) -EXTRA_DIST = $(glade_DATA) +EXTRA_DIST = diff --git a/gui/src/dialogs/render.cpp b/gui/src/dialogs/render.cpp index 48423ebb0..958b2d229 100644 --- a/gui/src/dialogs/render.cpp +++ b/gui/src/dialogs/render.cpp @@ -20,26 +20,86 @@ * *****************************************************/ +#include "../gtk-lumiera.hpp" + #include "render.hpp" +using namespace Gtk; + namespace lumiera { namespace gui { namespace dialogs { - Render::Render(BaseObjectType* cobject, const Glib::RefPtr& xml) : - Gtk::Dialog(cobject) + Render::Render(Window &parent) : + Dialog(_("Render"), parent, true), + outputFileLabel(_("Output File:")), + browseButtonImage(StockID(Stock::INDEX), ICON_SIZE_BUTTON), + browseButtonLabel(_("_Browse..."), true), + containerFormatLabel(_("Container Format:")), + cancelButton(Stock::CANCEL), + renderButtonImage(StockID(Stock::APPLY), ICON_SIZE_BUTTON), + renderButtonLabel(_("_Render"), true) { + VBox *v_box = get_vbox(); + g_assert(v_box != NULL); + + // The Output File Row + outputFileHBox.pack_start(outputFileLabel, PACK_SHRINK); + outputFileHBox.pack_start(outputFilePathEntry); + + browseButtonHBox.pack_start(browseButtonImage); + browseButtonHBox.pack_start(browseButtonLabel); + outputFileBrowseButton.add(browseButtonHBox); + + outputFileHBox.pack_start(outputFileBrowseButton, PACK_SHRINK); + outputFileHBox.set_spacing(4); + v_box->pack_start(outputFileHBox, PACK_SHRINK); + + // The Containter Format Row + containerFormatHBox.pack_start(containerFormatLabel, PACK_SHRINK); + containerFormatHBox.pack_start(containerFormat); + containerFormatHBox.set_spacing(4); + v_box->pack_start(containerFormatHBox, PACK_SHRINK); + + // Configure the dialog + v_box->set_spacing(4); + set_border_width(5); + set_resizable(false); + + // Configure the Cancel and Render buttons + Gtk::Box* action_area = get_action_area(); + g_assert(action_area != NULL); + cancelButton.signal_clicked().connect( + sigc::mem_fun(*this, &Render::on_button_cancel)); + action_area->pack_start(cancelButton); + + renderButtonHBox.pack_start(renderButtonImage); + renderButtonHBox.pack_start(renderButtonLabel); + renderButton.add(renderButtonHBox); + renderButton.signal_clicked().connect( + sigc::mem_fun(*this, &Render::on_button_render)); + renderButton.set_flags(Gtk::CAN_DEFAULT); + action_area->pack_start(renderButton); + renderButton.grab_default(); + + show_all_children(); } - void - Render::init(Gtk::Window &parent, - const Glib::RefPtr& glade_xml, Render*& dialog) + void Render::on_button_render() { - glade_xml->get_widget_derived("Render", dialog); - if(dialog != NULL) dialog->set_transient_for(parent); + g_message("render"); + hide(); } + void Render::on_button_cancel() + { + g_message("cancel"); + hide(); + } + + + } // namespace dialogs } // namespace gui } // namespace lumiera diff --git a/gui/src/dialogs/render.hpp b/gui/src/dialogs/render.hpp index d515ece96..e1a501573 100644 --- a/gui/src/dialogs/render.hpp +++ b/gui/src/dialogs/render.hpp @@ -28,7 +28,8 @@ #define RENDER_H #include -#include + +using namespace Gtk; namespace lumiera { namespace gui { @@ -37,13 +38,36 @@ namespace dialogs { /** * The defintion of render output dialog class */ - class Render : public Gtk::Dialog + class Render : public Dialog { public: - Render(BaseObjectType* cobject, const Glib::RefPtr& xml); + Render(Window &parent); - static void init(Gtk::Window &parent, - const Glib::RefPtr& glade_xml, Render*& dialog); + protected: + void on_button_render(); + + void on_button_cancel(); + + protected: + HBox outputFileHBox; + Label outputFileLabel; + Entry outputFilePathEntry; + + HBox browseButtonHBox; + Image browseButtonImage; + Label browseButtonLabel; + Button outputFileBrowseButton; + + HBox containerFormatHBox; + Label containerFormatLabel; + ComboBox containerFormat; + + Button cancelButton; + + HBox renderButtonHBox; + Image renderButtonImage; + Label renderButtonLabel; + Button renderButton; }; } // namespace dialogs diff --git a/gui/src/gtk-lumiera.glade b/gui/src/gtk-lumiera.glade deleted file mode 100644 index d0c8a28f4..000000000 --- a/gui/src/gtk-lumiera.glade +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - False - GTK_WIN_POS_CENTER_ON_PARENT - GDK_WINDOW_TYPE_HINT_DIALOG - False - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 2 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 4 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 4 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Output File: - - - False - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - 1 - - - - - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-open - True - 0 - - - False - 2 - - - - - False - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 4 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Container Format: - - - False - False - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - 1 - - - - - False - 1 - - - - - - - - - - - - - - - - - - - - 1 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - GTK_BUTTONBOX_END - - - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-cancel - True - 0 - - - - - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-ok - True - 0 - - - 1 - - - - - False - GTK_PACK_END - - - - - - diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp index e91ab9ff1..b08de0b0d 100644 --- a/gui/src/workspace/actions.cpp +++ b/gui/src/workspace/actions.cpp @@ -24,8 +24,11 @@ #include "actions.hpp" #include "main-window.hpp" +#include "../dialogs/render.hpp" + using namespace Gtk; using namespace Glib; +using namespace lumiera::gui; namespace lumiera { namespace gui { @@ -34,33 +37,35 @@ namespace workspace { Actions::Actions(MainWindow &main_window) : mainWindow(main_window) { - actionGroup = Gtk::ActionGroup::create(); + actionGroup = ActionGroup::create(); // File menu: - actionGroup->add(Gtk::Action::create("FileMenu", _("File"))); - actionGroup->add(Gtk::Action::create("FileNewProject", Gtk::Stock::NEW, _("_New Project...")), + actionGroup->add(Action::create("FileMenu", _("_File"))); + actionGroup->add(Action::create("FileNewProject", Stock::NEW, _("_New Project...")), sigc::mem_fun(*this, &Actions::on_menu_file_new_project)); - actionGroup->add(Gtk::Action::create("FileOpenProject", Gtk::Stock::OPEN, _("_Open Project...")), - sigc::mem_fun(*this, &Actions::on_menu_file_new_project)); - actionGroup->add(Gtk::Action::create("FileRender", _("_Render...")), + actionGroup->add(Action::create("FileOpenProject", Stock::OPEN, _("_Open Project...")), + sigc::mem_fun(*this, &Actions::on_menu_file_open_project)); + actionGroup->add(Action::create("FileRender", _("_Render...")), Gtk::AccelKey("R"), sigc::mem_fun(*this, &Actions::on_menu_file_render)); - actionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), + actionGroup->add(Action::create("FileQuit", Stock::QUIT), sigc::mem_fun(*this, &Actions::on_menu_file_quit)); // Edit menu: - actionGroup->add(Gtk::Action::create("EditMenu", _("Edit"))); - actionGroup->add(Gtk::Action::create("EditCopy", Gtk::Stock::COPY), + actionGroup->add(Action::create("EditMenu", _("_Edit"))); + actionGroup->add(Action::create("EditCopy", Stock::COPY), sigc::mem_fun(*this, &Actions::on_menu_others)); - actionGroup->add(Gtk::Action::create("EditPaste", Gtk::Stock::PASTE), + actionGroup->add(Action::create("EditPaste", Stock::PASTE), sigc::mem_fun(*this, &Actions::on_menu_others)); // Help menu: - actionGroup->add( Gtk::Action::create("HelpMenu", "Help") ); - actionGroup->add( Gtk::Action::create("HelpAbout", Gtk::Stock::ABOUT), + actionGroup->add(Action::create("HelpMenu", _("_Help")) ); + actionGroup->add(Action::create("HelpAbout", Stock::ABOUT), sigc::mem_fun(*this, &Actions::on_menu_help_about) ); } + /* ===== File Menu Event Handlers ===== */ + void Actions::on_menu_file_new_project() { @@ -76,7 +81,8 @@ namespace workspace { void Actions::on_menu_file_render() { - mainWindow.renderDialog->run(); + dialogs::Render dialog(mainWindow); + dialog.run(); } void diff --git a/gui/src/workspace/main-window.cpp b/gui/src/workspace/main-window.cpp index 1a57934e6..db55282ed 100644 --- a/gui/src/workspace/main-window.cpp +++ b/gui/src/workspace/main-window.cpp @@ -47,7 +47,6 @@ namespace workspace { : actions(*this) { create_ui(); - create_dialogs(); } MainWindow::~MainWindow() @@ -62,7 +61,7 @@ namespace workspace { set_default_size(1024, 768); //----- Set up the UI Manager -----// - // The UI will be nested within a VBOX + // The UI will be nested within a VBox add(base_container); uiManager = Gtk::UIManager::create(); @@ -92,6 +91,7 @@ namespace workspace { " " " " " " + " " " " ""; @@ -145,22 +145,6 @@ namespace workspace { gdl_dock_placeholder_new ("ph4", (GdlDockObject*)dock->gobj(), GDL_DOCK_RIGHT, FALSE); } - void - MainWindow::create_dialogs() - { - try - { - gladeXml = Gnome::Glade::Xml::create("gtk-lumiera.glade"); - } - catch(const Gnome::Glade::XmlError& ex) - { - g_message(ex.what().data()); - return; - } - - dialogs::Render::init(*this, gladeXml, renderDialog); - } - } // namespace workspace } // namespace gui } // namespace lumiera diff --git a/gui/src/workspace/main-window.hpp b/gui/src/workspace/main-window.hpp index 526f8df6c..c544ce5b0 100644 --- a/gui/src/workspace/main-window.hpp +++ b/gui/src/workspace/main-window.hpp @@ -31,7 +31,6 @@ #include #include -#include #include "actions.hpp" @@ -39,8 +38,6 @@ #include "../panels/viewer.hpp" #include "../panels/timeline.hpp" -#include "../dialogs/render.hpp" - using namespace lumiera::gui::panels; namespace lumiera { @@ -58,7 +55,6 @@ namespace workspace { protected: void create_ui(); - void create_dialogs(); /* ===== UI ===== */ protected: @@ -75,13 +71,7 @@ namespace workspace { Assets assets; Viewer viewer; Timeline timeline; - - /* ===== Dialogs ===== */ - protected: - Glib::RefPtr gladeXml; - - dialogs::Render *renderDialog; - + /* ===== Helpers ===== */ protected: /** From a3bd7c35fae3006bf4e00466f70aa42548a49d70 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Wed, 16 Apr 2008 22:59:46 +0100 Subject: [PATCH 018/245] Added 2 frames to the render dialog --- gui/src/dialogs/render.cpp | 7 ++++++- gui/src/dialogs/render.hpp | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gui/src/dialogs/render.cpp b/gui/src/dialogs/render.cpp index 958b2d229..af6c5b631 100644 --- a/gui/src/dialogs/render.cpp +++ b/gui/src/dialogs/render.cpp @@ -38,7 +38,9 @@ namespace dialogs { containerFormatLabel(_("Container Format:")), cancelButton(Stock::CANCEL), renderButtonImage(StockID(Stock::APPLY), ICON_SIZE_BUTTON), - renderButtonLabel(_("_Render"), true) + renderButtonLabel(_("_Render"), true), + audioFrame(_("Audio")), + videoFrame(_("Video")) { VBox *v_box = get_vbox(); g_assert(v_box != NULL); @@ -61,6 +63,9 @@ namespace dialogs { containerFormatHBox.set_spacing(4); v_box->pack_start(containerFormatHBox, PACK_SHRINK); + v_box->pack_start(audioFrame); + v_box->pack_start(videoFrame); + // Configure the dialog v_box->set_spacing(4); set_border_width(5); diff --git a/gui/src/dialogs/render.hpp b/gui/src/dialogs/render.hpp index e1a501573..4e7a57d50 100644 --- a/gui/src/dialogs/render.hpp +++ b/gui/src/dialogs/render.hpp @@ -62,6 +62,10 @@ namespace dialogs { Label containerFormatLabel; ComboBox containerFormat; + Frame audioFrame; + + Frame videoFrame; + Button cancelButton; HBox renderButtonHBox; From b042349936634d8f98332258f741bc392949e3bb Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 17 Apr 2008 18:06:00 +0100 Subject: [PATCH 019/245] Improved code for buttons --- gui/src/dialogs/render.cpp | 59 ++++++++++++++++---------------------- gui/src/dialogs/render.hpp | 11 +------ 2 files changed, 26 insertions(+), 44 deletions(-) diff --git a/gui/src/dialogs/render.cpp b/gui/src/dialogs/render.cpp index af6c5b631..f785ed6a4 100644 --- a/gui/src/dialogs/render.cpp +++ b/gui/src/dialogs/render.cpp @@ -34,11 +34,9 @@ namespace dialogs { Dialog(_("Render"), parent, true), outputFileLabel(_("Output File:")), browseButtonImage(StockID(Stock::INDEX), ICON_SIZE_BUTTON), - browseButtonLabel(_("_Browse..."), true), + outputFileBrowseButton(_("_Browse...")), containerFormatLabel(_("Container Format:")), - cancelButton(Stock::CANCEL), - renderButtonImage(StockID(Stock::APPLY), ICON_SIZE_BUTTON), - renderButtonLabel(_("_Render"), true), + renderButtonImage(StockID(Stock::OK), ICON_SIZE_BUTTON), audioFrame(_("Audio")), videoFrame(_("Video")) { @@ -49,15 +47,15 @@ namespace dialogs { outputFileHBox.pack_start(outputFileLabel, PACK_SHRINK); outputFileHBox.pack_start(outputFilePathEntry); - browseButtonHBox.pack_start(browseButtonImage); - browseButtonHBox.pack_start(browseButtonLabel); - outputFileBrowseButton.add(browseButtonHBox); + outputFileBrowseButton.set_image(browseButtonImage); + outputFileBrowseButton.signal_clicked().connect( + sigc::mem_fun(*this, &Render::on_button_browse)); outputFileHBox.pack_start(outputFileBrowseButton, PACK_SHRINK); outputFileHBox.set_spacing(4); v_box->pack_start(outputFileHBox, PACK_SHRINK); - // The Containter Format Row + // The Container Format Row containerFormatHBox.pack_start(containerFormatLabel, PACK_SHRINK); containerFormatHBox.pack_start(containerFormat); containerFormatHBox.set_spacing(4); @@ -71,40 +69,33 @@ namespace dialogs { set_border_width(5); set_resizable(false); - // Configure the Cancel and Render buttons - Gtk::Box* action_area = get_action_area(); - g_assert(action_area != NULL); - - cancelButton.signal_clicked().connect( - sigc::mem_fun(*this, &Render::on_button_cancel)); - action_area->pack_start(cancelButton); + // Configure the Cancel and Render buttons + add_button(Stock::CANCEL, RESPONSE_CANCEL); - renderButtonHBox.pack_start(renderButtonImage); - renderButtonHBox.pack_start(renderButtonLabel); - renderButton.add(renderButtonHBox); - renderButton.signal_clicked().connect( - sigc::mem_fun(*this, &Render::on_button_render)); - renderButton.set_flags(Gtk::CAN_DEFAULT); - action_area->pack_start(renderButton); - renderButton.grab_default(); + Button *render_button = add_button(Stock::OK, RESPONSE_OK); + render_button->set_label(_("_Render")); + render_button->set_image(renderButtonImage); + render_button->set_flags(Gtk::CAN_DEFAULT); + render_button->grab_default(); show_all_children(); } - void Render::on_button_render() + void Render::on_button_browse() { - g_message("render"); - hide(); + FileChooserDialog dialog(*this, _("Select a File Name for Rendering"), + FILE_CHOOSER_ACTION_SAVE); + + // Add response buttons the the dialog: + dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog.add_button(/*Gtk::Stock::SAVE*/"Save", Gtk::RESPONSE_OK); + + int result = dialog.run(); + g_message("%d", result); + if(result == RESPONSE_OK) + g_message("RESPONSE_OK"); } - void Render::on_button_cancel() - { - g_message("cancel"); - hide(); - } - - - } // namespace dialogs } // namespace gui } // namespace lumiera diff --git a/gui/src/dialogs/render.hpp b/gui/src/dialogs/render.hpp index 4e7a57d50..1474afe31 100644 --- a/gui/src/dialogs/render.hpp +++ b/gui/src/dialogs/render.hpp @@ -44,18 +44,14 @@ namespace dialogs { Render(Window &parent); protected: - void on_button_render(); - - void on_button_cancel(); + void on_button_browse(); protected: HBox outputFileHBox; Label outputFileLabel; Entry outputFilePathEntry; - HBox browseButtonHBox; Image browseButtonImage; - Label browseButtonLabel; Button outputFileBrowseButton; HBox containerFormatHBox; @@ -66,12 +62,7 @@ namespace dialogs { Frame videoFrame; - Button cancelButton; - - HBox renderButtonHBox; Image renderButtonImage; - Label renderButtonLabel; - Button renderButton; }; } // namespace dialogs From 3fc585de25ab29f8f5a976aa7fabf63b466e6f9b Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Fri, 18 Apr 2008 20:09:14 +0100 Subject: [PATCH 020/245] Reduced required gdl version number --- gui/configure.ac | 2 +- gui/src/workspace/main-window.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/gui/configure.ac b/gui/configure.ac index a858cf3ce..004b4ca93 100644 --- a/gui/configure.ac +++ b/gui/configure.ac @@ -30,7 +30,7 @@ AM_PROG_LIBTOOL -PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.7.6]) +PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.6.1]) AC_SUBST(GTK_LUMIERA_CFLAGS) AC_SUBST(GTK_LUMIERA_LIBS) diff --git a/gui/src/workspace/main-window.cpp b/gui/src/workspace/main-window.cpp index db55282ed..f4578794d 100644 --- a/gui/src/workspace/main-window.cpp +++ b/gui/src/workspace/main-window.cpp @@ -29,10 +29,8 @@ #include #include #include -#include #include #include -#include #include "gtk-lumiera.hpp" #include "main-window.hpp" From 82daa28f3aba5826bb361c225b485708f67cacb7 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Fri, 18 Apr 2008 21:35:10 +0100 Subject: [PATCH 021/245] Made some changes to make the gui work better with debian etch --- gui/configure.ac | 2 +- gui/src/widgets/video-display.cpp | 4 +--- gui/src/workspace/actions.cpp | 2 +- gui/src/workspace/main-window.cpp | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/gui/configure.ac b/gui/configure.ac index 004b4ca93..fbc00ed01 100644 --- a/gui/configure.ac +++ b/gui/configure.ac @@ -30,7 +30,7 @@ AM_PROG_LIBTOOL -PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.6.1]) +PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.6.1 cairomm-1.0 >= 0.6.0]) AC_SUBST(GTK_LUMIERA_CFLAGS) AC_SUBST(GTK_LUMIERA_LIBS) diff --git a/gui/src/widgets/video-display.cpp b/gui/src/widgets/video-display.cpp index 4ec1eada5..29d95268d 100644 --- a/gui/src/widgets/video-display.cpp +++ b/gui/src/widgets/video-display.cpp @@ -22,6 +22,7 @@ #include #include +#include #include "video-display.hpp" @@ -49,9 +50,6 @@ VideoDisplay::on_expose_event(GdkEventExpose* event) Glib::RefPtr window = get_window(); if(window) { - double scale_x = 1; - double scale_y = 1; - Cairo::RefPtr cr = window->create_cairo_context(); if(event) { diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp index b08de0b0d..2303b1000 100644 --- a/gui/src/workspace/actions.cpp +++ b/gui/src/workspace/actions.cpp @@ -97,7 +97,7 @@ namespace workspace { // Configure the about dialog AboutDialog dialog; - dialog.set_program_name(AppTitle); + //dialog.set_program_name(AppTitle); dialog.set_version(AppVersion); //dialog.set_version(Appconfig::get("version")); dialog.set_copyright(AppCopyright); diff --git a/gui/src/workspace/main-window.cpp b/gui/src/workspace/main-window.cpp index f4578794d..b3b728353 100644 --- a/gui/src/workspace/main-window.cpp +++ b/gui/src/workspace/main-window.cpp @@ -120,7 +120,6 @@ namespace workspace { layout = gdl_dock_layout_new((GdlDock*)dock->gobj()); dockbar = Glib::wrap(gdl_dock_bar_new ((GdlDock*)dock->gobj())); - gdl_dock_bar_set_style((GdlDockBar*)dockbar->gobj(), GDL_DOCK_BAR_TEXT); dock_container.pack_start(*dockbar, PACK_SHRINK); dock_container.pack_end(*dock, PACK_EXPAND_WIDGET); From f360ead450a55970c669307b0b2c967adb14c129 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 19 Apr 2008 18:21:20 +0100 Subject: [PATCH 022/245] Converted some _Hs to _HPPs in header gates --- gui/src/panels/assets.hpp | 6 +++--- gui/src/panels/panel.hpp | 6 +++--- gui/src/panels/viewer.hpp | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gui/src/panels/assets.hpp b/gui/src/panels/assets.hpp index 1a11107d9..f6d1d5544 100644 --- a/gui/src/panels/assets.hpp +++ b/gui/src/panels/assets.hpp @@ -23,8 +23,8 @@ ** This file contains the definition of the assets panel */ -#ifndef ASSETS_H -#define ASSETS_H +#ifndef ASSETS_HPP +#define ASSETS_HPP #include "panel.hpp" @@ -45,4 +45,4 @@ namespace panels { } // namespace gui } // namespace lumiera -#endif // ASSETS_H +#endif // ASSETS_HPP diff --git a/gui/src/panels/panel.hpp b/gui/src/panels/panel.hpp index fdb7296cf..05cc47dc6 100644 --- a/gui/src/panels/panel.hpp +++ b/gui/src/panels/panel.hpp @@ -24,8 +24,8 @@ ** for all docking panels */ -#ifndef PANEL_H -#define PANEL_H +#ifndef PANEL_HPP +#define PANEL_HPP #include #include @@ -56,4 +56,4 @@ namespace panels { } // namespace gui } // namespace lumiera -#endif // PANEL_H +#endif // PANEL_HPP diff --git a/gui/src/panels/viewer.hpp b/gui/src/panels/viewer.hpp index e6d459ffa..fb6d77760 100644 --- a/gui/src/panels/viewer.hpp +++ b/gui/src/panels/viewer.hpp @@ -23,8 +23,8 @@ ** This file contains the definition of the viewer panel */ -#ifndef VIEWER_H -#define VIEWER_H +#ifndef VIEWER_HPP +#define VIEWER_HPP #include @@ -59,4 +59,4 @@ namespace panels { } // namespace gui } // namespace lumiera -#endif // VIEWER_H +#endif // VIEWER_HPP From 82a000662ba0ff69f5b75a9f98a2df87b47655c1 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 19 Apr 2008 19:15:59 +0100 Subject: [PATCH 023/245] Added the data model of a project --- gui/src/Makefile.am | 8 ++-- gui/src/gtk-lumiera.cpp | 9 ++-- gui/src/model/project.cpp | 38 ++++++++++++++++ gui/src/model/project.hpp | 44 +++++++++++++++++++ gui/src/workspace/actions.cpp | 12 ++--- gui/src/workspace/actions.hpp | 8 ++-- .../{main-window.cpp => workspace-window.cpp} | 17 ++++--- .../{main-window.hpp => workspace-window.hpp} | 33 +++++++++----- 8 files changed, 135 insertions(+), 34 deletions(-) create mode 100644 gui/src/model/project.cpp create mode 100644 gui/src/model/project.hpp rename gui/src/workspace/{main-window.cpp => workspace-window.cpp} (91%) rename gui/src/workspace/{main-window.hpp => workspace-window.hpp} (78%) diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index e35cf0494..59ca02604 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -17,8 +17,8 @@ gtk_lumiera_SOURCES = \ gtk-lumiera.hpp \ workspace/actions.cpp \ workspace/actions.hpp \ - workspace/main-window.cpp \ - workspace/main-window.hpp \ + workspace/workspace-window.cpp \ + workspace/workspace-window.hpp \ dialogs/render.cpp \ dialogs/render.hpp \ panels/panel.cpp \ @@ -30,7 +30,9 @@ gtk_lumiera_SOURCES = \ panels/assets.cpp \ panels/assets.hpp \ widgets/video-display.cpp \ - widgets/video-display.hpp + widgets/video-display.hpp \ + model/project.cpp \ + model/project.hpp gtk_lumiera_LDFLAGS = diff --git a/gui/src/gtk-lumiera.cpp b/gui/src/gtk-lumiera.cpp index 4dff269b4..a7951b3a0 100644 --- a/gui/src/gtk-lumiera.cpp +++ b/gui/src/gtk-lumiera.cpp @@ -28,11 +28,13 @@ #endif #include "gtk-lumiera.hpp" -#include "workspace/main-window.hpp" +#include "workspace/workspace-window.hpp" +#include "model/project.hpp" +using namespace Gtk; using namespace lumiera::gui; using namespace lumiera::gui::workspace; -using namespace Gtk; +using namespace lumiera::gui::model; GtkLumiera the_application; @@ -54,7 +56,8 @@ namespace gui { Glib::set_application_name(AppTitle); - MainWindow main_window; + Project project; + WorkspaceWindow main_window(&project); kit.run(main_window); } diff --git a/gui/src/model/project.cpp b/gui/src/model/project.cpp new file mode 100644 index 000000000..345398c7a --- /dev/null +++ b/gui/src/model/project.cpp @@ -0,0 +1,38 @@ +/* + panel.cpp - Implementation of the Project class + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "project.hpp" + +namespace lumiera { +namespace gui { +namespace model { + +Project::Project() +{ + +} + +} // namespace model +} // namespace gui +} // namespace lumiera + + diff --git a/gui/src/model/project.hpp b/gui/src/model/project.hpp new file mode 100644 index 000000000..c7d02c51a --- /dev/null +++ b/gui/src/model/project.hpp @@ -0,0 +1,44 @@ +/* + project.hpp - Definition of the Project class + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file project.hpp + ** This file contains the definition of Project, a class which + ** store project data, and wraps proc layer data + */ + +#ifndef PROJECT_HPP +#define PROJECT_HPP + +namespace lumiera { +namespace gui { +namespace model { + +class Project +{ +public: + Project(); +}; + +} // namespace model +} // namespace gui +} // namespace lumiera + +#endif // PROJECT_HPP diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp index 2303b1000..8adfcc141 100644 --- a/gui/src/workspace/actions.cpp +++ b/gui/src/workspace/actions.cpp @@ -22,7 +22,7 @@ #include "../gtk-lumiera.hpp" #include "actions.hpp" -#include "main-window.hpp" +#include "workspace-window.hpp" #include "../dialogs/render.hpp" @@ -34,8 +34,8 @@ namespace lumiera { namespace gui { namespace workspace { - Actions::Actions(MainWindow &main_window) : - mainWindow(main_window) + Actions::Actions(WorkspaceWindow &workspace_window) : + workspaceWindow(workspace_window) { actionGroup = ActionGroup::create(); @@ -81,14 +81,14 @@ namespace workspace { void Actions::on_menu_file_render() { - dialogs::Render dialog(mainWindow); + dialogs::Render dialog(workspaceWindow); dialog.run(); } void Actions::on_menu_file_quit() { - mainWindow.hide(); // Closes the main window to stop the Gtk::Main::run(). + workspaceWindow.hide(); // Closes the main window to stop the Gtk::Main::run(). } void @@ -106,7 +106,7 @@ namespace workspace { sizeof(AppAuthors) / sizeof(gchar*), OWNERSHIP_NONE)); - dialog.set_transient_for(mainWindow); + dialog.set_transient_for(workspaceWindow); // Show the about dialog dialog.run(); diff --git a/gui/src/workspace/actions.hpp b/gui/src/workspace/actions.hpp index 2f24517c9..27b744549 100644 --- a/gui/src/workspace/actions.hpp +++ b/gui/src/workspace/actions.hpp @@ -35,7 +35,7 @@ namespace lumiera { namespace gui { namespace workspace { -class MainWindow; +class WorkspaceWindow; /** * A helper class which registers and handles @@ -44,12 +44,12 @@ class MainWindow; class Actions { private: - Actions(MainWindow &main_window); + Actions(WorkspaceWindow &workspace_window); /** * A reference to the MainWindow which owns * this helper */ - MainWindow &mainWindow; + WorkspaceWindow &workspaceWindow; /* ===== Event Handlers ===== */ void on_menu_file_new_project(); @@ -66,7 +66,7 @@ class MainWindow; Glib::RefPtr actionGroup; Glib::RefPtr m_refChoiceOne, m_refChoiceTwo; - friend class MainWindow; + friend class WorkspaceWindow; }; } // namespace workspace diff --git a/gui/src/workspace/main-window.cpp b/gui/src/workspace/workspace-window.cpp similarity index 91% rename from gui/src/workspace/main-window.cpp rename to gui/src/workspace/workspace-window.cpp index b3b728353..5d06b6d18 100644 --- a/gui/src/workspace/main-window.cpp +++ b/gui/src/workspace/workspace-window.cpp @@ -1,5 +1,5 @@ /* - main-window.cpp - Definition of the main workspace window object + workspace-window.cpp - Definition of the main workspace window object Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -33,26 +33,31 @@ #include #include "gtk-lumiera.hpp" -#include "main-window.hpp" +#include "workspace-window.hpp" using namespace Gtk; +using namespace lumiera::gui::model; namespace lumiera { namespace gui { namespace workspace { - MainWindow::MainWindow() - : actions(*this) + WorkspaceWindow::WorkspaceWindow(Project *source_project) : + project(source_project), + actions(*this) { + layout = NULL; + create_ui(); } - MainWindow::~MainWindow() + WorkspaceWindow::~WorkspaceWindow() { + if(layout != NULL) g_object_unref(layout); } void - MainWindow::create_ui() + WorkspaceWindow::create_ui() { //----- Configure the Window -----// set_title(AppTitle); diff --git a/gui/src/workspace/main-window.hpp b/gui/src/workspace/workspace-window.hpp similarity index 78% rename from gui/src/workspace/main-window.hpp rename to gui/src/workspace/workspace-window.hpp index c544ce5b0..5718ddc25 100644 --- a/gui/src/workspace/main-window.hpp +++ b/gui/src/workspace/workspace-window.hpp @@ -1,5 +1,5 @@ /* - main-window.hpp - Definition of the main workspace window object + workspace-window.hpp - Definition of the main workspace window object Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -19,15 +19,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/** @file mainwindow.hpp +/** @file workspace-window.hpp ** This file contains the definition of the main workspace window ** parent, which is the toplevel parent of the whole workspace. ** ** @see actions.hpp */ -#ifndef MAIN_WINDOW_HPP -#define MAIN_WINDOW_HPP +#ifndef WORKSPACE_WINDOW_HPP +#define WORKSPACE_WINDOW_HPP #include #include @@ -42,22 +42,31 @@ using namespace lumiera::gui::panels; namespace lumiera { namespace gui { + +namespace model { + class Project; +} // model + namespace workspace { /** * The main lumiera workspace window */ - class MainWindow : public Gtk::Window + class WorkspaceWindow : public Gtk::Window { public: - MainWindow(); - virtual ~MainWindow(); + WorkspaceWindow(lumiera::gui::model::Project *source_project); + virtual ~WorkspaceWindow(); - protected: + private: void create_ui(); + /* ===== Model ===== */ + private: + lumiera::gui::model::Project *project; + /* ===== UI ===== */ - protected: + private: Glib::RefPtr uiManager; Gtk::VBox base_container; Gtk::HBox dock_container; @@ -67,13 +76,13 @@ namespace workspace { GdlDockLayout *layout; /* ===== Panels ===== */ - protected: + private: Assets assets; Viewer viewer; Timeline timeline; /* ===== Helpers ===== */ - protected: + private: /** * The instantiation of the actions helper class, which * registers and handles user action events */ @@ -86,4 +95,4 @@ namespace workspace { } // namespace gui } // namespace lumiera -#endif // MAIN_WINDOW_HPP +#endif // WORKSPACE_WINDOW_HPP From b8fd3885f4087582d81bbcbde9efa91f935c02b3 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 19 Apr 2008 20:31:27 +0100 Subject: [PATCH 024/245] Added the base of a timeline widget --- gui/src/Makefile.am | 6 +- .../{timeline.cpp => timeline-panel.cpp} | 11 ++- .../{timeline.hpp => timeline-panel.hpp} | 19 +++-- gui/src/widgets/timeline-widget.cpp | 75 +++++++++++++++++++ gui/src/widgets/timeline-widget.hpp | 50 +++++++++++++ gui/src/widgets/video-display.hpp | 2 +- gui/src/workspace/workspace-window.hpp | 4 +- 7 files changed, 148 insertions(+), 19 deletions(-) rename gui/src/panels/{timeline.cpp => timeline-panel.cpp} (80%) rename gui/src/panels/{timeline.hpp => timeline-panel.hpp} (74%) create mode 100644 gui/src/widgets/timeline-widget.cpp create mode 100644 gui/src/widgets/timeline-widget.hpp diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index 59ca02604..056cad6ce 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -23,14 +23,16 @@ gtk_lumiera_SOURCES = \ dialogs/render.hpp \ panels/panel.cpp \ panels/panel.hpp \ - panels/timeline.cpp \ - panels/timeline.hpp \ + panels/timeline-panel.cpp \ + panels/timeline-panel.hpp \ panels/viewer.cpp \ panels/viewer.hpp \ panels/assets.cpp \ panels/assets.hpp \ widgets/video-display.cpp \ widgets/video-display.hpp \ + widgets/timeline-widget.cpp \ + widgets/timeline-widget.hpp \ model/project.cpp \ model/project.hpp diff --git a/gui/src/panels/timeline.cpp b/gui/src/panels/timeline-panel.cpp similarity index 80% rename from gui/src/panels/timeline.cpp rename to gui/src/panels/timeline-panel.cpp index 1e5086fd7..7d1de24ea 100644 --- a/gui/src/panels/timeline.cpp +++ b/gui/src/panels/timeline-panel.cpp @@ -1,5 +1,5 @@ /* - timeline.cpp - Implementation of the timeline panel + timeline-panel.cpp - Implementation of the timeline panel Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -20,17 +20,16 @@ * *****************************************************/ -#include "timeline.hpp" +#include "timeline-panel.hpp" namespace lumiera { namespace gui { namespace panels { -Timeline::Timeline() : - Panel("timeline", "Timeline"), - placeholder("Placeholder label. Is Timeline the correct title for this panel?") +TimelinePanel::TimelinePanel() : + Panel("timeline", "Timeline") { - pack_start(placeholder); + pack_start(timeline_widget); } } // namespace panels diff --git a/gui/src/panels/timeline.hpp b/gui/src/panels/timeline-panel.hpp similarity index 74% rename from gui/src/panels/timeline.hpp rename to gui/src/panels/timeline-panel.hpp index b219b3f55..bc1fbff08 100644 --- a/gui/src/panels/timeline.hpp +++ b/gui/src/panels/timeline-panel.hpp @@ -1,5 +1,5 @@ /* - timeline.hpp - Definition of the timeline panel + timeline-panel.hpp - Definition of the timeline panel Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -19,30 +19,33 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/** @file timeline.hpp +/** @file timeline-panel.hpp ** This file contains the definition of the timeline panel */ -#ifndef TIMELINE_HPP -#define TIMELINE_HPP +#ifndef TIMELINE_PANEL_HPP +#define TIMELINE_PANEL_HPP #include "panel.hpp" +#include "../widgets/timeline-widget.hpp" + +using namespace lumiera::gui::widgets; namespace lumiera { namespace gui { namespace panels { - class Timeline : public Panel + class TimelinePanel : public Panel { public: - Timeline(); + TimelinePanel(); protected: - Gtk::Label placeholder; + TimelineWidget timeline_widget; }; } // namespace panels } // namespace gui } // namespace lumiera -#endif // TIMELINE_H +#endif // TIMELINE_PANEL_H diff --git a/gui/src/widgets/timeline-widget.cpp b/gui/src/widgets/timeline-widget.cpp new file mode 100644 index 000000000..10eaa3fb0 --- /dev/null +++ b/gui/src/widgets/timeline-widget.cpp @@ -0,0 +1,75 @@ +/* + timeline.cpp - Implementation of the timeline widget + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include +#include +#include + +#include "timeline-widget.hpp" + +namespace lumiera { +namespace gui { +namespace widgets { + +TimelineWidget::TimelineWidget() + { + set_flags(Gtk::NO_WINDOW); + } + +void +TimelineWidget::on_realize() + { + //Call base class: + Gtk::Widget::on_realize(); + + } + +bool +TimelineWidget::on_expose_event(GdkEventExpose* event) + { + // This is where we draw on the window + Glib::RefPtr window = get_window(); + if(window) + { + /*Cairo::RefPtr cr = window->create_cairo_context(); + if(event) + { + // clip to the area that needs to be re-exposed so we don't draw any + // more than we need to. + cr->rectangle(event->area.x, event->area.y, + event->area.width, event->area.height); + cr->clip(); + } + + // Paint the background + cr->set_source_rgb(0.0, 0.0, 0.0); + cr->paint();*/ + } + return true; + } + + + +} // namespace widgets +} // namespace gui +} // namespace lumiera + diff --git a/gui/src/widgets/timeline-widget.hpp b/gui/src/widgets/timeline-widget.hpp new file mode 100644 index 000000000..a080d34b2 --- /dev/null +++ b/gui/src/widgets/timeline-widget.hpp @@ -0,0 +1,50 @@ +/* + timeline.hpp - Declaration of the timeline widget + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file timeline.hpp + ** This file contains the definition of timeline widget + */ + +#ifndef TIMELINE_WIDGET_HPP +#define TIMELINE_WIDGET_HPP + +#include + +namespace lumiera { +namespace gui { +namespace widgets { + + class TimelineWidget : public Gtk::Widget + { + public: + TimelineWidget(); + + /* ===== Overrides ===== */ + protected: + virtual void on_realize(); + virtual bool on_expose_event(GdkEventExpose* event); + }; + +} // namespace widgets +} // namespace gui +} // namespace lumiera + +#endif // TIMELINE_WIDGET_HPP diff --git a/gui/src/widgets/video-display.hpp b/gui/src/widgets/video-display.hpp index 34fbce81c..6fdd73958 100644 --- a/gui/src/widgets/video-display.hpp +++ b/gui/src/widgets/video-display.hpp @@ -47,4 +47,4 @@ namespace widgets { } // namespace gui } // namespace lumiera -#endif // VIDEO_DISPLAY_H +#endif // VIDEO_DISPLAY_HPP diff --git a/gui/src/workspace/workspace-window.hpp b/gui/src/workspace/workspace-window.hpp index 5718ddc25..a111cafeb 100644 --- a/gui/src/workspace/workspace-window.hpp +++ b/gui/src/workspace/workspace-window.hpp @@ -36,7 +36,7 @@ #include "../panels/assets.hpp" #include "../panels/viewer.hpp" -#include "../panels/timeline.hpp" +#include "../panels/timeline-panel.hpp" using namespace lumiera::gui::panels; @@ -79,7 +79,7 @@ namespace workspace { private: Assets assets; Viewer viewer; - Timeline timeline; + TimelinePanel timeline; /* ===== Helpers ===== */ private: From b020607065946e15eadd48057f2a12af536e0011 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 19 Apr 2008 20:47:53 +0100 Subject: [PATCH 025/245] Renamed some classes to be less ambiguous between namespaces --- gui/src/Makefile.am | 12 ++++++------ .../panels/{assets.cpp => assets-panel.cpp} | 6 +++--- .../panels/{assets.hpp => assets-panel.hpp} | 14 +++++++------- .../panels/{viewer.cpp => viewer-panel.cpp} | 6 +++--- .../panels/{viewer.hpp => viewer-panel.hpp} | 18 +++++++++--------- ...eo-display.cpp => video-display-widget.cpp} | 12 +++++------- ...eo-display.hpp => video-display-widget.hpp} | 14 +++++++------- gui/src/workspace/workspace-window.cpp | 10 +++++----- gui/src/workspace/workspace-window.hpp | 10 +++++----- 9 files changed, 50 insertions(+), 52 deletions(-) rename gui/src/panels/{assets.cpp => assets-panel.cpp} (91%) rename gui/src/panels/{assets.hpp => assets-panel.hpp} (82%) rename gui/src/panels/{viewer.cpp => viewer-panel.cpp} (93%) rename gui/src/panels/{viewer.hpp => viewer-panel.hpp} (81%) rename gui/src/widgets/{video-display.cpp => video-display-widget.cpp} (88%) rename gui/src/widgets/{video-display.hpp => video-display-widget.hpp} (80%) diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index 056cad6ce..d5a380fed 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -25,12 +25,12 @@ gtk_lumiera_SOURCES = \ panels/panel.hpp \ panels/timeline-panel.cpp \ panels/timeline-panel.hpp \ - panels/viewer.cpp \ - panels/viewer.hpp \ - panels/assets.cpp \ - panels/assets.hpp \ - widgets/video-display.cpp \ - widgets/video-display.hpp \ + panels/viewer-panel.cpp \ + panels/viewer-panel.hpp \ + panels/assets-panel.cpp \ + panels/asset-panels.hpp \ + widgets/video-display-widget.cpp \ + widgets/video-display-widget.hpp \ widgets/timeline-widget.cpp \ widgets/timeline-widget.hpp \ model/project.cpp \ diff --git a/gui/src/panels/assets.cpp b/gui/src/panels/assets-panel.cpp similarity index 91% rename from gui/src/panels/assets.cpp rename to gui/src/panels/assets-panel.cpp index daaa0f363..57a7edf6f 100644 --- a/gui/src/panels/assets.cpp +++ b/gui/src/panels/assets-panel.cpp @@ -1,5 +1,5 @@ /* - assets.cpp - Implementation of the assets panel + assets-panel.cpp - Implementation of the assets panel Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -20,13 +20,13 @@ * *****************************************************/ -#include "assets.hpp" +#include "assets-panel.hpp" namespace lumiera { namespace gui { namespace panels { -Assets::Assets() : +AssetsPanel::AssetsPanel() : Panel("assets", "Assets"), placeholder("Placeholder label. Is this supposed to be titled assets\nas in the proc layer? or resources\nas in cinelerra?") { diff --git a/gui/src/panels/assets.hpp b/gui/src/panels/assets-panel.hpp similarity index 82% rename from gui/src/panels/assets.hpp rename to gui/src/panels/assets-panel.hpp index f6d1d5544..899c15db4 100644 --- a/gui/src/panels/assets.hpp +++ b/gui/src/panels/assets-panel.hpp @@ -1,5 +1,5 @@ /* - assets.hpp - Definition of the assets panel + assets-panel.hpp - Definition of the assets panel Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -19,12 +19,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/** @file timeline.hpp +/** @file assets-panel.hpp ** This file contains the definition of the assets panel */ -#ifndef ASSETS_HPP -#define ASSETS_HPP +#ifndef ASSETS_PANEL_HPP +#define ASSETS_PANEL_HPP #include "panel.hpp" @@ -32,10 +32,10 @@ namespace lumiera { namespace gui { namespace panels { - class Assets : public Panel + class AssetsPanel : public Panel { public: - Assets(); + AssetsPanel(); protected: Gtk::Label placeholder; @@ -45,4 +45,4 @@ namespace panels { } // namespace gui } // namespace lumiera -#endif // ASSETS_HPP +#endif // ASSETS_PANEL_HPP diff --git a/gui/src/panels/viewer.cpp b/gui/src/panels/viewer-panel.cpp similarity index 93% rename from gui/src/panels/viewer.cpp rename to gui/src/panels/viewer-panel.cpp index 0c64f3d68..ea1bfeffd 100644 --- a/gui/src/panels/viewer.cpp +++ b/gui/src/panels/viewer-panel.cpp @@ -1,5 +1,5 @@ /* - viewer.cpp - Implementation of the viewer panel + viewer-panel.cpp - Implementation of the viewer panel Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -20,7 +20,7 @@ * *****************************************************/ -#include "viewer.hpp" +#include "viewer-panel.hpp" using namespace lumiera::gui::widgets; using namespace Gtk; @@ -29,7 +29,7 @@ namespace lumiera { namespace gui { namespace panels { -Viewer::Viewer() : +ViewerPanel::ViewerPanel() : Panel("viewer", "Viewer"), previousButton(Stock::MEDIA_PREVIOUS), rewindButton(Stock::MEDIA_REWIND), diff --git a/gui/src/panels/viewer.hpp b/gui/src/panels/viewer-panel.hpp similarity index 81% rename from gui/src/panels/viewer.hpp rename to gui/src/panels/viewer-panel.hpp index fb6d77760..9f92b4f63 100644 --- a/gui/src/panels/viewer.hpp +++ b/gui/src/panels/viewer-panel.hpp @@ -1,5 +1,5 @@ /* - viewer.hpp - Definition of the viewer panel + viewer-panel.hpp - Definition of the viewer panel Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -19,17 +19,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/** @file viewer.hpp +/** @file viewer-panel.hpp ** This file contains the definition of the viewer panel */ -#ifndef VIEWER_HPP -#define VIEWER_HPP +#ifndef VIEWER_PANEL_HPP +#define VIEWER_PANEL_HPP #include #include "panel.hpp" -#include "../widgets/video-display.hpp" +#include "../widgets/video-display-widget.hpp" using namespace lumiera::gui::widgets; using namespace Gtk; @@ -38,10 +38,10 @@ namespace lumiera { namespace gui { namespace panels { - class Viewer : public Panel + class ViewerPanel : public Panel { public: - Viewer(); + ViewerPanel(); protected: @@ -51,7 +51,7 @@ namespace panels { ToolButton forwardButton; ToolButton nextButton; - VideoDisplay display; + VideoDisplayWidget display; Toolbar toolBar; }; @@ -59,4 +59,4 @@ namespace panels { } // namespace gui } // namespace lumiera -#endif // VIEWER_HPP +#endif // VIEWER_PANEL_HPP diff --git a/gui/src/widgets/video-display.cpp b/gui/src/widgets/video-display-widget.cpp similarity index 88% rename from gui/src/widgets/video-display.cpp rename to gui/src/widgets/video-display-widget.cpp index 29d95268d..16b089c5b 100644 --- a/gui/src/widgets/video-display.cpp +++ b/gui/src/widgets/video-display-widget.cpp @@ -1,5 +1,5 @@ /* - video-display.cpp - Implementation of the video viewer widget + video-display-widget.cpp - Implementation of the video viewer widget Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -24,19 +24,19 @@ #include #include -#include "video-display.hpp" +#include "video-display-widget.hpp" namespace lumiera { namespace gui { namespace widgets { -VideoDisplay::VideoDisplay() +VideoDisplayWidget::VideoDisplayWidget() { set_flags(Gtk::NO_WINDOW); } void -VideoDisplay::on_realize() +VideoDisplayWidget::on_realize() { //Call base class: Gtk::Widget::on_realize(); @@ -44,7 +44,7 @@ VideoDisplay::on_realize() } bool -VideoDisplay::on_expose_event(GdkEventExpose* event) +VideoDisplayWidget::on_expose_event(GdkEventExpose* event) { // This is where we draw on the window Glib::RefPtr window = get_window(); @@ -67,8 +67,6 @@ VideoDisplay::on_expose_event(GdkEventExpose* event) return true; } - - } // namespace widgets } // namespace gui } // namespace lumiera diff --git a/gui/src/widgets/video-display.hpp b/gui/src/widgets/video-display-widget.hpp similarity index 80% rename from gui/src/widgets/video-display.hpp rename to gui/src/widgets/video-display-widget.hpp index 6fdd73958..d082e8a2f 100644 --- a/gui/src/widgets/video-display.hpp +++ b/gui/src/widgets/video-display-widget.hpp @@ -1,5 +1,5 @@ /* - video-display.hpp - Declaration of the video viewer widget + video-display-widget.hpp - Declaration of the video viewer widget Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -19,12 +19,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/** @file viewer.hpp +/** @file viewer-display-widget.hpp ** This file contains the definition of video viewer widget */ -#ifndef VIDEO_DISPLAY_HPP -#define VIDEO_DISPLAY_HPP +#ifndef VIDEO_DISPLAY_WIDGET_HPP +#define VIDEO_DISPLAY_WIDGET_HPP #include @@ -32,10 +32,10 @@ namespace lumiera { namespace gui { namespace widgets { - class VideoDisplay : public Gtk::Widget + class VideoDisplayWidget : public Gtk::Widget { public: - VideoDisplay(); + VideoDisplayWidget(); /* ===== Overrides ===== */ protected: @@ -47,4 +47,4 @@ namespace widgets { } // namespace gui } // namespace lumiera -#endif // VIDEO_DISPLAY_HPP +#endif // VIDEO_DISPLAY_WIDGET_HPP diff --git a/gui/src/workspace/workspace-window.cpp b/gui/src/workspace/workspace-window.cpp index 5d06b6d18..d78eb5b5c 100644 --- a/gui/src/workspace/workspace-window.cpp +++ b/gui/src/workspace/workspace-window.cpp @@ -130,14 +130,14 @@ namespace workspace { dock_container.pack_end(*dock, PACK_EXPAND_WIDGET); base_container.pack_start(dock_container, PACK_EXPAND_WIDGET); - gdl_dock_add_item ((GdlDock*)dock->gobj(), assets.get_dock_item(), GDL_DOCK_LEFT); - gdl_dock_add_item ((GdlDock*)dock->gobj(), viewer.get_dock_item(), GDL_DOCK_RIGHT); - gdl_dock_add_item ((GdlDock*)dock->gobj(), timeline.get_dock_item(), GDL_DOCK_BOTTOM); + gdl_dock_add_item ((GdlDock*)dock->gobj(), assets_panel.get_dock_item(), GDL_DOCK_LEFT); + gdl_dock_add_item ((GdlDock*)dock->gobj(), viewer_panel.get_dock_item(), GDL_DOCK_RIGHT); + gdl_dock_add_item ((GdlDock*)dock->gobj(), timeline_panel.get_dock_item(), GDL_DOCK_BOTTOM); // Manually dock and move around some of the items - gdl_dock_item_dock_to (timeline.get_dock_item(), assets.get_dock_item(), + gdl_dock_item_dock_to (timeline_panel.get_dock_item(), assets_panel.get_dock_item(), GDL_DOCK_BOTTOM, -1); - gdl_dock_item_dock_to (viewer.get_dock_item(), assets.get_dock_item(), + gdl_dock_item_dock_to (viewer_panel.get_dock_item(), assets_panel.get_dock_item(), GDL_DOCK_RIGHT, -1); show_all_children(); diff --git a/gui/src/workspace/workspace-window.hpp b/gui/src/workspace/workspace-window.hpp index a111cafeb..70d1a04e4 100644 --- a/gui/src/workspace/workspace-window.hpp +++ b/gui/src/workspace/workspace-window.hpp @@ -34,8 +34,8 @@ #include "actions.hpp" -#include "../panels/assets.hpp" -#include "../panels/viewer.hpp" +#include "../panels/assets-panel.hpp" +#include "../panels/viewer-panel.hpp" #include "../panels/timeline-panel.hpp" using namespace lumiera::gui::panels; @@ -77,9 +77,9 @@ namespace workspace { /* ===== Panels ===== */ private: - Assets assets; - Viewer viewer; - TimelinePanel timeline; + AssetsPanel assets_panel; + ViewerPanel viewer_panel; + TimelinePanel timeline_panel; /* ===== Helpers ===== */ private: From 786ff5743f17fe84684e4cdbbdea346929b99d03 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 19 Apr 2008 23:16:27 +0100 Subject: [PATCH 026/245] Added basic theme support --- gui/src/Makefile.am | 2 + gui/src/dialogs/render.cpp | 2 +- gui/src/gtk-lumiera.cpp | 6 +- gui/src/gtk-lumiera.hpp | 6 +- gui/src/lumiera_ui.rc | 1496 ++++++++++++++++++++++++++++++++++++ gui/src/window-manager.cpp | 48 ++ gui/src/window-manager.hpp | 51 ++ 7 files changed, 1606 insertions(+), 5 deletions(-) create mode 100644 gui/src/lumiera_ui.rc create mode 100644 gui/src/window-manager.cpp create mode 100644 gui/src/window-manager.hpp diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index d5a380fed..ac159ea65 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -15,6 +15,8 @@ bin_PROGRAMS = gtk-lumiera gtk_lumiera_SOURCES = \ gtk-lumiera.cpp \ gtk-lumiera.hpp \ + window-manager.cpp \ + window-manager.hpp \ workspace/actions.cpp \ workspace/actions.hpp \ workspace/workspace-window.cpp \ diff --git a/gui/src/dialogs/render.cpp b/gui/src/dialogs/render.cpp index f785ed6a4..6fadd82fb 100644 --- a/gui/src/dialogs/render.cpp +++ b/gui/src/dialogs/render.cpp @@ -88,7 +88,7 @@ namespace dialogs { // Add response buttons the the dialog: dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - dialog.add_button(/*Gtk::Stock::SAVE*/"Save", Gtk::RESPONSE_OK); + dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); int result = dialog.run(); g_message("%d", result); diff --git a/gui/src/gtk-lumiera.cpp b/gui/src/gtk-lumiera.cpp index a7951b3a0..7178c4170 100644 --- a/gui/src/gtk-lumiera.cpp +++ b/gui/src/gtk-lumiera.cpp @@ -21,13 +21,13 @@ * *****************************************************/ #include -#include #ifdef ENABLE_NLS # include #endif #include "gtk-lumiera.hpp" +#include "window-manager.hpp" #include "workspace/workspace-window.hpp" #include "model/project.hpp" @@ -57,6 +57,10 @@ namespace gui { Glib::set_application_name(AppTitle); Project project; + WindowManager window_manager; + + window_manager.set_theme("lumiera_ui.rc"); + WorkspaceWindow main_window(&project); kit.run(main_window); diff --git a/gui/src/gtk-lumiera.hpp b/gui/src/gtk-lumiera.hpp index 6532d2b42..a3586e0d1 100644 --- a/gui/src/gtk-lumiera.hpp +++ b/gui/src/gtk-lumiera.hpp @@ -22,11 +22,11 @@ /** @file gtk-lumiera.hpp ** This file contains application wide global definitions ** user actions. - ** @see main.cpp + ** @see gtk-lumiera.cpp */ #ifndef GTK_LUMIERA_HPP -#define GTK_LUMIERA_HPO +#define GTK_LUMIERA_HPP #include @@ -92,6 +92,6 @@ namespace gui { } // namespace gui } // namespace lumiera -#endif +#endif // GTK_LUMIERA_HPP diff --git a/gui/src/lumiera_ui.rc b/gui/src/lumiera_ui.rc new file mode 100644 index 000000000..d87322014 --- /dev/null +++ b/gui/src/lumiera_ui.rc @@ -0,0 +1,1496 @@ +# +# This is the GTK style file for Ardour +# +# + +style "very_small_text" +{ + font_name = "sans 7" +} + +style "small_text" +{ + font_name = "sans 8" +} + +style "small_bold_text" +{ + font_name = "sans bold 8" +} + +style "medium_bold_text" +{ + font_name = "sans bold 8" +} + +style "medium_text" +{ + font_name = "sans 8" +} + +style "red_medium_text" = "medium_text" +{ + fg[NORMAL] = { 1.0, 0, 0 } + fg[ACTIVE] = { 1.0, 0, 0 } + fg[SELECTED] = { 1.0, 0, 0 } +} + + +style "large_text" +{ + font_name = "sans 18" +} + +style "larger_bold_text" +{ + font_name = "sans bold 14" +} + +style "plugin_name_text" +{ + font_name = "sans bold 25" + fg[NORMAL] = { 0.80, 0.80, 0.80 } +} + +style "plugin_maker_text" +{ + font_name = "sans bold 14" + fg[NORMAL] = { 0.80, 0.80, 0.80 } +} + +style "automation_track_name" +{ + font_name = "sans italic 8" +} + +style "first_action_message" +{ + font_name = "sans medium 34" +} + +style "verbose_canvas_cursor" +{ + font_name = "sans bold 24" +} + +style "marker_text" +{ + font_name = "sans 8" +} + +style "time_axis_view_item_name" +{ + font_name = "sans 9" +} + +style "default_base" = "medium_text" +{ + GtkWidget::cursor_color = {1.0, 1.0, 1.0 } + GtkButton::default_border = { 0, 0, 0, 0 } + GtkButton::default_outside_border = { 0, 0, 0, 0 } + GtkTreeView::vertical-padding = 0 + GtkTreeView::horizontal-padding = 0 + GtkTreeView::even-row-color = { 0, 0, 0 } + GtkTreeView::odd-row-color = { 0, 0, 0 } + + fg[NORMAL] = { 0.80, 0.80, 0.80 } + fg[ACTIVE] = { 0.80, 0.80, 0.80 } + fg[PRELIGHT] = { 1.0, 1.0, 1.0 } + fg[INSENSITIVE] = { 0.80, 0.80, 0.80 } + fg[SELECTED] = { 0.80, 0.80, 0.80 } + + bg[NORMAL] = { 0.35, 0.35, 0.40 } + bg[ACTIVE] = { 0.35, 0.35, 0.40 } + bg[PRELIGHT] = "#565690" + bg[INSENSITIVE] = { 0.10, 0.10, 0.10 } + bg[SELECTED] = { 0, 0.40, 0.60 } + + text[NORMAL] = { 0.80, 0.80, 0.80 } + text[ACTIVE] = { 0.80, 0.80, 0.80 } + text[PRELIGHT] = { 0.80, 0.80, 0.80 } + text[INSENSITIVE] = { 0.80, 0.80, 0.80} + text[SELECTED] = { 1.0, 1.0, 1.0 } + + base[ACTIVE] = "#272a2f" + base[NORMAL] = "#1a1e20" + base[PRELIGHT] = { 0.20, 0.20, 0.20 } + base[INSENSITIVE] = "#4c5159" + base[SELECTED] = { 0.25, 0.25, 0.25 } + + engine "clearlooks" + { + menubarstyle = 2 # 0 = flat, 1 = sunken, 2 = flat gradient + menuitemstyle = 1 # 0 = flat, 1 = 3d-ish (gradient), 2 = 3d-ish (button) + listviewitemstyle = 1 # 0 = flat, 1 = 3d-ish (gradient) + progressbarstyle = 1 # 0 = candy bar, 1 = fancy candy bar, 2 = flat + } +} + +style "base_frame" +{ + fg[NORMAL] = { 0.80, 0.80, 0.80 } + bg[NORMAL] = { 0.35, 0.35, 0.40 } +} + +style "transport_base" = "medium_bold_text" +{ + bg[NORMAL] = { 0.10, 0.10, 0.10 } + bg[ACTIVE] = { 0, 0, 0 } + bg[PRELIGHT] = { 0, 0, 0 } + bg[INSENSITIVE] = { 0, 0, 0 } + bg[SELECTED] = { 0, 0, 0 } +} + +style "black_mackie_menu_bar" +{ + font_name = "sans bold 9" + fg[NORMAL] = { 1.0, 1.0, 1.0 } + bg[NORMAL] = { 0, 0, 0 } +} + +style "default_buttons_menus" +{ + font_name = "sans 8" + fg[ACTIVE] = { 1.0, 1.0, 1.0 } + + bg[NORMAL] = { 0.30, 0.30, 0.35 } + bg[ACTIVE] = "#565690" + bg[PRELIGHT] = { 0.15, 0.15, 0.20 } + bg[INSENSITIVE] = { 0.15, 0.15, 0.20 } + bg[SELECTED] = { 0.15, 0.15, 0.20 } +} + +style "very_small_button" = "default_buttons_menus" +{ + font_name = "sans 7" + ythickness = 0 + xthickness = 0 +} + +style "small_button" = "default_buttons_menus" +{ +} + +style "very_small_red_active_and_selected_button" = "very_small_button" +{ + bg[ACTIVE] = { 1.0, 0, 0} + bg[SELECTED] = { 1.0, 0, 0} +} + +style "small_red_active_and_selected_button" = "small_button" +{ + fg[ACTIVE] = { 0, 0, 0 } + bg[ACTIVE] = { 1.0, 0, 0} + bg[SELECTED] = { 1.0, 0, 0} +} + +style "gain_fader" +{ + bg[NORMAL] = { 0.269, 0.269, 0.300} + bg[ACTIVE] = { 0.152, 0.152, 0.168 } +} + + +style "track_rec_enable_button" = "small_button" +{ +} + +style "track_rec_enable_button_active" = "small_button" +{ + fg[SELECTED] = { 0.0, 0.0, 0.0 } + fg[ACTIVE] = { 0.0, 0.0, 0.0 } + fg[PRELIGHT] = { 0.0, 0.0, 0.0 } + fg[NORMAL] = { 0.0, 0.0, 0.0 } + + bg[NORMAL] = { 1.0, 0.0, 0.0 } + bg[ACTIVE] = { 1.0, 0.0, 0.0 } + bg[SELECTED] = { 1.0, 0.0, 0.0 } + bg[PRELIGHT] = { 1.0, 0.0, 0.0 } +} + +style "track_rec_enable_button_alternate" = "small_button" +{ + fg[SELECTED] = { 0.0, 0.0, 0.0 } + fg[ACTIVE] = { 0.0, 0.0, 0.0 } + fg[PRELIGHT] = { 0.0, 0.0, 0.0 } + fg[NORMAL] = { 0.0, 0.0, 0.0 } + + bg[NORMAL] = { 0.91, 0.68, 0.68} + bg[ACTIVE] = { 0.91, 0.68, 0.68} + bg[SELECTED] = { 0.91, 0.68, 0.68} + bg[PRELIGHT] = { 0.91, 0.68, 0.68} +} + +style "mixer_track_rec_enable_button" = "track_rec_enable_button" +{ + font_name = "sans 7" + xthickness = 0 + ythickness = 0 +} + +style "mixer_track_rec_enable_button_alternate" = "track_rec_enable_button_alternate" +{ + font_name = "sans 7" + xthickness = 0 + ythickness = 0 +} + +style "mixer_track_rec_enable_button_active" = "track_rec_enable_button_active" +{ + font_name = "sans 7" + xthickness = 0 + ythickness = 0 +} + +style "solo_button" = "small_button" +{ +} + +style "solo_button_alternate" = "small_button" +{ + bg[NORMAL] = { 0.19, 0.97, 0.69 } # solo-safe + bg[ACTIVE] = { 0.19, 0.97, 0.69 } # solo-safe + bg[SELECTED] = { 0.19, 0.97, 0.69 } # solo-safe + bg[PRELIGHT] = { 0.19, 0.97, 0.69 } # solo-safe + + fg[ACTIVE] = { 0, 0, 0 } + fg[SELECTED] = { 0, 0, 0 } + fg[NORMAL] = { 0, 0, 0 } + fg[PRELIGHT] = { 0, 0, 0 } +} + + +style "solo_button_active" = "small_button" +{ + bg[NORMAL] = { 0.66, 0.97, 0.19 } # solo + bg[ACTIVE] = { 0.66, 0.97, 0.19 } # solo + bg[SELECTED] = { 0.66, 0.97, 0.19 } # solo + bg[PRELIGHT] = { 0.66, 0.97, 0.19 } # solo + + fg[ACTIVE] = { 0, 0, 0 } + fg[SELECTED] = { 0, 0, 0 } + fg[NORMAL] = { 0, 0, 0 } + fg[PRELIGHT] = { 0, 0, 0 } +} + +style "mixer_solo_button" = "solo_button" +{ + font_name = "sans 7" + xthickness = 0 + ythickness = 0 +} + +style "mixer_solo_button_alternate" = "solo_button_alternate" +{ + font_name = "sans 7" + xthickness = 0 + ythickness = 0 +} +style "mixer_solo_button_active" = "solo_button_active" +{ + font_name = "sans 7" + xthickness = 0 + ythickness = 0 +} + + +style "mute_button" = "small_button" +{ +} + +style "mute_button_alternate" = "small_button" +{ + bg[ACTIVE] = { 1.0, 0.98, 0.53 } + bg[NORMAL] = { 1.0, 0.98, 0.53 } + bg[SELECTED] = { 1.0, 0.98, 0.53 } + bg[PRELIGHT] = { 1.0, 0.98, 0.53 } + + fg[SELECTED] = { 0, 0, 0 } + fg[ACTIVE] = { 0, 0, 0 } + fg[NORMAL] = { 0, 0, 0 } + fg[PRELIGHT] = { 0, 0, 0 } +} + +style "mute_button_active" = "small_button" +{ + bg[NORMAL] = { 0.90, 0.89, 0.73 } + bg[ACTIVE] = { 0.90, 0.89, 0.73 } + bg[PRELIGHT] = { 0.90, 0.89, 0.73 } + bg[SELECTED] = { 0.90, 0.89, 0.73 } + + fg[SELECTED] = { 0, 0, 0 } + fg[ACTIVE] = { 0, 0, 0 } + fg[NORMAL] = { 0, 0, 0 } + fg[PRELIGHT] = { 0, 0, 0 } +} + +style "mixer_mute_button" = "mute_button" +{ + font_name = "sans 7" + xthickness = 0 + ythickness = 0 +} + +style "mixer_mute_button_alternate" = "mute_button_alternate" +{ + font_name = "sans 7" + xthickness = 0 + ythickness = 0 +} + +style "mixer_mute_button_active" = "mute_button_active" +{ + font_name = "sans 7" + xthickness = 0 + ythickness = 0 +} + +style "multiline_combo" = "small_button" +{ + font_name = "sans 8" + xthickness = 0 + ythickness = 0 +} + +style "mixer_mute_button" = "mute_button" +{ + font_name = "sans 7" + xthickness = 0 + ythickness = 0 +} + +style "track_loop_button" = "small_button" +{ + bg[ACTIVE] = { 1.0, 0.98, 0.53 } + bg[PRELIGHT] = { 1.0, 0.98, 0.53 } + +} + +style "mixer_red_active_button" = "very_small_button" +{ + fg[ACTIVE] = { 0, 1.0, 1.0 } + bg[ACTIVE] = { 0.7, 0, 0 } + + base[INSENSITIVE] = { 0.16, 0.16, 0.21 } + bg[INSENSITIVE] = { 0.16, 0.16, 0.21 } +} + +style "time_button" = "default_buttons_menus" +{ + font_name = "sans 8" +} + +style "transport_button" +{ +} + +style "transport_button_active" +{ + bg[NORMAL] = { 0.50, 1.0, 0.50 } + bg[ACTIVE] = { 0.50, 1.0, 0.50 } + bg[SELECTED] = { 0.50, 1.0, 0.50 } + bg[PRELIGHT] = { 0.50, 1.0, 0.50 } + + fg[NORMAL] = { 0, 0, 0 } + fg[PRELIGHT] = { 0, 0, 0 } + fg[SELECTED] = { 0, 0, 0 } + fg[ACTIVE] = { 0, 0, 0 } +} + +style "transport_rec_button" +{ +} + +style "transport_rec_button_active" +{ + bg[ACTIVE] = { 1.0, 0, 0 } + bg[NORMAL] = { 1.0, 0, 0 } + bg[SELECTED] = { 1.0, 0, 0 } + bg[PRELIGHT] = { 1.0, 0, 0 } +} + +style "transport_rec_button_alternate" +{ + bg[PRELIGHT] = { 0.91, 0.68, 0.68 } + bg[NORMAL] = { 0.91, 0.68, 0.68 } + bg[SELECTED] = { 0.91, 0.68, 0.68 } + bg[ACTIVE] = { 0.91, 0.68, 0.68 } +} + +style "shuttle_control" = "very_small_text" +{ + fg[NORMAL] = { 0.85, 0.92, 0.98 } + fg[ACTIVE] = { 0.85, 0.92, 0.98 } + fg[PRELIGHT] = { 0.85, 0.92, 0.98 } + fg[SELECTED] = { 0.85, 0.92, 0.98 } + fg[INSENSITIVE] = { 0.85, 0.92, 0.98 } + + bg[NORMAL] = { 0.26, 0.26, 0.31 } + bg[PRELIGHT] = { 0.26, 0.26, 0.31 } + bg[INSENSITIVE] = { 0.26, 0.26, 0.31 } + bg[ACTIVE] = { 0.70, 0.70, 0.70 } + bg[SELECTED] = { 1.0, 0.04, 0.04 } +} + +style "ardour_adjusters" = "default_buttons_menus" +{ + bg[NORMAL] = { 0.60, 0.60, 0.60 } + bg[PRELIGHT] = { 0.80, 0.80, 0.80 } + bg[ACTIVE] = { 0.06, 0.06, 0.06 } +} + +style "editor_hscrollbar" = "ardour_adjusters" +{ + # + # special case: we want this scrollbar to be as tall as the + # zoom focus selector combobox. scrollbars don't expand to + # fill the space available to them, so we have to explicitly + # make it bigger. + # + GtkRange::slider_width = 27 + GtkScrollbar::slider_width = 27 +} + +style "ardour_progressbars" = "default_buttons_menus" +{ + bg[NORMAL] = { 0, 0, 0 } + bg[PRELIGHT] = { 0.00, 0.36, 0.40 } +} + +style "options_window" = "default_base" +{ + font_name = "sans 8" + fg[PRELIGHT] = { 0.80, 0.80, 0.80 } +} + +style "option_entry" = "default_base" +{ + fg[NORMAL] = { 1.0, 1.0, 1.0 } + fg[ACTIVE] = { 1.0, 1.0, 1.0 } + fg[INSENSITIVE] = { 0.80, 0.80, 0.80 } + + base[INSENSITIVE] = { 0.07, 0.07, 0.12 } + + bg[NORMAL] = { 0.35, 0.35, 0.40 } + bg[ACTIVE] = { 0.35, 0.35, 0.40 } +} + +style "red_when_active" = "medium_text" +{ + fg[NORMAL] = { 0.80, 0.80, 0.80 } + bg[NORMAL] = { 0.26, 0.26, 0.31 } + + fg[ACTIVE] = { 0.80, 0.80, 0.80 } + bg[ACTIVE] = { 1.0, 0, 0} +} + +style "xrun_warn" +{ + font_name = "sans bold 18" + + fg[NORMAL] = { 1.0, 1.0, 1.0 } + fg[ACTIVE] = { 1.0, 1.0, 1.0 } + text[NORMAL] = { 1.0, 1.0, 1.0 } + text[ACTIVE] = { 1.0, 1.0, 1.0 } + base[NORMAL] = { 0.09, 0.48, 0.46 } + base[ACTIVE] = { 0.09, 0.48, 0.46 } + bg[NORMAL] = { 1.0, 0.48, 0.46 } + bg[ACTIVE] = { 0.09, 1.0, 0.46 } +} + +style "menu_bar_base" = "default_base" +{ + bg[NORMAL] = { 0.2, 0.2, 0.3 } + bg[ACTIVE] = { 0, 0, 0 } + bg[PRELIGHT] = { 0, 0, 0 } + bg[INSENSITIVE] = { 0, 0, 0 } + bg[SELECTED] = { 0, 0, 0 } +} + +style "fatal_message" = "medium_text" +{ + fg[ACTIVE] = { 1.0, 0, 1.0 } + fg[NORMAL] = { 0.80, 0.80, 0.80 } + bg[ACTIVE] = { 0,0,0 } + bg[NORMAL] = { 0,0,0 } + base[ACTIVE] = { 0,0,0 } + base[NORMAL] = { 0,0,0 } +} + +style "error_message" = "medium_text" +{ + fg[ACTIVE] = { 1.0, 0, 0 } + fg[NORMAL] = { 0.80, 0.80, 0.80 } + bg[ACTIVE] = { 0,0,0 } + bg[NORMAL] = { 0,0,0 } + base[ACTIVE] = { 0,0,0 } + base[NORMAL] = { 0,0,0 } +} + +style "info_message" = "medium_text" +{ + fg[ACTIVE] = { 1.0, 0, 0 } + fg[NORMAL] = { 0.80, 0.80, 0.80 } + bg[ACTIVE] = { 0,0,0 } + bg[NORMAL] = { 0,0,0 } + base[ACTIVE] = { 0,0,0 } + base[NORMAL] = { 0,0,0 } +} + +style "warning_message" = "medium_text" +{ + fg[ACTIVE] = { 0.30,0.30, 1.0 } + fg[NORMAL] = { 0.80, 0.80, 0.80 } + bg[ACTIVE] = { 0, 0, 0 } + bg[NORMAL] = { 0, 0, 0 } + base[ACTIVE] = { 0, 0, 0 } + base[NORMAL] = { 0, 0, 0 } +} + +style "medium_entry" = "medium_text" +{ + fg[NORMAL] = { 0.70, 0.70, 0.70 } + fg[ACTIVE] = { 0.70, 0.70, 0.70 } + fg[SELECTED] = { 1.0, 1.0, 1.0 } + + bg[NORMAL] = { 0.35, 0.35, 0.40 } + + base[NORMAL] = { 0, 0, 0 } + base[ACTIVE] = { 0, 0, 0 } + base[SELECTED] = { 0.70, 0.70, 0.70 } +} + +style "medium_entry_noselection_fg" = "medium_entry" +{ + fg[SELECTED] = { 0.50, 1.0, 0.50 } +} + +style "medium_entry_noselection_bg" = "medium_entry" +{ + bg[SELECTED] = { 1.0, 1.0, 1.0 } +} + +style "medium_bold_entry" = "medium_bold_text" +{ + fg[NORMAL] = { 0.70, 0.70, 0.70 } + fg[ACTIVE] = { 0.70, 0.70, 0.70 } + + bg[NORMAL] = { 0.35, 0.35, 0.40 } + + base[NORMAL] = { 0, 0, 0 } + base[ACTIVE] = { 0, 0, 0 } + base[SELECTED] = { 0, 0, 0 } +} + +style "small_entry" = "small_text" +{ + fg[NORMAL] = { 0.70, 0.70, 0.70 } + fg[ACTIVE] = { 0, 1.0, 0 } + fg[SELECTED] = { 0, 1.0, 0 } + text[NORMAL] = { 0.70, 0.70, 0.70 } + text[ACTIVE] = { 0, 1.0, 0 } + text[SELECTED] = { 0, 1.0, 0 } + bg[NORMAL] = { 0.0, 0.0, 0.0 } + bg[SELECTED] = { 0.0, 0.0, 0.0 } + bg[SELECTED] = { 0.0, 0.0, 0.0 } + base[NORMAL] = { 0, 0, 0 } + base[ACTIVE] = { 0, 0, 0 } + base[SELECTED] = { 0, 0, 0 } +} + +style "red_active_small_entry" = "small_entry" +{ + fg[ACTIVE] = { 1.0, 0.0, 0.0 } + fg[SELECTED] = { 1.0, 0, 0 } +} + +style "small_bold_entry" = "small_bold_text" +{ + fg[NORMAL] = { 0.70, 0.70, 0.70 } + fg[ACTIVE] = { 0.70, 0.70, 0.70 } + + bg[NORMAL] = { 0.35, 0.35, 0.40 } + + base[NORMAL] = { 0, 0, 0 } + base[ACTIVE] = { 0, 0, 0 } + base[SELECTED] = { 0, 0, 0 } +} + +style "small_red_on_black_entry" = "small_bold_text" +{ + fg[NORMAL] = { 1.0, 0, 0 } + fg[ACTIVE] = { 1.0, 0, 0 } + base[NORMAL] = { 0.0, 0.0, 0.0 } + base[ACTIVE] = { 0.0, 0.0, 0.0 } + bg[NORMAL] = { 0.0, 0.0, 0.0 } + bg[ACTIVE] = { 0.0, 0.0, 0.0 } +} + +style "non_recording_big_clock_display" = "medium_entry" +{ + font_name = "sans 60" + + fg[NORMAL] = { 0.50, 1.0, 0.50 } + fg[ACTIVE] = { 1.0, 0, 0.0 } + fg[SELECTED] = { 1.0, 0, 0 } + fg[PRELIGHT] = { 1.0, 0, 0.0 } + fg[INSENSITIVE] = { 1.0, 0, 0.0 } + + base[NORMAL] = { 0.0, 0.0, 0.0 } + base[ACTIVE] = { 0.0, 0.0, 0.0 } + bg[NORMAL] = { 0.0, 0.0, 0.0 } + bg[ACTIVE] = { 0.7, 0.0, 0.0 } +} + +style "recording_big_clock_display" = "non_recording_big_clock_display" +{ + fg[NORMAL] = { 1.0, 0, 0 } +} + +style "transport_clock_display" +{ + font_name = "sans bold 14" + + fg[NORMAL] = { 0.50, 1.0, 0.50 } + fg[ACTIVE] = { 1.0, 0, 0.0 } + fg[SELECTED] = { 1.0, 0, 0 } + fg[PRELIGHT] = { 1.0, 0, 0.0 } + fg[INSENSITIVE] = { 1.0, 0, 0.0 } + + base[NORMAL] = { 0.0, 0.0, 0.0 } + base[ACTIVE] = { 0.0, 0.0, 0.0 } + bg[NORMAL] = { 0.0, 0.0, 0.0 } + bg[ACTIVE] = { 0.0, 0.0, 0.0 } +} + +style "tempo_meter_clock_display" +{ + font_name = "sans 7" + fg[NORMAL] = { 1.0, 1.0, 1.0 } + fg[ACTIVE] = { 1.0, 1.0, 0.0 } + fg[SELECTED] = { 1.0, 0, 0 } + base[NORMAL] = { 0.0, 0.48, 1.0 } + base[ACTIVE] = { 0.09, 0.98, 0.46 } + bg[NORMAL] = { 0.0, 0.48, 1.0 } + bg[ACTIVE] = { 0.09, 0.98, 0.46 } +} + +style "default_clock_display" = "medium text" +{ + fg[NORMAL] = { 0.50, 1.0, 0.50 } + fg[ACTIVE] = { 1.0, 0.0, 0.0 } + fg[SELECTED] = { 1.0, 0, 0 } + base[NORMAL] = { 0, 0, 0 } + base[ACTIVE] = { 0, 0, 0 } + bg[NORMAL] = { 0, 0, 0 } + bg[ACTIVE] = { 0, 0, 0 } +} + +style "editor_time_ruler" = "small_text" +{ + fg[NORMAL] = { 0.80, 0.80, 0.80 } + bg[NORMAL] = { 0.09, 0.09, 0.09 } +} + +style "audio_track_base" = "default_base" +{ + font_name = "sans 6" + fg[NORMAL] = { 0.77, 0.77, 0.72 } + bg[NORMAL] = { 0.18, 0.19, 0.22 } + bg[ACTIVE] = { 0.20, 0.20, 0.20 } + bg[PRELIGHT] = { 0.20, 0.20, 0.20 } + bg[INSENSITIVE] = { 0.20, 0.20, 0.20 } + bg[SELECTED] = { 0.20, 0.20, 0.20 } +} + +style "audio_bus_base" +{ + font_name = "sans 6" + fg[NORMAL] = { 0.77, 0.77, 0.72 } + fg[NORMAL] = { 0.7, 0.8, 0.2 } + #bg[NORMAL] = {0, 0.36, 0.40 } + bg[NORMAL] = "#444466" +} + +style "track_name_display" +{ + font_name = "sans medium 8" + fg[NORMAL] = { 0.80, 0.80, 0.80 } + fg[ACTIVE] = { 0.80, 0.80, 0.80 } + + base[NORMAL] = { 0.06, 0.06, 0.06 } + base[ACTIVE] = { 0.26, 0.26, 0.26 } + bg[NORMAL] = { 0.26, 0.26, 0.26 } + bg[ACTIVE] = { 0.26, 0.26, 0.26 } +} + +style "active_track_name_display" +{ + font_name = "sans medium 8" + text[NORMAL] = { 0.26, 0.26, 0.26 } + base[NORMAL] = { 0.89, 0.89, 0.89 } +} + +style "track_separator" +{ + bg[NORMAL] = { 0.35, 0.35, 0.40 } +} + +# +# Track edit groups. These styles define +# the colors that the "edit" button will +# use as a track is moved from +# track edit group to track edit group. +# There are 8 edit groups. Edit group 0 +# is used for tracks that are not editable, +# so we leave its style to the default. +# + +style "edit_group_0" + +{ + bg[ACTIVE] = { 1.0, 0.65, 0.13 } + bg[NORMAL] = { 0.31, 0.31, 0.31 } + fg[NORMAL] = { 0.82, 0.91, 0.99 } + fg[ACTIVE] = { 0, 0, 0 } +} + +style "edit_group_1" +{ + fg[NORMAL] = { 0, 0, 0 } + fg[PRELIGHT] = { 0, 0, 0 } + fg[SELECTED] = { 0, 0, 0 } + bg[NORMAL] = { 0.93, 0.34, 0.08 } + bg[PRELIGHT] = { 0.93, 0.34, 0.08 } + bg[SELECTED] = { 0.93, 0.34, 0.08 } +} + +style "edit_group_2" +{ + fg[NORMAL] = { 0, 0, 0 } + fg[PRELIGHT] = { 0, 0, 0 } + fg[SELECTED] = { 0, 0, 0 } + bg[NORMAL] = { 0.93, 0.34, 0.08 } + bg[PRELIGHT] = { 0.93, 0.34, 0.08 } + bg[SELECTED] = { 0.93, 0.34, 0.08 } +} + +style "edit_group_3" +{ + fg[NORMAL] = { 0, 0, 0 } + fg[PRELIGHT] = { 0, 0, 0 } + fg[SELECTED] = { 0, 0, 0 } + bg[NORMAL] = { 0.93, 0.34, 0.08 } + bg[PRELIGHT] = { 0.93, 0.34, 0.08 } + bg[SELECTED] = { 0.93, 0.34, 0.08 } +} + +style "treeview_parent_node" +{ + # specifies *just* the color used for whole file rows when not selected + fg[NORMAL] = { 0.0, 0.6, 0.85 } +} + +style "treeview_display" = "small_bold_text" +{ + # expander arrow border and DnD "icon" text + fg[NORMAL] = { 0.8, 0.8, 0.8 } + + # background with no rows or no selection, plus + # expander arrow core and DnD "icon" background + base[NORMAL] = { 0.20, 0.20, 0.25 } + + # selected row bg when window does not have focus (including during DnD) + base[ACTIVE] = { 0.0, 0.60, 0.60 } + + # selected row bg when window has focus + base[SELECTED] = { 0, 0.75, 0.75 } + + # row text when in normal state and not a parent + text[NORMAL] = { 0.80, 0.80, 0.80 } + + # selected row text with window focus + text[SELECTED] = { 0, 1.0, 1.0 } + + # selected row text without window focus (including during DnD) + text[ACTIVE] = { 0, 1.0, 1.0 } +} + +style "main_canvas_area" +{ + bg[NORMAL] = { 0.30, 0.30, 0.34 } + bg[ACTIVE] = { 0.30, 0.30, 0.34 } + bg[INSENSITIVE] = { 0.30, 0.30, 0.34 } + bg[SELECTED] = { 0.30, 0.30, 0.34 } + bg[PRELIGHT] = { 0.30, 0.30, 0.34 } +} + +style "track_controls_inactive" +{ + bg[NORMAL] = { 0.60, 0.60, 0.66 } + bg[ACTIVE] = { 0.60, 0.60, 0.66 } + bg[INSENSITIVE] = { 0.60, 0.60, 0.66 } + bg[SELECTED] = { 0.60, 0.60, 0.66 } + bg[PRELIGHT] = { 0.60, 0.60, 0.66 } + + font_name = "sans medium 10" + fg[NORMAL] = { 0.7, 0.8, 0.2 } +} + +style "edit_controls_base_selected" +{ + bg[NORMAL] = { 0.60, 0.54, 0.60 } + bg[ACTIVE] = { 0.60, 0.54, 0.60 } + bg[INSENSITIVE] = { 0.60, 0.54, 0.60 } + bg[SELECTED] = { 0.60, 0.54, 0.60 } + bg[PRELIGHT] = { 0.60, 0.54, 0.60 } +} + +style "automation_track_controls_base" +{ + bg[NORMAL] = { 0.22, 0.22, 0.29 } + bg[ACTIVE] = { 0.22, 0.22, 0.29 } + bg[INSENSITIVE] = { 0.22, 0.22, 0.29 } + bg[SELECTED] = { 0.22, 0.22, 0.29 } + bg[PRELIGHT] = { 0.22, 0.22, 0.29 } +} + +# Plugin Editors +style "plugin_slider" +{ + font_name ="sans bold 10" + + # the slider itself. the inactive part is INSENSITIVE, + # the active part is something else. + + fg[NORMAL] = { 0.37, 0.43, 0.52 } + fg[ACTIVE] = { 0.37, 0.43, 0.52 } + fg[INSENSITIVE] = {0.35, 0.35, 0.40 } # matches default_base + fg[SELECTED] = { 0.37, 0.43, 0.52 } + fg[PRELIGHT] = { 0.37, 0.43, 0.52 } + + # draws the outer rectangle around the slider + + bg[NORMAL] = { 0.80, 0.80, 0.80 } + bg[ACTIVE] = { 0.80, 0.80, 0.80 } + bg[INSENSITIVE] = {0.80, 0.80, 0.80 } + bg[SELECTED] = { 0.80, 0.80, 0.80 } + bg[PRELIGHT] = { 0.80, 0.80, 0.80 } + + # the numeric display + + text[NORMAL] = { 0.80, 0.80, 0.80 } + text[ACTIVE] = { 0.80, 0.80, 0.80 } + text[INSENSITIVE] = { 0.80, 0.80, 0.80 } + text[SELECTED] = { 0.80, 0.80, 0.80 } + text[PRELIGHT] = { 0.80, 0.80, 0.80 } +} + +style "track_list_display" = "small_bold_text" +{ + text[NORMAL] = { 0.80, 0.80, 0.80 } + text[ACTIVE] = { 0.3, 0.3, 0.3 } + text[INSENSITIVE] = { 0, 0, 0 } + text[SELECTED] = { 0.8, 0.8, 0.8 } + + base[NORMAL] = { 0, 0, 0 } + base[ACTIVE] = { 0, 0, 0 } + base[INSENSITIVE] = { 0, 0, 0 } + base[SELECTED] = { 0, 0, 0 } +} + +style "inspector_track_list_display" = "track_list_display" +{ + text[ACTIVE] = { 0.8, 0.8, 0.8 } + + base[NORMAL] = { 0, 0, 0 } + base[ACTIVE] = { 0.2, 0.2, 0.2 } + base[INSENSITIVE] = { 0, 0, 0 } + base[SELECTED] = { 0.3, 0.3, 0.4 } +} + +style "redirect_list_display" +{ + GtkTreeView::horizontal-separator = 0 + GtkTreeView::vertical-separator = 0 + + font_name = "sans 7" + text[NORMAL] = { 0.80, 0.80, 0.80 } + text[ACTIVE] = { 0.70, 0.70, 0.70 } + text[INSENSITIVE] = { 0, 0, 0 } + text[SELECTED] = { 0.9, 0.3, 0.3 } + + base[NORMAL] = { 0, 0, 0 } + base[ACTIVE] = { 0, 0, 0 } + base[INSENSITIVE] = { 0, 0, 0 } + base[SELECTED] = { 0, 0, 0 } + + # these two are explicitly used by the cell renderer for the + # text + + fg[NORMAL] = { 0.5, 0.5, 0.5 } # used for inactive + fg[ACTIVE] = { 1.0, 1.0, 1.0 } # used for active +} + +style "inspector_redirect_list_display" = "redirect_list_display" +{ + base[SELECTED] = { 0.3, 0.3, 0.3 } +} + +# MixerPanZone: +# +# the NORMAL fg color is used for the pan puck +# the ACTIVE fg color is used for the speaker boxes + +style "pan_zone" = "default_base" +{ + fg[NORMAL] = { 0.34, 0.95, 0.92 } + fg[ACTIVE] = { 0.95, 0.48, 0.11 } +} + +style "paler_red_when_active" = "medium_text" +{ + fg[NORMAL] = { 0.80, 0.80, 0.80 } + fg[PRELIGHT] = { 0.80, 0.80, 0.80 } + bg[NORMAL] = { 0.31, 0.31, 0.31 } + bg[PRELIGHT] = { 0.31, 0.31, 0.31 } + + fg[ACTIVE] = { 0.36, 0.46, 0.28 } + bg[ACTIVE] = { 1.00, 0.59, 0.59} +} + +style "peak_display_peaked_entry" = "small_text" +{ + fg[NORMAL] = { 1.0, 1.0, 1.0 } + fg[ACTIVE] = { 1.0, 1.0, 1.0 } + fg[SELECTED] = { 1.0, 1.0, 1.0 } + + bg[NORMAL] = {0.9, 0.0, 0.0 } + bg[ACTIVE] = { 0.9, 0.0, 0.0 } + bg[PRELIGHT] = { 0.9, 0.0, 0.0 } + bg[INSENSITIVE] = { 0.9, 0.0, 0.0 } + bg[SELECTED] = { 0.9, 0.0, 0.0 } + base[NORMAL] = { 0.9, 0.0, 0.0 } + base[ACTIVE] = { 0.9, 0.0, 0.0 } + base[PRELIGHT] = { 0.9, 0.0, 0.0 } + base[INSENSITIVE] = { 0.9, 0.0, 0.0 } + base[SELECTED] = { 0.9, 0.0, 0.0 } +} + +style "selected_strip_frame" +{ + fg[NORMAL] = { 0.74, 0.42, 0.47 } + bg[NORMAL] = { 0.79, 0.28, 0.18 } +} + +style "flashing_alert" = "very_small_text" +{ + fg[NORMAL] = { 0.80, 0.80, 0.80 } + bg[NORMAL] = { 0.26, 0.26, 0.31 } + + fg[ACTIVE] = { 0.80, 0.80, 0.80 } + bg[ACTIVE] = { 1.0, 0, 0} +} + +style "selected_io_selector_port_list" = "medium_bold_text" +{ + + GtkTreeView::even-row-color = { 0, 0, 0 } + GtkTreeView::odd-row-color = { 0, 0, 0 } + +# fg is used to color the fg (text) of the column header button + + fg[NORMAL] = { 0.85, 0.85, 0.85 } + fg[SELECTED] = { 0.85, 0.85, 0.85 } + fg[ACTIVE] = { 0.85, 0.85, 0.85 } + fg[PRELIGHT] = { 0.85, 0.85, 0.85 } + fg[INSENSITIVE] = { 0.85, 0.85, 0.85 } + +# bg is used used to color the background of the column header button + + bg[NORMAL] = { 0.30, 0.30, 0.35 } + bg[ACTIVE] = { 0.30, 0.30, 0.35 } + bg[PRELIGHT] = { 0.30, 0.30, 0.35 } + bg[INSENSITIVE] = { 0.30, 0.30, 0.35 } + bg[SELECTED] = { 0.30, 0.30, 0.35 } + +# text is used to color the treeview row text + + text[NORMAL] = { 0.85, 0.85, 0.85 } + text[SELECTED] = { 0.85, 0.85, 0.85 } + +# base is used to color a treeview with no rows + + base[NORMAL] = { 0.20, 0.20, 0.25 } + base[ACTIVE] = { 0.20, 0.20, 0.25 } + base[PRELIGHT] = { 0.20, 0.20, 0.25 } + base[INSENSITIVE] = { 0.20, 0.20, 0.25 } + base[SELECTED] = { 0.20, 0.20, 0.25 } + +} + +style "io_selector_port_list" = "medium_text" +{ + GtkTreeView::even-row-color = { 0.20, 0.20, 0.25 } + GtkTreeView::odd-row-color = { 0.20, 0.20, 0.25 } +# fg is used to color the fg (text) of the column header button + + fg[NORMAL] = { 0.70, 0.70, 0.70 } + fg[SELECTED] = { 0.70, 0.70, 0.70 } + fg[ACTIVE] = { 0.70, 0.70, 0.70 } + fg[PRELIGHT] = { 0.70, 0.70, 0.70 } + fg[INSENSITIVE] = { 0.70, 0.70, 0.70 } + +# bg is used used to color the background of the column header button + + bg[NORMAL] = { 0.30, 0.30, 0.35 } + bg[ACTIVE] = { 0.30, 0.30, 0.35 } + bg[PRELIGHT] = { 0.30, 0.30, 0.35 } + bg[INSENSITIVE] = { 0.30, 0.30, 0.35 } + bg[SELECTED] = { 0.30, 0.30, 0.35 } + +# text is used to color the treeview row text + + text[NORMAL] = { 0.80, 0.80, 0.80 } + text[SELECTED] = { 0.80, 0.80, 0.80 } + +# base is used to color a treeview with no rows + + base[NORMAL] = { 0.20, 0.20, 0.25 } + base[ACTIVE] = { 0.20, 0.20, 0.25 } + base[PRELIGHT] = { 0.20, 0.20, 0.25 } + base[INSENSITIVE] = { 0.20, 0.20, 0.25 } + base[SELECTED] = { 0.20, 0.20, 0.25 } +} + +style "io_selector_notebook" = "default_base" +{ + fg[NORMAL] = { 1.0, 1.0, 1.0 } + font_name ="sans bold 8" +} + +style "tearoff_arrow" = "medium_bold_entry" +{ + fg[NORMAL] = { 0.80, 0.80, 0.80 } + fg[PRELIGHT] = { 0.80, 0.80, 0.80 } + bg[NORMAL] = { 0.80, 0.80, 0.80 } + bg[PRELIGHT] = { 0.80, 0.80, 0.80 } +} + +style "meter_metrics_strip" = "default_base" +{ + font_name = "sans 4" + fg[NORMAL] = { 1.0, 0.8, 0.2 } +} + +style "location_row_button" = "default_buttons_menus" +{ + font_name = "sans 10" +} + +style "location_rows_clock" = "default_clock_display" +{ + font_name = "sans 12" +} + +style "pan_slider" +{ + font_name = "sans 8" + + fg[NORMAL] = { 0.22, 0.73, 0.22 } + fg[ACTIVE] = { 0.22, 0.73, 0.22 } + fg[INSENSITIVE] = {0.22, 0.53, 0.22 } + fg[SELECTED] = { 0.67, 0.23, 0.22 } + fg[PRELIGHT] = { 0.67, 0.23, 0.22 } + + bg[NORMAL] = { 0.05, 0.05, 0.05 } + bg[ACTIVE] = { 0, 0, 0 } + bg[INSENSITIVE] = {0.12, 0.19, 0.25 } + bg[SELECTED] = { 0, 0, 0 } + bg[PRELIGHT] = { 0, 0, 0 } + + text[NORMAL] = { 0.70, 0.70, 0.70 } + text[ACTIVE] = { 0.70, 0.70, 0.70 } + text[INSENSITIVE] = { 0.70, 0.70, 0.70 } + text[SELECTED] = { 0.70, 0.70, 0.70 } + text[PRELIGHT] = { 0.70, 0.70, 0.70 } + + # used to draw the triangular indicators + + base[NORMAL] = { 0.80, 0.80, 0.80 } + base[ACTIVE] = { 0.80, 0.80, 0.80 } + base[INSENSITIVE] = {0.6, 0.6, 0.6 } + base[SELECTED] = { 0.80, 0.80, 0.80 } + base[PRELIGHT] = { 0.80, 0.80, 0.80 } + +} + +style "ardour_button" ="default_buttons_menus" +{ + xthickness = 1 + ythickness = 1 +} + +#--------------------------------------------------------------- + +class "GtkWidget" style:highest "default_base" +class "GtkScrollbar" style:highest "ardour_adjusters" +class "GtkLabel" style:highest "default_buttons_menus" +class "GtkButton" style:highest "ardour_button" +class "GtkArrow" style:highest "tearoff_arrow" +class "GtkProgressBar" style:highest "ardour_progressbars" + +widget "*FirstActionMessage" style:highest "first_action_message" +widget "*VerboseCanvasCursor" style:highest "verbose_canvas_cursor" +widget "*MarkerText" style:highest "marker_text" +widget "*TimeAxisViewItemName*" style:highest "time_axis_view_item_name" +#widget "*ExportProgress" style:highest "default_buttons_menus" +widget "*ExportFileLabel" style:highest "small_bold_text" +widget "*ExportFormatLabel" style:highest "medium_bold_text" +widget "*ExportHeader" style:highest "small_bold_text" +widget "*ExportFileDisplay" style:highest "medium_entry" +widget "*ExportFormatDisplay" style:highest "medium_entry" +widget "*ExportCheckbox" style:highest "small_entry" +widget "*ExportTrackSelector*" style:highest "medium_entry_noselection_bg" +widget "*EditModeSelector" style:highest "medium_bold_entry" +widget "*SnapTypeSelector" style:highest "medium_bold_entry" +widget "*SnapModeSelector" style:highest "medium_bold_entry" +widget "*ZoomFocusSelector" style:highest "medium_bold_entry" +widget "*ArdourContextMenu*" style:highest "default_buttons_menus" +widget "*EditGroupTitleButton*" style:highest "default_buttons_menus" +widget "*MixerGroupTitleButton*" style:highest "default_buttons_menus" +widget "*ErrorLogCloseButton" style:highest "default_buttons_menus" +widget "*EditorGTKButton*" style:highest "default_buttons_menus" +widget "*ToolbarButton" style:highest "default_buttons_menus" +widget "*ToolbarButton*" style:highest "default_buttons_menus" +widget "*CrossfadeEditButton" style:highest "default_buttons_menus" +widget "*CrossfadeEditButton*" style:highest "default_buttons_menus" +widget "*TrackHistoryButton*" style:highest "default_buttons_menus" +widget "*TrackSizeButton*" style:highest "default_buttons_menus" +widget "*TrackPlaylistButton*" style:highest "default_buttons_menus" +widget "*TrackAutomationButton*" style:highest "default_buttons_menus" +widget "*TrackGroupButton*" style:highest "default_buttons_menus" +widget "*TrackMixButton*" style:highest "default_buttons_menus" +widget "*TrackVisualButton*" style:highest "default_buttons_menus" +widget "*TrackRemoveButton*" style:highest "default_buttons_menus" +widget "*BaseButton" style:highest "default_buttons_menus" +widget "*TakeButtonLabel" style:highest "default_buttons_menus" +widget "*MixerWidthButton" style:highest "default_buttons_menus" +widget "*MixerHideButton" style:highest "default_buttons_menus" +widget "*MixerSendButton" style:highest "default_buttons_menus" +widget "*MixerSendButtonLabel" style:highest "default_buttons_menus" +widget "*MixerSendSwitch" style:highest "default_buttons_menus" +widget "*MixerInsertButton" style:highest "default_buttons_menus" +widget "*MixerInsertButtonLabel" style:highest "default_buttons_menus" +widget "*MixerInsertSwitch" style:highest "default_buttons_menus" +widget "*MixerMonitorInputButton*" style:highest "very_small_button" +widget "*MixerMonitorInputButton.*" style:highest "very_small_button" +widget "*MixerIOButton" style:highest "very_small_button" +widget "*MixerIOButtonLabel" style:highest "very_small_button" +widget "*AddRouteDialogSpinner" style:highest "ardour_adjusters" +widget "*AddRouteDialogRadioButton*" style:highest "options_window" +widget "*OptionsNotebook" style:highest "options_window" +widget "*OptionEditorToggleButton*" style:highest "options_window" +widget "*OptionsLabel" style:highest "options_window" +widget "*OptionEditorAuditionerLabel" style:highest "options_window" +widget "*OptionsEntry" style:highest "option_entry" +widget "*InspectorNotebook" style:highest "options_window" +widget "*NewSessionDialog" style:highest "options_window" +widget "*NewSessionDialogButton*" style:highest "options_window" +widget "*MixerSendSwitch*" style:highest "very_small_red_active_and_selected_button" +widget "*OptionEditorToggleButton" style:highest "small_red_active_and_selected_button" +widget "*NewSessionDialogButton" style:highest "small_red_active_and_selected_button" +widget "*RecordEnableButton" style:highest "track_rec_enable_button" +widget "*RecordEnableButton-active" style:highest "track_rec_enable_button_active" +widget "*RecordEnableButton-alternate" style:highest "track_rec_enable_button_alternate" +widget "*MixerRecordEnableButton" style:highest "mixer_track_rec_enable_button" +widget "*MixerRecordEnableButton-active" style:highest "mixer_track_rec_enable_button_active" +widget "*MixerRecordEnableButton-alternate" style:highest "mixer_track_rec_enable_button_alternate" +widget "*MuteButton" style:highest "mute_button" +widget "*MuteButton-alternate" style:highest "mute_button_alternate" +widget "*MuteButton-active" style:highest "mute_button_active" +widget "*MixerMuteButton" style:highest "mixer_mute_button" +widget "*MixerMuteButton-alternate" style:highest "mixer_mute_button_alternate" +widget "*MixerMuteButton-active" style:highest "mixer_mute_button_active" +widget "*SoloButton" style:highest "solo_button" +widget "*SoloButton-alternate" style:highest "solo_button_alternate" +widget "*SoloButton-active" style:highest "solo_button_active" +widget "*MixerSoloButton" style:highest "mixer_solo_button" +widget "*MixerSoloButton-alternate" style:highest "mixer_solo_button_alternate" +widget "*MixerSoloButton-active" style:highest "mixer_solo_button_active" +widget "*TrackLoopButton*" style:highest "track_loop_button" +widget "*PanAutomationLineSelector*" style:highest "multiline_combo" +widget "*EditorTimeButton*" style:highest "time_button" +widget "*MixerPhaseInvertButton*" style:highest "very_small_button" +widget "*MixerPhaseInvertButton.*" style:highest "very_small_button" +widget "*MixerAutomationRecordingButton*" style:highest "very_small_button" +widget "*MixerAutomationRecordingButton.*" style:highest "very_small_button" +widget "*MixerAutomationModeButton*" style:highest "very_small_button" +widget "*MixerAutomationModeButton.*" style:highest "very_small_button" +widget "*MixerAutomationPlaybackButton*" style:highest "very_small_button" +widget "*MixerAutomationPlaybackButton.*" style:highest "very_small_button" +widget "*MixerNameButton" style:highest "very_small_button" +widget "*MixerNameButtonLabel" style:highest "very_small_button" +widget "*MixerGroupButton" style:highest "very_small_button" +widget "*MixerGroupButtonLabel" style:highest "very_small_button" +widget "*MixerCommentButton" style:highest "very_small_button" +widget "*MixerCommentButton*" style:highest "very_small_button" +widget "*EditGroupButton" style:highest "very_small_button" +widget "*EditGroupButtonLabel" style:highest "very_small_button" +widget "*TransportButton" style:highest "transport_rec_button" +widget "*TransportButton-active" style:highest "transport_button_active" +widget "*ShuttleButton" style:highest "transport_button" +widget "*ShuttleButton*" style:highest "transport_button" +widget "*ShuttleDisplay" style:highest "transport_button" +widget "*ShuttleDisplay*" style:highest "transport_button" +widget "*ShuttleControl" style:highest "shuttle_control" +widget "*TransportRecButton" style:highest "transport_rec_button" +widget "*TransportRecButton*" style:highest "transport_rec_button" +widget "*TransportRecButton-active" style:highest "transport_rec_button_active" +widget "*TransportRecButton-active*" style:highest "transport_rec_button_active" +widget "*TransportRecButton-alternate" style:highest "transport_rec_button_alternate" +widget "*TransportRecButton-alternate*" style:highest "transport_rec_button_alternate" +widget "*TransportRecButton*" style:highest "transport_rec_button" +widget "*RecordingXrunWarningWindow" style:highest "xrun_warn" +widget "*RecordingXrunWarningWindow*" style:highest "xrun_warn" +widget "*MainMenuBar" style:highest "menu_bar_base" +widget "*ErrorMessage" style:highest "error_message" +widget "*FatalMessage" style:highest "fatal_message" +widget "*InfoMessage" style:highest "info_message" +widget "*WarningMessage" style:highest "warning_message" +widget "*BigClockNonRecording" style:highest "non_recording_big_clock_display" +widget "*BigClockRecording" style:highest "recording_big_clock_display" +widget "*TransportClockDisplay" style:highest "transport_clock_display" +widget "*SecondaryClockDisplay" style:highest "transport_clock_display" +widget "*AudioClockFramesUpperInfo" style:highest "tempo_meter_clock_display" +widget "*AudioClockFramesLowerInfo" style:highest "tempo_meter_clock_display" +widget "*AudioClockSMPTEUpperInfo" style:highest "tempo_meter_clock_display" +widget "*AudioClockSMPTELowerInfo" style:highest "tempo_meter_clock_display" +widget "*AudioClockBBTUpperInfo" style:highest "tempo_meter_clock_display" +widget "*AudioClockBBTLowerInfo" style:highest "tempo_meter_clock_display" +widget "*SelectionStartClock" style:highest "default_clock_display" +widget "*SelectionEndClock" style:highest "default_clock_display" +widget "*EditCursorClock" style:highest "default_clock_display" +widget "*PreRollClock" style:highest "default_clock_display" +widget "*PostRollClock" style:highest "default_clock_display" +widget "*NudgeClock" style:highest "default_clock_display" +widget "*ZoomRangeClock" style:highest "default_clock_display" +widget "*SMPTEOffsetClock" style:highest "default_clock_display" +widget "*TransportLabel" style:highest "small_bold_text" +widget "*TakeLabel" style:highest "small_bold_text" +widget "*LocationLabel" style:highest "small_bold_text" +widget "*WipeLabel" style:highest "small_bold_text" +widget "*TakeTagLabel" style:highest "small_bold_text" +widget "*ToolBarLabel" style:highest "small_bold_text" +widget "*EditorDisplayLabel" style:highest "small_bold_text" +widget "*NewSessionLabel" style:highest "large_text" +widget "*GlobalButtonLabel" style:highest "default_buttons_menus" +widget "*ClickButton" style:highest "medium_entry" +widget "*RegionNameDisplay" style:highest "medium_entry" +widget "*PluginDisplay" style:highest "medium_entry" +widget "*SelectionDisplay" style:highest "medium_entry" +widget "*HistorySelector" style:highest "medium_entry" +widget "*LocationSelector" style:highest "medium_entry" +widget "*TakeSelector" style:highest "medium_entry" +widget "*RegionSelector" style:highest "medium_entry" +widget "*SMPTERuler" style:highest "editor_time_ruler" +widget "*BBTRuler" style:highest "editor_time_ruler" +widget "*FramesRuler" style:highest "editor_time_ruler" +widget "*MinSecRuler" style:highest "editor_time_ruler" +widget "*BaseFrame" style:highest "base_frame" +widget "*AudioTrackStripBase" style:highest "audio_track_base" +widget "*TimeAxisViewControlsBaseUnselected" style:highest "audio_track_base" +widget "*AudioTrackControlsBaseUnselected" style:highest "audio_track_base" +widget "*AudioTrackFader" style:highest "gain_fader" +widget "*AudioBusStripBase" style:highest "audio_bus_base" +widget "*BusControlsBaseUnselected" style:highest "audio_bus_base" +widget "*AudioBusFader" style:highest "gain_fader" +widget "*TrackSeparator" style:highest "track_separator" +widget "*TrackEditIndicator0*" style:highest "edit_group_0" +widget "*TrackEditIndicator1*" style:highest "edit_group_1" +widget "*TrackEditIndicator2*" style:highest "edit_group_2" +widget "*TrackEditIndicator3*" style:highest "edit_group_3" +widget "*TrackEditIndicator4*" style:highest "edit_group_3" +widget "*TrackEditIndicator5*" style:highest "edit_group_3" +widget "*TrackEditIndicator6*" style:highest "edit_group_3" +widget "*TrackEditIndicator7*" style:highest "edit_group_3" +widget "*EditorTrackNameDisplay" style:highest "track_name_display" +widget "*EditorTrackNameDisplay*" style:highest "track_name_display" +widget "*EditorActiveTrackNameDisplay" style:highest "active_track_name_display" +widget "*EditorActiveTrackNameDisplay*" style:highest "active_track_name_display" +widget "*CrossfadeEditAuditionButton" style:highest "red_when_active" +widget "*CrossfadeEditAuditionButton*" style:highest "red_when_active" +widget "*CrossfadeEditCurveButton" style:highest "red_when_active" +widget "*CrossfadeEditCurveButton*" style:highest "red_when_active" +widget "*CrossfadeEditLabel" style:highest "medium_text" +widget "*CrossfadeEditFrame" style:highest "base_frame" +widget "*MouseModeButton" style:highest "default_buttons_menus" +widget "*MouseModeButton*" style:highest "default_buttons_menus" +widget "*EditorMainCanvas" style:highest "main_canvas_area" +widget "*AudioTrackControlsBaseInactiveUnselected" style:highest "track_controls_inactive" +widget "*BusControlsBaseInactiveUnselected" style:highest "track_controls_inactive" +widget "*AutomationTrackControlsBaseInactiveUnselected" style:highest "track_controls_inactive" +widget "*AutomationTrackName" style:highest "automation_track_name" +widget "*AudioTrackControlsBaseInactiveSelected" style:highest "track_controls_inactive" +widget "*BusControlsBaseInactiveSelected" style:highest "track_controls_inactive" +widget "*AutomationTrackControlsBaseInactiveSelected" style:highest "track_controls_inactive" +widget "*AudioTrackStripBaseInactive" style:highest "track_controls_inactive" +widget "*AudioBusStripBaseInactive" style:highest "track_controls_inactive" +widget "*AudioTrackControlsBaseSelected" style:highest "edit_controls_base_selected" +widget "*BusControlsBaseSelected" style:highest "edit_controls_base_selected" +widget "*AutomationTrackControlsBase" style:highest "automation_track_controls_base" +widget "*AutomationTrackControlsBaseSelected" style:highest "edit_controls_base_selected" +widget "*EditorMenuBar*" style:highest "black_mackie_menu_bar" +widget "*MainMenuBar*" style:highest "black_mackie_menu_bar" +widget "*ZoomClickBox" style:highest "medium_bold_entry" +widget "*PluginParameterLabel" style:highest "medium_text" +widget "*PluginNameInfo" style:highest "plugin_name_text" +widget "*PluginMakerInfo" style:highest "plugin_maker_text" +widget "*PluginParameterInfo" style:highest "medium_text" +widget "*MotionControllerValue" style:highest "medium_entry" +widget "*ParameterValueDisplay" style:highest "medium_bold_entry" +widget "*PluginUIClickBox" style:highest "medium_bold_entry" +widget "*PluginUIClickBox*" style:highest "medium_bold_entry" +widget "*PluginSlider" style:highest "plugin_slider" +widget "*RedirectSelector" style:highest "redirect_list_display" +widget "*RedirectSelector.*" style:highest "redirect_list_display" +widget "*EditGroupDisplay" style:highest "treeview_display" +widget "*TrackListDisplay" style:highest "treeview_display" +widget "*RegionListDisplay" style:highest "treeview_display" +widget "*NamedSelectionDisplay" style:highest "treeview_display" +widget "*SnapshotDisplay" style:highest "treeview_display" +widget "*MixerTrackCommentArea" style:highest "option_entry" +widget "*MixerPanZone" style:highest "pan_zone" +widget "*MixerTrackDisplayList" style:highest "treeview_display" +widget "*MixerSnapshotDisplayList" style:highest "treeview_display" +widget "*MixerAuxDisplayList" style:highest "treeview_display" +widget "*MixerGroupList" style:highest "treeview_display" +widget "*RegionEditorLabel" style:highest "medium_text" +widget "*RegionEditorSmallLabel" style:highest "small_text" +widget "*RegionEditorEntry" style:highest "medium_entry" +widget "*RegionEditorClock" style:highest "default_clock_display" +widget "*RegionEditorToggleButton" style:highest "paler_red_when_active" +widget "*RegionEditorToggleButton*" style:highest "paler_red_when_active" +widget "*MixerStripSpeedBase" style:highest "small_entry" +widget "*MixerStripSpeedBase*" style:highest "small_entry" +widget "*MixerStripSpeedBaseNotOne" style:highest "small_red_on_black_entry" +widget "*MixerStripSpeedBaseNotOne*" style:highest "small_red_on_black_entry" +widget "*MixerStripGainDisplay" style:highest "small_entry" +widget "*MixerStripGainDisplay*" style:highest "small_entry" +widget "*MixerStripGainUnitButton" style:highest "very_small_button" +widget "*MixerStripGainUnitButton*" style:highest "very_small_button" +widget "*MixerStripMeterPreButton" style:highest "very_small_button" +widget "*MixerStripMeterPreButton*" style:highest "very_small_button" +widget "*MixerStripPeakDisplay*" style:highest "red_active_small_entry" +widget "*MixerStripPeakDisplayPeak*" style:highest "peak_display_peaked_entry" +widget "*MixerStripSelectedFrame" style:highest "selected_strip_frame" +widget "*MixerStripFrame" style:highest "base_frame" +widget "*HWMonitorButton" style:highest "red_when_active" +widget "*HWMonitorButton*" style:highest "red_when_active" +widget "*BypassButton" style:highest "red_when_active" +widget "*BypassButton*" style:highest "red_when_active" +widget "*TransportSoloAlert" style:highest "flashing_alert" +widget "*TransportSoloAlert.*" style:highest "flashing_alert" +widget "*TransportAuditioningAlert" style:highest "flashing_alert" +widget "*TransportAuditioningAlert.*" style:highest "flashing_alert" +widget "*FadeCurve" style:highest "medium_bold_entry" +widget "*FadeCurve*" style:highest "medium_bold_entry" +widget "*IOSelectorButton" style:highest "default_buttons_menus" +widget "*IOSelectorButton*" style:highest "default_buttons_menus" +widget "*IOSelectorList" style:highest "medium_entry_noselection_fg" +widget "*IOSelectorPortList" style:highest "io_selector_port_list" +widget "*IOSelectorPortList.*" style:highest "io_selector_port_list" +widget "*IOSelectorPortListSelected" style:highest "selected_io_selector_port_list" +widget "*IOSelectorPortListSelected.*" style:highest "selected_io_selector_port_list" +widget "*IOSelectorNotebook" style:highest "io_selector_notebook" +widget "*IOSelectorNotebookTab" style:highest "io_selector_notebook" +widget "*IOSelectorFrame" style:highest "base_frame" +widget "*ConnectionEditorButton" style:highest "default_buttons_menus" +widget "*ConnectionEditorButton*" style:highest "default_buttons_menus" +widget "*ConnectionEditorList" style:highest "medium_entry_noselection_fg" +widget "*ConnectionEditorConnectionList" style:highest "medium_entry" +widget "*ConnectionEditorPortList" style:highest "io_selector_port_list" +widget "*ConnectionEditorPortListSelected" style:highest "selected_io_selector_port_list" +widget "*ConnectionEditorNotebook" style:highest "io_selector_notebook" +widget "*ConnectionEditorNotebookTab" style:highest "io_selector_notebook" +widget "*ConnectionEditorFrame" style:highest "base_frame" +widget "*RouteParamsListDisplay" style:highest "inspector_track_list_display" +widget "*RouteParamsPreListDisplay" style:highest "inspector_redirect_list_display" +widget "*RouteParamsPostListDisplay" style:highest "inspector_redirect_list_display" +widget "*TearOffArrow" style:highest "tearoff_arrow" +widget "*RouteParamsTitleButton" style:highest "medium_text" +widget "*RouteParamsTitleLabel" style:highest "medium_text" +widget "*PluginAutomateRecordButton" style:highest "small_red_active_and_selected_button" +widget "*PluginAutomateRecordButton*" style:highest "small_red_active_and_selected_button" +widget "*PluginAutomatePlayButton" style:highest "small_red_active_and_selected_button" +widget "*PluginAutomatePlayButton*" style:highest "small_red_active_and_selected_button" +widget "*PluginAutomateButton" style:highest "small_button" +widget "*PluginAutomateButton*" style:highest "small_button" +widget "*PluginSaveButton" style:highest "small_button" +widget "*PluginSaveButton*" style:highest "small_button" +widget "*PluginLoadButton" style:highest "small_button" +widget "*PluginLoadButton*" style:highest "small_button" +widget "*FaderMetricsStrip" style:highest "meter_metrics_strip" +widget "*MeterMetricsStrip" style:highest "meter_metrics_strip" +widget "*MetricDialogFrame" style:highest "base_frame" +widget "*MetricEntry" style:highest "medium_bold_entry" +widget "*MetricButton" style:highest "default_buttons_menus" +widget "*MetricButton.*" style:highest "default_buttons_menus" +widget "*MetricLabel" style:highest "medium_text" +widget "*TimeStretchButton" style:highest "default_buttons_menus" +widget "*TimeStretchButton.*" style:highest "default_buttons_menus" +widget "*TimeStretchProgress" style:highest "default_buttons_menus" +widget "*ChoiceWindow" style:highest "default_buttons_menus" +widget "*ChoicePrompt" style:highest "default_buttons_menus" +widget "*ChoiceButton" style:highest "default_buttons_menus" +widget "*ChoiceButton*" style:highest "default_buttons_menus" +widget "*SelectionModeButton" style:highest "default_buttons_menus" +widget "*SelectionModeButton*" style:highest "default_buttons_menus" +widget "*TrackLabel" style:highest "medium_text" +widget "*TrackPlugName" style:highest "medium_text" +widget "*TrackParameterName" style:highest "small_text" +widget "*AddRouteDialog*" style:highest "medium_text" +widget "*AddRouteDialog.GtkLabel" style:highest "medium_text" +widget "*AddRouteDialogChannelChoice" style:highest "medium_bold_entry" +widget "*AddRouteDialogSpinner" style:highest "medium_bold_entry" +widget "*AddRouteDialogSpinner*" style:highest "medium_bold_entry" +widget "*AddRouteDialogRadioButton" style:highest "red_when_active" +widget "*AddRouteDialogButton" style:highest "default_buttons_menus" +widget "*AddRouteDialogNameTemplateEntry" style:highest "medium_bold_entry" +widget "*NewSessionIOLabel" style:highest "larger_bold_text" +widget "*NewSessionSR1Label" style:highest "red_medium_text" +widget "*NewSessionSR2Label" style:highest "medium_text" +widget "*NewSessionChannelChoice" style:highest "medium_bold_entry" +widget "*NewSessionMainButton" style:highest "larger_bold_text" +widget "*NewSessionMainButton*" style:highest "larger_bold_text" +widget "*NewSessionMainLabel" style:highest "larger_bold_text" +widget "*LocationEditRowClock" style:highest "location_rows_clock" +widget "*LocationEditNameLabel" style:highest "medium_text" +widget "*LocationEditSetButton" style:highest "location_row_button" +widget "*LocationEditSetButton*" style:highest "location_row_button" +widget "*LocationEditGoButton" style:highest "location_row_button" +widget "*LocationEditGoButton*" style:highest "location_row_button" +widget "*LocationEditCdButton" style:highest "small_red_active_and_selected_button" +widget "*LocationEditCdButton*" style:highest "small_red_active_and_selected_button" +widget "*LocationEditHideButton" style:highest "small_red_active_and_selected_button" +widget "*LocationEditHideButton*" style:highest "small_red_active_and_selected_button" +widget "*LocationEditNumberLabel" style:highest "small_text" +widget "*LocationLocEditorFrame" style:highest "base_frame" +widget "*LocationRangeEditorFrame" style:highest "base_frame" +widget "*LocationEditNameEntry" style:highest "option_entry" +widget "*LocationAddLocationButton" style:highest "default_buttons_menus" +widget "*LocationAddLocationButton*" style:highest "default_buttons_menus" +widget "*LocationAddRangeButton" style:highest "default_buttons_menus" +widget "*LocationAddRangeButton*" style:highest "default_buttons_menus" +widget "*LocationEditRemoveButton" style:highest "location_row_button" +widget "*LocationEditRemoveButton*" style:highest "location_row_button" +widget "*PanSlider" style:highest "pan_slider" +widget "*PanningLinkButton" style:highest "mixer_red_active_button" +widget "*PanningLinkButton.*" style:highest "mixer_red_active_button" +widget "*PanningLinkDirectionButton" style:highest "very_small_button" +widget "*PanningLinkDirectionButton.*" style:highest "very_small_button" +widget "*ChannelCountSelector" style:highest "medium_bold_entry" +widget "*ChannelCountSelector.GtkArrow" style:highest "default_buttons_menus" +widget "*RegionListWholeFile" style:highest "treeview_parent_node" +widget "*EditorHScrollbar" style:highest "editor_hscrollbar" + diff --git a/gui/src/window-manager.cpp b/gui/src/window-manager.cpp new file mode 100644 index 000000000..6314aba94 --- /dev/null +++ b/gui/src/window-manager.cpp @@ -0,0 +1,48 @@ +/* + window-manager.cpp - Defines the global UI Manager class + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "window-manager.hpp" + +namespace lumiera { +namespace gui { + + WindowManager::WindowManager() + { + + } + + bool WindowManager::set_theme(Glib::ustring path) + { + if(access(path.c_str(), R_OK)) + { + g_error("WindowManger: Unable to load rc file \"%s\"", path.c_str()); + return false; + } + + Gtk::RC rc(path); + gtk_rc_reset_styles (gtk_settings_get_default()); + + return true; + } + +} // namespace gui +} // namespace lumiera diff --git a/gui/src/window-manager.hpp b/gui/src/window-manager.hpp new file mode 100644 index 000000000..e2a9af8fa --- /dev/null +++ b/gui/src/window-manager.hpp @@ -0,0 +1,51 @@ +/* + window-manager.hpp - Defines the global UI Manager class + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file window-manager.hpp + ** This file contains the of global UI Manager class + ** user actions. + ** @see window-manager.cpp + ** @see gtk-lumiera.hpp + */ + +#include + +#ifndef WINDOW_MANAGER_HPP +#define WINDOW_MANAGER_HPP + +namespace lumiera { +namespace gui { + + class WindowManager + { + public: + WindowManager(); + + bool set_theme(Glib::ustring path); + + protected: + + }; + +} // namespace gui +} // namespace lumiera + +#endif // WINDOW_MANAGER_HPP From 7beaa3366d8e1126631f8aca3968f1f626a18bd8 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 21 Apr 2008 22:28:34 +0100 Subject: [PATCH 027/245] Added menu items which will eventually toggle panels on and off --- gui/src/workspace/actions.cpp | 25 +++++++++++++++-- gui/src/workspace/actions.hpp | 39 ++++++++++++++------------ gui/src/workspace/workspace-window.cpp | 4 +++ 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp index 8adfcc141..005fd06a4 100644 --- a/gui/src/workspace/actions.cpp +++ b/gui/src/workspace/actions.cpp @@ -39,7 +39,7 @@ namespace workspace { { actionGroup = ActionGroup::create(); - // File menu: + // File menu actionGroup->add(Action::create("FileMenu", _("_File"))); actionGroup->add(Action::create("FileNewProject", Stock::NEW, _("_New Project...")), sigc::mem_fun(*this, &Actions::on_menu_file_new_project)); @@ -51,14 +51,21 @@ namespace workspace { actionGroup->add(Action::create("FileQuit", Stock::QUIT), sigc::mem_fun(*this, &Actions::on_menu_file_quit)); - // Edit menu: + // Edit menu actionGroup->add(Action::create("EditMenu", _("_Edit"))); actionGroup->add(Action::create("EditCopy", Stock::COPY), sigc::mem_fun(*this, &Actions::on_menu_others)); actionGroup->add(Action::create("EditPaste", Stock::PASTE), sigc::mem_fun(*this, &Actions::on_menu_others)); - // Help menu: + // View Menu + actionGroup->add(Action::create("ViewMenu", _("_View"))); + actionGroup->add(Action::create("ViewViewer", _("_Viewer")), + sigc::mem_fun(*this, &Actions::on_menu_view_viewer)); + actionGroup->add(Action::create("ViewTimeline", _("_Timeline")), + sigc::mem_fun(*this, &Actions::on_menu_view_timeline)); + + // Help Menu actionGroup->add(Action::create("HelpMenu", _("_Help")) ); actionGroup->add(Action::create("HelpAbout", Stock::ABOUT), sigc::mem_fun(*this, &Actions::on_menu_help_about) ); @@ -91,6 +98,18 @@ namespace workspace { workspaceWindow.hide(); // Closes the main window to stop the Gtk::Main::run(). } + void + Actions::on_menu_view_viewer() + { + //workspaceWindow.viewer_panel.show(); + } + + void + Actions::on_menu_view_timeline() + { + //workspaceWindow.timeline_panel.show(); + } + void Actions::on_menu_help_about() { diff --git a/gui/src/workspace/actions.hpp b/gui/src/workspace/actions.hpp index 27b744549..25d0f36db 100644 --- a/gui/src/workspace/actions.hpp +++ b/gui/src/workspace/actions.hpp @@ -44,29 +44,32 @@ class WorkspaceWindow; class Actions { private: - Actions(WorkspaceWindow &workspace_window); + Actions(WorkspaceWindow &workspace_window); - /** - * A reference to the MainWindow which owns - * this helper */ - WorkspaceWindow &workspaceWindow; + /** + * A reference to the MainWindow which owns + * this helper */ + WorkspaceWindow &workspaceWindow; - /* ===== Event Handlers ===== */ - void on_menu_file_new_project(); - void on_menu_file_open_project(); - void on_menu_file_render(); - void on_menu_file_quit(); + /* ===== Event Handlers ===== */ + void on_menu_file_new_project(); + void on_menu_file_open_project(); + void on_menu_file_render(); + void on_menu_file_quit(); - void on_menu_help_about(); - - // Temporary Junk - void on_menu_others(); + void on_menu_view_viewer(); + void on_menu_view_timeline(); - /* ===== Actions ===== */ - Glib::RefPtr actionGroup; - Glib::RefPtr m_refChoiceOne, m_refChoiceTwo; + void on_menu_help_about(); + + // Temporary Junk + void on_menu_others(); - friend class WorkspaceWindow; + /* ===== Actions ===== */ + Glib::RefPtr actionGroup; + Glib::RefPtr m_refChoiceOne, m_refChoiceTwo; + + friend class WorkspaceWindow; }; } // namespace workspace diff --git a/gui/src/workspace/workspace-window.cpp b/gui/src/workspace/workspace-window.cpp index d78eb5b5c..1256d0233 100644 --- a/gui/src/workspace/workspace-window.cpp +++ b/gui/src/workspace/workspace-window.cpp @@ -88,6 +88,10 @@ namespace workspace { " " " " " " + " " + " " + " " + " " " " " " " " From 19a97878ce2415f5c367a28b91e92f029362dcb3 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 21 Apr 2008 22:59:35 +0100 Subject: [PATCH 028/245] Added the base of a preferences dialog --- gui/src/Makefile.am | 2 + gui/src/dialogs/preferences-dialog.cpp | 61 ++++++++++++++++++++++++++ gui/src/dialogs/preferences-dialog.hpp | 61 ++++++++++++++++++++++++++ gui/src/workspace/actions.cpp | 10 +++++ gui/src/workspace/actions.hpp | 2 + gui/src/workspace/workspace-window.cpp | 2 + 6 files changed, 138 insertions(+) create mode 100644 gui/src/dialogs/preferences-dialog.cpp create mode 100644 gui/src/dialogs/preferences-dialog.hpp diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index ac159ea65..2755fb0ae 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -23,6 +23,8 @@ gtk_lumiera_SOURCES = \ workspace/workspace-window.hpp \ dialogs/render.cpp \ dialogs/render.hpp \ + dialogs/preferences-dialog.cpp \ + dialogs/preferences-dialog.hpp \ panels/panel.cpp \ panels/panel.hpp \ panels/timeline-panel.cpp \ diff --git a/gui/src/dialogs/preferences-dialog.cpp b/gui/src/dialogs/preferences-dialog.cpp new file mode 100644 index 000000000..10f187c1c --- /dev/null +++ b/gui/src/dialogs/preferences-dialog.cpp @@ -0,0 +1,61 @@ +/* + preferences-dialog.cpp - Implementation of the application preferences dialog + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "../gtk-lumiera.hpp" + +#include "preferences-dialog.hpp" + +using namespace Gtk; + +namespace lumiera { +namespace gui { +namespace dialogs { + + PreferencesDialog::PreferencesDialog(Window &parent) : + Dialog(_("Preferences"), parent, true) + { + VBox *v_box = get_vbox(); + g_assert(v_box != NULL); + + interfaceBox.pack_start(interfaceThemeCombo, PACK_SHRINK); + interfaceBox.set_spacing(4); + interfaceBox.set_border_width(5); + + notebook.append_page(interfaceBox, _("Interface")); + + v_box->pack_start(notebook); + + // Configure the dialog + v_box->set_spacing(4); + set_border_width(5); + set_resizable(false); + + // Configure the Cancel and OK buttons + add_button(Stock::CANCEL, RESPONSE_CANCEL); + add_button(Stock::OK, RESPONSE_OK); + + show_all_children(); + } + +} // namespace dialogs +} // namespace gui +} // namespace lumiera diff --git a/gui/src/dialogs/preferences-dialog.hpp b/gui/src/dialogs/preferences-dialog.hpp new file mode 100644 index 000000000..31ad169c7 --- /dev/null +++ b/gui/src/dialogs/preferences-dialog.hpp @@ -0,0 +1,61 @@ +/* + preferences-dialog.hpp - Definition of the application preferences dialog + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file render.hpp + ** This file contains the definition of the application preferences dialog + ** + */ + +#ifndef PREFERENCES_DIALOG_HPP +#define PREFERENCES_DIALOG_HPP + +#include + +using namespace Gtk; + +namespace lumiera { +namespace gui { +namespace dialogs { + + /** + * The defintion of render output dialog class + */ + class PreferencesDialog : public Dialog + { + public: + PreferencesDialog(Window &parent); + + protected: + + + protected: + Notebook notebook; + + VBox interfaceBox; + ComboBox interfaceThemeCombo; + + }; + +} // namespace dialogs +} // namespace gui +} // namespace lumiera + +#endif // PREFERENCES_DIALOG_HPP diff --git a/gui/src/workspace/actions.cpp b/gui/src/workspace/actions.cpp index 005fd06a4..6d69a8e6a 100644 --- a/gui/src/workspace/actions.cpp +++ b/gui/src/workspace/actions.cpp @@ -25,6 +25,7 @@ #include "workspace-window.hpp" #include "../dialogs/render.hpp" +#include "../dialogs/preferences-dialog.hpp" using namespace Gtk; using namespace Glib; @@ -57,6 +58,8 @@ namespace workspace { sigc::mem_fun(*this, &Actions::on_menu_others)); actionGroup->add(Action::create("EditPaste", Stock::PASTE), sigc::mem_fun(*this, &Actions::on_menu_others)); + actionGroup->add(Action::create("EditPreferences", Stock::PREFERENCES), + sigc::mem_fun(*this, &Actions::on_menu_edit_preferences)); // View Menu actionGroup->add(Action::create("ViewMenu", _("_View"))); @@ -98,6 +101,13 @@ namespace workspace { workspaceWindow.hide(); // Closes the main window to stop the Gtk::Main::run(). } + void + Actions::on_menu_edit_preferences() + { + dialogs::PreferencesDialog dialog(workspaceWindow); + dialog.run(); + } + void Actions::on_menu_view_viewer() { diff --git a/gui/src/workspace/actions.hpp b/gui/src/workspace/actions.hpp index 25d0f36db..5ec50c33a 100644 --- a/gui/src/workspace/actions.hpp +++ b/gui/src/workspace/actions.hpp @@ -57,6 +57,8 @@ class WorkspaceWindow; void on_menu_file_render(); void on_menu_file_quit(); + void on_menu_edit_preferences(); + void on_menu_view_viewer(); void on_menu_view_timeline(); diff --git a/gui/src/workspace/workspace-window.cpp b/gui/src/workspace/workspace-window.cpp index 1256d0233..66d74e905 100644 --- a/gui/src/workspace/workspace-window.cpp +++ b/gui/src/workspace/workspace-window.cpp @@ -87,6 +87,8 @@ namespace workspace { " " " " " " + " " + " " " " " " " " From aea5ed323a577035cb0947dde8f625f96ac1f575 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 23 Apr 2008 04:16:45 +0200 Subject: [PATCH 029/245] refactor to use the customized lumiera::P instead of shared_ptr --- src/common/configrules.hpp | 8 ++-- src/common/query/mockconfigrules.hpp | 2 +- src/proc/asset/buildinstruct.hpp | 5 ++- src/proc/asset/clip.hpp | 2 +- src/proc/asset/db.hpp | 2 +- src/proc/asset/media.cpp | 2 +- src/proc/asset/media.hpp | 11 +++--- src/proc/asset/meta.hpp | 2 +- src/proc/asset/pipe.hpp | 3 +- src/proc/asset/proc.hpp | 4 +- src/proc/asset/procpatt.cpp | 2 +- src/proc/asset/procpatt.hpp | 8 ++-- src/proc/asset/struct.cpp | 12 +++--- src/proc/asset/struct.hpp | 6 +-- src/proc/asset/track.hpp | 2 +- src/proc/assetmanager.cpp | 32 ++++++++-------- src/proc/assetmanager.hpp | 6 +-- src/proc/lumiera.hpp | 1 + src/proc/mobject/mobject.hpp | 15 ++++++-- src/proc/mobject/session/abstractmo.cpp | 10 ++++- src/proc/mobject/session/abstractmo.hpp | 2 + src/proc/mobject/session/clip.hpp | 4 +- src/proc/mobject/session/defsmanager.cpp | 20 +++++----- src/proc/mobject/session/defsmanager.hpp | 14 +++---- src/proc/mobject/session/defsregistry.hpp | 37 ++++++++++--------- src/proc/mobject/session/mobjectfactory.hpp | 2 +- src/proc/mobject/session/track.hpp | 6 ++- .../mobject/session/defsregistryimpltest.cpp | 11 ++++-- 28 files changed, 128 insertions(+), 103 deletions(-) diff --git a/src/common/configrules.hpp b/src/common/configrules.hpp index 81da041ae..0968c88d4 100644 --- a/src/common/configrules.hpp +++ b/src/common/configrules.hpp @@ -46,6 +46,7 @@ #ifndef LUMIERA_CONFIGRULES_H #define LUMIERA_CONFIGRULES_H +#include "common/p.hpp" #include "common/query.hpp" #include "common/typelistutil.hpp" #include "common/singletonsubclass.hpp" @@ -57,14 +58,13 @@ #include "proc/asset/track.hpp" #include -#include namespace lumiera { using std::string; - using std::tr1::shared_ptr; + using lumiera::P; @@ -148,13 +148,13 @@ namespace lumiera * @query any goals to be fulfilled by the solution. * @return false if resolution failed. In this case, solution ptr is empty. */ - virtual bool resolve (shared_ptr& solution, const Query& q) = 0; + virtual bool resolve (P& solution, const Query& q) = 0; }; // TODO: the Idea is to provide specialisations for the concrete types // we want to participate in the ConfigRules system.... // Thus we get the possibility to create a specific return type, - // e.g. return a shared_ptr but a Placement, using the appropriate factory. + // e.g. return a P but a Placement, using the appropriate factory. // Of course then the definitions need to be split up in separate headers. diff --git a/src/common/query/mockconfigrules.hpp b/src/common/query/mockconfigrules.hpp index f5bea3264..f56519ed6 100644 --- a/src/common/query/mockconfigrules.hpp +++ b/src/common/query/mockconfigrules.hpp @@ -74,7 +74,7 @@ namespace lumiera /** a traits-class to define the smart-ptr to wrap the result */ template - struct WrapReturn { typedef shared_ptr Wrapper; }; + struct WrapReturn { typedef P Wrapper; }; template<> struct WrapReturn { typedef PProcPatt Wrapper; }; diff --git a/src/proc/asset/buildinstruct.hpp b/src/proc/asset/buildinstruct.hpp index 577a108c1..8b1162103 100644 --- a/src/proc/asset/buildinstruct.hpp +++ b/src/proc/asset/buildinstruct.hpp @@ -41,12 +41,13 @@ using std::string; namespace asset { + using lumiera::P; class Proc; class ProcPatt; - typedef shared_ptr PProc; - typedef shared_ptr PProcPatt; + typedef P PProc; + typedef P PProcPatt; static Symbol CURRENT = "current"; diff --git a/src/proc/asset/clip.hpp b/src/proc/asset/clip.hpp index f5e1ea629..53a74faa5 100644 --- a/src/proc/asset/clip.hpp +++ b/src/proc/asset/clip.hpp @@ -53,7 +53,7 @@ namespace asset }; - typedef shared_ptr PClipAsset; + typedef P PClipAsset; const string CLIP_SUBFOLDER = "clips"; // TODO: handling of hard-wired constants.... diff --git a/src/proc/asset/db.hpp b/src/proc/asset/db.hpp index cb32868d7..f35785e5e 100644 --- a/src/proc/asset/db.hpp +++ b/src/proc/asset/db.hpp @@ -100,7 +100,7 @@ namespace asset bool del (ID hash) { return table.erase (hash); } template - shared_ptr + P get (ID hash) const { return dynamic_pointer_cast (find (hash)); diff --git a/src/proc/asset/media.cpp b/src/proc/asset/media.cpp index a91e8284b..68fcb0b56 100644 --- a/src/proc/asset/media.cpp +++ b/src/proc/asset/media.cpp @@ -219,7 +219,7 @@ namespace asset * @throw Invalid if the given media asset is not top-level, * but rather part or a multichannel (compound) media */ - shared_ptr + P MediaFactory::operator() (asset::Media& mediaref) throw(lumiera::error::Invalid) { if (mediaref.checkCompound()) diff --git a/src/proc/asset/media.hpp b/src/proc/asset/media.hpp index 4e122cd53..b14399ce5 100644 --- a/src/proc/asset/media.hpp +++ b/src/proc/asset/media.hpp @@ -52,6 +52,7 @@ namespace asset class MediaFactory; class ProcPatt; + using lumiera::P; using lumiera::Time; @@ -74,9 +75,9 @@ namespace asset const Time len_; public: - typedef shared_ptr PMedia; - typedef shared_ptr PClip; - typedef shared_ptr PProcPatt; + typedef P PMedia; + typedef P PClip; + typedef P PProcPatt; typedef mobject::session::PClipMO PClipMO; @@ -142,7 +143,7 @@ namespace asset class MediaFactory : public lumiera::Factory { public: - typedef shared_ptr PType; + typedef P PType; PType operator() (Asset::Ident& key, const string& file=""); PType operator() (const string& file, const Category& cat); @@ -152,7 +153,7 @@ namespace asset PType operator() (const char* file, const Category& cat); PType operator() (const char* file, asset::Kind); - shared_ptr + P operator() (asset::Media& mediaref) throw(lumiera::error::Invalid); }; diff --git a/src/proc/asset/meta.hpp b/src/proc/asset/meta.hpp index 02be992db..c15f14fbf 100644 --- a/src/proc/asset/meta.hpp +++ b/src/proc/asset/meta.hpp @@ -95,7 +95,7 @@ namespace asset class MetaFactory : public lumiera::Factory { public: - typedef shared_ptr PType; + typedef P PType; PType operator() (Asset::Ident& key); ////////////TODO define actual operation diff --git a/src/proc/asset/pipe.hpp b/src/proc/asset/pipe.hpp index 110dd1975..c2a9a8ff0 100644 --- a/src/proc/asset/pipe.hpp +++ b/src/proc/asset/pipe.hpp @@ -31,9 +31,10 @@ namespace asset { + using lumiera::P; class Pipe; - typedef shared_ptr PPipe; + typedef P PPipe; template<> diff --git a/src/proc/asset/proc.hpp b/src/proc/asset/proc.hpp index 05eca4ddf..724c8a786 100644 --- a/src/proc/asset/proc.hpp +++ b/src/proc/asset/proc.hpp @@ -48,7 +48,7 @@ namespace asset class Proc; class ProcFactory; - typedef shared_ptr PProc; + typedef P PProc; @@ -97,7 +97,7 @@ namespace asset class ProcFactory : public lumiera::Factory { public: - typedef shared_ptr PType; + typedef P PType; PType operator() (Asset::Ident& key); ////////////TODO define actual operation diff --git a/src/proc/asset/procpatt.cpp b/src/proc/asset/procpatt.cpp index 1adf8736c..d5173b9ea 100644 --- a/src/proc/asset/procpatt.cpp +++ b/src/proc/asset/procpatt.cpp @@ -60,7 +60,7 @@ namespace asset * some ProcPatt as a template for creating more * spezialized patterns. */ - shared_ptr + P ProcPatt::newCopy (string newID) const { TODO ("implement the Pattern-ID within the propDescriptor!"); diff --git a/src/proc/asset/procpatt.hpp b/src/proc/asset/procpatt.hpp index 6c8cf37e0..65f832b41 100644 --- a/src/proc/asset/procpatt.hpp +++ b/src/proc/asset/procpatt.hpp @@ -35,13 +35,14 @@ using std::vector; namespace asset { + using lumiera::P; using lumiera::Symbol; class Proc; class ProcPatt; class BuildInstruct; - typedef shared_ptr PProc; - typedef shared_ptr PProcPatt; + typedef P PProc; + typedef P PProcPatt; typedef vector InstructionSequence; @@ -61,14 +62,13 @@ namespace asset friend class StructFactoryImpl; public: - shared_ptr newCopy (string newID) const; + P newCopy (string newID) const; ProcPatt& attach (Symbol where, PProc& node); ProcPatt& operator+= (PProcPatt& toReuse); }; - typedef shared_ptr PProcPatt; diff --git a/src/proc/asset/struct.cpp b/src/proc/asset/struct.cpp index 6e85c50c2..5813ce339 100644 --- a/src/proc/asset/struct.cpp +++ b/src/proc/asset/struct.cpp @@ -89,10 +89,10 @@ namespace asset * created as a side effect of calling the concrete Struct subclass ctor. */ template - shared_ptr + P StructFactory::operator() (const Query& capabilities) { - shared_ptr res; + P res; QueryHandler& typeHandler = ConfigRules::instance(); typeHandler.resolve (res, capabilities); @@ -117,7 +117,7 @@ namespace asset * @see ProcPatt * @see DefaultsManager */ - shared_ptr + P StructFactory::operator() (string pipeID, string streamID) { normalizeID (pipeID); @@ -147,9 +147,9 @@ namespace asset namespace asset { - template shared_ptr StructFactory::operator() (const Query& query); - template shared_ptr StructFactory::operator() (const Query& query); - template PProcPatt StructFactory::operator() (const Query& query); + template P StructFactory::operator() (const Query& query); + template P StructFactory::operator() (const Query& query); + template PProcPatt StructFactory::operator() (const Query& query); } // namespace asset diff --git a/src/proc/asset/struct.hpp b/src/proc/asset/struct.hpp index 7c4c4367b..5941bd13a 100644 --- a/src/proc/asset/struct.hpp +++ b/src/proc/asset/struct.hpp @@ -120,12 +120,12 @@ namespace asset public: - typedef shared_ptr PType; + typedef P PType; template - shared_ptr operator() (const Query& query); ////////////TODO actually do something sensible here + P operator() (const Query& query); ////////////TODO actually do something sensible here - shared_ptr operator() (string pipeID, string streamID); + P operator() (string pipeID, string streamID); }; diff --git a/src/proc/asset/track.hpp b/src/proc/asset/track.hpp index a36a6242c..01abe5e8e 100644 --- a/src/proc/asset/track.hpp +++ b/src/proc/asset/track.hpp @@ -48,7 +48,7 @@ namespace asset }; - typedef shared_ptr PTrack; + typedef P PTrack; diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp index fcdf45dc0..9acb29daa 100644 --- a/src/proc/assetmanager.cpp +++ b/src/proc/assetmanager.cpp @@ -130,11 +130,11 @@ namespace asset * of the stored object differs and can't be casted. */ template - shared_ptr + P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid) { - if (shared_ptr obj = registry.get (id)) + if (P obj = registry.get (id)) return obj; else if (known (id)) // provide Ident tuple of existing Asset @@ -143,14 +143,14 @@ namespace asset throw UnknownID (id); } - /** convienience shortcut for fetching the registered shared_ptr + /** convienience shortcut for fetching the registered smart-ptr * which is in charge of the given asset instance. By querying * directly asset.id (of type ID), the call to registry.get() * can bypass the dynamic cast, because the type of the asset * is explicitely given by type KIND. */ template - shared_ptr + P AssetManager::wrap (const KIND& asset) { ENSURE (instance().known(asset.id), @@ -169,7 +169,7 @@ namespace asset { return ( registry.get (ID(id)) ); } // query most general Asset ID-kind and use implicit - // conversion from shared_ptr to bool (test if empty) + // conversion from smart-ptr to bool (test if empty) /** @@ -245,18 +245,18 @@ namespace asset template ID AssetManager::reg (Asset* obj, const Asset::Ident& idi); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::wrap (const Asset& asset); - template shared_ptr AssetManager::wrap (const Media& asset); - template shared_ptr AssetManager::wrap (const Clip& asset); - template shared_ptr AssetManager::wrap (const Track& asset); - template shared_ptr AssetManager::wrap (const Pipe& asset); - template shared_ptr AssetManager::wrap (const ProcPatt& asset); + template P AssetManager::wrap (const Asset& asset); + template P AssetManager::wrap (const Media& asset); + template P AssetManager::wrap (const Clip& asset); + template P AssetManager::wrap (const Track& asset); + template P AssetManager::wrap (const Pipe& asset); + template P AssetManager::wrap (const ProcPatt& asset); } // namespace asset diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp index 22138065d..3f62d2ecd 100644 --- a/src/proc/assetmanager.hpp +++ b/src/proc/assetmanager.hpp @@ -73,13 +73,13 @@ namespace asset /** provide the unique ID for given Asset::Ident tuple */ static ID getID (const Asset::Ident&); - /** retrieve the registerd shared_ptr for any asset */ + /** retrieve the registerd smart-ptr for any asset */ template - static shared_ptr wrap (const KIND& asset); + static P wrap (const KIND& asset); /** find and return corresponging object */ template - shared_ptr getAsset (const ID& id) throw(lumiera::error::Invalid); + P getAsset (const ID& id) throw(lumiera::error::Invalid); /** @return true if the given id is registered in the internal asset DB */ diff --git a/src/proc/lumiera.hpp b/src/proc/lumiera.hpp index b56ab69b6..c00a70254 100644 --- a/src/proc/lumiera.hpp +++ b/src/proc/lumiera.hpp @@ -30,6 +30,7 @@ /* common types frequently used... */ +#include "common/p.hpp" #include "common/util.hpp" #include "common/time.hpp" #include "common/error.hpp" ///< pulls in NoBug via nobugcfg.hpp diff --git a/src/proc/mobject/mobject.hpp b/src/proc/mobject/mobject.hpp index a8c02c761..28ab788ed 100644 --- a/src/proc/mobject/mobject.hpp +++ b/src/proc/mobject/mobject.hpp @@ -26,17 +26,18 @@ #include "pre.hpp" -#include -#include #include "proc/lumiera.hpp" #include "proc/mobject/builder/buildertool.hpp" #include "proc/mobject/placement.hpp" #include "proc/asset.hpp" // TODO finally not needed? +#include +#include +#include + using std::list; -using std::tr1::shared_ptr; #include "proc/assetmanager.hpp" using proc_interface::IDA; // TODO finally not needed? @@ -45,6 +46,7 @@ using proc_interface::AssetManager; namespace mobject { + using lumiera::P; namespace session { @@ -58,7 +60,10 @@ namespace mobject * manipulated and finally rendered within Lumiera's EDL * are MObjects. */ - class MObject : public Buildable + class MObject + : public Buildable, + boost::noncopyable, + boost::equality_comparable< MObject > { protected: typedef lumiera::Time Time; @@ -79,6 +84,8 @@ namespace mobject virtual bool isValid() const =0; virtual Time& getLength() =0; ///< @todo how to deal with the time/length field?? + + virtual bool operator== (const MObject& oo) const =0; }; diff --git a/src/proc/mobject/session/abstractmo.cpp b/src/proc/mobject/session/abstractmo.cpp index e484eee6e..e3ebffd4f 100644 --- a/src/proc/mobject/session/abstractmo.cpp +++ b/src/proc/mobject/session/abstractmo.cpp @@ -28,8 +28,14 @@ namespace mobject namespace session { - /** */ - + /** default/fallback implementation of equality + * using literal object identity (same address) + */ + bool + AbstractMO::operator== (const MObject& oo) const + { + return (this == &oo); + } } // namespace mobject::session diff --git a/src/proc/mobject/session/abstractmo.hpp b/src/proc/mobject/session/abstractmo.hpp index 45942986d..5de61737f 100644 --- a/src/proc/mobject/session/abstractmo.hpp +++ b/src/proc/mobject/session/abstractmo.hpp @@ -49,6 +49,8 @@ namespace mobject DEFINE_PROCESSABLE_BY (builder::BuilderTool); + virtual bool operator== (const MObject& oo) const; + }; diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp index 75cac3ef7..cf15cbd27 100644 --- a/src/proc/mobject/session/clip.hpp +++ b/src/proc/mobject/session/clip.hpp @@ -38,8 +38,8 @@ namespace mobject namespace session { using asset::Media; - typedef shared_ptr PMedia; - typedef shared_ptr PClipAsset; + typedef P PMedia; + typedef P PClipAsset; /** diff --git a/src/proc/mobject/session/defsmanager.cpp b/src/proc/mobject/session/defsmanager.cpp index c84e5116d..b60e38064 100644 --- a/src/proc/mobject/session/defsmanager.cpp +++ b/src/proc/mobject/session/defsmanager.cpp @@ -39,7 +39,7 @@ namespace mobject { namespace session { - using std::tr1::shared_ptr; + using lumiera::P; @@ -52,10 +52,10 @@ namespace mobject template - shared_ptr + P DefsManager::search (const Query& capabilities) { - shared_ptr res; + P res; QueryHandler& typeHandler = ConfigRules::instance(); for (DefsRegistry::Iter i = defsRegistry->candidates(capabilities); res = *i ; ++i ) @@ -69,10 +69,10 @@ namespace mobject template - shared_ptr + P DefsManager::create (const Query& capabilities) { - shared_ptr res; + P res; QueryHandler& typeHandler = ConfigRules::instance(); typeHandler.resolve (res, capabilities); if (res) @@ -83,9 +83,9 @@ namespace mobject template bool - DefsManager::define (const shared_ptr& defaultObj, const Query& capabilities) + DefsManager::define (const P& defaultObj, const Query& capabilities) { - shared_ptr candidate (defaultObj); + P candidate (defaultObj); QueryHandler& typeHandler = ConfigRules::instance(); typeHandler.resolve (candidate, capabilities); if (!candidate) @@ -97,17 +97,17 @@ namespace mobject template bool - DefsManager::forget (const shared_ptr& defaultObj) + DefsManager::forget (const P& defaultObj) { return defsRegistry->forget (defaultObj); } template - shared_ptr + P DefsManager::operator() (const Query& capabilities) { - shared_ptr res (search (capabilities)); + P res (search (capabilities)); if (res) return res; else diff --git a/src/proc/mobject/session/defsmanager.hpp b/src/proc/mobject/session/defsmanager.hpp index 753b452d2..eb2ca1502 100644 --- a/src/proc/mobject/session/defsmanager.hpp +++ b/src/proc/mobject/session/defsmanager.hpp @@ -25,11 +25,11 @@ #define MOBJECT_SESSION_DEFSMANAGER_H +#include "common/p.hpp" #include "common/query.hpp" #include #include -#include @@ -37,7 +37,7 @@ namespace mobject { namespace session { - using std::tr1::shared_ptr; + using lumiera::P; using boost::scoped_ptr; class DefsRegistry; @@ -69,14 +69,14 @@ namespace mobject * is considered \e misconfiguration. */ template - shared_ptr operator() (const lumiera::Query&); + P operator() (const lumiera::Query&); /** search through the registered defaults, never create anything. * @return object fulfilling the query, \c empty ptr if not found. */ template - shared_ptr search (const lumiera::Query&); + P search (const lumiera::Query&); /** retrieve an object fulfilling the query and register it as default. * The resolution is delegated to the ConfigQuery system (which may cause @@ -84,7 +84,7 @@ namespace mobject * @return object fulfilling the query, \c empty ptr if no solution. */ template - shared_ptr create (const lumiera::Query&); + P create (const lumiera::Query&); /** register the given object as default, after ensuring it fulfills the * query. The latter may cause some properties of the object to be set, @@ -93,13 +93,13 @@ namespace mobject * @note only a weak ref to the object is stored */ template - bool define (const shared_ptr&, const lumiera::Query&); + bool define (const P&, const lumiera::Query&); /** remove the defaults registration of the given object, if there was such * @return false if nothing has been changed because the object wasn't registered */ template - bool forget (const shared_ptr&); + bool forget (const P&); // Q: can we have something along the line of...? diff --git a/src/proc/mobject/session/defsregistry.hpp b/src/proc/mobject/session/defsregistry.hpp index 4aca10868..7d7589110 100644 --- a/src/proc/mobject/session/defsregistry.hpp +++ b/src/proc/mobject/session/defsregistry.hpp @@ -28,6 +28,7 @@ #include "common/multithread.hpp" #include "common/query.hpp" #include "common/util.hpp" +#include "common/p.hpp" #include #include @@ -41,10 +42,10 @@ namespace mobject { namespace session { - using std::tr1::shared_ptr; - using std::tr1::weak_ptr; - using lumiera::Thread; + using lumiera::P; using lumiera::Query; + using lumiera::Thread; + using std::tr1::weak_ptr; using std::string; using boost::format; @@ -60,7 +61,7 @@ namespace mobject /** we maintain an independent defaults registry * for every participating kind of objects */ - typedef std::vector > Table; + typedef std::vector< P > Table; uint maxSlots (0); ///< number of different registered Types @@ -76,7 +77,7 @@ namespace mobject Query query; weak_ptr objRef; - Record (const Query& q, const shared_ptr& obj) + Record (const Query& q, const P& obj) : degree (lumiera::query::countPraed (q)), query (q), objRef (obj) @@ -85,15 +86,15 @@ namespace mobject struct Search ///< Functor searching for a specific object { - Search (const shared_ptr& obj) + Search (const P& obj) : obj_(obj) { } - const shared_ptr& obj_; + const P& obj_; bool operator() (const Record& rec) { - shared_ptr storedObj (rec.objRef.lock()); + P storedObj (rec.objRef.lock()); return storedObj && (storedObj == obj_); } }; @@ -110,7 +111,7 @@ namespace mobject }; operator string () const { return str (dumpRecord % degree % query % dumpObj()); } - string dumpObj () const { shared_ptr o (objRef.lock()); return o? string(*o):"dead"; } + string dumpObj () const { P o (objRef.lock()); return o? string(*o):"dead"; } }; /** every new kind of object (Type) creates a new @@ -186,7 +187,7 @@ namespace mobject typedef typename Slot::Registry::iterator II; II p,i,e; - shared_ptr next, ptr; + P next, ptr; Iter (II from, II to) ///< just ennumerates the given range : p(from), i(from), e(to) @@ -201,7 +202,7 @@ namespace mobject operator++ (); // init to first element (or to null if emty) } - shared_ptr findNext () throw() + P findNext () throw() { while (!next) { @@ -214,9 +215,9 @@ namespace mobject public: - shared_ptr operator* () { return ptr; } - bool hasNext () { return next || findNext(); } - Iter operator++ (int) { Iter tmp=*this; operator++(); return tmp; } + P operator* () { return ptr; } + bool hasNext () { return next || findNext(); } + Iter operator++ (int) { Iter tmp=*this; operator++(); return tmp; } Iter& operator++ () { ptr=findNext(); @@ -237,7 +238,7 @@ namespace mobject template Iter candidates (const Query& query) { - shared_ptr dummy; + P dummy; Record entry (query, dummy); typedef typename Slot::Registry Registry; Registry& registry = Slot::access(table_); @@ -261,7 +262,7 @@ namespace mobject * case, also the param obj shared-ptr is rebound! */ template - bool put (shared_ptr& obj, const Query& query) + bool put (P& obj, const Query& query) { Record entry (query, obj); typedef typename Slot::Registry Registry; @@ -272,7 +273,7 @@ namespace mobject if ( pos!=registry.end() && pos->query == query) { - shared_ptr storedObj (pos->objRef.lock()); + P storedObj (pos->objRef.lock()); if (storedObj) return (storedObj == obj); else @@ -290,7 +291,7 @@ namespace mobject * @return false if the object wasn't registered at all. */ template - bool forget (const shared_ptr& obj) + bool forget (const P& obj) { typedef typename Slot::Registry Registry; typedef typename Record::Search SearchFunc; diff --git a/src/proc/mobject/session/mobjectfactory.hpp b/src/proc/mobject/session/mobjectfactory.hpp index cff884ca7..427385194 100644 --- a/src/proc/mobject/session/mobjectfactory.hpp +++ b/src/proc/mobject/session/mobjectfactory.hpp @@ -45,7 +45,7 @@ namespace mobject class Track; class Effect; - typedef shared_ptr PTrackAsset; + typedef P PTrackAsset; class MObjectFactory diff --git a/src/proc/mobject/session/track.hpp b/src/proc/mobject/session/track.hpp index 2b8f090b9..2b9801273 100644 --- a/src/proc/mobject/session/track.hpp +++ b/src/proc/mobject/session/track.hpp @@ -34,11 +34,13 @@ namespace mobject { namespace session { + using lumiera::P; + class Track; typedef asset::Track TrackAsset; - typedef shared_ptr PTrack; - typedef shared_ptr PTrackAsset; + typedef P PTrack; + typedef P PTrackAsset; /** diff --git a/tests/components/proc/mobject/session/defsregistryimpltest.cpp b/tests/components/proc/mobject/session/defsregistryimpltest.cpp index 0aae90b3a..e605880a1 100644 --- a/tests/components/proc/mobject/session/defsregistryimpltest.cpp +++ b/tests/components/proc/mobject/session/defsregistryimpltest.cpp @@ -27,6 +27,7 @@ #include "proc/mobject/session/defsregistry.hpp" #include "common/factory.hpp" #include "common/query.hpp" +#include "common/p.hpp" #include "../common/query/querydiagnostics.hpp" @@ -35,11 +36,11 @@ #include #include +using lumiera::P; using lumiera::Query; using lumiera::query::test::garbage_query; using util::isnil; -using std::tr1::shared_ptr; using boost::scoped_ptr; using boost::format; using std::string; @@ -75,7 +76,9 @@ namespace mobject { static string name; string instanceID; - operator string () const { return instanceID; } + operator string () const { return instanceID; } + bool operator== (const Dummy& odu) const { return this == &odu; } + Dummy () : instanceID (newID (name)) {} }; @@ -99,8 +102,8 @@ namespace mobject { scoped_ptr reg_; - typedef shared_ptr > O; - typedef shared_ptr > P; + typedef P > O; + typedef P > P; typedef Query > Q13; typedef Query > Q23; From d9e6adfe020797e4ae3a5e3b859816883b9d8f22 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 23 Apr 2008 05:48:45 +0200 Subject: [PATCH 030/245] make Placement implement the interface Buildable. WIP: works, but isnt what I intended. Rather need a specialisation to be able to define functions treat (Placement) based on the concrete TY.... --- src/common/visitor.hpp | 2 +- src/common/visitorpolicies.hpp | 2 +- src/proc/mobject/explicitplacement.hpp | 3 ++ src/proc/mobject/placement.hpp | 4 +- src/proc/mobject/session/locatingpin.hpp | 5 +- .../proc/mobject/builder/buildertooltest.cpp | 47 +++++++++++++++---- 6 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/common/visitor.hpp b/src/common/visitor.hpp index 837ddf713..3d22f11e6 100644 --- a/src/common/visitor.hpp +++ b/src/common/visitor.hpp @@ -105,7 +105,7 @@ namespace lumiera typedef RET ReturnType; ///< Tool function invocation return type typedef Tool ToolBase; ///< for templating the Tag and Dispatcher - virtual ~Tool () { }; ///< use RTTI for all visiting tools + virtual ~Tool () { }; ///< use RTTI for all visiting tools /** allows discovery of the concrete Tool type when dispatching a * visitor call. Can be implemented by inheriting from ToolTag */ diff --git a/src/common/visitorpolicies.hpp b/src/common/visitorpolicies.hpp index e59a2f5b2..829dd5546 100644 --- a/src/common/visitorpolicies.hpp +++ b/src/common/visitorpolicies.hpp @@ -23,7 +23,7 @@ /** @file visitorpolicies.hpp ** Policies usable for configuring the lumiera::visitor::Tool for different kinds of error handling. - ** @see buildertool.hpp for another flavor (calling and catch-all-function) + ** @see buildertool.hpp for another flavour (calling an catch-all-function there) ** */ diff --git a/src/proc/mobject/explicitplacement.hpp b/src/proc/mobject/explicitplacement.hpp index 388a0ac82..cb5e424b5 100644 --- a/src/proc/mobject/explicitplacement.hpp +++ b/src/proc/mobject/explicitplacement.hpp @@ -60,6 +60,9 @@ namespace mobject { return *this; } + + /** */ /////////////////////////////////////////////////////////////TODO: wip-wip... + DEFINE_PROCESSABLE_BY (builder::BuilderTool); protected: /* @todo ichthyo considers a much more elegant implementation utilizing a subclass diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index c5d56169d..7bd3a9ce4 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -82,7 +82,7 @@ namespace mobject * be within the Session/EDL */ template - class Placement : protected shared_ptr + class Placement : public Buildable, protected shared_ptr { protected: typedef lumiera::Time Time; @@ -105,7 +105,7 @@ namespace mobject virtual ~Placement() {}; /** */ /////////////////////////////////////////////////////////////TODO: totmachen? - // DEFINE_PROCESSABLE_BY (builder::BuilderTool); + DEFINE_PROCESSABLE_BY (builder::BuilderTool); /** interface for defining the kind of placement diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp index f978d4f4e..ecd82ab30 100644 --- a/src/proc/mobject/session/locatingpin.hpp +++ b/src/proc/mobject/session/locatingpin.hpp @@ -111,9 +111,12 @@ namespace mobject virtual LocatingPin* clone () const; virtual ~LocatingPin() {}; - protected: +// protected: LocatingPin () {}; +//TODO (for working out the buildable interface; ctor should be protected) +protected: + friend class Placement; /** diff --git a/tests/components/proc/mobject/builder/buildertooltest.cpp b/tests/components/proc/mobject/builder/buildertooltest.cpp index 8a445ef18..584b41ea0 100644 --- a/tests/components/proc/mobject/builder/buildertooltest.cpp +++ b/tests/components/proc/mobject/builder/buildertooltest.cpp @@ -1,5 +1,5 @@ /* - BuilderTool(Test) - specialized form of the acyclic visitor + BuilderTool(Test) - specialized visitor used within the builder for processing Placements Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -27,6 +27,9 @@ #include "proc/asset/media.hpp" #include "proc/mobject/session/clip.hpp" +#include "proc/mobject/explicitplacement.hpp" //////////TODO + + #include using std::string; using std::cout; @@ -48,15 +51,31 @@ namespace mobject public: DummyMO() { }; virtual bool isValid() const { return true;} - DEFINE_PROCESSABLE_BY (BuilderTool); +// DEFINE_PROCESSABLE_BY (BuilderTool); + + static void killDummy (AbstractMO* dum) { delete (DummyMO*)dum; } }; - - class TestTool - : public Applicable::List> + + + //////////////////////////////////////////////////////TODO: wip-wip + + class DummyPlacement : public Placement { public: - void treat (Clip& c) { cout << "media is: "<< str(c.getMedia()) <<"\n"; } - void treat (AbstractMO&){ cout << "unspecific MO.\n"; } + DummyPlacement() + : Placement::Placement(*new DummyMO, &DummyMO::killDummy) + { } + }; + //////////////////////////////////////////////////////TODO: wip-wip + + + + class TestTool + : public Applicable, Placement >::List> + { + public: + void treat (Placement& pC) { cout << "media is: "<< str(pC->getMedia()) <<"\n"; } + void treat (Placement&){ cout << "unspecific MO.\n"; } void onUnknown (Buildable&){ cout << "catch-all-function called.\n"; } }; @@ -88,10 +107,10 @@ namespace mobject TestTool t1; BuilderTool& tool (t1); - DummyMO dumm; + DummyPlacement dumm; PMO clip = asset::Media::create("test-1", asset::VIDEO)->createClip(); - clip->apply (tool); + clip.apply (tool); dumm.apply (tool); } }; @@ -105,5 +124,15 @@ namespace mobject } // namespace test } // namespace builder + + //////////////////////////////////////////////////////TODO: wip-wip + template<> + ExplicitPlacement + Placement::resolve () const + { + UNIMPLEMENTED ("just a test"); + } + //////////////////////////////////////////////////////TODO: wip-wip + } // namespace mobject From 03047e6d176f4b24525c2eeb8d11fcae32c4fb18 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 26 Apr 2008 05:38:19 +0200 Subject: [PATCH 031/245] WIP maybe a solution for getting the correct wrapper within Builder Tools. works, but problem is: you need to know the exact type of the wrapper, e.g. Placement or shared_ptr --- src/proc/mobject/session/clip.hpp | 1 + src/tool/try.cpp | 11 ++ .../proc/mobject/builder/buildertooltest.cpp | 112 ++++++++++++++++-- 3 files changed, 114 insertions(+), 10 deletions(-) diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp index cf15cbd27..7f1fe23c0 100644 --- a/src/proc/mobject/session/clip.hpp +++ b/src/proc/mobject/session/clip.hpp @@ -66,6 +66,7 @@ namespace mobject and the unlink() function of the asset should take it into account when breaking circular references. */ +public: ////////////////////////////////////TODO: temporarily for buildertooltest const Media & mediaDef_; const asset::Clip & clipDef_; diff --git a/src/tool/try.cpp b/src/tool/try.cpp index 90bdfadf8..da5ca97c0 100644 --- a/src/tool/try.cpp +++ b/src/tool/try.cpp @@ -8,25 +8,36 @@ // 1/08 - working out a static initialisation problem for Visitor (Tag creation) // 1/08 - check 64bit longs // 4/08 - comparison operators on shared_ptr +// 4/08 - conversions on the value_type used for boost::any #include #include #include +#include using std::string; using std::cout; +using boost::any; +using boost::any_cast; +struct B {}; +struct D : B {}; int main (int argc, char* argv[]) { NOBUG_INIT; + D d; + D* pD =&d; + + any aD (pD); + any_cast (aD); cout << "\ngulp\n"; diff --git a/tests/components/proc/mobject/builder/buildertooltest.cpp b/tests/components/proc/mobject/builder/buildertooltest.cpp index 584b41ea0..995325025 100644 --- a/tests/components/proc/mobject/builder/buildertooltest.cpp +++ b/tests/components/proc/mobject/builder/buildertooltest.cpp @@ -29,7 +29,7 @@ #include "proc/mobject/explicitplacement.hpp" //////////TODO - +#include #include using std::string; using std::cout; @@ -45,8 +45,62 @@ namespace mobject using session::Clip; using session::AbstractMO; +/////////////////////////////////////////////////////TODO: move to buildertool.hpp + using boost::any; + using boost::any_cast; + +// Problem +/* + - brauche Laufzeittyp des Zielobjektes + - an wen wird die Dispatcher-Tabelle gebunden? + - falls an den Wrapper: Gefahr, zur Laufzeit nicht die Tabelle zu bekommen, in die das Trampolin registriert wurde + - falls an das Zielobjekt: wie gebe ich Referenz und konkreten Typ des Wrappers an den Funktionsaufruf im Tool? + - vieleicht einen allgemeinen Argument-Adapter nutzen? + - Zielobjekt oder Wrapper als Argumenttyp? +*/ - class DummyMO : public AbstractMO + class BuTuul + : public lumiera::visitor::Tool + { + any currentArgument_; + + public: + + void rememberWrapper (any argument) + { + currentArgument_ = argument; + } + + template + WRA& getCurrentArgumentWrapper () + { + WRA* argument = any_cast (currentArgument_); + ASSERT (argument); + return *argument; + } + }; + + + + + template + < class TOOLImpl, // concrete BuilderTool implementation + class TYPELIST // list of all concrete Buildables to be treated + > + class Appli + : public lumiera::visitor::Applicable + { } + ; + + using lumiera::typelist::Types; // convienience for the users of "Applicable" + + class BDable : public lumiera::visitor::Visitable + { + + }; +/////////////////////////////////////////////////////TODO: move to buildertool.hpp + + class DummyMO : public AbstractMO, public BDable { public: DummyMO() { }; @@ -54,8 +108,34 @@ namespace mobject // DEFINE_PROCESSABLE_BY (BuilderTool); static void killDummy (AbstractMO* dum) { delete (DummyMO*)dum; } + + virtual void + apply (BuTuul& tool) + { + return BDable::dispatchOp (*this, tool); + } + }; + class Clop : public Clip, public BDable + { + Clop (Clip& base) : Clip (base.clipDef_, base.mediaDef_) {} + + virtual void + apply (BuTuul& tool) + { + return BDable::dispatchOp (*this, tool); + } + }; + + + template + inline BDable::ReturnType + apply (BuTuul& tool, TAR& wrappedTargetObj) + { + tool.rememberWrapper(any (&wrappedTargetObj)); + wrappedTargetObj->apply (tool); + } //////////////////////////////////////////////////////TODO: wip-wip @@ -71,12 +151,23 @@ namespace mobject class TestTool - : public Applicable, Placement >::List> + : public Appli::List> { public: - void treat (Placement& pC) { cout << "media is: "<< str(pC->getMedia()) <<"\n"; } - void treat (Placement&){ cout << "unspecific MO.\n"; } - void onUnknown (Buildable&){ cout << "catch-all-function called.\n"; } + void treat (Clip& c) + { + Placement& pC = getCurrentArgumentWrapper >(); + cout << "media is: "<< str(pC->getMedia()) <<"\n"; + } + void treat (AbstractMO&) + { + Placement& placement = getCurrentArgumentWrapper(); + cout << "unspecific MO; Placement(adr) " << &placement <<"\n"; + } + void onUnknown (Buildable&) + { + cout << "catch-all-function called.\n"; + } }; @@ -105,13 +196,14 @@ namespace mobject { TestTool t1; - BuilderTool& tool (t1); + BuTuul& tool (t1); DummyPlacement dumm; - PMO clip = asset::Media::create("test-1", asset::VIDEO)->createClip(); + Placement clip = asset::Media::create("test-1", asset::VIDEO)->createClip(); - clip.apply (tool); - dumm.apply (tool); + apply (tool, clip); + cout << "Placement(adr) " << &dumm <<"\n"; + apply (tool, dumm); } }; From 03bc0cd276960923d60d5e11a5f8f34af6b0c1f3 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Fri, 2 May 2008 17:26:50 +0100 Subject: [PATCH 032/245] Relocated gui into the src folder --- gui/COPYING | 1 - gui/INSTALL | 1 - gui/po/POTFILES.in | 3 --- {gui => src/gui}/AUTHORS | 0 src/gui/COPYING | 1 + {gui => src/gui}/ChangeLog | 0 src/gui/INSTALL | 1 + {gui => src/gui}/Makefile.am | 0 {gui => src/gui}/NEWS | 0 {gui => src/gui}/README | 0 {gui => src/gui}/TODO.tasks | 0 {gui => src/gui}/autogen.sh | 0 {gui => src/gui}/configure.ac | 0 {gui => src/gui}/po/ChangeLog | 0 {gui => src/gui}/po/LINGUAS | 0 {gui => src/gui}/src/Makefile.am | 0 {gui => src/gui}/src/dialogs/preferences-dialog.cpp | 0 {gui => src/gui}/src/dialogs/preferences-dialog.hpp | 0 {gui => src/gui}/src/dialogs/render.cpp | 0 {gui => src/gui}/src/dialogs/render.hpp | 0 {gui => src/gui}/src/gtk-lumiera.cpp | 0 {gui => src/gui}/src/gtk-lumiera.hpp | 0 {gui => src/gui}/src/lumiera_ui.rc | 0 {gui => src/gui}/src/model/project.cpp | 0 {gui => src/gui}/src/model/project.hpp | 0 {gui => src/gui}/src/panels/assets-panel.cpp | 0 {gui => src/gui}/src/panels/assets-panel.hpp | 0 {gui => src/gui}/src/panels/panel.cpp | 0 {gui => src/gui}/src/panels/panel.hpp | 0 {gui => src/gui}/src/panels/timeline-panel.cpp | 0 {gui => src/gui}/src/panels/timeline-panel.hpp | 0 {gui => src/gui}/src/panels/viewer-panel.cpp | 0 {gui => src/gui}/src/panels/viewer-panel.hpp | 0 {gui => src/gui}/src/widgets/timeline-widget.cpp | 0 {gui => src/gui}/src/widgets/timeline-widget.hpp | 0 {gui => src/gui}/src/widgets/video-display-widget.cpp | 0 {gui => src/gui}/src/widgets/video-display-widget.hpp | 0 {gui => src/gui}/src/window-manager.cpp | 2 +- {gui => src/gui}/src/window-manager.hpp | 0 {gui => src/gui}/src/workspace/actions.cpp | 0 {gui => src/gui}/src/workspace/actions.hpp | 0 {gui => src/gui}/src/workspace/workspace-window.cpp | 0 {gui => src/gui}/src/workspace/workspace-window.hpp | 0 43 files changed, 3 insertions(+), 6 deletions(-) delete mode 120000 gui/COPYING delete mode 120000 gui/INSTALL delete mode 100644 gui/po/POTFILES.in rename {gui => src/gui}/AUTHORS (100%) create mode 120000 src/gui/COPYING rename {gui => src/gui}/ChangeLog (100%) create mode 120000 src/gui/INSTALL rename {gui => src/gui}/Makefile.am (100%) rename {gui => src/gui}/NEWS (100%) rename {gui => src/gui}/README (100%) rename {gui => src/gui}/TODO.tasks (100%) rename {gui => src/gui}/autogen.sh (100%) rename {gui => src/gui}/configure.ac (100%) rename {gui => src/gui}/po/ChangeLog (100%) rename {gui => src/gui}/po/LINGUAS (100%) rename {gui => src/gui}/src/Makefile.am (100%) rename {gui => src/gui}/src/dialogs/preferences-dialog.cpp (100%) rename {gui => src/gui}/src/dialogs/preferences-dialog.hpp (100%) rename {gui => src/gui}/src/dialogs/render.cpp (100%) rename {gui => src/gui}/src/dialogs/render.hpp (100%) rename {gui => src/gui}/src/gtk-lumiera.cpp (100%) rename {gui => src/gui}/src/gtk-lumiera.hpp (100%) rename {gui => src/gui}/src/lumiera_ui.rc (100%) rename {gui => src/gui}/src/model/project.cpp (100%) rename {gui => src/gui}/src/model/project.hpp (100%) rename {gui => src/gui}/src/panels/assets-panel.cpp (100%) rename {gui => src/gui}/src/panels/assets-panel.hpp (100%) rename {gui => src/gui}/src/panels/panel.cpp (100%) rename {gui => src/gui}/src/panels/panel.hpp (100%) rename {gui => src/gui}/src/panels/timeline-panel.cpp (100%) rename {gui => src/gui}/src/panels/timeline-panel.hpp (100%) rename {gui => src/gui}/src/panels/viewer-panel.cpp (100%) rename {gui => src/gui}/src/panels/viewer-panel.hpp (100%) rename {gui => src/gui}/src/widgets/timeline-widget.cpp (100%) rename {gui => src/gui}/src/widgets/timeline-widget.hpp (100%) rename {gui => src/gui}/src/widgets/video-display-widget.cpp (100%) rename {gui => src/gui}/src/widgets/video-display-widget.hpp (100%) rename {gui => src/gui}/src/window-manager.cpp (97%) rename {gui => src/gui}/src/window-manager.hpp (100%) rename {gui => src/gui}/src/workspace/actions.cpp (100%) rename {gui => src/gui}/src/workspace/actions.hpp (100%) rename {gui => src/gui}/src/workspace/workspace-window.cpp (100%) rename {gui => src/gui}/src/workspace/workspace-window.hpp (100%) diff --git a/gui/COPYING b/gui/COPYING deleted file mode 120000 index 0b6cbf81b..000000000 --- a/gui/COPYING +++ /dev/null @@ -1 +0,0 @@ -/usr/share/automake-1.10/COPYING \ No newline at end of file diff --git a/gui/INSTALL b/gui/INSTALL deleted file mode 120000 index 5bb6e7b7e..000000000 --- a/gui/INSTALL +++ /dev/null @@ -1 +0,0 @@ -/usr/share/automake-1.10/INSTALL \ No newline at end of file diff --git a/gui/po/POTFILES.in b/gui/po/POTFILES.in deleted file mode 100644 index a0b3c552e..000000000 --- a/gui/po/POTFILES.in +++ /dev/null @@ -1,3 +0,0 @@ -# List of source files containing translatable strings. - -src/main.c diff --git a/gui/AUTHORS b/src/gui/AUTHORS similarity index 100% rename from gui/AUTHORS rename to src/gui/AUTHORS diff --git a/src/gui/COPYING b/src/gui/COPYING new file mode 120000 index 000000000..71537690b --- /dev/null +++ b/src/gui/COPYING @@ -0,0 +1 @@ +/usr/share/automake-1.9/COPYING \ No newline at end of file diff --git a/gui/ChangeLog b/src/gui/ChangeLog similarity index 100% rename from gui/ChangeLog rename to src/gui/ChangeLog diff --git a/src/gui/INSTALL b/src/gui/INSTALL new file mode 120000 index 000000000..81fa6ffa4 --- /dev/null +++ b/src/gui/INSTALL @@ -0,0 +1 @@ +/usr/share/automake-1.9/INSTALL \ No newline at end of file diff --git a/gui/Makefile.am b/src/gui/Makefile.am similarity index 100% rename from gui/Makefile.am rename to src/gui/Makefile.am diff --git a/gui/NEWS b/src/gui/NEWS similarity index 100% rename from gui/NEWS rename to src/gui/NEWS diff --git a/gui/README b/src/gui/README similarity index 100% rename from gui/README rename to src/gui/README diff --git a/gui/TODO.tasks b/src/gui/TODO.tasks similarity index 100% rename from gui/TODO.tasks rename to src/gui/TODO.tasks diff --git a/gui/autogen.sh b/src/gui/autogen.sh similarity index 100% rename from gui/autogen.sh rename to src/gui/autogen.sh diff --git a/gui/configure.ac b/src/gui/configure.ac similarity index 100% rename from gui/configure.ac rename to src/gui/configure.ac diff --git a/gui/po/ChangeLog b/src/gui/po/ChangeLog similarity index 100% rename from gui/po/ChangeLog rename to src/gui/po/ChangeLog diff --git a/gui/po/LINGUAS b/src/gui/po/LINGUAS similarity index 100% rename from gui/po/LINGUAS rename to src/gui/po/LINGUAS diff --git a/gui/src/Makefile.am b/src/gui/src/Makefile.am similarity index 100% rename from gui/src/Makefile.am rename to src/gui/src/Makefile.am diff --git a/gui/src/dialogs/preferences-dialog.cpp b/src/gui/src/dialogs/preferences-dialog.cpp similarity index 100% rename from gui/src/dialogs/preferences-dialog.cpp rename to src/gui/src/dialogs/preferences-dialog.cpp diff --git a/gui/src/dialogs/preferences-dialog.hpp b/src/gui/src/dialogs/preferences-dialog.hpp similarity index 100% rename from gui/src/dialogs/preferences-dialog.hpp rename to src/gui/src/dialogs/preferences-dialog.hpp diff --git a/gui/src/dialogs/render.cpp b/src/gui/src/dialogs/render.cpp similarity index 100% rename from gui/src/dialogs/render.cpp rename to src/gui/src/dialogs/render.cpp diff --git a/gui/src/dialogs/render.hpp b/src/gui/src/dialogs/render.hpp similarity index 100% rename from gui/src/dialogs/render.hpp rename to src/gui/src/dialogs/render.hpp diff --git a/gui/src/gtk-lumiera.cpp b/src/gui/src/gtk-lumiera.cpp similarity index 100% rename from gui/src/gtk-lumiera.cpp rename to src/gui/src/gtk-lumiera.cpp diff --git a/gui/src/gtk-lumiera.hpp b/src/gui/src/gtk-lumiera.hpp similarity index 100% rename from gui/src/gtk-lumiera.hpp rename to src/gui/src/gtk-lumiera.hpp diff --git a/gui/src/lumiera_ui.rc b/src/gui/src/lumiera_ui.rc similarity index 100% rename from gui/src/lumiera_ui.rc rename to src/gui/src/lumiera_ui.rc diff --git a/gui/src/model/project.cpp b/src/gui/src/model/project.cpp similarity index 100% rename from gui/src/model/project.cpp rename to src/gui/src/model/project.cpp diff --git a/gui/src/model/project.hpp b/src/gui/src/model/project.hpp similarity index 100% rename from gui/src/model/project.hpp rename to src/gui/src/model/project.hpp diff --git a/gui/src/panels/assets-panel.cpp b/src/gui/src/panels/assets-panel.cpp similarity index 100% rename from gui/src/panels/assets-panel.cpp rename to src/gui/src/panels/assets-panel.cpp diff --git a/gui/src/panels/assets-panel.hpp b/src/gui/src/panels/assets-panel.hpp similarity index 100% rename from gui/src/panels/assets-panel.hpp rename to src/gui/src/panels/assets-panel.hpp diff --git a/gui/src/panels/panel.cpp b/src/gui/src/panels/panel.cpp similarity index 100% rename from gui/src/panels/panel.cpp rename to src/gui/src/panels/panel.cpp diff --git a/gui/src/panels/panel.hpp b/src/gui/src/panels/panel.hpp similarity index 100% rename from gui/src/panels/panel.hpp rename to src/gui/src/panels/panel.hpp diff --git a/gui/src/panels/timeline-panel.cpp b/src/gui/src/panels/timeline-panel.cpp similarity index 100% rename from gui/src/panels/timeline-panel.cpp rename to src/gui/src/panels/timeline-panel.cpp diff --git a/gui/src/panels/timeline-panel.hpp b/src/gui/src/panels/timeline-panel.hpp similarity index 100% rename from gui/src/panels/timeline-panel.hpp rename to src/gui/src/panels/timeline-panel.hpp diff --git a/gui/src/panels/viewer-panel.cpp b/src/gui/src/panels/viewer-panel.cpp similarity index 100% rename from gui/src/panels/viewer-panel.cpp rename to src/gui/src/panels/viewer-panel.cpp diff --git a/gui/src/panels/viewer-panel.hpp b/src/gui/src/panels/viewer-panel.hpp similarity index 100% rename from gui/src/panels/viewer-panel.hpp rename to src/gui/src/panels/viewer-panel.hpp diff --git a/gui/src/widgets/timeline-widget.cpp b/src/gui/src/widgets/timeline-widget.cpp similarity index 100% rename from gui/src/widgets/timeline-widget.cpp rename to src/gui/src/widgets/timeline-widget.cpp diff --git a/gui/src/widgets/timeline-widget.hpp b/src/gui/src/widgets/timeline-widget.hpp similarity index 100% rename from gui/src/widgets/timeline-widget.hpp rename to src/gui/src/widgets/timeline-widget.hpp diff --git a/gui/src/widgets/video-display-widget.cpp b/src/gui/src/widgets/video-display-widget.cpp similarity index 100% rename from gui/src/widgets/video-display-widget.cpp rename to src/gui/src/widgets/video-display-widget.cpp diff --git a/gui/src/widgets/video-display-widget.hpp b/src/gui/src/widgets/video-display-widget.hpp similarity index 100% rename from gui/src/widgets/video-display-widget.hpp rename to src/gui/src/widgets/video-display-widget.hpp diff --git a/gui/src/window-manager.cpp b/src/gui/src/window-manager.cpp similarity index 97% rename from gui/src/window-manager.cpp rename to src/gui/src/window-manager.cpp index 6314aba94..1bc8c1e16 100644 --- a/gui/src/window-manager.cpp +++ b/src/gui/src/window-manager.cpp @@ -38,7 +38,7 @@ namespace gui { return false; } - Gtk::RC rc(path); + gtk_rc_parse(path.c_str()); gtk_rc_reset_styles (gtk_settings_get_default()); return true; diff --git a/gui/src/window-manager.hpp b/src/gui/src/window-manager.hpp similarity index 100% rename from gui/src/window-manager.hpp rename to src/gui/src/window-manager.hpp diff --git a/gui/src/workspace/actions.cpp b/src/gui/src/workspace/actions.cpp similarity index 100% rename from gui/src/workspace/actions.cpp rename to src/gui/src/workspace/actions.cpp diff --git a/gui/src/workspace/actions.hpp b/src/gui/src/workspace/actions.hpp similarity index 100% rename from gui/src/workspace/actions.hpp rename to src/gui/src/workspace/actions.hpp diff --git a/gui/src/workspace/workspace-window.cpp b/src/gui/src/workspace/workspace-window.cpp similarity index 100% rename from gui/src/workspace/workspace-window.cpp rename to src/gui/src/workspace/workspace-window.cpp diff --git a/gui/src/workspace/workspace-window.hpp b/src/gui/src/workspace/workspace-window.hpp similarity index 100% rename from gui/src/workspace/workspace-window.hpp rename to src/gui/src/workspace/workspace-window.hpp From 130da1ec7705ce608d393c8b5b952b97195891ff Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 5 May 2008 22:21:58 +0100 Subject: [PATCH 033/245] Layed the foundation of a --- src/gui/AUTHORS | 0 src/gui/COPYING | 1 - src/gui/ChangeLog | 0 src/gui/INSTALL | 1 - src/gui/Makefile.am | 9 +- src/gui/NEWS | 0 src/gui/README | 0 src/gui/TODO.tasks | 6 - src/gui/autogen.sh | 4 +- src/gui/configure.ac | 41 +++- src/gui/src/Makefile.am | 6 +- src/gui/src/output/displayer.cpp | 65 ++++++ src/gui/src/output/displayer.hpp | 107 ++++++++++ src/gui/src/output/xvdisplayer.cpp | 214 +++++++++++++++++++ src/gui/src/output/xvdisplayer.hpp | 68 ++++++ src/gui/src/widgets/video-display-widget.hpp | 6 +- src/gui/src/window-manager.hpp | 2 +- 17 files changed, 505 insertions(+), 25 deletions(-) delete mode 100644 src/gui/AUTHORS delete mode 120000 src/gui/COPYING delete mode 100644 src/gui/ChangeLog delete mode 120000 src/gui/INSTALL delete mode 100644 src/gui/NEWS delete mode 100644 src/gui/README delete mode 100644 src/gui/TODO.tasks create mode 100644 src/gui/src/output/displayer.cpp create mode 100644 src/gui/src/output/displayer.hpp create mode 100644 src/gui/src/output/xvdisplayer.cpp create mode 100644 src/gui/src/output/xvdisplayer.hpp diff --git a/src/gui/AUTHORS b/src/gui/AUTHORS deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/gui/COPYING b/src/gui/COPYING deleted file mode 120000 index 71537690b..000000000 --- a/src/gui/COPYING +++ /dev/null @@ -1 +0,0 @@ -/usr/share/automake-1.9/COPYING \ No newline at end of file diff --git a/src/gui/ChangeLog b/src/gui/ChangeLog deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/gui/INSTALL b/src/gui/INSTALL deleted file mode 120000 index 81fa6ffa4..000000000 --- a/src/gui/INSTALL +++ /dev/null @@ -1 +0,0 @@ -/usr/share/automake-1.9/INSTALL \ No newline at end of file diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 329e83f38..50af375e8 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,16 +1,9 @@ ## Process this file with automake to produce Makefile.in -## Created by Anjuta SUBDIRS = src po gtk_lumieradocdir = ${prefix}/doc/gtk-lumiera -gtk_lumieradoc_DATA = \ - README\ - COPYING\ - AUTHORS\ - ChangeLog\ - INSTALL\ - NEWS +gtk_lumieradoc_DATA = EXTRA_DIST = $(gtk_lumieradoc_DATA) diff --git a/src/gui/NEWS b/src/gui/NEWS deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/gui/README b/src/gui/README deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/gui/TODO.tasks b/src/gui/TODO.tasks deleted file mode 100644 index d1fa282d9..000000000 --- a/src/gui/TODO.tasks +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/gui/autogen.sh b/src/gui/autogen.sh index 9ab346a30..5e54fc413 100755 --- a/src/gui/autogen.sh +++ b/src/gui/autogen.sh @@ -140,8 +140,8 @@ do echo "Running autoheader..." autoheader fi - echo "Running automake --gnu $am_opt ..." - automake --add-missing --gnu $am_opt + echo "Running automake --foreign $am_opt ..." + automake --add-missing --foreign $am_opt echo "Running autoconf ..." autoconf ) diff --git a/src/gui/configure.ac b/src/gui/configure.ac index fbc00ed01..2e3a7cd21 100644 --- a/src/gui/configure.ac +++ b/src/gui/configure.ac @@ -1,5 +1,4 @@ dnl Process this file with autoconf to produce a configure script. -dnl Created by Anjuta application wizard. AC_INIT(gtk-lumiera, 0.1) @@ -29,14 +28,48 @@ IT_PROG_INTLTOOL([0.35.0]) AM_PROG_LIBTOOL +# ###################################################################### +# Checks for X11 and XVideo +# ###################################################################### +AC_PATH_X +AC_PATH_XTRA +# CFLAGS="$CFLAGS $X_CFLAGS" +LIBS="$LIBS $X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS" +AC_CHECK_HEADERS([X11/Xlib.h X11/Xutil.h],[], + [AC_MSG_ERROR([Xlib.h or Xutil.h not found install xdevel])]) + +# OK, this is confusing. The old tests test for the existence of a number +# of header files, and add -lXv to the linker flags if they are there. +# However, if they are _not_ there, only a warning is issued, but +# src/displayer.h includes these unconditionally. +# I conclude that -lXv _is_ required. If not, src/displayer.h should be edited, +# I think. +# This test requires libXv and, therefore, libXext + +AC_CHECK_HEADERS([sys/ipc.h sys/shm.h],, + [AC_MSG_ERROR([Required header not found. Please check that it is installed])] +) +AC_CHECK_HEADERS([X11/extensions/Xvlib.h X11/extensions/XShm.h],, + [AC_MSG_ERROR([Required xvideo (Xv) extension to X not found. Please check that it is installed.])], + [#include ] +) + +AC_CHECK_LIB(Xext, XInitExtension, , + [AC_MSG_ERROR([Could not link with libXext. Check that you have libXext installed])], -lX11 +) +AC_CHECK_LIB(Xv, XvQueryAdaptors, , + [AC_MSG_ERROR([Could not link with libXv. Check that you have libXv installed])] +) + +# ###################################################################### +# Checks for GTK stuff +# ###################################################################### PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.6.1 cairomm-1.0 >= 0.6.0]) + AC_SUBST(GTK_LUMIERA_CFLAGS) AC_SUBST(GTK_LUMIERA_LIBS) - - - AC_OUTPUT([ Makefile src/Makefile diff --git a/src/gui/src/Makefile.am b/src/gui/src/Makefile.am index 2755fb0ae..29e6a6cfb 100644 --- a/src/gui/src/Makefile.am +++ b/src/gui/src/Makefile.am @@ -38,7 +38,11 @@ gtk_lumiera_SOURCES = \ widgets/timeline-widget.cpp \ widgets/timeline-widget.hpp \ model/project.cpp \ - model/project.hpp + model/project.hpp \ + output/displayer.cpp \ + output/displayer.hpp \ + output/xvdisplayer.cpp \ + output/xvdisplayer.hpp gtk_lumiera_LDFLAGS = diff --git a/src/gui/src/output/displayer.cpp b/src/gui/src/output/displayer.cpp new file mode 100644 index 000000000..0570d5a19 --- /dev/null +++ b/src/gui/src/output/displayer.cpp @@ -0,0 +1,65 @@ +/* + displayer.cpp - Implements the base class for displaying video + + Copyright (C) Lumiera.org + 2000, Arne Schirmacher + 2001-2007, Dan Dennedy + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "displayer.hpp" + +namespace lumiera { +namespace gui { +namespace output { + + + + DisplayerInput Displayer::format() + { + return DISPLAY_NONE; + } + + int Displayer::preferredWidth() + { + return imageWidth; + } + + int Displayer::preferredHeight() + { + return imageHeight; + } + + void Displayer::put( void *image, int width, int height ) + { + if ( width == preferredWidth() && height == preferredHeight() ) + { + put( image ); + } + else + { + reformat( format(), format(), image, width, height ); + put( pixels ); + } + } + + + +} // namespace output +} // namespace gui +} // namespace lumiera diff --git a/src/gui/src/output/displayer.hpp b/src/gui/src/output/displayer.hpp new file mode 100644 index 000000000..a04eca784 --- /dev/null +++ b/src/gui/src/output/displayer.hpp @@ -0,0 +1,107 @@ +/* + displayer.hpp - Defines the base class for displaying video + + Copyright (C) Lumiera.org + 2000, Arne Schirmacher + 2001-2007, Dan Dennedy + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file displayer.hpp + ** This file contains the defintion of Displayer; the base class + ** of all video display implementations + ** @see displayer.cpp + */ + +#ifndef DISPLAYER_HPP +#define DISPLAYER_HPP + +namespace lumiera { +namespace gui { +namespace output { + + /** Supported Displayer formats + */ + + typedef enum { + DISPLAY_NONE, + DISPLAY_YUV, + DISPLAY_RGB, + DISPLAY_BGR, + DISPLAY_BGR0, + DISPLAY_RGB16 + } + DisplayerInput; + + /** A Displayer is a class which is responsible for rendering an image in some + way (ie: Xvideo, GDK, OpenGL etc). + + All Displayer classes must extend the Displayer class and minimally rewrite: + + + usable() - to indicate if the object can be used, + + format() - to indicate what type of input the put method expects + + put( void * ) - deal with an image of the expected type and size + + By default, all images will be delivered to the put method in a resolution + of IMG_WIDTH * IMG_HEIGHT. If another size is required, then the rewrite + the methods: + + + preferredWidth + + preferredHeight + + If the widget being written to doesn't need a fixed size, then rewrite + the two other put methods as required. + */ + class Displayer + { + public: + + /** Indicates the format required by the abstract put method. + */ + virtual DisplayerInput format(); + + /** Expected width of input to put. + */ + virtual int preferredWidth(); + + /** Expected height of input to put. + */ + virtual int preferredHeight(); + + /** Put an image of a given width and height with the expected input + format (as indicated by the format method). + + \param image image of correct format and specified width/height + \param width width of image + \param height height of image + */ + virtual void put( void *image, int width, int height ); + + virtual bool usable(); + + protected: + int imageWidth; + int imageHeight; + + virtual void put( void * ) = 0; + }; + +} // namespace output +} // namespace gui +} // namespace lumiera + +#endif // DISPLAYER_HPP diff --git a/src/gui/src/output/xvdisplayer.cpp b/src/gui/src/output/xvdisplayer.cpp new file mode 100644 index 000000000..ac15c86d1 --- /dev/null +++ b/src/gui/src/output/xvdisplayer.cpp @@ -0,0 +1,214 @@ +/* + displayer.cpp - Implements the base class for displaying video + + Copyright (C) Lumiera.org + 2000, Arne Schirmacher + 2001-2007, Dan Dennedy + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "xvdisplayer.hpp" + +namespace lumiera { +namespace gui { +namespace output { + +XvDisplayer::XvDisplayer( GtkWidget *drawingarea, int width, int height, bool isPAL, bool isWidescreen ) : + xvImage( NULL ) +{ + cerr << ">> Trying XVideo at " << width << "x" << height << endl; + + this->drawingarea = drawingarea; + img_width = width; + img_height = height; + this->isPAL = isPAL; + this->isWidescreen = isWidescreen; + + shmInfo.shmaddr = NULL; + gotPort = false; + + window = GDK_WINDOW_XID( drawingarea->window ); + display = GDK_WINDOW_XDISPLAY( drawingarea->window ); + + unsigned int count; + XvAdaptorInfo *adaptorInfo; + + if ( XvQueryAdaptors( display, window, &count, &adaptorInfo ) == Success ) + { + + cerr << ">>> XvQueryAdaptors count: " << count << endl; + for ( unsigned int n = 0; gotPort == false && n < count; ++n ) + { + // Diagnostics + cerr << ">>> Xv: " << adaptorInfo[ n ].name + << ": ports " << adaptorInfo[ n ].base_id + << " - " << adaptorInfo[ n ].base_id + + adaptorInfo[ n ].num_ports - 1 + << endl; + + for ( port = adaptorInfo[ n ].base_id; + port < adaptorInfo[ n ].base_id + adaptorInfo[ n ].num_ports; + port ++ ) + { + if ( XvGrabPort( display, port, CurrentTime ) == 0 ) + { + + int formats; + XvImageFormatValues *list; + + list = XvListImageFormats( display, port, &formats ); + + cerr << ">>> formats supported: " << formats << endl; + + for ( int i = 0; i < formats; i ++ ) + { + fprintf( stderr, ">>> 0x%x (%c%c%c%c) %s\n", + list[ i ].id, + ( list[ i ].id ) & 0xff, + ( list[ i ].id >> 8 ) & 0xff, + ( list[ i ].id >> 16 ) & 0xff, + ( list[ i ].id >> 24 ) & 0xff, + ( list[ i ].format == XvPacked ) ? "packed" : "planar" ); + if ( list[ i ].id == 0x32595559 && !gotPort ) + gotPort = true; + } + + if ( !gotPort ) + { + XvUngrabPort( display, port, CurrentTime ); + } + else + { + grabbedPort = port; + break; + } + } + } + } + + if ( gotPort ) + { + int num; + unsigned int unum; + XvEncodingInfo *enc; + + XvQueryEncodings( display, grabbedPort, &unum, &enc ); + for ( unsigned int index = 0; index < unum; index ++ ) + { + fprintf( stderr, ">>> %d: %s, %ldx%ld rate = %d/%d\n", index, enc->name, + enc->width, enc->height, enc->rate.numerator, + enc->rate.denominator ); + } + + XvAttribute *xvattr = XvQueryPortAttributes( display, port, &num ); + for ( int k = 0; k < num; k++ ) + { + if ( xvattr[k].flags & XvSettable ) + { + if ( strcmp( xvattr[k].name, "XV_AUTOPAINT_COLORKEY") == 0 ) + { + Atom val_atom = XInternAtom( display, xvattr[k].name, False ); + if ( XvSetPortAttribute( display, port, val_atom, 1 ) != Success ) + fprintf(stderr, "Couldn't set Xv attribute %s\n", xvattr[k].name); + } + else if ( strcmp( xvattr[k].name, "XV_COLORKEY") == 0 ) + { + Atom val_atom = XInternAtom( display, xvattr[k].name, False ); + if ( XvSetPortAttribute( display, port, val_atom, 0x010102 ) != Success ) + fprintf(stderr, "Couldn't set Xv attribute %s\n", xvattr[k].name); + } + } + } + } + + if ( gotPort ) + { + gc = XCreateGC( display, window, 0, &values ); + + xvImage = ( XvImage * ) XvShmCreateImage( display, port, 0x32595559, 0, width, height, &shmInfo ); + + shmInfo.shmid = shmget( IPC_PRIVATE, xvImage->data_size, IPC_CREAT | 0777 ); + if (shmInfo.shmid < 0) { + perror("shmget"); + gotPort = false; + } else { + shmInfo.shmaddr = ( char * ) shmat( shmInfo.shmid, 0, 0 ); + xvImage->data = shmInfo.shmaddr; + shmInfo.readOnly = 0; + if ( !XShmAttach( gdk_display, &shmInfo ) ) + { + gotPort = false; + } + XSync( display, false ); + shmctl( shmInfo.shmid, IPC_RMID, 0 ); +#if 0 + xvImage = ( XvImage * ) XvCreateImage( display, port, 0x32595559, pix, width , height ); +#endif + } + } + } + else + { + gotPort = false; + } +} + +XvDisplayer::~XvDisplayer() +{ + cerr << ">> Destroying XV Displayer" << endl; + + if ( gotPort ) + { + XvUngrabPort( display, grabbedPort, CurrentTime ); + } + + if ( xvImage != NULL ) + XvStopVideo( display, port, window ); + + if ( shmInfo.shmaddr != NULL ) + { + XShmDetach( display, &shmInfo ); + shmctl( shmInfo.shmid, IPC_RMID, 0 ); + shmdt( shmInfo.shmaddr ); + } + if ( xvImage != NULL ) + XFree( xvImage ); +} + +bool XvDisplayer::usable() +{ + return gotPort; +} + + void XvDisplayer::put( void *image ) + { + AspectRatioCalculator calc( ( ( GtkWidget * ) drawingarea ) ->allocation.width, + ( ( GtkWidget * ) drawingarea ) ->allocation.height, + this->preferredWidth(), this->preferredHeight(), + isPAL, isWidescreen ); + + memcpy( xvImage->data, image, xvImage->data_size ); + + XvShmPutImage( display, port, window, gc, xvImage, + 0, 0, this->preferredWidth(), this->preferredHeight(), + calc.x, calc.y, calc.width, calc.height, false ); + } + +} // namespace output +} // namespace gui +} // namespace lumiera diff --git a/src/gui/src/output/xvdisplayer.hpp b/src/gui/src/output/xvdisplayer.hpp new file mode 100644 index 000000000..77cd27459 --- /dev/null +++ b/src/gui/src/output/xvdisplayer.hpp @@ -0,0 +1,68 @@ +/* + xcdisplayer.hpp - Defines the base class for XVideo display + + Copyright (C) Lumiera.org + 2000, Arne Schirmacher + 2001-2007, Dan Dennedy + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file xvdisplayer.hpp + ** This file contains the definition of XvDisplayer, the XVideo + ** video output implementation + ** @see xvdisplayer.cpp + */ + +#include "displayer.hpp" + +#include +#include +#include + +#ifndef XVDISPLAYER_HPP +#define XVDISPLAYER_HPP + +namespace lumiera { +namespace gui { +namespace output { + + class XvDisplayer + { + public: + XvDisplayer(); + ~XvDisplayer(); + + protected: + void put( void *image ); + + private: + bool canuse; + int depth; + GtkWidget *drawingarea; + Display *display; + Window window; + GC gc; + XImage *xImage; + XGCValues values; + XShmSegmentInfo shmInfo; + }; + +} // namespace output +} // namespace gui +} // namespace lumiera + +#endif // XVDISPLAYER_HPP diff --git a/src/gui/src/widgets/video-display-widget.hpp b/src/gui/src/widgets/video-display-widget.hpp index d082e8a2f..b7ef32200 100644 --- a/src/gui/src/widgets/video-display-widget.hpp +++ b/src/gui/src/widgets/video-display-widget.hpp @@ -38,9 +38,13 @@ namespace widgets { VideoDisplayWidget(); /* ===== Overrides ===== */ - protected: + private: virtual void on_realize(); virtual bool on_expose_event(GdkEventExpose* event); + + /* ===== Internals ===== */ + private: + }; } // namespace widgets diff --git a/src/gui/src/window-manager.hpp b/src/gui/src/window-manager.hpp index e2a9af8fa..f41d9945c 100644 --- a/src/gui/src/window-manager.hpp +++ b/src/gui/src/window-manager.hpp @@ -20,7 +20,7 @@ */ /** @file window-manager.hpp - ** This file contains the of global UI Manager class + ** This file contains the defintion of global UI Manager class ** user actions. ** @see window-manager.cpp ** @see gtk-lumiera.hpp From f1fdfdf94abd2b185ada65f01b939af190ed5a10 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 8 May 2008 20:56:55 +0100 Subject: [PATCH 034/245] Added XVideo code --- src/gui/src/Makefile.am | 2 + src/gui/src/output/displayer.cpp | 62 ++-- src/gui/src/output/displayer.hpp | 21 +- src/gui/src/output/xvdisplayer.cpp | 313 ++++++++++--------- src/gui/src/output/xvdisplayer.hpp | 30 +- src/gui/src/widgets/video-display-widget.cpp | 114 +++++-- src/gui/src/widgets/video-display-widget.hpp | 13 + 7 files changed, 340 insertions(+), 215 deletions(-) diff --git a/src/gui/src/Makefile.am b/src/gui/src/Makefile.am index 29e6a6cfb..0bee8fedd 100644 --- a/src/gui/src/Makefile.am +++ b/src/gui/src/Makefile.am @@ -39,6 +39,8 @@ gtk_lumiera_SOURCES = \ widgets/timeline-widget.hpp \ model/project.cpp \ model/project.hpp \ + output/aspectratiocalculator.cpp \ + output/aspectratiocalculator.hpp \ output/displayer.cpp \ output/displayer.hpp \ output/xvdisplayer.cpp \ diff --git a/src/gui/src/output/displayer.cpp b/src/gui/src/output/displayer.cpp index 0570d5a19..359d0aaa3 100644 --- a/src/gui/src/output/displayer.cpp +++ b/src/gui/src/output/displayer.cpp @@ -28,37 +28,45 @@ namespace lumiera { namespace gui { namespace output { +bool +Displayer::usable() +{ + return false; +} +DisplayerInput +Displayer::format() +{ + return DISPLAY_NONE; +} - DisplayerInput Displayer::format() - { - return DISPLAY_NONE; - } - - int Displayer::preferredWidth() - { - return imageWidth; - } - - int Displayer::preferredHeight() - { - return imageHeight; - } - - void Displayer::put( void *image, int width, int height ) - { - if ( width == preferredWidth() && height == preferredHeight() ) - { - put( image ); - } - else - { - reformat( format(), format(), image, width, height ); - put( pixels ); - } - } +int +Displayer::preferredWidth() +{ + return imageWidth; +} +int +Displayer::preferredHeight() +{ + return imageHeight; +} +void +Displayer::CalculateVideoLayout( + int widget_width, int widget_height, + int image_width, int image_height, + int &video_x, int &video_y, int &video_width, int &video_height ) +{ + double ratio_width = ( double ) widget_width / ( double ) image_width; + double ratio_height = ( double ) widget_height / ( double ) image_height; + double ratio_constant = ratio_height < ratio_width ? + ratio_height : ratio_width; + video_width = ( int ) ( image_width * ratio_constant + 0.5 ); + video_height = ( int ) ( image_height * ratio_constant + 0.5 ); + video_x = ( widget_width - video_width ) / 2; + video_y = ( widget_height - video_height ) / 2; +} } // namespace output } // namespace gui diff --git a/src/gui/src/output/displayer.hpp b/src/gui/src/output/displayer.hpp index a04eca784..2d568607e 100644 --- a/src/gui/src/output/displayer.hpp +++ b/src/gui/src/output/displayer.hpp @@ -34,6 +34,9 @@ namespace lumiera { namespace gui { namespace output { +#define MAX_WIDTH 720 +#define MAX_HEIGHT 576 + /** Supported Displayer formats */ @@ -70,6 +73,11 @@ namespace output { { public: + /** Indicates if an object can be used to render images on the running + system. + */ + virtual bool usable(); + /** Indicates the format required by the abstract put method. */ virtual DisplayerInput format(); @@ -86,18 +94,19 @@ namespace output { format (as indicated by the format method). \param image image of correct format and specified width/height - \param width width of image - \param height height of image */ - virtual void put( void *image, int width, int height ); + virtual void put( void * ) = 0; - virtual bool usable(); + protected: + + static void CalculateVideoLayout( + int widget_width, int widget_height, + int image_width, int image_height, + int &video_x, int &video_y, int &video_width, int &video_height ); protected: int imageWidth; int imageHeight; - - virtual void put( void * ) = 0; }; } // namespace output diff --git a/src/gui/src/output/xvdisplayer.cpp b/src/gui/src/output/xvdisplayer.cpp index ac15c86d1..8fe96d03f 100644 --- a/src/gui/src/output/xvdisplayer.cpp +++ b/src/gui/src/output/xvdisplayer.cpp @@ -22,192 +22,211 @@ * *****************************************************/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +using std::cerr; +using std::endl; + #include "xvdisplayer.hpp" namespace lumiera { namespace gui { namespace output { -XvDisplayer::XvDisplayer( GtkWidget *drawingarea, int width, int height, bool isPAL, bool isWidescreen ) : - xvImage( NULL ) +XvDisplayer::XvDisplayer( Gtk::Widget *drawingarea, int width, int height ) : + xvImage( NULL ) { - cerr << ">> Trying XVideo at " << width << "x" << height << endl; + cerr << ">> Trying XVideo at " << width << "x" << height << endl; - this->drawingarea = drawingarea; - img_width = width; - img_height = height; - this->isPAL = isPAL; - this->isWidescreen = isWidescreen; + this->drawingarea = drawingarea; + imageWidth = width; + imageHeight = height; - shmInfo.shmaddr = NULL; - gotPort = false; + shmInfo.shmaddr = NULL; + gotPort = false; - window = GDK_WINDOW_XID( drawingarea->window ); - display = GDK_WINDOW_XDISPLAY( drawingarea->window ); + Glib::RefPtr area_window = drawingarea->get_window(); - unsigned int count; - XvAdaptorInfo *adaptorInfo; + window = gdk_x11_drawable_get_xid( area_window->gobj() ); + display = gdk_x11_drawable_get_xdisplay( area_window->gobj() ); - if ( XvQueryAdaptors( display, window, &count, &adaptorInfo ) == Success ) - { + unsigned int count; + XvAdaptorInfo *adaptorInfo; - cerr << ">>> XvQueryAdaptors count: " << count << endl; - for ( unsigned int n = 0; gotPort == false && n < count; ++n ) - { - // Diagnostics - cerr << ">>> Xv: " << adaptorInfo[ n ].name - << ": ports " << adaptorInfo[ n ].base_id - << " - " << adaptorInfo[ n ].base_id + - adaptorInfo[ n ].num_ports - 1 - << endl; + if ( XvQueryAdaptors( display, window, &count, &adaptorInfo ) == Success ) + { - for ( port = adaptorInfo[ n ].base_id; - port < adaptorInfo[ n ].base_id + adaptorInfo[ n ].num_ports; - port ++ ) - { - if ( XvGrabPort( display, port, CurrentTime ) == 0 ) - { + cerr << ">>> XvQueryAdaptors count: " << count << endl; + for ( unsigned int n = 0; gotPort == false && n < count; ++n ) + { + // Diagnostics + cerr << ">>> Xv: " << adaptorInfo[ n ].name + << ": ports " << adaptorInfo[ n ].base_id + << " - " << adaptorInfo[ n ].base_id + + adaptorInfo[ n ].num_ports - 1 + << endl; - int formats; - XvImageFormatValues *list; + for ( port = adaptorInfo[ n ].base_id; + port < adaptorInfo[ n ].base_id + adaptorInfo[ n ].num_ports; + port ++ ) + { + if ( XvGrabPort( display, port, CurrentTime ) == Success ) + { + g_message("XvGrabPort == 0"); + int formats; + XvImageFormatValues *list; - list = XvListImageFormats( display, port, &formats ); + list = XvListImageFormats( display, port, &formats ); - cerr << ">>> formats supported: " << formats << endl; + cerr << ">>> formats supported: " << formats << endl; - for ( int i = 0; i < formats; i ++ ) - { - fprintf( stderr, ">>> 0x%x (%c%c%c%c) %s\n", - list[ i ].id, - ( list[ i ].id ) & 0xff, - ( list[ i ].id >> 8 ) & 0xff, - ( list[ i ].id >> 16 ) & 0xff, - ( list[ i ].id >> 24 ) & 0xff, - ( list[ i ].format == XvPacked ) ? "packed" : "planar" ); - if ( list[ i ].id == 0x32595559 && !gotPort ) - gotPort = true; - } + for ( int i = 0; i < formats; i ++ ) + { + fprintf( stderr, ">>> 0x%x (%c%c%c%c) %s\n", + list[ i ].id, + ( list[ i ].id ) & 0xff, + ( list[ i ].id >> 8 ) & 0xff, + ( list[ i ].id >> 16 ) & 0xff, + ( list[ i ].id >> 24 ) & 0xff, + ( list[ i ].format == XvPacked ) ? "packed" : "planar" ); + if ( list[ i ].id == 0x32595559 && !gotPort ) + gotPort = true; + } - if ( !gotPort ) - { - XvUngrabPort( display, port, CurrentTime ); - } - else - { - grabbedPort = port; - break; - } - } - } - } + if ( !gotPort ) + { + XvUngrabPort( display, port, CurrentTime ); + } + else + { + grabbedPort = port; + break; + } + } + } + } - if ( gotPort ) - { - int num; - unsigned int unum; - XvEncodingInfo *enc; - - XvQueryEncodings( display, grabbedPort, &unum, &enc ); - for ( unsigned int index = 0; index < unum; index ++ ) - { - fprintf( stderr, ">>> %d: %s, %ldx%ld rate = %d/%d\n", index, enc->name, - enc->width, enc->height, enc->rate.numerator, - enc->rate.denominator ); - } - - XvAttribute *xvattr = XvQueryPortAttributes( display, port, &num ); - for ( int k = 0; k < num; k++ ) - { - if ( xvattr[k].flags & XvSettable ) - { - if ( strcmp( xvattr[k].name, "XV_AUTOPAINT_COLORKEY") == 0 ) - { - Atom val_atom = XInternAtom( display, xvattr[k].name, False ); - if ( XvSetPortAttribute( display, port, val_atom, 1 ) != Success ) - fprintf(stderr, "Couldn't set Xv attribute %s\n", xvattr[k].name); - } - else if ( strcmp( xvattr[k].name, "XV_COLORKEY") == 0 ) - { - Atom val_atom = XInternAtom( display, xvattr[k].name, False ); - if ( XvSetPortAttribute( display, port, val_atom, 0x010102 ) != Success ) - fprintf(stderr, "Couldn't set Xv attribute %s\n", xvattr[k].name); - } - } - } - } + if ( gotPort ) + { + int num; + unsigned int unum; + XvEncodingInfo *enc; + + XvQueryEncodings( display, grabbedPort, &unum, &enc ); + for ( unsigned int index = 0; index < unum; index ++ ) + { + fprintf( stderr, ">>> %d: %s, %ldx%ld rate = %d/%d\n", index, enc->name, + enc->width, enc->height, enc->rate.numerator, + enc->rate.denominator ); + } + + XvAttribute *xvattr = XvQueryPortAttributes( display, port, &num ); + for ( int k = 0; k < num; k++ ) + { + if ( xvattr[k].flags & XvSettable ) + { + if ( strcmp( xvattr[k].name, "XV_AUTOPAINT_COLORKEY") == 0 ) + { + Atom val_atom = XInternAtom( display, xvattr[k].name, False ); + if ( XvSetPortAttribute( display, port, val_atom, 1 ) != Success ) + fprintf(stderr, "Couldn't set Xv attribute %s\n", xvattr[k].name); + } + else if ( strcmp( xvattr[k].name, "XV_COLORKEY") == 0 ) + { + Atom val_atom = XInternAtom( display, xvattr[k].name, False ); + if ( XvSetPortAttribute( display, port, val_atom, 0x010102 ) != Success ) + fprintf(stderr, "Couldn't set Xv attribute %s\n", xvattr[k].name); + } + } + } + } - if ( gotPort ) - { - gc = XCreateGC( display, window, 0, &values ); + if ( gotPort ) + { + gc = XCreateGC( display, window, 0, &values ); - xvImage = ( XvImage * ) XvShmCreateImage( display, port, 0x32595559, 0, width, height, &shmInfo ); + xvImage = ( XvImage * ) XvShmCreateImage( display, port, 0x32595559, 0, width, height, &shmInfo ); - shmInfo.shmid = shmget( IPC_PRIVATE, xvImage->data_size, IPC_CREAT | 0777 ); - if (shmInfo.shmid < 0) { - perror("shmget"); - gotPort = false; - } else { - shmInfo.shmaddr = ( char * ) shmat( shmInfo.shmid, 0, 0 ); - xvImage->data = shmInfo.shmaddr; - shmInfo.readOnly = 0; - if ( !XShmAttach( gdk_display, &shmInfo ) ) - { - gotPort = false; - } - XSync( display, false ); - shmctl( shmInfo.shmid, IPC_RMID, 0 ); + shmInfo.shmid = shmget( IPC_PRIVATE, xvImage->data_size, IPC_CREAT | 0777 ); + if (shmInfo.shmid < 0) { + perror("shmget"); + gotPort = false; + } else { + shmInfo.shmaddr = ( char * ) shmat( shmInfo.shmid, 0, 0 ); + xvImage->data = shmInfo.shmaddr; + shmInfo.readOnly = 0; + if ( !XShmAttach( gdk_display, &shmInfo ) ) + { + gotPort = false; + } + XSync( display, false ); + shmctl( shmInfo.shmid, IPC_RMID, 0 ); #if 0 - xvImage = ( XvImage * ) XvCreateImage( display, port, 0x32595559, pix, width , height ); + xvImage = ( XvImage * ) XvCreateImage( display, port, 0x32595559, pix, width , height ); #endif - } - } - } - else - { - gotPort = false; - } + } + } + } + else + { + gotPort = false; + } } XvDisplayer::~XvDisplayer() { - cerr << ">> Destroying XV Displayer" << endl; + cerr << ">> Destroying XV Displayer" << endl; - if ( gotPort ) - { - XvUngrabPort( display, grabbedPort, CurrentTime ); - } + if ( gotPort ) + { + XvUngrabPort( display, grabbedPort, CurrentTime ); + } - if ( xvImage != NULL ) - XvStopVideo( display, port, window ); + if ( xvImage != NULL ) + XvStopVideo( display, port, window ); - if ( shmInfo.shmaddr != NULL ) - { - XShmDetach( display, &shmInfo ); - shmctl( shmInfo.shmid, IPC_RMID, 0 ); - shmdt( shmInfo.shmaddr ); - } - if ( xvImage != NULL ) - XFree( xvImage ); + if ( shmInfo.shmaddr != NULL ) + { + XShmDetach( display, &shmInfo ); + shmctl( shmInfo.shmid, IPC_RMID, 0 ); + shmdt( shmInfo.shmaddr ); + } + if ( xvImage != NULL ) + XFree( xvImage ); } -bool XvDisplayer::usable() +bool +XvDisplayer::usable() { - return gotPort; + return gotPort; } - void XvDisplayer::put( void *image ) - { - AspectRatioCalculator calc( ( ( GtkWidget * ) drawingarea ) ->allocation.width, - ( ( GtkWidget * ) drawingarea ) ->allocation.height, - this->preferredWidth(), this->preferredHeight(), - isPAL, isWidescreen ); +void +XvDisplayer::put( void *image ) +{ + g_assert(drawingarea != NULL); - memcpy( xvImage->data, image, xvImage->data_size ); + if(xvImage != NULL) + { + int video_x = 0, video_y = 0, video_width = 0, video_height = 0; + CalculateVideoLayout( + drawingarea->get_width(), + drawingarea->get_height(), + preferredWidth(), preferredHeight(), + video_x, video_y, video_width, video_height ); - XvShmPutImage( display, port, window, gc, xvImage, - 0, 0, this->preferredWidth(), this->preferredHeight(), - calc.x, calc.y, calc.width, calc.height, false ); - } + memcpy( xvImage->data, image, xvImage->data_size ); + + XvShmPutImage( display, port, window, gc, xvImage, + 0, 0, preferredWidth(), preferredHeight(), + video_x, video_y, video_width, video_height, false ); + } +} } // namespace output } // namespace gui diff --git a/src/gui/src/output/xvdisplayer.hpp b/src/gui/src/output/xvdisplayer.hpp index 77cd27459..6c64609bc 100644 --- a/src/gui/src/output/xvdisplayer.hpp +++ b/src/gui/src/output/xvdisplayer.hpp @@ -27,38 +27,48 @@ ** @see xvdisplayer.cpp */ -#include "displayer.hpp" - +#include +#include +#include #include #include -#include + +#include "displayer.hpp" #ifndef XVDISPLAYER_HPP #define XVDISPLAYER_HPP +namespace Gtk { + class Widget; +} + namespace lumiera { namespace gui { namespace output { - class XvDisplayer + class XvDisplayer : public Displayer { public: - XvDisplayer(); + XvDisplayer( Gtk::Widget *drawingarea, int width, int height ); ~XvDisplayer(); + + void put( void *image ); protected: - void put( void *image ); + bool usable(); private: - bool canuse; - int depth; - GtkWidget *drawingarea; + bool gotPort; + int grabbedPort; + Gtk::Widget *drawingarea; Display *display; Window window; GC gc; - XImage *xImage; XGCValues values; + XvImage *xvImage; + unsigned int port; XShmSegmentInfo shmInfo; + char pix[ MAX_WIDTH * MAX_HEIGHT * 4 ]; }; } // namespace output diff --git a/src/gui/src/widgets/video-display-widget.cpp b/src/gui/src/widgets/video-display-widget.cpp index 16b089c5b..2969f0aec 100644 --- a/src/gui/src/widgets/video-display-widget.cpp +++ b/src/gui/src/widgets/video-display-widget.cpp @@ -30,42 +30,106 @@ namespace lumiera { namespace gui { namespace widgets { -VideoDisplayWidget::VideoDisplayWidget() - { - set_flags(Gtk::NO_WINDOW); - } +VideoDisplayWidget::VideoDisplayWidget() : + gdkWindow(NULL), + xvDisplayer(NULL) +{ + set_flags(Gtk::NO_WINDOW); +} + +VideoDisplayWidget::~VideoDisplayWidget() +{ + if(xvDisplayer != NULL) + delete xvDisplayer; +} void VideoDisplayWidget::on_realize() - { - //Call base class: - Gtk::Widget::on_realize(); +{ + //Call base class: + Gtk::Widget::on_realize(); + if(!gdkWindow) + { + //Create the GdkWindow: + + GdkWindowAttr attributes; + memset(&attributes, 0, sizeof(attributes)); + + Gtk::Allocation allocation = get_allocation(); + + //Set initial position and size of the Gdk::Window: + attributes.x = allocation.get_x(); + attributes.y = allocation.get_y(); + attributes.width = allocation.get_width(); + attributes.height = allocation.get_height(); + + attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + + gdkWindow = Gdk::Window::create(get_window() /* parent */, &attributes, + GDK_WA_X | GDK_WA_Y); + unset_flags(Gtk::NO_WINDOW); + set_window(gdkWindow); + + //set colors + modify_bg(Gtk::STATE_NORMAL , Gdk::Color("black")); + + //make the widget receive expose events + gdkWindow->set_user_data(gobj()); } + xvDisplayer = new XvDisplayer(this, 320, 240 ); + + add_events(Gdk::ALL_EVENTS_MASK); +} + +void +VideoDisplayWidget::on_unrealize() +{ + gdkWindow.clear(); + + //Call base class: + Gtk::Widget::on_unrealize(); +} + +bool +VideoDisplayWidget::on_button_press_event (GdkEventButton* event) +{ + unsigned char buffer[320 * 240 * 4]; + + for(int i = 0; i < 320*240*4; i++) + buffer[i] = rand(); + + xvDisplayer->put((void*)buffer); + + return true; +} + bool VideoDisplayWidget::on_expose_event(GdkEventExpose* event) +{ + // This is where we draw on the window + /*Glib::RefPtr window = get_window(); + if(window) { - // This is where we draw on the window - Glib::RefPtr window = get_window(); - if(window) + Cairo::RefPtr cr = window->create_cairo_context(); + if(event) { - Cairo::RefPtr cr = window->create_cairo_context(); - if(event) - { - // clip to the area that needs to be re-exposed so we don't draw any - // more than we need to. - cr->rectangle(event->area.x, event->area.y, - event->area.width, event->area.height); - cr->clip(); - } - - // Paint the background - cr->set_source_rgb(0.0, 0.0, 0.0); - cr->paint(); + // clip to the area that needs to be re-exposed so we don't draw any + // more than we need to. + cr->rectangle(event->area.x, event->area.y, + event->area.width, event->area.height); + cr->clip(); } - return true; - } + + // Paint the background + cr->set_source_rgb(0.0, 0.0, 0.0); + cr->paint(); + }*/ + return true; +} } // namespace widgets } // namespace gui diff --git a/src/gui/src/widgets/video-display-widget.hpp b/src/gui/src/widgets/video-display-widget.hpp index b7ef32200..b883426ec 100644 --- a/src/gui/src/widgets/video-display-widget.hpp +++ b/src/gui/src/widgets/video-display-widget.hpp @@ -28,6 +28,10 @@ #include +#include "../output/xvdisplayer.hpp" + +using namespace lumiera::gui::output; + namespace lumiera { namespace gui { namespace widgets { @@ -37,14 +41,23 @@ namespace widgets { public: VideoDisplayWidget(); + ~VideoDisplayWidget(); + /* ===== Overrides ===== */ private: virtual void on_realize(); + + virtual void on_unrealize(); + virtual bool on_expose_event(GdkEventExpose* event); +virtual bool on_button_press_event (GdkEventButton* event); + /* ===== Internals ===== */ private: + Glib::RefPtr gdkWindow; + XvDisplayer *xvDisplayer; }; } // namespace widgets From b8c94df12afb439f58a52f4f6c71d19dbba3a47c Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 8 May 2008 23:09:04 +0100 Subject: [PATCH 035/245] Further XVideo tidy ups --- src/gui/src/Makefile.am | 2 -- src/gui/src/output/xvdisplayer.cpp | 12 ++++++------ src/gui/src/output/xvdisplayer.hpp | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/gui/src/Makefile.am b/src/gui/src/Makefile.am index 0bee8fedd..29e6a6cfb 100644 --- a/src/gui/src/Makefile.am +++ b/src/gui/src/Makefile.am @@ -39,8 +39,6 @@ gtk_lumiera_SOURCES = \ widgets/timeline-widget.hpp \ model/project.cpp \ model/project.hpp \ - output/aspectratiocalculator.cpp \ - output/aspectratiocalculator.hpp \ output/displayer.cpp \ output/displayer.hpp \ output/xvdisplayer.cpp \ diff --git a/src/gui/src/output/xvdisplayer.cpp b/src/gui/src/output/xvdisplayer.cpp index 8fe96d03f..0ed73b7b0 100644 --- a/src/gui/src/output/xvdisplayer.cpp +++ b/src/gui/src/output/xvdisplayer.cpp @@ -38,19 +38,19 @@ namespace lumiera { namespace gui { namespace output { -XvDisplayer::XvDisplayer( Gtk::Widget *drawingarea, int width, int height ) : +XvDisplayer::XvDisplayer( Gtk::Widget *drawing_area, int width, int height ) : xvImage( NULL ) { cerr << ">> Trying XVideo at " << width << "x" << height << endl; - this->drawingarea = drawingarea; + this->drawingArea = drawing_area; imageWidth = width; imageHeight = height; shmInfo.shmaddr = NULL; gotPort = false; - Glib::RefPtr area_window = drawingarea->get_window(); + Glib::RefPtr area_window = drawing_area->get_window(); window = gdk_x11_drawable_get_xid( area_window->gobj() ); display = gdk_x11_drawable_get_xdisplay( area_window->gobj() ); @@ -209,14 +209,14 @@ XvDisplayer::usable() void XvDisplayer::put( void *image ) { - g_assert(drawingarea != NULL); + g_assert(drawingArea != NULL); if(xvImage != NULL) { int video_x = 0, video_y = 0, video_width = 0, video_height = 0; CalculateVideoLayout( - drawingarea->get_width(), - drawingarea->get_height(), + drawingArea->get_width(), + drawingArea->get_height(), preferredWidth(), preferredHeight(), video_x, video_y, video_width, video_height ); diff --git a/src/gui/src/output/xvdisplayer.hpp b/src/gui/src/output/xvdisplayer.hpp index 6c64609bc..6daf614cf 100644 --- a/src/gui/src/output/xvdisplayer.hpp +++ b/src/gui/src/output/xvdisplayer.hpp @@ -49,7 +49,7 @@ namespace output { class XvDisplayer : public Displayer { public: - XvDisplayer( Gtk::Widget *drawingarea, int width, int height ); + XvDisplayer( Gtk::Widget *drawing_area, int width, int height ); ~XvDisplayer(); void put( void *image ); @@ -60,7 +60,7 @@ namespace output { private: bool gotPort; int grabbedPort; - Gtk::Widget *drawingarea; + Gtk::Widget *drawingArea; Display *display; Window window; GC gc; From 67413c7c17ce10b36255a857daee3c0318257777 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 8 May 2008 23:34:28 +0100 Subject: [PATCH 036/245] Made a temporary fix for the crash-on-undock bug --- src/gui/src/output/xvdisplayer.cpp | 5 +- src/gui/src/widgets/video-display-widget.cpp | 48 ++++++++++---------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/gui/src/output/xvdisplayer.cpp b/src/gui/src/output/xvdisplayer.cpp index 0ed73b7b0..5ca9d8c63 100644 --- a/src/gui/src/output/xvdisplayer.cpp +++ b/src/gui/src/output/xvdisplayer.cpp @@ -187,8 +187,8 @@ XvDisplayer::~XvDisplayer() XvUngrabPort( display, grabbedPort, CurrentTime ); } - if ( xvImage != NULL ) - XvStopVideo( display, port, window ); + //if ( xvImage != NULL ) + // XvStopVideo( display, port, window ); if ( shmInfo.shmaddr != NULL ) { @@ -196,6 +196,7 @@ XvDisplayer::~XvDisplayer() shmctl( shmInfo.shmid, IPC_RMID, 0 ); shmdt( shmInfo.shmaddr ); } + if ( xvImage != NULL ) XFree( xvImage ); } diff --git a/src/gui/src/widgets/video-display-widget.cpp b/src/gui/src/widgets/video-display-widget.cpp index 2969f0aec..6ec626e9d 100644 --- a/src/gui/src/widgets/video-display-widget.cpp +++ b/src/gui/src/widgets/video-display-widget.cpp @@ -46,40 +46,40 @@ VideoDisplayWidget::~VideoDisplayWidget() void VideoDisplayWidget::on_realize() { + set_flags(Gtk::NO_WINDOW); + //Call base class: Gtk::Widget::on_realize(); - if(!gdkWindow) - { - //Create the GdkWindow: + //Create the GdkWindow: + GdkWindowAttr attributes; + memset(&attributes, 0, sizeof(attributes)); - GdkWindowAttr attributes; - memset(&attributes, 0, sizeof(attributes)); + Gtk::Allocation allocation = get_allocation(); - Gtk::Allocation allocation = get_allocation(); + //Set initial position and size of the Gdk::Window: + attributes.x = allocation.get_x(); + attributes.y = allocation.get_y(); + attributes.width = allocation.get_width(); + attributes.height = allocation.get_height(); - //Set initial position and size of the Gdk::Window: - attributes.x = allocation.get_x(); - attributes.y = allocation.get_y(); - attributes.width = allocation.get_width(); - attributes.height = allocation.get_height(); + attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; - attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; + gdkWindow = Gdk::Window::create(get_window() /* parent */, &attributes, + GDK_WA_X | GDK_WA_Y); + unset_flags(Gtk::NO_WINDOW); + set_window(gdkWindow); - gdkWindow = Gdk::Window::create(get_window() /* parent */, &attributes, - GDK_WA_X | GDK_WA_Y); - unset_flags(Gtk::NO_WINDOW); - set_window(gdkWindow); + //set colors + modify_bg(Gtk::STATE_NORMAL , Gdk::Color("black")); - //set colors - modify_bg(Gtk::STATE_NORMAL , Gdk::Color("black")); - - //make the widget receive expose events - gdkWindow->set_user_data(gobj()); - } + //make the widget receive expose events + gdkWindow->set_user_data(gobj()); + if(xvDisplayer != NULL) + delete xvDisplayer; xvDisplayer = new XvDisplayer(this, 320, 240 ); add_events(Gdk::ALL_EVENTS_MASK); From 85b0029166097ccf2317c13746ad813dfad11007 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 11 May 2008 15:44:24 +0200 Subject: [PATCH 037/245] WIP: how to get at the actual wrapper (here Placement) from within BuilderTool. Nasty problem ... draft solution using boost::variant. To be reconsidered later... --- .../proc/mobject/builder/buildertooltest.cpp | 130 +++++++++++++++--- 1 file changed, 110 insertions(+), 20 deletions(-) diff --git a/tests/components/proc/mobject/builder/buildertooltest.cpp b/tests/components/proc/mobject/builder/buildertooltest.cpp index 995325025..f9adc1308 100644 --- a/tests/components/proc/mobject/builder/buildertooltest.cpp +++ b/tests/components/proc/mobject/builder/buildertooltest.cpp @@ -27,9 +27,12 @@ #include "proc/asset/media.hpp" #include "proc/mobject/session/clip.hpp" +#include "proc/asset.hpp" +#include "common/p.hpp" +#include "proc/mobject/placement.hpp" #include "proc/mobject/explicitplacement.hpp" //////////TODO -#include +#include #include using std::string; using std::cout; @@ -37,6 +40,10 @@ using std::cout; namespace mobject { + + DEFINE_SPECIALIZED_PLACEMENT (session::AbstractMO); + + namespace builder { namespace test @@ -46,8 +53,8 @@ namespace mobject using session::AbstractMO; /////////////////////////////////////////////////////TODO: move to buildertool.hpp - using boost::any; - using boost::any_cast; + + using lumiera::P; // Problem /* @@ -58,29 +65,106 @@ namespace mobject - vieleicht einen allgemeinen Argument-Adapter nutzen? - Zielobjekt oder Wrapper als Argumenttyp? */ + struct Nothing {}; + /** + * helper to treat various sorts of smart-ptrs uniformly. + * Implemented as a variant-type value object, it is preconfigured + * with the possible hierarchy-base classes used within this application. + * Thus, when passing in an arbitrary smart-ptr, the best fitting smart-ptr + * type pointing to the corresponding base class is selected for internal storage. + * Later on, stored values can be retrieved either utilitzing static or dynamic casts; + * error reporting is similar to the bahaviour of dynamic_cast: when retrieving + * a pointer, in case of mismatch NULL is returned. + */ + class WrapperPtr // NONCOPYABLE!! + { + + template + struct accessor; + + template class WRA, class TAR> + struct accessor< WRA > + : public boost::static_visitor*> + { + template WRA* operator() (X&) { return 0; } + template WRA* operator() (WRA& stored) { return static_cast*> (stored); } + }; + + + private: + /** storage: buffer holding either and "empty" marker, + * or one of the configured pointer to wrapper types */ + boost::variant*, P*> holder_; + + public: + void reset () { holder_ = Nothing(); } + + template + WrapperPtr& + operator= (WRA* src) ///< store a ptr to the given wrapper, after casting to base + { + if (src) holder_ = src; + else holder_ = Nothing(); + return *this; + } + + template + WRA* + get () ///< retrieve ptr and try to downcast to type WRA + { + accessor acc; + WRA* res = boost::apply_visitor(acc, this->holder_); + return res; + } + }; + + class BuTuul : public lumiera::visitor::Tool { - any currentArgument_; + WrapperPtr currentWrapper_; public: - void rememberWrapper (any argument) + template class WRA, class TAR> + void rememberWrapper (WRA* argument) { - currentArgument_ = argument; + currentWrapper_ = argument; } - template - WRA& getCurrentArgumentWrapper () + void forgetWrapper () { - WRA* argument = any_cast (currentArgument_); - ASSERT (argument); - return *argument; + currentWrapper_.reset(); + } + + + template + Placement& + getPlacement () + { + Placement* pPlacement = currentWrapper_.get >(); + return *pPlacement; + } + ExplicitPlacement + getExplicitPlacement () + { + return getPlacement().resolve(); + } + template + P + getPtr () + { + P* pP = currentWrapper_.get >(); + return *pP; } }; + + + + template @@ -107,7 +191,7 @@ namespace mobject virtual bool isValid() const { return true;} // DEFINE_PROCESSABLE_BY (BuilderTool); - static void killDummy (AbstractMO* dum) { delete (DummyMO*)dum; } + static void killDummy (MObject* dum) { delete (DummyMO*)dum; } virtual void apply (BuTuul& tool) @@ -129,12 +213,15 @@ namespace mobject }; - template + template inline BDable::ReturnType - apply (BuTuul& tool, TAR& wrappedTargetObj) + apply (BuTuul& tool, WRA& wrappedTargetObj) { - tool.rememberWrapper(any (&wrappedTargetObj)); + WRA* ptr = &wrappedTargetObj; + (*ptr)->isValid(); + tool.rememberWrapper(ptr); wrappedTargetObj->apply (tool); + tool.forgetWrapper(); } //////////////////////////////////////////////////////TODO: wip-wip @@ -156,12 +243,12 @@ namespace mobject public: void treat (Clip& c) { - Placement& pC = getCurrentArgumentWrapper >(); + Placement& pC = getPlacement(); cout << "media is: "<< str(pC->getMedia()) <<"\n"; } void treat (AbstractMO&) { - Placement& placement = getCurrentArgumentWrapper(); + Placement& placement = getPlacement(); cout << "unspecific MO; Placement(adr) " << &placement <<"\n"; } void onUnknown (Buildable&) @@ -199,11 +286,14 @@ namespace mobject BuTuul& tool (t1); DummyPlacement dumm; + Placement& dummy(dumm); + Placement clip = asset::Media::create("test-1", asset::VIDEO)->createClip(); + apply (tool, clip); cout << "Placement(adr) " << &dumm <<"\n"; - apply (tool, dumm); + apply (tool, dummy); } }; @@ -218,13 +308,13 @@ namespace mobject } // namespace builder //////////////////////////////////////////////////////TODO: wip-wip - template<> +/* template<> ExplicitPlacement Placement::resolve () const { UNIMPLEMENTED ("just a test"); } - //////////////////////////////////////////////////////TODO: wip-wip +*/ //////////////////////////////////////////////////////TODO: wip-wip } // namespace mobject From f72dab3257c506fea5dc10ae0a6cc7e441bcf17c Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 12 May 2008 13:02:14 +0100 Subject: [PATCH 038/245] Added support for video via a GDK fallback --- src/gui/src/Makefile.am | 2 + src/gui/src/output/displayer.cpp | 22 +++--- src/gui/src/output/displayer.hpp | 2 +- src/gui/src/output/gdkdisplayer.cpp | 76 ++++++++++++++++++++ src/gui/src/output/gdkdisplayer.hpp | 62 ++++++++++++++++ src/gui/src/output/xvdisplayer.cpp | 13 ++-- src/gui/src/output/xvdisplayer.hpp | 3 +- src/gui/src/widgets/video-display-widget.cpp | 37 ++++++++-- src/gui/src/widgets/video-display-widget.hpp | 10 ++- 9 files changed, 198 insertions(+), 29 deletions(-) create mode 100644 src/gui/src/output/gdkdisplayer.cpp create mode 100644 src/gui/src/output/gdkdisplayer.hpp diff --git a/src/gui/src/Makefile.am b/src/gui/src/Makefile.am index 29e6a6cfb..455dcdd60 100644 --- a/src/gui/src/Makefile.am +++ b/src/gui/src/Makefile.am @@ -41,6 +41,8 @@ gtk_lumiera_SOURCES = \ model/project.hpp \ output/displayer.cpp \ output/displayer.hpp \ + output/gdkdisplayer.cpp \ + output/gdkdisplayer.hpp \ output/xvdisplayer.cpp \ output/xvdisplayer.hpp diff --git a/src/gui/src/output/displayer.cpp b/src/gui/src/output/displayer.cpp index 359d0aaa3..567bc8748 100644 --- a/src/gui/src/output/displayer.cpp +++ b/src/gui/src/output/displayer.cpp @@ -23,6 +23,8 @@ * *****************************************************/ #include "displayer.hpp" +#include "xvdisplayer.hpp" +#include "gdkdisplayer.hpp" namespace lumiera { namespace gui { @@ -31,7 +33,7 @@ namespace output { bool Displayer::usable() { - return false; + return false; } DisplayerInput @@ -53,19 +55,19 @@ Displayer::preferredHeight() } void -Displayer::CalculateVideoLayout( +Displayer::calculateVideoLayout( int widget_width, int widget_height, int image_width, int image_height, int &video_x, int &video_y, int &video_width, int &video_height ) { - double ratio_width = ( double ) widget_width / ( double ) image_width; - double ratio_height = ( double ) widget_height / ( double ) image_height; - double ratio_constant = ratio_height < ratio_width ? - ratio_height : ratio_width; - video_width = ( int ) ( image_width * ratio_constant + 0.5 ); - video_height = ( int ) ( image_height * ratio_constant + 0.5 ); - video_x = ( widget_width - video_width ) / 2; - video_y = ( widget_height - video_height ) / 2; + double ratio_width = ( double ) widget_width / ( double ) image_width; + double ratio_height = ( double ) widget_height / ( double ) image_height; + double ratio_constant = ratio_height < ratio_width ? + ratio_height : ratio_width; + video_width = ( int ) ( image_width * ratio_constant + 0.5 ); + video_height = ( int ) ( image_height * ratio_constant + 0.5 ); + video_x = ( widget_width - video_width ) / 2; + video_y = ( widget_height - video_height ) / 2; } } // namespace output diff --git a/src/gui/src/output/displayer.hpp b/src/gui/src/output/displayer.hpp index 2d568607e..c117d5cb9 100644 --- a/src/gui/src/output/displayer.hpp +++ b/src/gui/src/output/displayer.hpp @@ -99,7 +99,7 @@ namespace output { protected: - static void CalculateVideoLayout( + static void calculateVideoLayout( int widget_width, int widget_height, int image_width, int image_height, int &video_x, int &video_y, int &video_width, int &video_height ); diff --git a/src/gui/src/output/gdkdisplayer.cpp b/src/gui/src/output/gdkdisplayer.cpp new file mode 100644 index 000000000..262d28d5b --- /dev/null +++ b/src/gui/src/output/gdkdisplayer.cpp @@ -0,0 +1,76 @@ +/* + gdkdisplayer.cpp - Implements the class for displaying video via GDK + + Copyright (C) Lumiera.org + 2000, Arne Schirmacher + 2001-2007, Dan Dennedy + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +using std::cerr; +using std::endl; + +#include "gdkdisplayer.hpp" + +namespace lumiera { +namespace gui { +namespace output { + +GdkDisplayer::GdkDisplayer( Gtk::Widget *drawing_area, int width, int height ) : + drawingArea( drawing_area ) +{ + imageWidth = width, imageHeight = height; +} + +bool +GdkDisplayer::usable() +{ + return true; +} + +void +GdkDisplayer::put( void *image ) +{ + int video_x = 0, video_y = 0, video_width = 0, video_height = 0; + calculateVideoLayout( + drawingArea->get_width(), + drawingArea->get_height(), + preferredWidth(), preferredHeight(), + video_x, video_y, video_width, video_height ); + + GdkWindow *window = drawingArea->get_window()->gobj(); + GdkGC *gc = gdk_gc_new( window ); + GdkPixbuf *pix = gdk_pixbuf_new_from_data( (const guchar*)image, GDK_COLORSPACE_RGB, FALSE, 8, + preferredWidth(), preferredHeight(), preferredWidth() * 3, NULL, NULL ); + GdkPixbuf *im = gdk_pixbuf_scale_simple( pix, video_width, video_height, GDK_INTERP_NEAREST ); + gdk_draw_pixbuf( window, gc, im, 0, 0, video_x, video_y, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0 ); + g_object_unref( im ); + g_object_unref( pix ); + g_object_unref( gc ); +} + +} // namespace output +} // namespace gui +} // namespace lumiera diff --git a/src/gui/src/output/gdkdisplayer.hpp b/src/gui/src/output/gdkdisplayer.hpp new file mode 100644 index 000000000..7e72fa24e --- /dev/null +++ b/src/gui/src/output/gdkdisplayer.hpp @@ -0,0 +1,62 @@ +/* + gdkdisplayer.hpp - Defines the class for displaying video via GDK + + Copyright (C) Lumiera.org + 2000, Arne Schirmacher + 2001-2007, Dan Dennedy + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file gdkdisplayer.hpp + ** This file contains the definition of XvDisplayer, the XVideo + ** video output implementation + ** @see gdkdisplayer.cpp + ** @see displayer.hpp + */ + +#include "displayer.hpp" + +#ifndef GDKDISPLAYER_HPP +#define GDKDISPLAYER_HPP + +namespace Gtk { + class Widget; +} + +namespace lumiera { +namespace gui { +namespace output { + + class GdkDisplayer : public Displayer + { + public: + GdkDisplayer( Gtk::Widget *drawing_area, int width, int height ); + + void put( void *image ); + + protected: + bool usable(); + + private: + Gtk::Widget *drawingArea; + }; + +} // namespace output +} // namespace gui +} // namespace lumiera + +#endif // GDKDISPLAYER_HPP diff --git a/src/gui/src/output/xvdisplayer.cpp b/src/gui/src/output/xvdisplayer.cpp index 5ca9d8c63..428decc62 100644 --- a/src/gui/src/output/xvdisplayer.cpp +++ b/src/gui/src/output/xvdisplayer.cpp @@ -1,5 +1,5 @@ /* - displayer.cpp - Implements the base class for displaying video + xvdisplayer.cpp - Implements the base class for XVideo display Copyright (C) Lumiera.org 2000, Arne Schirmacher @@ -39,16 +39,15 @@ namespace gui { namespace output { XvDisplayer::XvDisplayer( Gtk::Widget *drawing_area, int width, int height ) : - xvImage( NULL ) + xvImage( NULL ), + drawingArea( drawing_area ), + gotPort( false ) { cerr << ">> Trying XVideo at " << width << "x" << height << endl; - this->drawingArea = drawing_area; - imageWidth = width; - imageHeight = height; + imageWidth = width, imageHeight = height; shmInfo.shmaddr = NULL; - gotPort = false; Glib::RefPtr area_window = drawing_area->get_window(); @@ -215,7 +214,7 @@ XvDisplayer::put( void *image ) if(xvImage != NULL) { int video_x = 0, video_y = 0, video_width = 0, video_height = 0; - CalculateVideoLayout( + calculateVideoLayout( drawingArea->get_width(), drawingArea->get_height(), preferredWidth(), preferredHeight(), diff --git a/src/gui/src/output/xvdisplayer.hpp b/src/gui/src/output/xvdisplayer.hpp index 6daf614cf..aae4e0281 100644 --- a/src/gui/src/output/xvdisplayer.hpp +++ b/src/gui/src/output/xvdisplayer.hpp @@ -1,5 +1,5 @@ /* - xcdisplayer.hpp - Defines the base class for XVideo display + xvdisplayer.hpp - Defines the base class for XVideo display Copyright (C) Lumiera.org 2000, Arne Schirmacher @@ -25,6 +25,7 @@ ** This file contains the definition of XvDisplayer, the XVideo ** video output implementation ** @see xvdisplayer.cpp + ** @see displayer.hpp */ #include diff --git a/src/gui/src/widgets/video-display-widget.cpp b/src/gui/src/widgets/video-display-widget.cpp index 6ec626e9d..87fff7ecd 100644 --- a/src/gui/src/widgets/video-display-widget.cpp +++ b/src/gui/src/widgets/video-display-widget.cpp @@ -24,6 +24,9 @@ #include #include +#include "../output/xvdisplayer.hpp" +#include "../output/gdkdisplayer.hpp" + #include "video-display-widget.hpp" namespace lumiera { @@ -32,15 +35,15 @@ namespace widgets { VideoDisplayWidget::VideoDisplayWidget() : gdkWindow(NULL), - xvDisplayer(NULL) + displayer(NULL) { set_flags(Gtk::NO_WINDOW); } VideoDisplayWidget::~VideoDisplayWidget() { - if(xvDisplayer != NULL) - delete xvDisplayer; + if(displayer != NULL) + delete displayer; } void @@ -78,9 +81,9 @@ VideoDisplayWidget::on_realize() //make the widget receive expose events gdkWindow->set_user_data(gobj()); - if(xvDisplayer != NULL) - delete xvDisplayer; - xvDisplayer = new XvDisplayer(this, 320, 240 ); + if(displayer != NULL) + delete displayer; + displayer = createDisplayer(this, 320, 240); add_events(Gdk::ALL_EVENTS_MASK); } @@ -102,7 +105,7 @@ VideoDisplayWidget::on_button_press_event (GdkEventButton* event) for(int i = 0; i < 320*240*4; i++) buffer[i] = rand(); - xvDisplayer->put((void*)buffer); + displayer->put((void*)buffer); return true; } @@ -131,6 +134,26 @@ VideoDisplayWidget::on_expose_event(GdkEventExpose* event) return true; } +Displayer* +VideoDisplayWidget::createDisplayer( Gtk::Widget *drawingArea, int width, int height ) +{ + Displayer *displayer = NULL; + + displayer = new XvDisplayer( drawingArea, width, height ); + if ( !displayer->usable() ) + { + delete displayer; + displayer = NULL; + } + + if ( displayer == NULL ) + { + displayer = new GdkDisplayer( drawingArea, width, height ); + } + + return displayer; +} + } // namespace widgets } // namespace gui } // namespace lumiera diff --git a/src/gui/src/widgets/video-display-widget.hpp b/src/gui/src/widgets/video-display-widget.hpp index b883426ec..7a80a4b04 100644 --- a/src/gui/src/widgets/video-display-widget.hpp +++ b/src/gui/src/widgets/video-display-widget.hpp @@ -28,7 +28,7 @@ #include -#include "../output/xvdisplayer.hpp" +#include "../output/displayer.hpp" using namespace lumiera::gui::output; @@ -51,13 +51,17 @@ namespace widgets { virtual bool on_expose_event(GdkEventExpose* event); -virtual bool on_button_press_event (GdkEventButton* event); + virtual bool on_button_press_event (GdkEventButton* event); /* ===== Internals ===== */ + private: + static Displayer* + createDisplayer( Gtk::Widget *drawingArea, int width, int height ); + private: Glib::RefPtr gdkWindow; - XvDisplayer *xvDisplayer; + Displayer *displayer; }; } // namespace widgets From ed2146dae069aec4c4c0b1403b1e5f13cdcf19ba Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Tue, 13 May 2008 17:33:18 +0100 Subject: [PATCH 039/245] Added the icon which will be used for the video viewer panel's caption --- src/gui/icons/viewer-panel.png | Bin 0 -> 631 bytes src/gui/src/widgets/video-display-widget.cpp | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/gui/icons/viewer-panel.png diff --git a/src/gui/icons/viewer-panel.png b/src/gui/icons/viewer-panel.png new file mode 100644 index 0000000000000000000000000000000000000000..a73a169ac5130a02303b025b4b4fc957f6da4602 GIT binary patch literal 631 zcmV--0*L*IP)Mh53JODVWnpw>WFU8GbZ8({Xk{Qr zNlj3Y*^6%g00F~EL_t(I%cYV*YZFlr$A51(OE!uLO)CiM!JbSJKR}B$UbG6i=*hcc z5O22P7Z5}cJ&5+My=uIqYY*bV#IvU!g6PS#8WNM;u=_Uq@;oHFR2rqkfnj)m-v2iY zGveW+2QPp!)5UrUD6d>znab^KI^|USc>b(Py|#S-n`Uuof!lYk0FVIcwQWkJB1(bQ zn&D7mn#M##wfbQ{06?ix6+&Q|BGFwpKuU#DLs~8W4_Ina2hWrEzM|ic2t$Ps0uUI6 zz_v6026Ve2?RGRaS=hFf0OI;rK&uro7#L(Sb}~v_4P!540$_2eK)v?yKFj>M z>e@B*nnvqUqCtid4Ol5_q%+c!KV!hUv*}EIiSa-gAbaor>Zj#%=MR7V_GL~=X@p@o zIvox9{0s|)GqUowvh(Ee(-P1Hy734Wklx+>QFGni^~ux z@28v1=6ApbB;dyY1w=s*)L(AA>J$p6ubw!5GCx0m%FfTsibkUmI`6i8&-Fat58eZV zaRz&LatO!)M{eG_aaSpo)FG|gset_user_data(gobj()); From 8b299e74937960b57603a12c22a00cc6e765d281 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 13 May 2008 20:00:34 +0200 Subject: [PATCH 040/245] add a compatibility/dependecy/style wiki Conflicts: wiki/compatibility.html wiki/index.html --- wiki/index.html | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/wiki/index.html b/wiki/index.html index 1ed553afd..d1bf1bbea 100755 --- a/wiki/index.html +++ b/wiki/index.html @@ -1807,17 +1807,16 @@ Wiki works. It is simple to use and just flexible enough to handle the task. I d Please __end your tiddlers in a newline__, this makes merging in git easier since the /pre tag used in tiddlywiki will become on a single line. ---- -!Architecture and Subsystems +!Design Draft to get started, we create design drafts emphasizing different aspects and regions of Lumiera -* Cehteh works on the data backend, see [[this page|backend.html]] -* Ichthyo focuses mainly on Edit operations and Builder, [[see this separate page|renderengine.html]] -* Gmerlin is in charge of [[GAVL|http://gmerlin.sourceforge.net/gavl.html]] for processing of video data -* as of 4/08 a GuiWorkingGroup is emerging... +* Ichthyo focuses mainly on the Render Engine and its interconnection to the EDL, [[see this separate page|renderengine.html]] +* Cehteh works on the data backend draft, see [[this page|backend.html]] * Some tools which don't fit somewhere else and are used everywhere are put into a [[Support Library|support_library.html]] +* [[Description of the Test System|TestSh]] -!Coding &mdash; Building &mdash; Testing -how to organize several aspects of the practical coding... +!Coding Structures +next we should //start thinking// on how to organize several aspects of the practical coding... * what to do in BOUML? &rarr; [[more|whatInBOUML]] * how to organize packages, files, includes? &rarr; [[more|SrcTreeStructure]] * how to organize the executable to be built? From 4b07cd6f856f15d2d1d6c70e10959c3f55fe6cb9 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 26 Mar 2008 22:40:40 +0100 Subject: [PATCH 041/245] Some more notes for the compatibility wiki --- wiki/compatibility.html | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/wiki/compatibility.html b/wiki/compatibility.html index 979f2301c..6eec84d85 100644 --- a/wiki/compatibility.html +++ b/wiki/compatibility.html @@ -2104,13 +2104,26 @@ if (oldText.indexOf("SplashScreen")==-1) } //}}} -
+
! Source code formatting
-http://www.gnu.org/prep/standards/html_node/Formatting.html#Formatting
+We decided to use the 'gnu-style' for indenting (using spaces and never tabs!):
+ http://www.gnu.org/prep/standards/html_node/Formatting.html#Formatting
+
+It is reasonable to be relaxed about soem formatting rules:
+ * line length might be longer when required
+ * inter expession spacing can be changed to the actual needed ex: (2*x + 2)
+
+Things we are pedantic about:
+ * use never ever tab characters in C/C++ sources
+ * be consistent
+ * source files should end with a newline
+ * no trailing or bogus whitespaces
+
+! Coding Practices
+
+! Writing Tests
 
 ! Contibuting
-
-! Tests
 
From 8d59d601a8c2b78f5f1a9eaca281eb35588b0eae Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 13 May 2008 20:33:44 +0200 Subject: [PATCH 042/245] Add protocol of the 2nd developer meeting to the wiki Conflicts: wiki/index.html --- wiki/index.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wiki/index.html b/wiki/index.html index d1bf1bbea..c0c2e2a5f 100755 --- a/wiki/index.html +++ b/wiki/index.html @@ -930,11 +930,10 @@ git push git://git.pipapo.org/lumiera/mob lumiera/mob is an anonymous account at pipapo.org where everyone can commit changes.
-
+
We keep a protocol or short summary of each important discussion. The summaries of the monthly developer meetings are posted to the Mailinglist and can be found on pipapo.org too
 
-* [[04-08 developer meeting 3.Apr.2008|IRC_2008-04-03]]
-* [[03-08 developer meeting 6.Mar.2008|IRC_2008-03-06]]
+* [[2.official developer meeting 6.March.2008|IRC_2008-03-06]]
 * [[1.official developer meeting 1.Feb.2008|IRC_2008-02-01]]
 * [[informal developer meeting 10.Aug.2007|IRC_2007-08-10]]
 
From 19ee8afa087b0e0ade66c4e04e29d8e2d4bdd47e Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 26 Mar 2008 16:44:55 +0100 Subject: [PATCH 043/245] safeclib wraps some common c library functions and adds some tools * lumiera_malloc which succeeds or dies * some safe string functions * Thread local round robin buffers for temporary data --- src/lib/Makefile.am | 7 +- src/lib/safeclib.c | 181 ++++++++++++++++++++++++++++++++++++++++++++ src/lib/safeclib.h | 97 ++++++++++++++++++++++++ 3 files changed, 283 insertions(+), 2 deletions(-) create mode 100644 src/lib/safeclib.c create mode 100644 src/lib/safeclib.h diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 77fc26d90..6ecd00e97 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -28,7 +28,9 @@ liblumi_a_SOURCES = \ $(liblumi_a_srcdir)/mutex.c \ $(liblumi_a_srcdir)/rwlock.c \ $(liblumi_a_srcdir)/condition.c \ - $(liblumi_a_srcdir)/references.c + $(liblumi_a_srcdir)/references.c \ + $(liblumi_a_srcdir)/safeclib.c + noinst_HEADERS += \ @@ -39,5 +41,6 @@ noinst_HEADERS += \ $(liblumi_a_srcdir)/mutex.h \ $(liblumi_a_srcdir)/rwlock.h \ $(liblumi_a_srcdir)/condition.h \ - $(liblumi_a_srcdir)/references.h + $(liblumi_a_srcdir)/references.h \ + $(liblumi_a_srcdir)/safeclib.h diff --git a/src/lib/safeclib.c b/src/lib/safeclib.c new file mode 100644 index 000000000..58116ae90 --- /dev/null +++ b/src/lib/safeclib.c @@ -0,0 +1,181 @@ +/* + safe_clib.c - Portable and safe wrapers around some clib functions and some tools + + Copyright (C) CinelerraCV + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#define _GNU_SOURCE + +#include "error.h" + +#include +#include +#include +#include + +/** + * @file Portable and safe wrapers around some clib functions and some tools + */ + +LUMIERA_ERROR_DEFINE (NO_MEMORY, "Out of Memory!"); + +/** + * Allocate memory. + * always succeeds or dies + * @param size memory to be allocated + * @return pointer to the allocated memory + */ +void* +lumiera_malloc (size_t sz) +{ + void* o = malloc (sz); + if (!o) + LUMIERA_DIE (NO_MEMORY); + return o; +} + + +/** + * Duplicate a C string. + * always succeeds or dies + * @param str string to be copied + * @param len maximal length to be copied + * @return pointer to the new string, "" if NULL was passed as str + */ +char* +lumiera_strndup (const char* str, size_t len) +{ + char* o; + if (str) + o = strndup (str, len); + else + o = strdup (""); + + if (!o) + LUMIERA_DIE (NO_MEMORY); + return o; +} + + +/** + * Compare two C strings. + * Handles NULL pointers as "", shortcut for same addresses + * @param a first string for comparsion + * @param b second string for comparsion + * @param len maximal length for the comparsion + * @return 0 if the strings are identical, -1 if smaller 1 if bigger. + */ +int +lumiera_strncmp (const char* a, const char* b, size_t len) +{ + return a == b ? 0 : strncmp (a?a:"", b?b:"", len); +} + + +/** + * check 2 strings for identity. + * @param a first string for comparsion + * @param b second string for comparsion + * @return 1 when the strings are the the same, 0 if not. + */ +int +lumiera_streq (const char* a, const char* b) +{ + return !lumiera_strncmp (a, b, SIZE_MAX); +} + + +/** + * Round robin temporary buffers. + * This provides 64 buffers per thread which are recycled with each use. + * The idea here is to have fast buffers for temporal data without need for explicit heap management. + */ +struct lumiera_buffer_struct +{ + void* buffers[64]; + size_t sizes[64]; + unsigned idx; +}; + +static pthread_once_t lumiera_buffer_tls_once = PTHREAD_ONCE_INIT; +static pthread_key_t lumiera_buffer_tls_key; + +void +lumiera_buffer_freeall (void); + +static void +lumiera_buffer_destroy (void* buf) +{ + lumiera_buffer_freeall (); + free (buf); +} + +static void +lumiera_buffer_init (void) +{ + pthread_key_create (&lumiera_buffer_tls_key, lumiera_buffer_destroy); +} + + +/** + * free all buffers associated with this thread. + * This function is called automatically, usually one doesnt need to call it. + */ +void +lumiera_buffer_freeall (void) +{ + pthread_once (&lumiera_buffer_tls_once, lumiera_buffer_init); + struct lumiera_buffer_struct* buf = pthread_getspecific (lumiera_buffer_tls_key); + if (!buf) + pthread_setspecific (lumiera_buffer_tls_key, + buf = lumiera_malloc (sizeof (struct lumiera_buffer_struct))); + + for (buf->idx = 0; buf->idx < 64; ++buf->idx) + { + free (buf->buffers[buf->idx]); + buf->buffers[buf->idx] = NULL; + buf->sizes[buf->idx] = 0; + } + buf->idx = 0; +} + + +/** + * Query a thread local buffer. + * @param size minimal needed size for the buffer + * @return the buffer + */ +void* +lumiera_buffer_provide (size_t size) +{ + pthread_once (&lumiera_buffer_tls_once, lumiera_buffer_init); + struct lumiera_buffer_struct* buf = pthread_getspecific (lumiera_buffer_tls_key); + if (!buf) + pthread_setspecific (lumiera_buffer_tls_key, + buf = lumiera_malloc (sizeof (struct lumiera_buffer_struct))); + + buf->idx = (buf->idx + 1) & 0x3f; + + if (buf->sizes[buf->idx] < size || buf->sizes[buf->idx] > 8*size) + { + free (buf->buffers[buf->idx]); + buf->sizes[buf->idx] = (size+4*sizeof(long)) & ~(4*sizeof(long)-1); + buf->buffers[buf->idx] = lumiera_malloc (buf->sizes[buf->idx]); + } + return buf->buffers[buf->idx]; +} + diff --git a/src/lib/safeclib.h b/src/lib/safeclib.h new file mode 100644 index 000000000..e4e803acc --- /dev/null +++ b/src/lib/safeclib.h @@ -0,0 +1,97 @@ +/* + safe_clib.h - Portable and safe wrapers around some clib functions and some tools + + Copyright (C) CinelerraCV + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "error.h" + +//#include +//#include +//#include + +/** + * @file Portable and safe wrapers around some clib functions and some tools + */ +LUMIERA_ERROR_DECLARE(NO_MEMORY); + +/** + * Allocate memory. + * always succeeds or dies + * @param size memory to be allocated + * @return pointer to the allocated memory + */ +void* +lumiera_malloc (size_t sz); + + +/** + * Duplicate a C string. + * always succeeds or dies + * @param str string to be copied + * @param len maximal length to be copied + * @return pointer to the new string, "" if NULL was passed as str + */ +char* +lumiera_strndup (const char* str, size_t len); + + +/** + * Compare two C strings. + * Handles NULL pointers as "", shortcut for same addresses + * @param a first string for comparsion + * @param b second string for comparsion + * @param len maximal length for the comparsion + * @return 0 if the strings are identical, -1 if smaller 1 if bigger. + */ +int +lumiera_strncmp (const char* a, const char* b, size_t len); + + +/** + * check 2 strings for identity. + * @param a first string for comparsion + * @param b second string for comparsion + * @return 1 when the strings are the the same, 0 if not. + */ +int +lumiera_streq (const char* a, const char* b); + + +/** + * Round robin temporary buffers. + * This provides 64 buffers per thread which are recycled with each use. + * The idea here is to have fast buffers for temporal data without need for explicit heap management. + */ + +/** + * free all buffers associated with this thread. + * This function is called automatically, usually one doesnt need to call it. + */ +void +lumiera_buffer_freeall (void); + + +/** + * Query a thread local buffer. + * @param size minimal needed size for the buffer + * @return the buffer + */ +void* +lumiera_buffer_provide (size_t size); + From 8b162cada426ac46229e442c7ba8767033e27686 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 26 Mar 2008 16:48:44 +0100 Subject: [PATCH 044/245] llist update --- src/lib/llist.h | 96 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 20 deletions(-) diff --git a/src/lib/llist.h b/src/lib/llist.h index 4f77b20dc..efb3f5202 100644 --- a/src/lib/llist.h +++ b/src/lib/llist.h @@ -88,6 +88,7 @@ typedef llist * LList; typedef const llist * const_LList; typedef llist ** LList_ref; + /** * Macro to instantiate a local llist. * @param name of the llist node @@ -95,6 +96,14 @@ typedef llist ** LList_ref; #define LLIST_AUTO(name) llist name = {&name,&name} +/* + some macros for convenience +*/ +#define llist_insert_head(list, element) llist_insert_next (list, element) +#define llist_insert_tail(list, element) llist_insert_prev (list, element) +#define llist_head llist_next +#define llist_tail llist_prev + /** * cast back from a member of a structure to a pointer of the structure */ @@ -129,6 +138,30 @@ typedef llist ** LList_ref; ! llist_is_end (node, list); \ llist_backward (&node)) + +/** + * Iterate forward over a range. + * @param start first node to be interated + * @param end node after the last node be iterated + * @param node pointer to the iterated node + */ +#define LLIST_FORRANGE(start, end, node) \ + for (LList node = start; \ + node != end; \ + llist_forward (&node)) + +/** + * Iterate backward over a range. + * @param rstart first node to be interated + * @param rend node before the last node be iterated + * @param node pointer to the iterated node + */ +#define LLIST_FORRANGE_REV(rstart, rend, node) \ + for (LList node = rstart; \ + node != rend; \ + llist_backward (&node)) + + /** * Consume a list from head. * The body of this statement should remove the head from the list, else it would be a infinite loop @@ -290,7 +323,7 @@ LLIST_FUNC (LList llist_insert_next (LList self, LList next), /** * Insert a node before another. * @param self node before which we want to insert - * @param prev node which shall be inserted nefore self. Could already linked to a list from where it will be removed. + * @param prev node which shall be inserted before self. Could already linked to a list from where it will be removed. * @return self */ LLIST_FUNC (LList llist_insert_prev (LList self, LList prev), @@ -314,10 +347,9 @@ LLIST_FUNC (LList llist_insertlist_next (LList self, LList next), if (!llist_is_empty (next)) { self->next->prev = next->prev; - self->next = next->next; - - next->next->prev = self; next->prev->next = self->next; + self->next = next->next; + next->next->prev = self; next->prev = next->next = next; } @@ -335,10 +367,9 @@ LLIST_FUNC (LList llist_insertlist_prev (LList self, LList prev), if (!llist_is_empty (prev)) { self->prev->next = prev->next; - self->prev = prev->prev; - - prev->prev->next = self; prev->next->prev = self->prev; + self->prev = prev->prev; + prev->prev->next = self; prev->prev = prev->next = prev; } @@ -494,20 +525,45 @@ LLIST_FUNC (LList llist_get_nth_stop (LList self, int n, const_LList stop), return self; ); -/* - some macros for convenience -*/ -#define llist_insert_head(list, element) llist_insert_next (list, element) -#define llist_insert_tail(list, element) llist_insert_prev (list, element) -#define llist_head llist_next -#define llist_tail llist_prev + +/** + * Sort a list. + * @param self list to be sorted + * @param cmp function takeing 2 LLists + * simple recursive mergesort + */ +typedef int (*llist_cmpfn)(LList a, LList b); + +LLIST_FUNC (LList llist_sort (LList self, llist_cmpfn cmp), + llist left; + llist right; + llist_init (&left); + llist_init (&right); + unsigned n = 0; + if (!llist_is_single (self)) + { + LLIST_WHILE_HEAD (self, head) + llist_insert_prev (++n & 1 ? &left : &right, head); + + llist_sort (&left, cmp); + llist_sort (&right, cmp); + + while (!llist_is_empty (&left) && !llist_is_empty (&right)) + llist_insert_prev (self, cmp (left.next, right.next) < 0 ? left.next : right.next); + + if (!llist_is_empty (&left)) + llist_insertlist_prev (self, &left); + if (!llist_is_empty (&right)) + llist_insertlist_prev (self, &right); + } + return self; +) #endif /* LLIST_H */ /* -// Local Variables: -// mode: C -// c-file-style: "gnu" -// End: -// arch-tag: e8fe4a59-fd55-4c45-b860-5cd1e0771213 -// end_of_file +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: */ From 27ca8a73620399f94981a4a87b242c2e0103388c Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 26 Mar 2008 18:09:56 +0100 Subject: [PATCH 045/245] let LUMIERA_DIE take an error identifier as parameter --- src/lib/condition.c | 6 ++++-- src/lib/condition.h | 15 ++++++++------- src/lib/error.h | 6 ++++-- src/lib/locking.h | 5 +++++ src/lib/mutex.c | 6 +++++- src/lib/mutex.h | 9 ++++----- src/lib/plugin.c | 15 ++++++++------- src/lib/references.c | 4 ++-- src/lib/rwlock.c | 14 +++++++++----- src/lib/rwlock.h | 6 +++++- tests/plugin/plugin_main.c | 9 +++++---- 11 files changed, 59 insertions(+), 36 deletions(-) diff --git a/src/lib/condition.c b/src/lib/condition.c index 7427b431d..1bfa2ef96 100644 --- a/src/lib/condition.c +++ b/src/lib/condition.c @@ -25,6 +25,8 @@ * @file Condition variables */ +LUMIERA_ERROR_DEFINE (CONDITION_DESTROY, "condition destroy failed"); + /** * Initialize a condition variable * @param self is a pointer to the condition variable to be initialized @@ -53,9 +55,9 @@ lumiera_condition_destroy (LumieraCondition self) if (self) { if (pthread_mutex_destroy (&self->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_DESTROY); else if (pthread_cond_destroy (&self->cond)) - LUMIERA_DIE; + LUMIERA_DIE (CONDITION_DESTROY); } return self; } diff --git a/src/lib/condition.h b/src/lib/condition.h index b2fd76c63..066c6b267 100644 --- a/src/lib/condition.h +++ b/src/lib/condition.h @@ -28,6 +28,7 @@ * @file Condition variables, header */ +LUMIERA_ERROR_DECLARE (CONDITION_DESTROY); /** * Condition variables. @@ -59,10 +60,10 @@ lumiera_condition_signal (LumieraCondition self) { REQUIRE (self); if (pthread_mutex_lock (&self->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_LOCK); pthread_cond_signal (&self->cond); if (pthread_mutex_unlock (&self->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_UNLOCK); } /** @@ -74,10 +75,10 @@ lumiera_condition_broadcast (LumieraCondition self) { REQUIRE (self); if (pthread_mutex_lock (&self->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_LOCK); pthread_cond_broadcast (&self->cond); if (pthread_mutex_unlock (&self->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_UNLOCK); } @@ -124,7 +125,7 @@ lumiera_conditionacquirer_init (LumieraConditionacquirer self, LumieraCondition self->state = state; if (state == LUMIERA_LOCKED) if (pthread_mutex_lock (&cond->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_LOCK); return self; } @@ -141,7 +142,7 @@ lumiera_conditionacquirer_lock (LumieraConditionacquirer self) REQUIRE (self->state == LUMIERA_UNLOCKED, "mutex already locked"); if (pthread_mutex_lock (&self->cond->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_LOCK); self->state = LUMIERA_LOCKED; } @@ -172,7 +173,7 @@ lumiera_conditionacquirer_unlock (LumieraConditionacquirer self) REQUIRE (self); REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked"); if (pthread_mutex_unlock (&self->cond->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_UNLOCK); self->state = LUMIERA_UNLOCKED; } diff --git a/src/lib/error.h b/src/lib/error.h index 24c73f0a5..e71c0cdfa 100644 --- a/src/lib/error.h +++ b/src/lib/error.h @@ -39,7 +39,8 @@ extern "C" { * Abort unconditionally with a 'Fatal Error!' message. * This macro is used whenever the program end up in a invalid state from which no runtime recovery is possible */ -#define LUMIERA_DIE do { NOBUG_ERROR(NOBUG_ON, "Fatal Error!"); abort(); } while(0) +#define LUMIERA_DIE(err) \ + do { NOBUG_ERROR(NOBUG_ON, "Fatal Error: %s ", strchr(LUMIERA_ERROR_##err, ':')); abort(); } while(0) /** * Forward declare an error constant. @@ -58,7 +59,8 @@ extern const char* LUMIERA_ERROR_##err #define LUMIERA_ERROR_DEFINE(err, msg) \ const char* LUMIERA_ERROR_##err = "LUMIERA_ERROR_" #err ":" msg -/** Helper macro to raise an error for the current thread. +/** + * Helper macro to raise an error for the current thread. * This macro eases setting an error. It adds NoBug logging support to the low level error handling. * @param flag NoBug flag describing the subsystem where the error was raised * @param err name of the error without the 'LUMIERA_ERROR_' prefix (example: NO_MEMORY) diff --git a/src/lib/locking.h b/src/lib/locking.h index 01ad8bb29..f62dd6c29 100644 --- a/src/lib/locking.h +++ b/src/lib/locking.h @@ -28,6 +28,11 @@ #include "lib/error.h" + +LUMIERA_ERROR_DECLARE (MUTEX_LOCK); +LUMIERA_ERROR_DECLARE (MUTEX_UNLOCK); +LUMIERA_ERROR_DECLARE (MUTEX_DESTROY); + /** * @file Shared declarations for all locking primitives. */ diff --git a/src/lib/mutex.c b/src/lib/mutex.c index a08d89e51..009502e5a 100644 --- a/src/lib/mutex.c +++ b/src/lib/mutex.c @@ -25,6 +25,10 @@ * @file Mutual exclusion locking. */ +LUMIERA_ERROR_DEFINE (MUTEX_LOCK, "Mutex locking failed"); +LUMIERA_ERROR_DEFINE (MUTEX_UNLOCK, "Mutex unlocking failed"); +LUMIERA_ERROR_DEFINE (MUTEX_DESTROY, "Mutex destroy failed"); + /** * Initialize a mutex variable @@ -52,7 +56,7 @@ lumiera_mutex_destroy (LumieraMutex self) if (self) { if (pthread_mutex_destroy (&self->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_DESTROY); } return self; } diff --git a/src/lib/mutex.h b/src/lib/mutex.h index ced7118e2..ecd99529d 100644 --- a/src/lib/mutex.h +++ b/src/lib/mutex.h @@ -28,7 +28,6 @@ * @file Mutual exclusion locking, header. */ - /** * Mutex. * @@ -106,7 +105,7 @@ lumiera_mutexacquirer_init_mutex (LumieraMutexacquirer self, LumieraMutex mutex, self->state = state; if (state == LUMIERA_LOCKED) if (pthread_mutex_lock (&mutex->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_LOCK); return self; } @@ -124,7 +123,7 @@ lumiera_mutexacquirer_lock (LumieraMutexacquirer self) REQUIRE (self->state == LUMIERA_UNLOCKED, "mutex already locked"); if (pthread_mutex_lock (&self->mutex->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_LOCK); self->state = LUMIERA_LOCKED; } @@ -164,7 +163,7 @@ lumiera_mutexacquirer_try_mutex (LumieraMutexacquirer self, LumieraMutex mutex) case EBUSY: return LUMIERA_UNLOCKED; default: - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_LOCK); } } @@ -180,7 +179,7 @@ lumiera_mutexacquirer_unlock (LumieraMutexacquirer self) REQUIRE (self); REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked"); if (pthread_mutex_unlock (&self->mutex->mutex)) - LUMIERA_DIE; + LUMIERA_DIE (MUTEX_UNLOCK); self->state = LUMIERA_UNLOCKED; } diff --git a/src/lib/plugin.c b/src/lib/plugin.c index 87939533d..8345d9887 100644 --- a/src/lib/plugin.c +++ b/src/lib/plugin.c @@ -25,8 +25,10 @@ #include #include #include +#include #include "plugin.h" +#include "safeclib.h" /** * @file Plugin loader. @@ -159,8 +161,8 @@ lumiera_plugin_lookup (struct lumiera_plugin* self, const char* path) { /* got it */ TRACE (lumiera_plugin, "found %s", pathname); - self->pathname = strdup (pathname); - if (!self->pathname) LUMIERA_DIE; + self->pathname = lumiera_strndup (pathname, PATH_MAX); + self->type = lumiera_plugin_extensions[i].type; return 0; } @@ -195,21 +197,20 @@ lumiera_interface_open (const char* name, const char* interface, size_t min_revi plugin.name = name; /* for searching */ found = tsearch (&plugin, &lumiera_plugin_registry, lumiera_plugin_name_cmp); - if (!found) LUMIERA_DIE; + if (!found) + LUMIERA_DIE (NO_MEMORY); if (*found == &plugin) { NOTICE (lumiera_plugin, "new plugin"); /* now really create new item */ - *found = malloc (sizeof (struct lumiera_plugin)); - if (!*found) LUMIERA_DIE; + *found = lumiera_malloc (sizeof (struct lumiera_plugin)); if (name) /* NULL is main app, no lookup needed */ { /*lookup for $LUMIERA_PLUGIN_PATH*/ - (*found)->name = strdup (name); - if (!(*found)->name) LUMIERA_DIE; + (*found)->name = lumiera_strndup (name, PATH_MAX); if (!!lumiera_plugin_lookup (*found, getenv("LUMIERA_PLUGIN_PATH")) #ifdef LUMIERA_PLUGIN_PATH diff --git a/src/lib/references.c b/src/lib/references.c index ad4f9562f..3e9d5f260 100644 --- a/src/lib/references.c +++ b/src/lib/references.c @@ -19,6 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "lib/references.h" +#include "lib/safeclib.h" /** * @file Strong and Weak references @@ -43,8 +44,7 @@ LumieraReference lumiera_reference_strong_init_once (LumieraReference self, void* obj, void (*dtor)(void*)) { - LumieraReftarget target = malloc (sizeof(lumiera_reftarget)); - if (!target) LUMIERA_DIE; + LumieraReftarget target = lumiera_malloc (sizeof(lumiera_reftarget)); target->object = obj; target->dtor = dtor; diff --git a/src/lib/rwlock.c b/src/lib/rwlock.c index c7ee3a37d..0862aa808 100644 --- a/src/lib/rwlock.c +++ b/src/lib/rwlock.c @@ -25,6 +25,10 @@ LUMIERA_ERROR_DEFINE(RWLOCK_AGAIN, "maximum number of readlocks exceed"); LUMIERA_ERROR_DEFINE(RWLOCK_DEADLOCK, "deadlock detected"); +LUMIERA_ERROR_DEFINE(RWLOCK_DESTROY, "destroy rwlock"); +LUMIERA_ERROR_DEFINE(RWLOCK_UNLOCK, "unlock"); +LUMIERA_ERROR_DEFINE(RWLOCK_RLOCK, "rlock"); +LUMIERA_ERROR_DEFINE(RWLOCK_WLOCK, "wlock"); /** * @file Read/write locks. @@ -57,7 +61,7 @@ lumiera_rwlock_destroy (LumieraRWLock self) if (self) { if (pthread_rwlock_destroy (&self->rwlock)) - LUMIERA_DIE; + LUMIERA_DIE (RWLOCK_DESTROY); } return self; } @@ -95,7 +99,7 @@ lumiera_rwlockacquirer_init (LumieraRWLockacquirer self, LumieraRWLock rwlock, e lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - LUMIERA_DIE; + LUMIERA_DIE (RWLOCK_RLOCK); } case LUMIERA_WRLOCKED: switch (pthread_rwlock_wrlock (&rwlock->rwlock)) @@ -106,7 +110,7 @@ lumiera_rwlockacquirer_init (LumieraRWLockacquirer self, LumieraRWLock rwlock, e lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - LUMIERA_DIE; + LUMIERA_DIE (RWLOCK_WLOCK); } default: break; @@ -138,7 +142,7 @@ lumiera_rwlockacquirer_rdlock (LumieraRWLockacquirer self) lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - LUMIERA_DIE; + LUMIERA_DIE (RWLOCK_RLOCK); } self->state = LUMIERA_RDLOCKED; @@ -166,7 +170,7 @@ lumiera_rwlockacquirer_wrlock (LumieraRWLockacquirer self) lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); return NULL; default: - LUMIERA_DIE; + LUMIERA_DIE (RWLOCK_WLOCK); } self->state = LUMIERA_WRLOCKED; diff --git a/src/lib/rwlock.h b/src/lib/rwlock.h index 922a05e7b..5e121fbcc 100644 --- a/src/lib/rwlock.h +++ b/src/lib/rwlock.h @@ -33,6 +33,10 @@ LUMIERA_ERROR_DECLARE(RWLOCK_AGAIN); LUMIERA_ERROR_DECLARE(RWLOCK_DEADLOCK); +LUMIERA_ERROR_DECLARE(RWLOCK_DESTROY); +LUMIERA_ERROR_DECLARE(RWLOCK_UNLOCK); +LUMIERA_ERROR_DECLARE(RWLOCK_RLOCK); +LUMIERA_ERROR_DECLARE(RWLOCK_WLOCK); /** * @file Read/write locks, header. @@ -106,7 +110,7 @@ lumiera_rwlockacquirer_unlock (LumieraRWLockacquirer self) REQUIRE (self); REQUIRE (self->state != LUMIERA_UNLOCKED, "rwlock was not locked"); if (pthread_rwlock_unlock (&self->rwlock->rwlock)) - LUMIERA_DIE; + LUMIERA_DIE (RWLOCK_UNLOCK); self->state = LUMIERA_UNLOCKED; } diff --git a/tests/plugin/plugin_main.c b/tests/plugin/plugin_main.c index 2efe32471..4b95ea60c 100644 --- a/tests/plugin/plugin_main.c +++ b/tests/plugin/plugin_main.c @@ -3,6 +3,7 @@ #include "lib/plugin.h" #include "hello_interface.h" +LUMIERA_ERROR_DEFINE(FAILURE, "test failure"); int main(int argc, char** argv) @@ -25,7 +26,7 @@ main(int argc, char** argv) LUMIERA_INTERFACE_TYPE(hello, 1)* hello_de = (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin", "german_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); - if (!hello_de) LUMIERA_DIE; + if (!hello_de) LUMIERA_DIE (FAILURE); hello_de->hello(); hello_de->goodbye(argv[1]); @@ -33,7 +34,7 @@ main(int argc, char** argv) LUMIERA_INTERFACE_TYPE(hello, 1)* hello_en = (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin", "english_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); - if (!hello_en) LUMIERA_DIE; + if (!hello_en) LUMIERA_DIE (FAILURE); hello_en->hello(); hello_en->goodbye(argv[1]); @@ -48,7 +49,7 @@ main(int argc, char** argv) LUMIERA_INTERFACE_TYPE(hello, 1)* hello_de = (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin_cpp", "german_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); - if (!hello_de) LUMIERA_DIE; + if (!hello_de) LUMIERA_DIE (FAILURE); hello_de->hello(); hello_de->goodbye(argv[1]); @@ -56,7 +57,7 @@ main(int argc, char** argv) LUMIERA_INTERFACE_TYPE(hello, 1)* hello_en = (LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin_cpp", "english_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1))); - if (!hello_en) LUMIERA_DIE; + if (!hello_en) LUMIERA_DIE (FAILURE); hello_en->hello(); hello_en->goodbye(argv[1]); From 0b8b5bf5078ddf98955d56dc1216ab36fb6290a0 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 26 Mar 2008 18:11:03 +0100 Subject: [PATCH 046/245] uuid functions --- src/lib/Makefile.am | 2 + src/lib/uuid.c | 94 +++++++++++++++++++++++++++++++++++++++ src/lib/uuid.h | 66 +++++++++++++++++++++++++++ tests/15uuid.tests | 15 +++++++ tests/Makefile.am | 5 +++ tests/library/test-uuid.c | 71 +++++++++++++++++++++++++++++ 6 files changed, 253 insertions(+) create mode 100644 src/lib/uuid.c create mode 100644 src/lib/uuid.h create mode 100644 tests/15uuid.tests create mode 100644 tests/library/test-uuid.c diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 6ecd00e97..844f817a6 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -29,6 +29,7 @@ liblumi_a_SOURCES = \ $(liblumi_a_srcdir)/rwlock.c \ $(liblumi_a_srcdir)/condition.c \ $(liblumi_a_srcdir)/references.c \ + $(liblumi_a_srcdir)/uuid.c \ $(liblumi_a_srcdir)/safeclib.c @@ -42,5 +43,6 @@ noinst_HEADERS += \ $(liblumi_a_srcdir)/rwlock.h \ $(liblumi_a_srcdir)/condition.h \ $(liblumi_a_srcdir)/references.h \ + $(liblumi_a_srcdir)/uuid.h \ $(liblumi_a_srcdir)/safeclib.h diff --git a/src/lib/uuid.c b/src/lib/uuid.c new file mode 100644 index 000000000..e313df992 --- /dev/null +++ b/src/lib/uuid.c @@ -0,0 +1,94 @@ +/* + uuid - Universal unique identifiers + + Copyright (C) CinelerraCV + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "uuid.h" + +#include +#include +#include +#include +#include + +void +lumiera_uuid_set_ptr (lumiera_uuid* uuid, void* ptr) +{ + memset (uuid, 0, 16); + *(void**)uuid = ptr; +} + + +void* +lumiera_uuid_ptr_get (lumiera_uuid* uuid) +{ + return *(void**)uuid; +} + + +void +lumiera_uuid_gen (lumiera_uuid* uuid) +{ + static int fd = -2; + if (!uuid) + return; + + if (fd == -2) + { + fd = open ("/dev/urandom", O_RDONLY); + if (fd == -1) + fd = open ("/dev/random", O_RDONLY); + if (fd >= 0) + fcntl (fd, F_SETFD, FD_CLOEXEC); + else + srand (getpid () + time (NULL)); + } + if (fd < 0) + { + for (int i = 0; i < 16; ++i) + ((unsigned char*)uuid)[i] = (unsigned char)(rand()>>7); + } + else + { + if (read (fd, uuid, 16) < 0) + abort (); + } +} + + +void +lumiera_uuid_copy (lumiera_uuid* dest, lumiera_uuid* src) +{ + memcpy (dest, src, 16); +} + + +int +lumiera_uuid_eq (lumiera_uuid* uuida, lumiera_uuid* uuidb) +{ + return !memcmp (uuida, uuidb, 16); +} + +size_t +lumiera_uuid_hash (lumiera_uuid* uuid) +{ + return *(size_t*)uuid; +} + + diff --git a/src/lib/uuid.h b/src/lib/uuid.h new file mode 100644 index 000000000..a1ab6fa6a --- /dev/null +++ b/src/lib/uuid.h @@ -0,0 +1,66 @@ +/* + uuid - Universal unique identifiers + + Copyright (C) CinelerraCV + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#ifndef LUMIERA_UUID_H +#define LUMIERA_UUID_H +#include "lumiera.h" + +typedef unsigned char lumiera_uuid[16]; + +/** + * Retrieve a generic pointer stored in a uuid + */ +void* +lumiera_uuid_ptr_get (lumiera_uuid* uuid); + +/** + * Generate a new uuid + */ +void +lumiera_uuid_gen (lumiera_uuid* uuid); + +/** + * Store a generic pointer in a uuid + */ +void +lumiera_uuid_set_ptr (lumiera_uuid* uuid, void* ptr); + + +/** + * Copy an uuid + */ +void +lumiera_uuid_copy (lumiera_uuid* dest, lumiera_uuid* src); + + +/** + * Test 2 uuid's for equality + */ +int +lumiera_uuid_eq (lumiera_uuid* uuida, lumiera_uuid* uuidb); + + +/** + * Generate a hashsum over an uuid + */ +size_t +lumiera_uuid_hash (lumiera_uuid* uuid); + +#endif diff --git a/tests/15uuid.tests b/tests/15uuid.tests new file mode 100644 index 000000000..072b2545e --- /dev/null +++ b/tests/15uuid.tests @@ -0,0 +1,15 @@ +TESTING "UUID's" ./test-uuid + +TEST "uuid generate" uuidgen_2 < + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +//#include "cinelerra-config.h" + +//#include +//#include + +#include "lib/uuid.h" + +//CINELERRA_ERROR_DEFINE(TEST, "test error"); + +int +main (int argc, char** argv) +{ + NOBUG_INIT; + + if (argc == 1) + return 0; + + if (!strcmp(argv[1], "uuidgen_2")) + { + lumiera_uuid uuid1; + lumiera_uuid uuid2; + + lumiera_uuid_gen (&uuid1); + lumiera_uuid_gen (&uuid2); + + printf ("%d\n", lumiera_uuid_eq (&uuid2, &uuid1)); + } + else if (!strcmp(argv[1], "uuidgen_copy")) + { + lumiera_uuid uuid1; + lumiera_uuid uuid2; + + lumiera_uuid_gen (&uuid1); + + lumiera_uuid_copy (&uuid2, &uuid1); + + printf ("%d\n", lumiera_uuid_eq (&uuid2, &uuid1)); + } + else if (!strcmp(argv[1], "ptrs")) + { + lumiera_uuid uuid; + + lumiera_uuid_set_ptr (&uuid, &uuid); + + printf ("%d\n", lumiera_uuid_ptr_get (&uuid) == &uuid); + } + else + return 1; + + return 0; +} From 646d6fa0d3370e17d79028401dba7d79cdacbc15 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 26 Mar 2008 19:26:51 +0100 Subject: [PATCH 047/245] Test simplification, plaything * test.h provides some macros to aid test writing * applied that to some tests --- tests/library/test-llist.c | 321 +++++++++++++++++------------------ tests/locking/test-locking.c | 34 ++-- tests/test.h | 52 ++++++ 3 files changed, 220 insertions(+), 187 deletions(-) create mode 100644 tests/test.h diff --git a/tests/library/test-llist.c b/tests/library/test-llist.c index 12592aa4a..66bfa614d 100644 --- a/tests/library/test-llist.c +++ b/tests/library/test-llist.c @@ -23,173 +23,166 @@ //#include #include "lib/llist.h" -#include "lib/error.h" +#include "tests/test.h" +TESTS_BEGIN -LUMIERA_ERROR_DEFINE(TEST, "test error"); - -int -main (int argc, char** argv) +TEST ("basic") { - NOBUG_INIT; + LLIST_AUTO (node1); - if (argc == 1) - return 0; + llist node2; + llist_init (&node2); - if (!strcmp(argv[1], "basic")) - { - LLIST_AUTO (node1); - - llist node2; - llist_init (&node2); - - printf ("%d\n", llist_is_empty (&node1)); - printf ("%d\n", llist_is_empty (&node2)); - } - else if (!strcmp(argv[1], "nodeinsert")) - { - LLIST_AUTO (list); - LLIST_AUTO (node1); - LLIST_AUTO (node2); - LLIST_AUTO (node3); - - llist_insert_next (&list, &node1); - printf ("%d\n", llist_is_empty (&list)); - printf ("%d\n", llist_is_empty (&node1)); - printf ("%d\n", llist_is_single (&node1)); - llist_insert_next (&node1, &node2); - printf ("%d\n", llist_is_single (&node1)); - llist_insert_prev (&node1, &node3); - printf ("%d\n", llist_next (&list) == &node3); - printf ("%d\n", llist_next (&node3) == &node1); - printf ("%d\n", llist_next (&node1) == &node2); - printf ("%d\n", llist_prev (&list) == &node2); - printf ("%d\n", llist_count (&list)); - } - else if (!strcmp(argv[1], "predicates")) - { - LLIST_AUTO (list); - LLIST_AUTO (node1); - LLIST_AUTO (node2); - LLIST_AUTO (node3); - LLIST_AUTO (node4); - LLIST_AUTO (nil); - - llist_insert_tail (&list, &node2); - llist_insert_tail (&list, &node3); - llist_insert_tail (&list, &node4); - llist_insert_head (&list, &node1); - - printf ("%d\n", llist_is_head (&list, &node1)); - printf ("%d\n", llist_is_tail (&list, &node4)); - printf ("%d\n", llist_is_head (&list, &node4)); - printf ("%d\n", llist_is_tail (&list, &node1)); - printf ("%d\n", llist_is_end (&list, &list)); - printf ("%d\n", llist_is_member (&list, &node3)); - printf ("%d\n", llist_is_member (&list, &nil)); - - printf ("%d\n", llist_is_before_after (&list, &node1, &node3)); - printf ("%d\n", llist_is_before_after (&list, &node3, &node1)); - printf ("%d\n", llist_is_before_after (&list, &node1, &nil)); - } - else if (!strcmp(argv[1], "unlink")) - { - LLIST_AUTO (list); - LLIST_AUTO (node1); - LLIST_AUTO (node2); - LLIST_AUTO (node3); - LLIST_AUTO (node4); - LLIST_AUTO (nil); - - llist_insert_tail (&list, &node2); - llist_insert_tail (&list, &node3); - llist_insert_tail (&list, &node4); - llist_insert_head (&list, &node1); - - LLIST_FOREACH_REV (&list, itr) - { - if(itr == &node1) printf ("node1 "); - else if(itr == &node2) printf ("node2 "); - else if(itr == &node3) printf ("node3 "); - else if(itr == &node4) printf ("node4 "); - else printf ("unknown "); - } - printf (".\n"); - - llist_unlink (&nil); - llist_unlink (&node2); - llist_unlink (&node3); - - LLIST_FOREACH (&list, itr) - { - if(itr == &node1) printf ("node1 "); - else if(itr == &node2) printf ("node2 "); - else if(itr == &node3) printf ("node3 "); - else if(itr == &node4) printf ("node4 "); - else printf ("unknown "); - } - printf (".\n"); - printf ("%d\n", llist_is_empty (&node2)); - printf ("%d\n", llist_is_empty (&node3)); - printf ("%d\n", llist_is_empty (&nil)); - } - else if (!strcmp(argv[1], "whiles")) - { - LLIST_AUTO (list); - LLIST_AUTO (node1); - LLIST_AUTO (node2); - LLIST_AUTO (node3); - LLIST_AUTO (node4); - LLIST_AUTO (nil); - - llist_insert_tail (&list, &node2); - llist_insert_tail (&list, &node3); - llist_insert_tail (&list, &node4); - llist_insert_head (&list, &node1); - - LLIST_FOREACH_REV (&list, itr) - { - if(itr == &node1) printf ("node1 "); - else if(itr == &node2) printf ("node2 "); - else if(itr == &node3) printf ("node3 "); - else if(itr == &node4) printf ("node4 "); - else printf ("unknown "); - } - printf (".\n"); - - LLIST_WHILE_HEAD (&list, head) - llist_unlink (head); - - LLIST_FOREACH (&list, itr) - { - if(itr == &node1) printf ("node1 "); - else if(itr == &node2) printf ("node2 "); - else if(itr == &node3) printf ("node3 "); - else if(itr == &node4) printf ("node4 "); - else printf ("unknown "); - } - printf (".\n"); - - llist_insert_tail (&list, &node2); - llist_insert_tail (&list, &node3); - llist_insert_tail (&list, &node4); - llist_insert_head (&list, &node1); - - LLIST_WHILE_TAIL (&list, tail) - llist_unlink (tail); - - LLIST_FOREACH (&list, itr) - { - if(itr == &node1) printf ("node1 "); - else if(itr == &node2) printf ("node2 "); - else if(itr == &node3) printf ("node3 "); - else if(itr == &node4) printf ("node4 "); - else printf ("unknown "); - } - printf (".\n"); - } - else - return 1; - - return 0; + printf ("%d\n", llist_is_empty (&node1)); + printf ("%d\n", llist_is_empty (&node2)); } + +TEST ("nodeinsert") +{ + LLIST_AUTO (list); + LLIST_AUTO (node1); + LLIST_AUTO (node2); + LLIST_AUTO (node3); + + llist_insert_next (&list, &node1); + printf ("%d\n", llist_is_empty (&list)); + printf ("%d\n", llist_is_empty (&node1)); + printf ("%d\n", llist_is_single (&node1)); + llist_insert_next (&node1, &node2); + printf ("%d\n", llist_is_single (&node1)); + llist_insert_prev (&node1, &node3); + printf ("%d\n", llist_next (&list) == &node3); + printf ("%d\n", llist_next (&node3) == &node1); + printf ("%d\n", llist_next (&node1) == &node2); + printf ("%d\n", llist_prev (&list) == &node2); + printf ("%d\n", llist_count (&list)); +} + +TEST ("predicates") +{ + LLIST_AUTO (list); + LLIST_AUTO (node1); + LLIST_AUTO (node2); + LLIST_AUTO (node3); + LLIST_AUTO (node4); + LLIST_AUTO (nil); + + llist_insert_tail (&list, &node2); + llist_insert_tail (&list, &node3); + llist_insert_tail (&list, &node4); + llist_insert_head (&list, &node1); + + printf ("%d\n", llist_is_head (&list, &node1)); + printf ("%d\n", llist_is_tail (&list, &node4)); + printf ("%d\n", llist_is_head (&list, &node4)); + printf ("%d\n", llist_is_tail (&list, &node1)); + printf ("%d\n", llist_is_end (&list, &list)); + printf ("%d\n", llist_is_member (&list, &node3)); + printf ("%d\n", llist_is_member (&list, &nil)); + + printf ("%d\n", llist_is_before_after (&list, &node1, &node3)); + printf ("%d\n", llist_is_before_after (&list, &node3, &node1)); + printf ("%d\n", llist_is_before_after (&list, &node1, &nil)); +} + +TEST ("unlink") +{ + LLIST_AUTO (list); + LLIST_AUTO (node1); + LLIST_AUTO (node2); + LLIST_AUTO (node3); + LLIST_AUTO (node4); + LLIST_AUTO (nil); + + llist_insert_tail (&list, &node2); + llist_insert_tail (&list, &node3); + llist_insert_tail (&list, &node4); + llist_insert_head (&list, &node1); + + LLIST_FOREACH_REV (&list, itr) + { + if(itr == &node1) printf ("node1 "); + else if(itr == &node2) printf ("node2 "); + else if(itr == &node3) printf ("node3 "); + else if(itr == &node4) printf ("node4 "); + else printf ("unknown "); + } + printf (".\n"); + + llist_unlink (&nil); + llist_unlink (&node2); + llist_unlink (&node3); + + LLIST_FOREACH (&list, itr) + { + if(itr == &node1) printf ("node1 "); + else if(itr == &node2) printf ("node2 "); + else if(itr == &node3) printf ("node3 "); + else if(itr == &node4) printf ("node4 "); + else printf ("unknown "); + } + printf (".\n"); + printf ("%d\n", llist_is_empty (&node2)); + printf ("%d\n", llist_is_empty (&node3)); + printf ("%d\n", llist_is_empty (&nil)); +} + +TEST ("whiles") +{ + LLIST_AUTO (list); + LLIST_AUTO (node1); + LLIST_AUTO (node2); + LLIST_AUTO (node3); + LLIST_AUTO (node4); + LLIST_AUTO (nil); + + llist_insert_tail (&list, &node2); + llist_insert_tail (&list, &node3); + llist_insert_tail (&list, &node4); + llist_insert_head (&list, &node1); + + LLIST_FOREACH_REV (&list, itr) + { + if(itr == &node1) printf ("node1 "); + else if(itr == &node2) printf ("node2 "); + else if(itr == &node3) printf ("node3 "); + else if(itr == &node4) printf ("node4 "); + else printf ("unknown "); + } + printf (".\n"); + + LLIST_WHILE_HEAD (&list, head) + llist_unlink (head); + + LLIST_FOREACH (&list, itr) + { + if(itr == &node1) printf ("node1 "); + else if(itr == &node2) printf ("node2 "); + else if(itr == &node3) printf ("node3 "); + else if(itr == &node4) printf ("node4 "); + else printf ("unknown "); + } + printf (".\n"); + + llist_insert_tail (&list, &node2); + llist_insert_tail (&list, &node3); + llist_insert_tail (&list, &node4); + llist_insert_head (&list, &node1); + + LLIST_WHILE_TAIL (&list, tail) + llist_unlink (tail); + + LLIST_FOREACH (&list, itr) + { + if(itr == &node1) printf ("node1 "); + else if(itr == &node2) printf ("node2 "); + else if(itr == &node3) printf ("node3 "); + else if(itr == &node4) printf ("node4 "); + else printf ("unknown "); + } + printf (".\n"); +} + + +TESTS_END diff --git a/tests/locking/test-locking.c b/tests/locking/test-locking.c index 1b54d152e..b37c2c07f 100644 --- a/tests/locking/test-locking.c +++ b/tests/locking/test-locking.c @@ -21,33 +21,21 @@ #include #include - -#include "lib/error.h" - -LUMIERA_ERROR_DEFINE(TEST, "test error"); +#include "tests/test.h" int conditionforgotunlock (); int mutexforgotunlock (); +TESTS_BEGIN -int -main (int argc, char** argv) +TEST ("conditionforgotunlock") { - NOBUG_INIT; - - if (argc == 1) - return 0; - - if (!strcmp(argv[1], "conditionforgotunlock")) - { - return conditionforgotunlock (); - } - if (!strcmp(argv[1], "mutexforgotunlock")) - { - return mutexforgotunlock (); - } - else - return 1; - - return 0; + return conditionforgotunlock (); } + +TEST ("mutexforgotunlock") +{ + return mutexforgotunlock (); +} + +TESTS_END diff --git a/tests/test.h b/tests/test.h new file mode 100644 index 000000000..d25fa0a59 --- /dev/null +++ b/tests/test.h @@ -0,0 +1,52 @@ +/* + test.h - macros for running tests + + Copyright (C) CinelerraCV + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef TEST_H +#define TEST_H + +#include + +#include "lib/error.h" + +LUMIERA_ERROR_DEFINE (TEST, "test error"); + +#define TESTS_BEGIN \ +int \ +main (int argc, char** argv) \ +{ \ + NOBUG_INIT; \ + \ + if (argc == 1) \ + return 1; + +#define TEST(name) \ + else if (!strcmp(argv[1], name)) + + +#define TESTS_END \ + else \ + return 1; \ + \ + return 0; \ +} + + +#endif From 7686a2ec564e02c88ec263bde0b28d93c72816c3 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 26 Mar 2008 20:11:28 +0100 Subject: [PATCH 048/245] Renamed the temporary 'buffer' functions to 'tmpbuf' --- src/lib/safeclib.c | 38 +++++++++++++++++++------------------- src/lib/safeclib.h | 10 +++++----- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/lib/safeclib.c b/src/lib/safeclib.c index 58116ae90..2a4bc50b4 100644 --- a/src/lib/safeclib.c +++ b/src/lib/safeclib.c @@ -42,7 +42,7 @@ LUMIERA_ERROR_DEFINE (NO_MEMORY, "Out of Memory!"); void* lumiera_malloc (size_t sz) { - void* o = malloc (sz); + void* o = sz? malloc (sz) : NULL; if (!o) LUMIERA_DIE (NO_MEMORY); return o; @@ -104,30 +104,30 @@ lumiera_streq (const char* a, const char* b) * This provides 64 buffers per thread which are recycled with each use. * The idea here is to have fast buffers for temporal data without need for explicit heap management. */ -struct lumiera_buffer_struct +struct lumiera_tmpbuf_struct { void* buffers[64]; size_t sizes[64]; unsigned idx; }; -static pthread_once_t lumiera_buffer_tls_once = PTHREAD_ONCE_INIT; -static pthread_key_t lumiera_buffer_tls_key; +static pthread_once_t lumiera_tmpbuf_tls_once = PTHREAD_ONCE_INIT; +static pthread_key_t lumiera_tmpbuf_tls_key; void -lumiera_buffer_freeall (void); +lumiera_tmpbuf_freeall (void); static void -lumiera_buffer_destroy (void* buf) +lumiera_tmpbuf_destroy (void* buf) { - lumiera_buffer_freeall (); + lumiera_tmpbuf_freeall (); free (buf); } static void -lumiera_buffer_init (void) +lumiera_tmpbuf_init (void) { - pthread_key_create (&lumiera_buffer_tls_key, lumiera_buffer_destroy); + pthread_key_create (&lumiera_tmpbuf_tls_key, lumiera_tmpbuf_destroy); } @@ -136,13 +136,13 @@ lumiera_buffer_init (void) * This function is called automatically, usually one doesnt need to call it. */ void -lumiera_buffer_freeall (void) +lumiera_tmpbuf_freeall (void) { - pthread_once (&lumiera_buffer_tls_once, lumiera_buffer_init); - struct lumiera_buffer_struct* buf = pthread_getspecific (lumiera_buffer_tls_key); + pthread_once (&lumiera_tmpbuf_tls_once, lumiera_tmpbuf_init); + struct lumiera_tmpbuf_struct* buf = pthread_getspecific (lumiera_tmpbuf_tls_key); if (!buf) - pthread_setspecific (lumiera_buffer_tls_key, - buf = lumiera_malloc (sizeof (struct lumiera_buffer_struct))); + pthread_setspecific (lumiera_tmpbuf_tls_key, + buf = lumiera_malloc (sizeof (struct lumiera_tmpbuf_struct))); for (buf->idx = 0; buf->idx < 64; ++buf->idx) { @@ -160,13 +160,13 @@ lumiera_buffer_freeall (void) * @return the buffer */ void* -lumiera_buffer_provide (size_t size) +lumiera_tmpbuf_provide (size_t size) { - pthread_once (&lumiera_buffer_tls_once, lumiera_buffer_init); - struct lumiera_buffer_struct* buf = pthread_getspecific (lumiera_buffer_tls_key); + pthread_once (&lumiera_tmpbuf_tls_once, lumiera_tmpbuf_init); + struct lumiera_tmpbuf_struct* buf = pthread_getspecific (lumiera_tmpbuf_tls_key); if (!buf) - pthread_setspecific (lumiera_buffer_tls_key, - buf = lumiera_malloc (sizeof (struct lumiera_buffer_struct))); + pthread_setspecific (lumiera_tmpbuf_tls_key, + buf = lumiera_malloc (sizeof (struct lumiera_tmpbuf_struct))); buf->idx = (buf->idx + 1) & 0x3f; diff --git a/src/lib/safeclib.h b/src/lib/safeclib.h index e4e803acc..90333abd0 100644 --- a/src/lib/safeclib.h +++ b/src/lib/safeclib.h @@ -84,14 +84,14 @@ lumiera_streq (const char* a, const char* b); * This function is called automatically, usually one doesnt need to call it. */ void -lumiera_buffer_freeall (void); +lumiera_tmpbuf_freeall (void); /** - * Query a thread local buffer. - * @param size minimal needed size for the buffer - * @return the buffer + * Query a thread local tmpbuf. + * @param size minimal needed size for the tmpbuf + * @return the tmpbuf */ void* -lumiera_buffer_provide (size_t size); +lumiera_tmpbuf_provide (size_t size); From ecd6ba66b829f6a4b028257c7bfc991363529d03 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 26 Mar 2008 20:11:42 +0100 Subject: [PATCH 049/245] safeclib testsuite --- tests/15safeclib.tests | 28 ++++++++++++ tests/Makefile.am | 5 +++ tests/library/test-safeclib.c | 85 +++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 tests/15safeclib.tests create mode 100644 tests/library/test-safeclib.c diff --git a/tests/15safeclib.tests b/tests/15safeclib.tests new file mode 100644 index 000000000..7e4039ead --- /dev/null +++ b/tests/15safeclib.tests @@ -0,0 +1,28 @@ + +TESTING "Safe clib and tools" ./test-safeclib + +TEST "Allocating 0 bytes" allocation0 < + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "lib/safeclib.h" +#include "tests/test.h" + +#include +#include + +TESTS_BEGIN + +TEST ("allocation0") +{ + lumiera_malloc (0); + NOTREACHED; +} + +TEST ("allocation1024") +{ + void* data[1024]; + for (int i = 0; i < 1024; ++i) + { + data[i] = lumiera_malloc (1024); + ENSURE (data); + } + for (int i = 0; i < 1024; ++i) + { + free (data[i]); + } +} + +TEST ("allocationtoobig") +{ + struct rlimit rl; + rl.rlim_cur = 100*1024*1024; + rl.rlim_max = 100*1024*1024; + setrlimit (RLIMIT_AS, &rl); + lumiera_malloc (200*1024*1024); + NOTREACHED; +} + +TEST ("streq") +{ + if (!lumiera_streq ("foo", "foo")) + LUMIERA_DIE (TEST); + if (!lumiera_streq (NULL, NULL)) + LUMIERA_DIE (TEST); + if (!!lumiera_streq (NULL, "foo")) + LUMIERA_DIE (TEST); + if (!!lumiera_streq ("foo", NULL)) + LUMIERA_DIE (TEST); + if (!!lumiera_streq ("foo", "bar")) + LUMIERA_DIE (TEST); +} + +TEST ("tmpbuf") +{ + for (int i = 0; i < 256; ++i) + { + char* buf = lumiera_tmpbuf_provide (1024); + + for (int j = 0; j < 1024; ++j) + { + buf[j] = i; + } + } +} + + +TESTS_END From 328127980a43d11c1e1550fd79a764aa7f7a443d Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 26 Mar 2008 22:32:01 +0100 Subject: [PATCH 050/245] a small most-recent-used cache implementation --- src/lib/Makefile.am | 8 +-- src/lib/mrucache.c | 65 ++++++++++++++++++++++++ src/lib/mrucache.h | 119 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 4 deletions(-) create mode 100644 src/lib/mrucache.c create mode 100644 src/lib/mrucache.h diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 844f817a6..2c90304fb 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -30,8 +30,8 @@ liblumi_a_SOURCES = \ $(liblumi_a_srcdir)/condition.c \ $(liblumi_a_srcdir)/references.c \ $(liblumi_a_srcdir)/uuid.c \ - $(liblumi_a_srcdir)/safeclib.c - + $(liblumi_a_srcdir)/safeclib.c \ + $(liblumi_a_srcdir)/mrucache.c noinst_HEADERS += \ @@ -44,5 +44,5 @@ noinst_HEADERS += \ $(liblumi_a_srcdir)/condition.h \ $(liblumi_a_srcdir)/references.h \ $(liblumi_a_srcdir)/uuid.h \ - $(liblumi_a_srcdir)/safeclib.h - + $(liblumi_a_srcdir)/safeclib.h \ + $(liblumi_a_srcdir)/mrucache.h diff --git a/src/lib/mrucache.c b/src/lib/mrucache.c new file mode 100644 index 000000000..15b38d1d1 --- /dev/null +++ b/src/lib/mrucache.c @@ -0,0 +1,65 @@ +/* + mrucache.h - most recent used cache + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "lib/mrucache.h" + +/** + * @file Most recent used cache + * Elements (addressed by a LList node) are either in the cache and thereby subject of aging + * or checked out under control of the user. + */ + + +LumieraMruCache +lumiera_mrucache_init (LumieraMruCache self, lumiera_cache_destructor_fn destructor_cb) +{ + REQUIRE (self); + llist_init (&self->cache_list); + self->cached = 0; + self->destructor_cb = destructor_cb; + return self; +} + +LumieraMruCache +lumiera_mrucache_destroy (LumieraMruCache self) +{ + LLIST_WHILE_TAIL (&self->cache_list, node) + { + if (self->destructor_cb) + free (self->destructor_cb (node)); + else + free (node); + } + self->cached = 0; + return self; +} + + +/** + * destroy and free the nelem oldest elements + */ +void +lumiera_mrucache_age (LumieraMruCache self, size_t nelem) +{ + REQUIRE (self); + while (self->cached && nelem--) + free (lumiera_mrucache_pop (self)); +} diff --git a/src/lib/mrucache.h b/src/lib/mrucache.h new file mode 100644 index 000000000..4802ed6a1 --- /dev/null +++ b/src/lib/mrucache.h @@ -0,0 +1,119 @@ +/* + mrucache.h - most recent used cache + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef LUMIERA_CACHE_H +#define LUMIERA_CACHE_H + +#include "lib/llist.h" + +#include + +/** + * @file Most recent used cache + * Elements (addressed by a LList node) are either in the cache and thereby subject of aging + * or checked out under control of the user. + */ + +/** + * Callback function used to destruct/cleanup aged elements. + * shall clean the element sufficiently up to be ready for being freed or reused + * @param node the llist node used to link cache elements (will be empty at call) + * @return pointer to the begin of the element + */ +typedef void* (*lumiera_cache_destructor_fn)(LList node); + +struct lumiera_mrucache_struct +{ + llist cache_list; + size_t cached; + lumiera_cache_destructor_fn destructor_cb; +}; +typedef struct lumiera_mrucache_struct lumiera_mrucache; +typedef lumiera_mrucache* LumieraMruCache; + +/** + * Initialize a mrucache + */ +LumieraMruCache +lumiera_mrucache_init (LumieraMruCache self, lumiera_cache_destructor_fn destructor_cb); + + +/** + * Destroy a mrucache + */ +LumieraMruCache +lumiera_mrucache_destroy (LumieraMruCache self); + + +/** + * add an element to a mrucache + */ +static inline void +lumiera_mrucache_add (LumieraMruCache self, LList node) +{ + REQUIRE (self); + REQUIRE (node && llist_is_empty (node)); + llist_insert_head (&self->cache_list, node); + ++self->cached; +} + + +/** + * Remove an element from a mrucache. + */ +static inline void +lumiera_mrucache_remove (LumieraMruCache self, LList node) +{ + REQUIRE (self); + REQUIRE (node && llist_is_member (&self->cache_list, node)); /* speedup loop warning :P, this check is costly */ + llist_unlink (node); + --self->cached; +} + +/** + * destroy the oldest element and return a pointer to it for reuse. + */ +static inline void* +lumiera_mrucache_pop (LumieraMruCache self) +{ + REQUIRE (self); + if (llist_is_empty (&self->cache_list)) + return NULL; + + LList node = llist_tail (&self->cache_list); + llist_unlink (node); + --self->cached; + + if (self->destructor_cb) + return self->destructor_cb (node); + else + return node; +} + + +/** + * destroy and free the nelem oldest elements + */ +void +lumiera_mrucache_age (LumieraMruCache self, size_t nelem); + + +#endif From eab6b64f6d8f25cc8a096b2473175488d9ffe44e Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Thu, 27 Mar 2008 11:58:38 +0100 Subject: [PATCH 051/245] let mrucache age return how much elements it couldn't purge --- src/lib/mrucache.c | 6 ++++-- src/lib/mrucache.h | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/lib/mrucache.c b/src/lib/mrucache.c index 15b38d1d1..ebe9ef71b 100644 --- a/src/lib/mrucache.c +++ b/src/lib/mrucache.c @@ -56,10 +56,12 @@ lumiera_mrucache_destroy (LumieraMruCache self) /** * destroy and free the nelem oldest elements */ -void -lumiera_mrucache_age (LumieraMruCache self, size_t nelem) +int +lumiera_mrucache_age (LumieraMruCache self, size_t int) { REQUIRE (self); while (self->cached && nelem--) free (lumiera_mrucache_pop (self)); + + return nelem; } diff --git a/src/lib/mrucache.h b/src/lib/mrucache.h index 4802ed6a1..8af7434d9 100644 --- a/src/lib/mrucache.h +++ b/src/lib/mrucache.h @@ -36,7 +36,7 @@ * Callback function used to destruct/cleanup aged elements. * shall clean the element sufficiently up to be ready for being freed or reused * @param node the llist node used to link cache elements (will be empty at call) - * @return pointer to the begin of the element + * @return pointer to the begin of the element. */ typedef void* (*lumiera_cache_destructor_fn)(LList node); @@ -112,8 +112,8 @@ lumiera_mrucache_pop (LumieraMruCache self) /** * destroy and free the nelem oldest elements */ -void -lumiera_mrucache_age (LumieraMruCache self, size_t nelem); +int +lumiera_mrucache_age (LumieraMruCache self, int nelem); #endif From 69ba3b389c829fd832b3827a8ac8469740615233 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Thu, 27 Mar 2008 14:30:08 +0100 Subject: [PATCH 052/245] LUMIERA_MUTEX_SECTION(mutex) macro for sections of mutex protected code --- src/lib/mutex.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib/mutex.h b/src/lib/mutex.h index ecd99529d..9381c3ca1 100644 --- a/src/lib/mutex.h +++ b/src/lib/mutex.h @@ -28,6 +28,13 @@ * @file Mutual exclusion locking, header. */ +#define LUMIERA_MUTEX_SECTION(mutex) \ +lumiera_mutexacquirer lock_##__LINE__##_; \ +for (lumiera_mutexacquirer_init_mutex (&lock_##__LINE__##_, mutex, LUMIERA_LOCKED); \ + lock_##__LINE__##_.state == LUMIERA_LOCKED; \ + lumiera_mutexacquirer_unlock (&lock_##__LINE__##_)) + + /** * Mutex. * From d32c74361be4d1e6ffd6749f016be8655f375167 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Fri, 28 Mar 2008 16:53:35 +0100 Subject: [PATCH 053/245] Fix: typo in mrucache_age() --- src/lib/mrucache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/mrucache.c b/src/lib/mrucache.c index ebe9ef71b..d98976184 100644 --- a/src/lib/mrucache.c +++ b/src/lib/mrucache.c @@ -57,7 +57,7 @@ lumiera_mrucache_destroy (LumieraMruCache self) * destroy and free the nelem oldest elements */ int -lumiera_mrucache_age (LumieraMruCache self, size_t int) +lumiera_mrucache_age (LumieraMruCache self, int nelem) { REQUIRE (self); while (self->cached && nelem--) From 3a8b3feb96d30c744d607209dc0073fbe5b0cc28 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Fri, 28 Mar 2008 16:56:36 +0100 Subject: [PATCH 054/245] add string creating functions to tmpbuf * lumiera_tmpbuf_strndup() duplicates a string * lumiera_tmpbuf_sprintf() creates a formatted string --- src/lib/safeclib.c | 33 +++++++++++++++++++++++++++++++++ src/lib/safeclib.h | 23 ++++++++++++++++++++--- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/lib/safeclib.c b/src/lib/safeclib.c index 2a4bc50b4..71e347ab7 100644 --- a/src/lib/safeclib.c +++ b/src/lib/safeclib.c @@ -26,6 +26,7 @@ #include #include #include +#include /** * @file Portable and safe wrapers around some clib functions and some tools @@ -179,3 +180,35 @@ lumiera_tmpbuf_provide (size_t size) return buf->buffers[buf->idx]; } + +char* +lumiera_tmpbuf_strndup (const char* src, size_t size) +{ + size_t len = strlen (src); + len = len > size ? size : len; + + char* buf = lumiera_tmpbuf_provide (len + 1); + strncpy (buf, src, len); + buf[len] = '\0'; + + return buf; +} + + +char* +lumiera_tmpbuf_sprintf (size_t size, const char* fmt, ...) +{ + va_list args; + + va_start (args, fmt); + size_t len = vsnprintf (NULL, 0, fmt, args); + va_end (args); + + len = len > size ? size : len; + char* buf = lumiera_tmpbuf_provide (len); + va_start (args, fmt); + vsnprintf (buf, len, fmt, args); + va_end (args); + + return buf; +} diff --git a/src/lib/safeclib.h b/src/lib/safeclib.h index 90333abd0..02d931cb7 100644 --- a/src/lib/safeclib.h +++ b/src/lib/safeclib.h @@ -21,9 +21,7 @@ #include "error.h" -//#include -//#include -//#include +#include /** * @file Portable and safe wrapers around some clib functions and some tools @@ -95,3 +93,22 @@ lumiera_tmpbuf_freeall (void); void* lumiera_tmpbuf_provide (size_t size); +/** + * Duplicate string to a tmpbuf. + * @param src string to be duplicated + * @param size maximal length to be copied + * @return temporary buffer containing a copy of the string + */ +char* +lumiera_tmpbuf_strndup (const char* src, size_t size); + +/** + * Construct a string in a tmpbuf. + * @param size maximal length for the string + * @param fmt printf like formatstring + * @param ... parameters + * @return temporary buffer containing the constructed of the string + */ +char* +lumiera_tmpbuf_sprintf (size_t size, const char* fmt, ...); + From b41115d1b2dd4ef5165302c8f5479f0fad938b06 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Fri, 28 Mar 2008 16:59:11 +0100 Subject: [PATCH 055/245] Add cuckoo hashing to the library This implementation of cuckoo hashing gives guaranteed O(1) lookup complexity and amortized O(1) insert and remove complexity. Hash tables by default grow and shrink automatically. It is posible to preallocate entries and turn automatic shrinking off, taking out the memory management factors for insert and remove operations. --- src/lib/Makefile.am | 2 + src/lib/cuckoo.c | 497 ++++++++++++++++++++++++++++++++++++++++++++ src/lib/cuckoo.h | 167 +++++++++++++++ 3 files changed, 666 insertions(+) create mode 100644 src/lib/cuckoo.c create mode 100644 src/lib/cuckoo.h diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 2c90304fb..89a418b03 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -31,6 +31,7 @@ liblumi_a_SOURCES = \ $(liblumi_a_srcdir)/references.c \ $(liblumi_a_srcdir)/uuid.c \ $(liblumi_a_srcdir)/safeclib.c \ + $(liblumi_a_srcdir)/cuckoo.c \ $(liblumi_a_srcdir)/mrucache.c @@ -45,4 +46,5 @@ noinst_HEADERS += \ $(liblumi_a_srcdir)/references.h \ $(liblumi_a_srcdir)/uuid.h \ $(liblumi_a_srcdir)/safeclib.h \ + $(liblumi_a_srcdir)/cuckoo.h \ $(liblumi_a_srcdir)/mrucache.h diff --git a/src/lib/cuckoo.c b/src/lib/cuckoo.c new file mode 100644 index 000000000..0d0b4efef --- /dev/null +++ b/src/lib/cuckoo.c @@ -0,0 +1,497 @@ +/* + A cuckoo hash implementation + + Copyright (C) + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "cuckoo.h" + +#include + +enum compact_state + { + COMPACTING_OFF, + COMPACTING_AUTO, + COMPACTED + }; + +struct cuckoo_struct +{ + size_t size; /* t1 = 4*size; t2 = 2*size; t3 = size */ + size_t itemsize; + + cuckoo_hashfunc h1; /* hash function */ + uint32_t r1; /* random, reset for each rehash */ + cuckoo_hashfunc h2; + uint32_t r2; + cuckoo_hashfunc h3; + uint32_t r3; + + cuckoo_cmpfunc cmp; + + void* t1; + void* t2; + void* t3; + + unsigned maxloops; /* sqrt (4 * size) */ + + enum compact_state autocompact; + size_t elements; +}; + + +static inline uint32_t cuckoo_fast_prng () +{ + static uint32_t rnd = 0xbabeface; + return rnd = rnd<<1 ^ ((rnd>>30) & 1) ^ ((rnd>>2) & 1); +} + +Cuckoo +cuckoo_init (Cuckoo self, + cuckoo_hashfunc h1, + cuckoo_hashfunc h2, + cuckoo_hashfunc h3, + cuckoo_cmpfunc cmp, + size_t itemsize, + unsigned startsize) +{ + if (!self) + return NULL; + + self->size = 1<itemsize = itemsize; + self->h1 = h1; + self->r1 = cuckoo_fast_prng (); + self->h2 = h2; + self->r2 = cuckoo_fast_prng (); + self->h3 = h3; + self->r3 = cuckoo_fast_prng (); + + self->cmp = cmp; + + self->t1 = calloc (self->size * 4, itemsize); + self->t2 = calloc (self->size * 2, itemsize); + self->t3 = calloc (self->size, itemsize); + if (!self->t1 || !self->t2 || !self->t3) + { + free (self->t1); + free (self->t2); + free (self->t3); + return NULL; + } + + self->maxloops = 1; + while (self->maxloops * self->maxloops < self->size * 4) + ++self->maxloops; + + self->autocompact = COMPACTING_AUTO; + self->elements = 0; + return self; +} + +Cuckoo +cuckoo_new (cuckoo_hashfunc h1, + cuckoo_hashfunc h2, + cuckoo_hashfunc h3, + cuckoo_cmpfunc cmp, + size_t itemsize, + unsigned startsize) +{ + Cuckoo self = malloc (sizeof (struct cuckoo_struct)); + if (!cuckoo_init (self, h1, h2, h3, cmp, itemsize, startsize)) + { + free (self); + return NULL; + } + return self; +} + +Cuckoo +cuckoo_destroy (Cuckoo self) +{ + if (self) + { + free (self->t1); + free (self->t2); + free (self->t3); + } + return self; +} + + +void +cuckoo_free (Cuckoo self) +{ + free (cuckoo_destroy (self)); +} + + +static inline int +iszero (void* mem, size_t size) +{ + while (size && !*(int*)mem) + { + size -= sizeof (int); + mem += sizeof (int); + } + return !size; +} + +static inline void +xmemcpy (void* dst, void* src, size_t size) +{ + while (size) + { + size -= sizeof (int); + *(int*)(dst + size) = *(int*)(src + size); + } +} + + +static int +cuckoo_insert_internal_ (Cuckoo self, void* item) +{ + void* pos; + char tmp[self->itemsize]; + + for (unsigned n = 0; n < self->maxloops; ++n) + { + /* find nest */ + pos = self->t1 + self->itemsize * (self->h1 (item, self->r1) % (4*self->size)); + /* kick old egg out */ + xmemcpy (tmp, pos, self->itemsize); + /* lay egg */ + xmemcpy (pos, item, self->itemsize); + + if (iszero (tmp, self->itemsize)) + return 1; + + /* find nest */ + pos = self->t2 + self->itemsize * (self->h2 (tmp, self->r2) % (2*self->size)); + /* kick old egg out */ + xmemcpy (item, pos, self->itemsize); + /* lay egg */ + xmemcpy (pos, tmp, self->itemsize); + + if (iszero (item, self->itemsize)) + return 1; + + /* find nest */ + pos = self->t3 + self->itemsize * (self->h3 (item, self->r3) % self->size); + /* kick old egg out */ + xmemcpy (tmp, pos, self->itemsize); + /* lay egg */ + xmemcpy (pos, item, self->itemsize); + + if (iszero (tmp, self->itemsize)) + return 1; + + /* copy tmp to item, which will be reinserted on next interation / after rehashing */ + xmemcpy (item, tmp, self->itemsize); + } + return 0; +} + + +static void +cuckoo_rehash (Cuckoo self) +{ + retry1: + + self->r1 = cuckoo_fast_prng (); + + for (size_t i = 0; i < 4*self->size; ++i) + { + unsigned n; + void* pos = self->t1 + self->itemsize * i; + if (!iszero (pos, self->itemsize)) + { + for (n = 0; n < self->maxloops; ++n) + { + unsigned hash = self->h1 (pos, self->r1) % (4*self->size); + if (hash != i) + { + char t[self->itemsize]; + void* hpos = self->t1 + self->itemsize * hash; + xmemcpy (t, hpos, self->itemsize); + xmemcpy (hpos, pos, self->itemsize); + xmemcpy (pos, t, self->itemsize); + if (iszero (t, self->itemsize)) + break; + } + else + break; + } + if (n == self->maxloops) + goto retry1; + } + } + + retry2: + self->r2 = cuckoo_fast_prng (); + + for (size_t i = 0; i < 2*self->size; ++i) + { + unsigned n; + void* pos = self->t2 + self->itemsize * i; + if (!iszero (pos, self->itemsize)) + { + for (n = 0; n < self->maxloops; ++n) + { + unsigned hash = self->h2 (pos, self->r2) % (2*self->size); + if (hash != i) + { + char t[self->itemsize]; + void* hpos = self->t2 + self->itemsize * hash; + xmemcpy (t, hpos, self->itemsize); + xmemcpy (hpos, pos, self->itemsize); + xmemcpy (pos, t, self->itemsize); + if (iszero (t, self->itemsize)) + break; + } + else + break; + } + if (n == self->maxloops) + goto retry2; + } + } + + retry3: + self->r3 = cuckoo_fast_prng (); + + for (size_t i = 0; i < self->size; ++i) + { + unsigned n; + void* pos = self->t3 + self->itemsize * i; + if (!iszero (pos, self->itemsize)) + { + for (n = 0; n < self->maxloops; ++n) + { + unsigned hash = self->h3 (pos, self->r3) % self->size; + if (hash != i) + { + char t[self->itemsize]; + void* hpos = self->t3 + self->itemsize * hash; + xmemcpy (t, hpos, self->itemsize); + xmemcpy (hpos, pos, self->itemsize); + xmemcpy (pos, t, self->itemsize); + if (iszero (t, self->itemsize)) + break; + } + else + break; + } + if (n == self->maxloops) + goto retry3; + } + } +} + +static int +cuckoo_grow (Cuckoo self) +{ + /* rotate hashfuncs, tables, randoms */ + cuckoo_hashfunc th = self->h3; + self->h3 = self->h2; + self->h2 = self->h1; + self->h1 = th; + + uint32_t tr = self->r3; + self->r3 = self->r2; + self->r2 = self->r1; + self->r1 = tr; + + void* tt = self->t3; + self->t3 = self->t2; + self->t2 = self->t1; + + /* double new base size */ + self->size *= 2; + while (self->maxloops * self->maxloops < self->size * 4) + ++self->maxloops; + + /* alloc new t1 */ + self->t1 = calloc (self->size * 4, self->itemsize); + if (!self->t1) + { + self->t1 = tt; + return 0; + } + + /* reinsert tt */ + size_t ttsize = self->size / 2; + for (size_t i = 0; i < ttsize; ++i) + { + void* pos = tt + i * self->itemsize; + if (!iszero (pos, self->itemsize)) + { + while (!cuckoo_insert_internal_ (self, pos)) + cuckoo_rehash (self); + } + } + free (tt); + + self->autocompact = COMPACTING_AUTO; + return 1; +} + + +int +cuckoo_reserve (Cuckoo self, size_t more) +{ + int ret = 1; + if (more) + while (self->elements+self->maxloops+more >= 6*self->size) + ret = cuckoo_grow (self); + + self->autocompact = COMPACTING_OFF; + return ret; +} + + +int +cuckoo_compact (Cuckoo self) +{ + if (self->autocompact == COMPACTED) + return 1; + + if (self->size > 2 && self->elements < self->size * 3) + { + cuckoo_hashfunc th = self->h1; + self->h1 = self->h2; + self->h2 = self->h3; + self->h3 = th; + + uint32_t tr = self->r1; + self->r1 = self->r2; + self->r2 = self->r3; + self->r3 = tr; + + void* tt = self->t1; + self->t1 = self->t2; + self->t2 = self->t3; + + /* halve base size */ + self->size /= 2; + while (self->maxloops * self->maxloops >= self->size * 4) + --self->maxloops; + + /* alloc new t3 */ + self->t3 = calloc (self->size, self->itemsize); + if (!self->t3) + { + self->t3 = tt; + return 0; + } + + /* reinsert tt */ + size_t ttsize = self->size * 8; + for (size_t i = 0; i < ttsize; ++i) + { + void* pos = tt + i * self->itemsize; + if (!iszero (pos, self->itemsize)) + { + --self->elements; + cuckoo_insert (self, pos); + } + } + free (tt); + self->autocompact = COMPACTED; + } + return 1; +} + + +int +cuckoo_insert (Cuckoo self, void* item) +{ + char tmp[self->itemsize]; + + void* found; + if ((found = cuckoo_find (self, item))) + { + xmemcpy (found, item, self->itemsize); + return 1; + } + + xmemcpy (tmp, item, self->itemsize); + + for (unsigned n = 6; n; --n) /* rehash/grow loop */ + { + if (cuckoo_insert_internal_ (self, tmp)) + { + ++self->elements; + return 1; + } + + if (self->elements > n*self->size) + { + n = 6; + if (!cuckoo_grow (self)) + return 0; + } + else + cuckoo_rehash (self); + } + return 0; +} + + +void* +cuckoo_find (Cuckoo self, void* item) +{ + void* pos; + + pos = self->t1 + self->itemsize * (self->h1 (item, self->r1) % (4*self->size)); + if (!iszero (pos, self->itemsize) && self->cmp (item, pos)) + return pos; + + pos = self->t2 + self->itemsize * (self->h2 (item, self->r2) % (2*self->size)); + if (!iszero (pos, self->itemsize) && self->cmp (item, pos)) + return pos; + + pos = self->t3 + self->itemsize * (self->h3 (item, self->r3) % self->size); + if (!iszero (pos, self->itemsize) && self->cmp (item, pos)) + return pos; + + return NULL; +} + + +void +cuckoo_remove (Cuckoo self, void* item) +{ + if (item) + { + memset (item, 0, self->itemsize); + --self->elements; + + if (self->autocompact == COMPACTING_AUTO && self->size > 2 && self->elements <= self->size*2) + cuckoo_compact (self); + } +} + + +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/src/lib/cuckoo.h b/src/lib/cuckoo.h new file mode 100644 index 000000000..db1d33da3 --- /dev/null +++ b/src/lib/cuckoo.h @@ -0,0 +1,167 @@ +/* + A cuckoo hash implementation + + Copyright (C) + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#ifndef CUCKOO_H +#define CUCKOO_H + +/** + * @file Cuckoo hashing + * This hashing gives guaranteed O(1) lookup complexity and amortized O(1) insert and remove complexity. + * Hash tables by default grow and shrink automatically. It is posible to preallocate entries and turn + * automatic shrinking off taking out the memory management factors for insert and remove operations. + * This implementation uses 3 Tables which exponential growing sizes. + */ + +#include +#include + +struct cuckoo_struct; +typedef struct cuckoo_struct * Cuckoo; + +/** + * Hash function. + * User supplied universal hash function + * @param item address of the item to be hashed + * @param r pseudo random number, 31 significant bits, regenerated on each rehash + * @return hash value + */ +typedef size_t (*cuckoo_hashfunc)(const void* item, const uint32_t r); + +/** + * Compare function. + * User supplied compare function + * @param item1 address of the first item + * @param item2 address of the second item + * @return 1 when the items are identical, 0 otherwise + */ +typedef int (*cuckoo_cmpfunc)(const void* item1, const void* item2); + +/** + * Initialize a cuckoo hash. + * @param self pointer to a uninitialized cuckoo datastructure + * @param h1 hash function for the first table + * @param h2 hash function for the second table + * @param h3 hash function for the third table + * @param cmp function which compares two keys + * @param startsize initial size of table t3, as 2's exponent + * @return The initialized hashtable or NULL at allocation failure + */ +Cuckoo +cuckoo_init (Cuckoo self, + cuckoo_hashfunc h1, + cuckoo_hashfunc h2, + cuckoo_hashfunc h3, + cuckoo_cmpfunc cmp, + size_t itemsize, + unsigned startsize); + +/** + * Allocate a new cuckoo hash. + * @param h1 hash function for the first table + * @param h2 hash function for the second table + * @param h3 hash function for the third table + * @param cmp function which compares two keys + * @param startsize initial size of table t3, as 2's exponent + * @return The initialized hashtable or NULL at allocation failure + */ +Cuckoo +cuckoo_new (cuckoo_hashfunc h1, + cuckoo_hashfunc h2, + cuckoo_hashfunc h3, + cuckoo_cmpfunc cmp, + size_t itemsize, + unsigned startsize); + +/** + * Destroy a cuckoo hash. + * Frees internal used resources. + * @param self cuckoo hash to destroy + * @return The now uninitialized hashtable + */ +Cuckoo +cuckoo_destroy (Cuckoo self); + +/** + * Deallocate a cuckoo hash. + * @param self handle of the hash table to be freed + */ +void +cuckoo_free (Cuckoo self); + +/** + * Insert an element into a hash. + * amortized O(1) complexity because it may rarely rehash the tables or even grow them. + * see cuckoo_reserve() about how to preallocate entries to prevent the growing costs. + * @param self handle to the hash table + * @param item pointer to a item to be inserted + * @return 1 on successful insert, 0 on allocation failure + * Note: at failure there is one arbitary hash cell lost! + */ +int +cuckoo_insert (Cuckoo self, void* item); + +/** + * Find a value by key in a hash. + * @param self handle to the hash table + * @param item pointer to an item to be looked up + * @return found object or NULL if not present + */ +void* +cuckoo_find (Cuckoo self, void* item); + +/** + * Remove a item from a hash. + * amortized O(1) complexity when it automatically shrink its tables. + * guaranteed O(1) complexity when automatic shrinking is turned off. + * see cuckoo_reserve() about how turn automatic shrinking off. + * @param self handle to the hash table + * @param item pointer to the item to be removed + */ +void +cuckoo_remove (Cuckoo self, void* item); + +/** + * Shrink the hash sizes when possible and turn autocompacting on. + * only useful when autmatic shrinking is turned off. + * see cuckoo_reserve() about how turn shrinking off. + * @param self handle to the hash table + */ +int +cuckoo_compact (Cuckoo self); + +/** + * Prereserve hash entries and turn autocompacting off. + * @param self handle to the hash table + * @param more number of entries to be additionally reserved + * In rare circumstances inserting into a hash which has reserved some entries + * it may still need to rehash (or even rarer) to grow the table. + * While autocompacting is turned off, removing is completely O(1). + */ +int +cuckoo_reserve (Cuckoo self, size_t more); + +#endif +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ From 05055fa7952004d6b8211dd5c8d1171a2afbac48 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Tue, 13 May 2008 20:07:21 +0100 Subject: [PATCH 056/245] Added POTFILES.in --- src/gui/po/POTFILES.in | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/gui/po/POTFILES.in diff --git a/src/gui/po/POTFILES.in b/src/gui/po/POTFILES.in new file mode 100644 index 000000000..f8afa6162 --- /dev/null +++ b/src/gui/po/POTFILES.in @@ -0,0 +1,12 @@ +# List of source files containing translatable strings. + +src/gtk-lumiera.cpp + +src/workspace/actions.cpp + +src/dialogs/preferences-dialog.cpp +src/dialogs/render.cpp + +src/panels/assets-panel.cpp +src/panels/timeline-panel.cpp +src/panels/viewer-panel.cpp From 380c1d2c47a90abbe69c5695b17ff55530e319e6 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 7 Apr 2008 06:48:49 +0200 Subject: [PATCH 057/245] dropped the pre-gavl framerate sources out of lib --- src/lib/Makefile.am | 2 - src/lib/framerate.h | 107 -------------------------------------------- 2 files changed, 109 deletions(-) delete mode 100644 src/lib/framerate.h diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 89a418b03..0e0c2f22e 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -24,7 +24,6 @@ liblumi_a_CPPFLAGS = -I$(top_srcdir)/src/ liblumi_a_SOURCES = \ $(liblumi_a_srcdir)/plugin.c \ $(liblumi_a_srcdir)/error.c \ - $(liblumi_a_srcdir)/framerate.c \ $(liblumi_a_srcdir)/mutex.c \ $(liblumi_a_srcdir)/rwlock.c \ $(liblumi_a_srcdir)/condition.c \ @@ -38,7 +37,6 @@ liblumi_a_SOURCES = \ noinst_HEADERS += \ $(liblumi_a_srcdir)/plugin.h \ $(liblumi_a_srcdir)/error.h \ - $(liblumi_a_srcdir)/framerate.h \ $(liblumi_a_srcdir)/locking.h \ $(liblumi_a_srcdir)/mutex.h \ $(liblumi_a_srcdir)/rwlock.h \ diff --git a/src/lib/framerate.h b/src/lib/framerate.h deleted file mode 100644 index 581d7fa78..000000000 --- a/src/lib/framerate.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - framerate.h - framerate calculations - - Copyright (C) Lumiera.org - 2008, Christian Thaeter - - This program 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 2 of the - License, or (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef LUMIERA_FRAMERATE_H -#define LUMIERA_FRAMERATE_H - -#include - -#include "lib/error.h" - -/** - * @file Framerate calculations, header. - */ - - -/** - * framerates are defined as a rational number - * for example NTSC with 30000/1001fps - */ -struct lumiera_framerate_struct -{ - unsigned n; //numerator - unsigned d; //denominator -}; - -typedef struct lumiera_framerate_struct lumiera_framerate; -typedef lumiera_framerate* LumieraFramerate; - -typedef signed long lumiera_framepos; - -LUMIERA_ERROR_DECLARE(FRAMERATE_ILLEGAL_TIME); -LUMIERA_ERROR_DECLARE(FRAMERATE_ILLEGAL_FRAME); - -#define LUMIERA_FRAMEPOS_ERROR LONG_MIN - -/** - * Get the frame number of a given time at a given frame rate. - * frame indexing starts with 1 - * @param framerate is a pointer to the framerate used, defined as rational number. Must be given. - * @param time is a pointer to a lumiera_time which shall be converted. - * @return frame at the given time or LUMIERA_FRAMEPOS_ERROR on error. - */ -static inline lumiera_framepos -lumiera_framerate_frame_get_time (const LumieraFramerate framerate, LumieraTime time) -{ - REQUIRE (framerate); - if (!time || time->tv_sec == (time_t)-1) - { - lumiera_error_set(LUMIERA_ERROR_FRAMERATE_ILLEGAL_TIME); - return LUMIERA_FRAMEPOS_ERROR; - } - - /* we add a magic microsecond for rounding, because of integer truncation frames may be calculated at most 1us earlier, - the idea is to compensate odd framerates which fall out off microsecond precision. - */ - return ((time->tv_sec * 1000000ULL + time->tv_usec + /*magic*/1) * framerate->n)/(framerate->d * 1000000ULL) + 1; -} - -/** - * Get the start time for a frame. - * frame indexing starts with 1 - * @param framerate is a pointer to the framerate used, defined as rational number. Must be given. - * @param time is a pointer to a lumiera_time which shall take the result. - * @param frame frame number to be converted to time. This frame number must be greater than 0. - * @return the pointer given in time or NULL on error (or when it was given as time). - */ -static inline LumieraTime -lumiera_framerate_time_get_time_frame (const LumieraFramerate framerate, - LumieraTime time, - lumiera_framepos frame) -{ - REQUIRE (framerate); - if (time) - { - if (frame < 1) - { - lumiera_error_set(LUMIERA_ERROR_FRAMERATE_ILLEGAL_FRAME); - return NULL; - } - - unsigned long long usec = ((frame-1) * framerate->d * 1000000ULL - (/*magic*/frame>1?1:0)) / framerate->n; - - time->tv_sec = usec / 1000000; - time->tv_usec = usec % 1000000; - } - return time; -} - -#endif From 23e32d31fca47b82d8cd932451da1c678e7d6de3 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 13 May 2008 21:42:17 +0200 Subject: [PATCH 058/245] don't build the backend things for now --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index bf7ebec19..69cc34288 100644 --- a/Makefile.am +++ b/Makefile.am @@ -34,7 +34,7 @@ include $(top_srcdir)/admin/Makefile.am # core include $(top_srcdir)/src/lib/Makefile.am -include $(top_srcdir)/src/backend/Makefile.am +#include $(top_srcdir)/src/backend/Makefile.am # plugins #include $(top_srcdir)/src... From a9cf2c719df9cf7a79d523ea52c98ac78716d86d Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 13 May 2008 21:42:51 +0200 Subject: [PATCH 059/245] Fix: uuid includes --- src/lib/uuid.c | 3 ++- src/lib/uuid.h | 3 ++- tests/library/test-uuid.c | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/lib/uuid.c b/src/lib/uuid.c index e313df992..d4eee69be 100644 --- a/src/lib/uuid.c +++ b/src/lib/uuid.c @@ -19,13 +19,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "uuid.h" +#include "lib/uuid.h" #include #include #include #include #include +#include void lumiera_uuid_set_ptr (lumiera_uuid* uuid, void* ptr) diff --git a/src/lib/uuid.h b/src/lib/uuid.h index a1ab6fa6a..d4cf8ce9d 100644 --- a/src/lib/uuid.h +++ b/src/lib/uuid.h @@ -20,7 +20,8 @@ */ #ifndef LUMIERA_UUID_H #define LUMIERA_UUID_H -#include "lumiera.h" + +#include typedef unsigned char lumiera_uuid[16]; diff --git a/tests/library/test-uuid.c b/tests/library/test-uuid.c index b5b3b6746..4a6050163 100644 --- a/tests/library/test-uuid.c +++ b/tests/library/test-uuid.c @@ -21,10 +21,12 @@ //#include "cinelerra-config.h" //#include -//#include + #include "lib/uuid.h" +#include + //CINELERRA_ERROR_DEFINE(TEST, "test error"); int From 2a1d6c6232d2f84924bfd2d03d9fbc04ee601977 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 13 May 2008 21:43:08 +0200 Subject: [PATCH 060/245] Fix: safeclib-test --- tests/library/test-safeclib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/library/test-safeclib.c b/tests/library/test-safeclib.c index 52a99405f..837e3d5fd 100644 --- a/tests/library/test-safeclib.c +++ b/tests/library/test-safeclib.c @@ -36,7 +36,7 @@ TEST ("allocation1024") for (int i = 0; i < 1024; ++i) { data[i] = lumiera_malloc (1024); - ENSURE (data); + ENSURE (data[i]); } for (int i = 0; i < 1024; ++i) { From ae2c74ff42f77e6c3a6e19cb7780a1762834ce58 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Wed, 14 May 2008 00:26:00 +0100 Subject: [PATCH 061/245] Tied gui into main lumiera build --- Makefile.am | 3 + configure.ac | 46 ++++++++++ {src/gui/icons => icons}/viewer-panel.png | Bin {src/gui/po => po}/ChangeLog | 0 {src/gui/po => po}/LINGUAS | 0 {src/gui/po => po}/POTFILES.in | 0 src/gui/Makefile.am | 83 +++++++++++++++--- .../{src => }/dialogs/preferences-dialog.cpp | 0 .../{src => }/dialogs/preferences-dialog.hpp | 0 src/gui/{src => }/dialogs/render.cpp | 0 src/gui/{src => }/dialogs/render.hpp | 0 src/gui/{src => }/gtk-lumiera.cpp | 0 src/gui/{src => }/gtk-lumiera.hpp | 0 src/gui/{src => }/lumiera_ui.rc | 0 src/gui/{src => }/model/project.cpp | 0 src/gui/{src => }/model/project.hpp | 0 src/gui/{src => }/output/displayer.cpp | 0 src/gui/{src => }/output/displayer.hpp | 0 src/gui/{src => }/output/gdkdisplayer.cpp | 0 src/gui/{src => }/output/gdkdisplayer.hpp | 0 src/gui/{src => }/output/xvdisplayer.cpp | 0 src/gui/{src => }/output/xvdisplayer.hpp | 0 src/gui/{src => }/panels/assets-panel.cpp | 0 src/gui/{src => }/panels/assets-panel.hpp | 0 src/gui/{src => }/panels/panel.cpp | 0 src/gui/{src => }/panels/panel.hpp | 0 src/gui/{src => }/panels/timeline-panel.cpp | 0 src/gui/{src => }/panels/timeline-panel.hpp | 0 src/gui/{src => }/panels/viewer-panel.cpp | 0 src/gui/{src => }/panels/viewer-panel.hpp | 0 src/gui/src/Makefile.am | 55 ------------ src/gui/{src => }/widgets/timeline-widget.cpp | 0 src/gui/{src => }/widgets/timeline-widget.hpp | 0 .../widgets/video-display-widget.cpp | 0 .../widgets/video-display-widget.hpp | 0 src/gui/{src => }/window-manager.cpp | 0 src/gui/{src => }/window-manager.hpp | 0 src/gui/{src => }/workspace/actions.cpp | 0 src/gui/{src => }/workspace/actions.hpp | 0 .../{src => }/workspace/workspace-window.cpp | 2 +- .../{src => }/workspace/workspace-window.hpp | 0 41 files changed, 121 insertions(+), 68 deletions(-) rename {src/gui/icons => icons}/viewer-panel.png (100%) rename {src/gui/po => po}/ChangeLog (100%) rename {src/gui/po => po}/LINGUAS (100%) rename {src/gui/po => po}/POTFILES.in (100%) rename src/gui/{src => }/dialogs/preferences-dialog.cpp (100%) rename src/gui/{src => }/dialogs/preferences-dialog.hpp (100%) rename src/gui/{src => }/dialogs/render.cpp (100%) rename src/gui/{src => }/dialogs/render.hpp (100%) rename src/gui/{src => }/gtk-lumiera.cpp (100%) rename src/gui/{src => }/gtk-lumiera.hpp (100%) rename src/gui/{src => }/lumiera_ui.rc (100%) rename src/gui/{src => }/model/project.cpp (100%) rename src/gui/{src => }/model/project.hpp (100%) rename src/gui/{src => }/output/displayer.cpp (100%) rename src/gui/{src => }/output/displayer.hpp (100%) rename src/gui/{src => }/output/gdkdisplayer.cpp (100%) rename src/gui/{src => }/output/gdkdisplayer.hpp (100%) rename src/gui/{src => }/output/xvdisplayer.cpp (100%) rename src/gui/{src => }/output/xvdisplayer.hpp (100%) rename src/gui/{src => }/panels/assets-panel.cpp (100%) rename src/gui/{src => }/panels/assets-panel.hpp (100%) rename src/gui/{src => }/panels/panel.cpp (100%) rename src/gui/{src => }/panels/panel.hpp (100%) rename src/gui/{src => }/panels/timeline-panel.cpp (100%) rename src/gui/{src => }/panels/timeline-panel.hpp (100%) rename src/gui/{src => }/panels/viewer-panel.cpp (100%) rename src/gui/{src => }/panels/viewer-panel.hpp (100%) delete mode 100644 src/gui/src/Makefile.am rename src/gui/{src => }/widgets/timeline-widget.cpp (100%) rename src/gui/{src => }/widgets/timeline-widget.hpp (100%) rename src/gui/{src => }/widgets/video-display-widget.cpp (100%) rename src/gui/{src => }/widgets/video-display-widget.hpp (100%) rename src/gui/{src => }/window-manager.cpp (100%) rename src/gui/{src => }/window-manager.hpp (100%) rename src/gui/{src => }/workspace/actions.cpp (100%) rename src/gui/{src => }/workspace/actions.hpp (100%) rename src/gui/{src => }/workspace/workspace-window.cpp (99%) rename src/gui/{src => }/workspace/workspace-window.hpp (100%) diff --git a/Makefile.am b/Makefile.am index 69cc34288..bf4c80872 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,6 +36,9 @@ include $(top_srcdir)/admin/Makefile.am include $(top_srcdir)/src/lib/Makefile.am #include $(top_srcdir)/src/backend/Makefile.am +# gui +include $(top_srcdir)/src/gui/Makefile.am + # plugins #include $(top_srcdir)/src... diff --git a/configure.ac b/configure.ac index 78d76c136..e179d8a24 100644 --- a/configure.ac +++ b/configure.ac @@ -75,5 +75,51 @@ AC_MSG_RESULT([NoBug build level: $nobug_level]) # END NoBug +############## Internatinalization +#GETTEXT_PACKAGE=gtk-lumiera +#AC_SUBST(GETTEXT_PACKAGE) +#AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name]) +#AM_GLIB_GNU_GETTEXT +#IT_PROG_INTLTOOL([0.35.0]) + +# END Internatinalization + + +############## X11 Dependancies +AC_PATH_X +AC_PATH_XTRA +# CFLAGS="$CFLAGS $X_CFLAGS" +LIBS="$LIBS $X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS" + +AC_CHECK_HEADERS([X11/Xlib.h X11/Xutil.h],[], + [AC_MSG_ERROR([Xlib.h or Xutil.h not found install xdevel])]) + +AC_CHECK_HEADERS([sys/ipc.h sys/shm.h],, + [AC_MSG_ERROR([Required header not found. Please check that it is installed])] +) +AC_CHECK_HEADERS([X11/extensions/Xvlib.h X11/extensions/XShm.h],, + [AC_MSG_ERROR([Required xvideo (Xv) extension to X not found. Please check that it is installed.])], + [#include ] +) + +AC_CHECK_LIB(Xext, XInitExtension, , + [AC_MSG_ERROR([Could not link with libXext. Check that you have libXext installed])], -lX11 +) +AC_CHECK_LIB(Xv, XvQueryAdaptors, , + [AC_MSG_ERROR([Could not link with libXv. Check that you have libXv installed])] +) + +# END X11 Dependancies + + +############## Gtk Dependancies +PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.6.1 cairomm-1.0 >= 0.6.0]) + +AC_SUBST(GTK_LUMIERA_CFLAGS) +AC_SUBST(GTK_LUMIERA_LIBS) + +# END Gtk Dependancies + + AC_CONFIG_FILES(Makefile) AC_OUTPUT diff --git a/src/gui/icons/viewer-panel.png b/icons/viewer-panel.png similarity index 100% rename from src/gui/icons/viewer-panel.png rename to icons/viewer-panel.png diff --git a/src/gui/po/ChangeLog b/po/ChangeLog similarity index 100% rename from src/gui/po/ChangeLog rename to po/ChangeLog diff --git a/src/gui/po/LINGUAS b/po/LINGUAS similarity index 100% rename from src/gui/po/LINGUAS rename to po/LINGUAS diff --git a/src/gui/po/POTFILES.in b/po/POTFILES.in similarity index 100% rename from src/gui/po/POTFILES.in rename to po/POTFILES.in diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 50af375e8..818c2f582 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,17 +1,76 @@ -## Process this file with automake to produce Makefile.in +# Copyright (C) Lumiera.org +# 2007, Joel Holdsworth +# +# This program 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 2 of the +# License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -SUBDIRS = src po +lumigui_srcdir = $(top_srcdir)/src/gui +#noinst_LIBRARIES += liblumigui.a -gtk_lumieradocdir = ${prefix}/doc/gtk-lumiera -gtk_lumieradoc_DATA = +#lumigui_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror +#lumigui_CPPFLAGS = -I$(top_srcdir)/src/ -EXTRA_DIST = $(gtk_lumieradoc_DATA) +INCLUDES = \ + -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ + -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \ + -DPACKAGE_DATA_DIR=\""$(datadir)"\" \ + $(GTK_LUMIERA_CFLAGS) -# Copy all the spec files. Of cource, only one is actually used. -dist-hook: - for specfile in *.spec; do \ - if test -f $$specfile; then \ - cp -p $$specfile $(distdir); \ - fi \ - done +AM_CFLAGS =\ + -Wall\ + -g +bin_PROGRAMS += lumigui + +lumigui_SOURCES = \ + $(lumigui_srcdir)/gtk-lumiera.cpp \ + $(lumigui_srcdir)/gtk-lumiera.hpp \ + $(lumigui_srcdir)/window-manager.cpp \ + $(lumigui_srcdir)/window-manager.hpp \ + $(lumigui_srcdir)/workspace/actions.cpp \ + $(lumigui_srcdir)/workspace/actions.hpp \ + $(lumigui_srcdir)/workspace/workspace-window.cpp \ + $(lumigui_srcdir)/workspace/workspace-window.hpp \ + $(lumigui_srcdir)/dialogs/render.cpp \ + $(lumigui_srcdir)/dialogs/render.hpp \ + $(lumigui_srcdir)/dialogs/preferences-dialog.cpp \ + $(lumigui_srcdir)/dialogs/preferences-dialog.hpp \ + $(lumigui_srcdir)/panels/panel.cpp \ + $(lumigui_srcdir)/panels/panel.hpp \ + $(lumigui_srcdir)/panels/timeline-panel.cpp \ + $(lumigui_srcdir)/panels/timeline-panel.hpp \ + $(lumigui_srcdir)/panels/viewer-panel.cpp \ + $(lumigui_srcdir)/panels/viewer-panel.hpp \ + $(lumigui_srcdir)/panels/assets-panel.cpp \ + $(lumigui_srcdir)/panels/asset-panels.hpp \ + $(lumigui_srcdir)/widgets/video-display-widget.cpp \ + $(lumigui_srcdir)/widgets/video-display-widget.hpp \ + $(lumigui_srcdir)/widgets/timeline-widget.cpp \ + $(lumigui_srcdir)/widgets/timeline-widget.hpp \ + $(lumigui_srcdir)/model/project.cpp \ + $(lumigui_srcdir)/model/project.hpp \ + $(lumigui_srcdir)/output/displayer.cpp \ + $(lumigui_srcdir)/output/displayer.hpp \ + $(lumigui_srcdir)/output/gdkdisplayer.cpp \ + $(lumigui_srcdir)/output/gdkdisplayer.hpp \ + $(lumigui_srcdir)/output/xvdisplayer.cpp \ + $(lumigui_srcdir)/output/xvdisplayer.hpp + +lumigui_LDFLAGS = +lumigui_LDADD = $(GTK_LUMIERA_LIBS) + +themesdir = $(datadir)/themes +themes_DATA = $(lumigui_srcdir)/lumiera_ui.rc + +EXTRA_DIST += $(themes_DATA) diff --git a/src/gui/src/dialogs/preferences-dialog.cpp b/src/gui/dialogs/preferences-dialog.cpp similarity index 100% rename from src/gui/src/dialogs/preferences-dialog.cpp rename to src/gui/dialogs/preferences-dialog.cpp diff --git a/src/gui/src/dialogs/preferences-dialog.hpp b/src/gui/dialogs/preferences-dialog.hpp similarity index 100% rename from src/gui/src/dialogs/preferences-dialog.hpp rename to src/gui/dialogs/preferences-dialog.hpp diff --git a/src/gui/src/dialogs/render.cpp b/src/gui/dialogs/render.cpp similarity index 100% rename from src/gui/src/dialogs/render.cpp rename to src/gui/dialogs/render.cpp diff --git a/src/gui/src/dialogs/render.hpp b/src/gui/dialogs/render.hpp similarity index 100% rename from src/gui/src/dialogs/render.hpp rename to src/gui/dialogs/render.hpp diff --git a/src/gui/src/gtk-lumiera.cpp b/src/gui/gtk-lumiera.cpp similarity index 100% rename from src/gui/src/gtk-lumiera.cpp rename to src/gui/gtk-lumiera.cpp diff --git a/src/gui/src/gtk-lumiera.hpp b/src/gui/gtk-lumiera.hpp similarity index 100% rename from src/gui/src/gtk-lumiera.hpp rename to src/gui/gtk-lumiera.hpp diff --git a/src/gui/src/lumiera_ui.rc b/src/gui/lumiera_ui.rc similarity index 100% rename from src/gui/src/lumiera_ui.rc rename to src/gui/lumiera_ui.rc diff --git a/src/gui/src/model/project.cpp b/src/gui/model/project.cpp similarity index 100% rename from src/gui/src/model/project.cpp rename to src/gui/model/project.cpp diff --git a/src/gui/src/model/project.hpp b/src/gui/model/project.hpp similarity index 100% rename from src/gui/src/model/project.hpp rename to src/gui/model/project.hpp diff --git a/src/gui/src/output/displayer.cpp b/src/gui/output/displayer.cpp similarity index 100% rename from src/gui/src/output/displayer.cpp rename to src/gui/output/displayer.cpp diff --git a/src/gui/src/output/displayer.hpp b/src/gui/output/displayer.hpp similarity index 100% rename from src/gui/src/output/displayer.hpp rename to src/gui/output/displayer.hpp diff --git a/src/gui/src/output/gdkdisplayer.cpp b/src/gui/output/gdkdisplayer.cpp similarity index 100% rename from src/gui/src/output/gdkdisplayer.cpp rename to src/gui/output/gdkdisplayer.cpp diff --git a/src/gui/src/output/gdkdisplayer.hpp b/src/gui/output/gdkdisplayer.hpp similarity index 100% rename from src/gui/src/output/gdkdisplayer.hpp rename to src/gui/output/gdkdisplayer.hpp diff --git a/src/gui/src/output/xvdisplayer.cpp b/src/gui/output/xvdisplayer.cpp similarity index 100% rename from src/gui/src/output/xvdisplayer.cpp rename to src/gui/output/xvdisplayer.cpp diff --git a/src/gui/src/output/xvdisplayer.hpp b/src/gui/output/xvdisplayer.hpp similarity index 100% rename from src/gui/src/output/xvdisplayer.hpp rename to src/gui/output/xvdisplayer.hpp diff --git a/src/gui/src/panels/assets-panel.cpp b/src/gui/panels/assets-panel.cpp similarity index 100% rename from src/gui/src/panels/assets-panel.cpp rename to src/gui/panels/assets-panel.cpp diff --git a/src/gui/src/panels/assets-panel.hpp b/src/gui/panels/assets-panel.hpp similarity index 100% rename from src/gui/src/panels/assets-panel.hpp rename to src/gui/panels/assets-panel.hpp diff --git a/src/gui/src/panels/panel.cpp b/src/gui/panels/panel.cpp similarity index 100% rename from src/gui/src/panels/panel.cpp rename to src/gui/panels/panel.cpp diff --git a/src/gui/src/panels/panel.hpp b/src/gui/panels/panel.hpp similarity index 100% rename from src/gui/src/panels/panel.hpp rename to src/gui/panels/panel.hpp diff --git a/src/gui/src/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp similarity index 100% rename from src/gui/src/panels/timeline-panel.cpp rename to src/gui/panels/timeline-panel.cpp diff --git a/src/gui/src/panels/timeline-panel.hpp b/src/gui/panels/timeline-panel.hpp similarity index 100% rename from src/gui/src/panels/timeline-panel.hpp rename to src/gui/panels/timeline-panel.hpp diff --git a/src/gui/src/panels/viewer-panel.cpp b/src/gui/panels/viewer-panel.cpp similarity index 100% rename from src/gui/src/panels/viewer-panel.cpp rename to src/gui/panels/viewer-panel.cpp diff --git a/src/gui/src/panels/viewer-panel.hpp b/src/gui/panels/viewer-panel.hpp similarity index 100% rename from src/gui/src/panels/viewer-panel.hpp rename to src/gui/panels/viewer-panel.hpp diff --git a/src/gui/src/Makefile.am b/src/gui/src/Makefile.am deleted file mode 100644 index 455dcdd60..000000000 --- a/src/gui/src/Makefile.am +++ /dev/null @@ -1,55 +0,0 @@ -## Process this file with automake to produce Makefile.in - -INCLUDES = \ - -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ - -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \ - -DPACKAGE_DATA_DIR=\""$(datadir)"\" \ - $(GTK_LUMIERA_CFLAGS) - -AM_CFLAGS =\ - -Wall\ - -g - -bin_PROGRAMS = gtk-lumiera - -gtk_lumiera_SOURCES = \ - gtk-lumiera.cpp \ - gtk-lumiera.hpp \ - window-manager.cpp \ - window-manager.hpp \ - workspace/actions.cpp \ - workspace/actions.hpp \ - workspace/workspace-window.cpp \ - workspace/workspace-window.hpp \ - dialogs/render.cpp \ - dialogs/render.hpp \ - dialogs/preferences-dialog.cpp \ - dialogs/preferences-dialog.hpp \ - panels/panel.cpp \ - panels/panel.hpp \ - panels/timeline-panel.cpp \ - panels/timeline-panel.hpp \ - panels/viewer-panel.cpp \ - panels/viewer-panel.hpp \ - panels/assets-panel.cpp \ - panels/asset-panels.hpp \ - widgets/video-display-widget.cpp \ - widgets/video-display-widget.hpp \ - widgets/timeline-widget.cpp \ - widgets/timeline-widget.hpp \ - model/project.cpp \ - model/project.hpp \ - output/displayer.cpp \ - output/displayer.hpp \ - output/gdkdisplayer.cpp \ - output/gdkdisplayer.hpp \ - output/xvdisplayer.cpp \ - output/xvdisplayer.hpp - -gtk_lumiera_LDFLAGS = - -gtk_lumiera_LDADD = $(GTK_LUMIERA_LIBS) - -EXTRA_DIST = - - diff --git a/src/gui/src/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp similarity index 100% rename from src/gui/src/widgets/timeline-widget.cpp rename to src/gui/widgets/timeline-widget.cpp diff --git a/src/gui/src/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp similarity index 100% rename from src/gui/src/widgets/timeline-widget.hpp rename to src/gui/widgets/timeline-widget.hpp diff --git a/src/gui/src/widgets/video-display-widget.cpp b/src/gui/widgets/video-display-widget.cpp similarity index 100% rename from src/gui/src/widgets/video-display-widget.cpp rename to src/gui/widgets/video-display-widget.cpp diff --git a/src/gui/src/widgets/video-display-widget.hpp b/src/gui/widgets/video-display-widget.hpp similarity index 100% rename from src/gui/src/widgets/video-display-widget.hpp rename to src/gui/widgets/video-display-widget.hpp diff --git a/src/gui/src/window-manager.cpp b/src/gui/window-manager.cpp similarity index 100% rename from src/gui/src/window-manager.cpp rename to src/gui/window-manager.cpp diff --git a/src/gui/src/window-manager.hpp b/src/gui/window-manager.hpp similarity index 100% rename from src/gui/src/window-manager.hpp rename to src/gui/window-manager.hpp diff --git a/src/gui/src/workspace/actions.cpp b/src/gui/workspace/actions.cpp similarity index 100% rename from src/gui/src/workspace/actions.cpp rename to src/gui/workspace/actions.cpp diff --git a/src/gui/src/workspace/actions.hpp b/src/gui/workspace/actions.hpp similarity index 100% rename from src/gui/src/workspace/actions.hpp rename to src/gui/workspace/actions.hpp diff --git a/src/gui/src/workspace/workspace-window.cpp b/src/gui/workspace/workspace-window.cpp similarity index 99% rename from src/gui/src/workspace/workspace-window.cpp rename to src/gui/workspace/workspace-window.cpp index 66d74e905..c203c7584 100644 --- a/src/gui/src/workspace/workspace-window.cpp +++ b/src/gui/workspace/workspace-window.cpp @@ -32,7 +32,7 @@ #include #include -#include "gtk-lumiera.hpp" +#include "../gtk-lumiera.hpp" #include "workspace-window.hpp" using namespace Gtk; diff --git a/src/gui/src/workspace/workspace-window.hpp b/src/gui/workspace/workspace-window.hpp similarity index 100% rename from src/gui/src/workspace/workspace-window.hpp rename to src/gui/workspace/workspace-window.hpp From 4c9eea2c73eb18e56d5916a3f93c9c23700b2558 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Wed, 14 May 2008 22:02:02 +0100 Subject: [PATCH 062/245] Modified Makefile.am to test lumiera_gui.rc copying failure --- src/gui/Makefile.am | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 818c2f582..c54cd2efb 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -70,7 +70,9 @@ lumigui_SOURCES = \ lumigui_LDFLAGS = lumigui_LDADD = $(GTK_LUMIERA_LIBS) -themesdir = $(datadir)/themes -themes_DATA = $(lumigui_srcdir)/lumiera_ui.rc +$(top_builddir)/lumiera_ui.rc: + echo TEST TEST + exit 1 + +#cp $(lumigui_srcdir)/lumiera_ui.rc $(top_builddir) -EXTRA_DIST += $(themes_DATA) From 0b70cf132a7403eeaaf159b895d37465fe43b2eb Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Wed, 14 May 2008 22:29:05 +0100 Subject: [PATCH 063/245] Copying lumiera_gui.rc now works --- src/gui/Makefile.am | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index c54cd2efb..6fcc0a5a3 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -70,9 +70,7 @@ lumigui_SOURCES = \ lumigui_LDFLAGS = lumigui_LDADD = $(GTK_LUMIERA_LIBS) +lumigui_DEPENDENCIES = $(top_builddir)/lumiera_ui.rc $(top_builddir)/lumiera_ui.rc: - echo TEST TEST - exit 1 - -#cp $(lumigui_srcdir)/lumiera_ui.rc $(top_builddir) + cp $(lumigui_srcdir)/lumiera_ui.rc $(top_builddir) From 1d89341fa42c63fe79ba9054a1198786b9b6afe8 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Wed, 14 May 2008 22:50:53 +0100 Subject: [PATCH 064/245] Removed a couple of redundant files --- src/gui/autogen.sh | 159 ------------------------------------------- src/gui/configure.ac | 77 --------------------- 2 files changed, 236 deletions(-) delete mode 100755 src/gui/autogen.sh delete mode 100644 src/gui/configure.ac diff --git a/src/gui/autogen.sh b/src/gui/autogen.sh deleted file mode 100755 index 5e54fc413..000000000 --- a/src/gui/autogen.sh +++ /dev/null @@ -1,159 +0,0 @@ -#!/bin/sh -# Run this to generate all the initial makefiles, etc. - -srcdir=`dirname $0` -test -z "$srcdir" && srcdir=. - -DIE=0 - -if [ -n "$GNOME2_DIR" ]; then - ACLOCAL_FLAGS="-I $GNOME2_DIR/share/aclocal $ACLOCAL_FLAGS" - LD_LIBRARY_PATH="$GNOME2_DIR/lib:$LD_LIBRARY_PATH" - PATH="$GNOME2_DIR/bin:$PATH" - export PATH - export LD_LIBRARY_PATH -fi - -(test -f $srcdir/configure.ac) || { - echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" - echo " top-level package directory" - exit 1 -} - -(autoconf --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "**Error**: You must have \`autoconf' installed." - echo "Download the appropriate package for your distribution," - echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" - DIE=1 -} - -(grep "^IT_PROG_INTLTOOL" $srcdir/configure.ac >/dev/null) && { - (intltoolize --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "**Error**: You must have \`intltool' installed." - echo "You can get it from:" - echo " ftp://ftp.gnome.org/pub/GNOME/" - DIE=1 - } -} - -(grep "^AM_PROG_XML_I18N_TOOLS" $srcdir/configure.ac >/dev/null) && { - (xml-i18n-toolize --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "**Error**: You must have \`xml-i18n-toolize' installed." - echo "You can get it from:" - echo " ftp://ftp.gnome.org/pub/GNOME/" - DIE=1 - } -} - -(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && { - (libtool --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "**Error**: You must have \`libtool' installed." - echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/" - DIE=1 - } -} - -(grep "^AM_GLIB_GNU_GETTEXT" $srcdir/configure.ac >/dev/null) && { - (grep "sed.*POTFILES" $srcdir/configure.ac) > /dev/null || \ - (glib-gettextize --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "**Error**: You must have \`glib' installed." - echo "You can get it from: ftp://ftp.gtk.org/pub/gtk" - DIE=1 - } -} - -(automake --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "**Error**: You must have \`automake' installed." - echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/" - DIE=1 - NO_AUTOMAKE=yes -} - - -# if no automake, don't bother testing for aclocal -test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "**Error**: Missing \`aclocal'. The version of \`automake'" - echo "installed doesn't appear recent enough." - echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/" - DIE=1 -} - -if test "$DIE" -eq 1; then - exit 1 -fi - -if test -z "$*"; then - echo "**Warning**: I am going to run \`configure' with no arguments." - echo "If you wish to pass any to it, please specify them on the" - echo \`$0\'" command line." - echo -fi - -case $CC in -xlc ) - am_opt=--include-deps;; -esac - -for coin in `find $srcdir -path $srcdir/CVS -prune -o -name configure.ac -print` -do - dr=`dirname $coin` - if test -f $dr/NO-AUTO-GEN; then - echo skipping $dr -- flagged as no auto-gen - else - echo processing $dr - ( cd $dr - - aclocalinclude="$ACLOCAL_FLAGS" - - if grep "^AM_GLIB_GNU_GETTEXT" configure.ac >/dev/null; then - echo "Creating $dr/aclocal.m4 ..." - test -r $dr/aclocal.m4 || touch $dr/aclocal.m4 - echo "Running glib-gettextize... Ignore non-fatal messages." - echo "no" | glib-gettextize --force --copy - echo "Making $dr/aclocal.m4 writable ..." - test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4 - fi - if grep "^IT_PROG_INTLTOOL" configure.ac >/dev/null; then - echo "Running intltoolize..." - intltoolize --copy --force --automake - fi - if grep "^AM_PROG_XML_I18N_TOOLS" configure.ac >/dev/null; then - echo "Running xml-i18n-toolize..." - xml-i18n-toolize --copy --force --automake - fi - if grep "^AM_PROG_LIBTOOL" configure.ac >/dev/null; then - if test -z "$NO_LIBTOOLIZE" ; then - echo "Running libtoolize..." - libtoolize --force --copy - fi - fi - echo "Running aclocal $aclocalinclude ..." - aclocal $aclocalinclude - if grep "^AM_CONFIG_HEADER" configure.ac >/dev/null; then - echo "Running autoheader..." - autoheader - fi - echo "Running automake --foreign $am_opt ..." - automake --add-missing --foreign $am_opt - echo "Running autoconf ..." - autoconf - ) - fi -done - -conf_flags="--enable-maintainer-mode" - -if test x$NOCONFIGURE = x; then - echo Running $srcdir/configure $conf_flags "$@" ... - $srcdir/configure $conf_flags "$@" \ - && echo Now type \`make\' to compile. || exit 1 -else - echo Skipping configure process. -fi diff --git a/src/gui/configure.ac b/src/gui/configure.ac deleted file mode 100644 index 2e3a7cd21..000000000 --- a/src/gui/configure.ac +++ /dev/null @@ -1,77 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. - -AC_INIT(gtk-lumiera, 0.1) - -AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) -AM_CONFIG_HEADER(config.h) -AM_MAINTAINER_MODE - -AC_ISC_POSIX -AC_PROG_CXX -AM_PROG_CC_STDC -AC_HEADER_STDC - - - - -dnl *************************************************************************** -dnl Internatinalization -dnl *************************************************************************** -GETTEXT_PACKAGE=gtk-lumiera -AC_SUBST(GETTEXT_PACKAGE) -AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name]) -AM_GLIB_GNU_GETTEXT -IT_PROG_INTLTOOL([0.35.0]) - - - -AM_PROG_LIBTOOL - - -# ###################################################################### -# Checks for X11 and XVideo -# ###################################################################### -AC_PATH_X -AC_PATH_XTRA -# CFLAGS="$CFLAGS $X_CFLAGS" -LIBS="$LIBS $X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS" - -AC_CHECK_HEADERS([X11/Xlib.h X11/Xutil.h],[], - [AC_MSG_ERROR([Xlib.h or Xutil.h not found install xdevel])]) - -# OK, this is confusing. The old tests test for the existence of a number -# of header files, and add -lXv to the linker flags if they are there. -# However, if they are _not_ there, only a warning is issued, but -# src/displayer.h includes these unconditionally. -# I conclude that -lXv _is_ required. If not, src/displayer.h should be edited, -# I think. -# This test requires libXv and, therefore, libXext - -AC_CHECK_HEADERS([sys/ipc.h sys/shm.h],, - [AC_MSG_ERROR([Required header not found. Please check that it is installed])] -) -AC_CHECK_HEADERS([X11/extensions/Xvlib.h X11/extensions/XShm.h],, - [AC_MSG_ERROR([Required xvideo (Xv) extension to X not found. Please check that it is installed.])], - [#include ] -) - -AC_CHECK_LIB(Xext, XInitExtension, , - [AC_MSG_ERROR([Could not link with libXext. Check that you have libXext installed])], -lX11 -) -AC_CHECK_LIB(Xv, XvQueryAdaptors, , - [AC_MSG_ERROR([Could not link with libXv. Check that you have libXv installed])] -) - -# ###################################################################### -# Checks for GTK stuff -# ###################################################################### -PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.6.1 cairomm-1.0 >= 0.6.0]) - -AC_SUBST(GTK_LUMIERA_CFLAGS) -AC_SUBST(GTK_LUMIERA_LIBS) - -AC_OUTPUT([ -Makefile -src/Makefile -po/Makefile.in -]) From 41d5ff9610a81a3da5850b1bfeff5d394e6155bf Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 15 May 2008 00:04:10 +0100 Subject: [PATCH 065/245] Added an icon to the viewer panel --- src/gui/Makefile.am | 8 ++++++- src/gui/panels/panel.cpp | 16 ++++++++++++-- src/gui/panels/panel.hpp | 9 ++++++++ src/gui/panels/viewer-panel.cpp | 2 +- src/gui/workspace/actions.cpp | 39 ++++++++++++++++++++++++++++++++- src/gui/workspace/actions.hpp | 11 ++++++++-- 6 files changed, 78 insertions(+), 7 deletions(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 6fcc0a5a3..ff02570bd 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -70,7 +70,13 @@ lumigui_SOURCES = \ lumigui_LDFLAGS = lumigui_LDADD = $(GTK_LUMIERA_LIBS) -lumigui_DEPENDENCIES = $(top_builddir)/lumiera_ui.rc +lumigui_DEPENDENCIES = \ + $(top_builddir)/lumiera_ui.rc \ + $(top_builddir)/viewer-panel.png + $(top_builddir)/lumiera_ui.rc: cp $(lumigui_srcdir)/lumiera_ui.rc $(top_builddir) +$(top_builddir)/viewer-panel.png: + cp $(top_srcdir)/icons/viewer-panel.png $(top_builddir) + diff --git a/src/gui/panels/panel.cpp b/src/gui/panels/panel.cpp index 67ac1fd3f..efe3f3b38 100644 --- a/src/gui/panels/panel.cpp +++ b/src/gui/panels/panel.cpp @@ -29,8 +29,14 @@ namespace panels { Panel::Panel(const gchar *name, const gchar *long_name, GdlDockItemBehavior behavior) { dock_item = (GdlDockItem*)gdl_dock_item_new (name, long_name, behavior); - gtk_container_add ((GtkContainer*)dock_item, (GtkWidget*)gobj()); - gtk_widget_show ((GtkWidget*)dock_item); + internal_setup(); +} + +Panel::Panel(const gchar *name, const gchar *long_name, const gchar *stock_id, + GdlDockItemBehavior behavior) +{ + dock_item = (GdlDockItem*)gdl_dock_item_new_with_stock (name, long_name, stock_id, behavior); + internal_setup(); } Panel::~Panel() @@ -43,6 +49,12 @@ GdlDockItem* Panel::get_dock_item() const return dock_item; } +void Panel::internal_setup() +{ + gtk_container_add ((GtkContainer*)dock_item, (GtkWidget*)gobj()); + gtk_widget_show ((GtkWidget*)dock_item); +} + } // namespace panels } // namespace gui } // namespace lumiera diff --git a/src/gui/panels/panel.hpp b/src/gui/panels/panel.hpp index 05cc47dc6..05e180e77 100644 --- a/src/gui/panels/panel.hpp +++ b/src/gui/panels/panel.hpp @@ -40,13 +40,22 @@ namespace panels { class Panel : public Gtk::VBox { protected: + Panel(const gchar *name, const gchar *long_name, GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL); + Panel(const gchar *name, const gchar *long_name, const gchar *stock_id, + GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL); ~Panel(); public: GdlDockItem* get_dock_item() const; + private: + /** + * The internal constructor for this class, whose purpose + * is to set up the internal container widgets. + */ + void internal_setup(); protected: GdlDockItem* dock_item; diff --git a/src/gui/panels/viewer-panel.cpp b/src/gui/panels/viewer-panel.cpp index ea1bfeffd..c5a64f781 100644 --- a/src/gui/panels/viewer-panel.cpp +++ b/src/gui/panels/viewer-panel.cpp @@ -30,7 +30,7 @@ namespace gui { namespace panels { ViewerPanel::ViewerPanel() : - Panel("viewer", "Viewer"), + Panel("viewer", "Viewer", "viewer_panel"), previousButton(Stock::MEDIA_PREVIOUS), rewindButton(Stock::MEDIA_REWIND), playPauseButton(Stock::MEDIA_PLAY), diff --git a/src/gui/workspace/actions.cpp b/src/gui/workspace/actions.cpp index 6d69a8e6a..389c0059a 100644 --- a/src/gui/workspace/actions.cpp +++ b/src/gui/workspace/actions.cpp @@ -38,6 +38,8 @@ namespace workspace { Actions::Actions(WorkspaceWindow &workspace_window) : workspaceWindow(workspace_window) { + register_stock_items(); + actionGroup = ActionGroup::create(); // File menu @@ -63,7 +65,7 @@ namespace workspace { // View Menu actionGroup->add(Action::create("ViewMenu", _("_View"))); - actionGroup->add(Action::create("ViewViewer", _("_Viewer")), + actionGroup->add(Action::create("ViewViewer", Gtk::StockID("viewer_panel")), sigc::mem_fun(*this, &Actions::on_menu_view_viewer)); actionGroup->add(Action::create("ViewTimeline", _("_Timeline")), sigc::mem_fun(*this, &Actions::on_menu_view_timeline)); @@ -74,6 +76,41 @@ namespace workspace { sigc::mem_fun(*this, &Actions::on_menu_help_about) ); } + void + Actions::register_stock_items() + { + RefPtr factory = IconFactory::create(); + add_stock_item(factory, "viewer-panel.png", "viewer_panel", _("_Viewer")); + factory->add_default(); //Add factory to list of factories. + } + + void + Actions::add_stock_item(const Glib::RefPtr& factory, + const Glib::ustring& filepath, + const Glib::ustring& id, const Glib::ustring& label) + { + Gtk::IconSource source; + try + { + //This throws an exception if the file is not found: + source.set_pixbuf( Gdk::Pixbuf::create_from_file(filepath) ); + } + catch(const Glib::Exception& ex) + { + g_message(ex.what().c_str()); + } + + source.set_size(Gtk::ICON_SIZE_SMALL_TOOLBAR); + source.set_size_wildcarded(); //Icon may be scaled. + + Gtk::IconSet icon_set; + icon_set.add_source(source); //More than one source per set is allowed. + + const Gtk::StockID stock_id(id); + factory->add(stock_id, icon_set); + Gtk::Stock::add(Gtk::StockItem(stock_id, label)); + } + /* ===== File Menu Event Handlers ===== */ void diff --git a/src/gui/workspace/actions.hpp b/src/gui/workspace/actions.hpp index 5ec50c33a..9b9092250 100644 --- a/src/gui/workspace/actions.hpp +++ b/src/gui/workspace/actions.hpp @@ -46,12 +46,19 @@ class WorkspaceWindow; private: Actions(WorkspaceWindow &workspace_window); + void register_stock_items(); + + void add_stock_item(const Glib::RefPtr& factory, + const Glib::ustring& filepath, + const Glib::ustring& id, const Glib::ustring& label); + /** - * A reference to the MainWindow which owns - * this helper */ + * A reference to the MainWindow which owns + * this helper */ WorkspaceWindow &workspaceWindow; /* ===== Event Handlers ===== */ + private: void on_menu_file_new_project(); void on_menu_file_open_project(); void on_menu_file_render(); From fdbdfe2493d7d109099a7d2455dfdf54f2f2a4ad Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Fri, 16 May 2008 18:49:32 +0100 Subject: [PATCH 066/245] Added an icon for the timeline --- icons/timeline-panel.png | Bin 0 -> 447 bytes icons/timeline-panel.svg | 415 ++++++++++++++++++++++++++++++ src/gui/Makefile.am | 6 +- src/gui/panels/timeline-panel.cpp | 2 +- src/gui/workspace/actions.cpp | 3 +- 5 files changed, 423 insertions(+), 3 deletions(-) create mode 100644 icons/timeline-panel.png create mode 100644 icons/timeline-panel.svg diff --git a/icons/timeline-panel.png b/icons/timeline-panel.png new file mode 100644 index 0000000000000000000000000000000000000000..91bf10a962e7fd33e70a5eadfe8db1f796294e16 GIT binary patch literal 447 zcmV;w0YLtVP)CRRU+^Y6#W6gA!-nZ zi-OdkM&cq4;b=oY!ru_q(h@|_)DlG?-0%Cm=iCOhv`Mk0122d7;heLabG$f?StR_0 zy8mK;cX)J=R@JhoW>ghbMI;{PvH!(KtgEWkL@Kp|h#(?FksuO%`yV!`Xo~p&C&#A% z6!HZCia`m0v+_9rwMq?uM!f+*tJwmeebvUhDPE^TW6Q?aOlT~jvGh0I*=CE-Sj>op z#`3cA#Qxgen0G^CtG;yuoEtFC&J6&VmHU&%js!3(_lMIR);Zir + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index ff02570bd..5ea08b2a8 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -72,7 +72,8 @@ lumigui_LDADD = $(GTK_LUMIERA_LIBS) lumigui_DEPENDENCIES = \ $(top_builddir)/lumiera_ui.rc \ - $(top_builddir)/viewer-panel.png + $(top_builddir)/viewer-panel.png \ + $(top_builddir)/timeline.png $(top_builddir)/lumiera_ui.rc: cp $(lumigui_srcdir)/lumiera_ui.rc $(top_builddir) @@ -80,3 +81,6 @@ $(top_builddir)/lumiera_ui.rc: $(top_builddir)/viewer-panel.png: cp $(top_srcdir)/icons/viewer-panel.png $(top_builddir) +$(top_builddir)/timeline.png: + cp $(top_srcdir)/icons/timeline.png $(top_builddir) + diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index 7d1de24ea..06e6187e0 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -27,7 +27,7 @@ namespace gui { namespace panels { TimelinePanel::TimelinePanel() : - Panel("timeline", "Timeline") + Panel("timeline", "Timeline", "timeline_panel") { pack_start(timeline_widget); } diff --git a/src/gui/workspace/actions.cpp b/src/gui/workspace/actions.cpp index 389c0059a..73c3d7983 100644 --- a/src/gui/workspace/actions.cpp +++ b/src/gui/workspace/actions.cpp @@ -67,7 +67,7 @@ namespace workspace { actionGroup->add(Action::create("ViewMenu", _("_View"))); actionGroup->add(Action::create("ViewViewer", Gtk::StockID("viewer_panel")), sigc::mem_fun(*this, &Actions::on_menu_view_viewer)); - actionGroup->add(Action::create("ViewTimeline", _("_Timeline")), + actionGroup->add(Action::create("ViewTimeline", Gtk::StockID("timeline_panel")), sigc::mem_fun(*this, &Actions::on_menu_view_timeline)); // Help Menu @@ -81,6 +81,7 @@ namespace workspace { { RefPtr factory = IconFactory::create(); add_stock_item(factory, "viewer-panel.png", "viewer_panel", _("_Viewer")); + add_stock_item(factory, "timeline-panel.png", "timeline_panel", _("_Timeline")); factory->add_default(); //Add factory to list of factories. } From a51d91d7b544cb4c89e10dfcc443c4768986e61b Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Fri, 16 May 2008 18:53:45 +0100 Subject: [PATCH 067/245] Corrected the makefile --- src/gui/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 5ea08b2a8..1373db120 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -81,6 +81,6 @@ $(top_builddir)/lumiera_ui.rc: $(top_builddir)/viewer-panel.png: cp $(top_srcdir)/icons/viewer-panel.png $(top_builddir) -$(top_builddir)/timeline.png: - cp $(top_srcdir)/icons/timeline.png $(top_builddir) +$(top_builddir)/timeline-panel.png: + cp $(top_srcdir)/icons/timeline-panel.png $(top_builddir) From 2d11d5186082aea7b6c818d28700ccafa1268834 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Fri, 16 May 2008 20:17:43 +0200 Subject: [PATCH 068/245] Checks for NoBug (and other) headers have to follow the particular configurations. If not the generated conftest would bail out NoBug complaining that no build level is selected --- configure.ac | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 78d76c136..72c616a17 100644 --- a/configure.ac +++ b/configure.ac @@ -37,9 +37,6 @@ AC_PROG_LIBTOOL # test for headers # AC_STDC_HEADERS -AC_CHECK_HEADER([nobug.h], AC_DEFINE(HAVE_NOBUG_H)) -AC_CHECK_HEADER([execinfo.h], AC_DEFINE(HAVE_EXECINFO_H)) -# there is a warning in nobug, disabled til fixed AC_CHECK_HEADER([valgrind/valgrind.h], AC_DEFINE(HAVE_VALGRIND_VALGRIND_H)) ACX_PTHREAD ##AM_CONDITIONAL([HAVE_THREADING], [test x"$acx_pthread_ok" = xyes]) @@ -71,6 +68,12 @@ AC_ARG_ENABLE(release, AC_HELP_STRING([--enable-release], [select NoBug RELEASE nobug_level=alpha AC_DEFINE(EBUG_ALPHA) )])]) + +AC_CHECK_HEADER([nobug.h], AC_DEFINE(HAVE_NOBUG_H)) +AC_CHECK_HEADER([execinfo.h], AC_DEFINE(HAVE_EXECINFO_H)) +# there is a warning in nobug, disabled til fixed AC_CHECK_HEADER([valgrind/valgrind.h], AC_DEFINE(HAVE_VALGRIND_VALGRIND_H)) + + AC_MSG_RESULT([NoBug build level: $nobug_level]) # END NoBug From 84374507671b5976728b83cd3246679cf65d9d59 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Fri, 16 May 2008 19:23:12 +0100 Subject: [PATCH 069/245] More work on icons --- icons/assets-panel.png | Bin 0 -> 540 bytes icons/timeline-panel.png | Bin 447 -> 453 bytes icons/timeline-panel.svg | 116 ++++++++++++++++++------- src/gui/Makefile.am | 11 ++- src/gui/panels/assets-panel.cpp | 2 +- src/gui/workspace/actions.cpp | 20 +++-- src/gui/workspace/actions.hpp | 3 +- src/gui/workspace/workspace-window.cpp | 3 +- 8 files changed, 111 insertions(+), 44 deletions(-) create mode 100644 icons/assets-panel.png diff --git a/icons/assets-panel.png b/icons/assets-panel.png new file mode 100644 index 0000000000000000000000000000000000000000..9015426153054c0b529b4d9ebdfa06a221d568ac GIT binary patch literal 540 zcmV+%0^|LOP)Vhlm95D^5CAW0*NO~l4h2`Gn+SSXee3p=k!DITN| zloYWEXca63MGv(U^qPobY>b#9Dp8{0UEbTVcsUg#cu}XB*@6F?*_nZVGy!PT%rNk5 zliHE-nb49(%`}10vsV}N{rqDUTQ;Bo7$dnCNIoxON&^{bA}^laGjk880qPdu^yOBT zEWa_clc&Tx2f*4|8y`gof^!a2aQL`dICk+4OK+dE`@k5lTlYsTutSWPkfmY@o;2kB zMZE(6RQjtR27v0WeY98J5hzgEvJDN{um$>(l@Gjpa+{MEra-d|pH&4=2yN1juSixu z;fgT;7AQWtIU$FSo`duYWUHV7)eJ(4YRG+92Ww!@-u*n7y$)#60)BA&kYbGBD?sJP zdQc>%Uxr2wvM|?-q){`MfcjsaLA`SadgR1;mgk#Ysp6f7xO?jg<1;~QC+VXy zJ@MAA0M19>h5)Ouem$!j+riU-~Y#ZtnKd2kxFF@Gk?R(=ynaW?xnwCgX&&m z1weh}{RBYc~1N zGA7O*oifT}%9w~fR>s7?2Y-3;aJujVL0oXjajNBK73k}B;KvQl_cIQy_O^vU%iwh7GBIt60>v9C5h>osUt~*_02}r y%<5)VyWtw!X4V`zK0dj2EH^kL+?{a$pXnTgN1ipT4s-ed0000P-*3uG0(9{w|Al&c!yyx5owX{jGr2{XA_u-tgoO8T5j#(u9 zg}VP@fOmLwkXF^QsAg0ZRYfEo=CS|9N35%=)kG?_gNPs^M1PSW5`Ft0HmPWe`2Z)! zrvMc41ptac34pWmIRLdv4S+_y0YIzS0-$}>#=9wAr$b}Q#@I|~ETOUVH{RK1i_loi zh=s=Tvhu|K+TNIVLu0GHbpxCmFwV{m0GO5glg5q&Fe~?m(;e11+(_fXS-9U%ev)fu zVbc+G@+|Lq6jOr|FRRbwnpxh~UkN&S!sG{ydV{;@mRvK-i3y;K$M_os(%>V!Z07*qoM6N<$f{?POKmY&$ diff --git a/icons/timeline-panel.svg b/icons/timeline-panel.svg index f77c1c0a0..306f56c9b 100644 --- a/icons/timeline-panel.svg +++ b/icons/timeline-panel.svg @@ -14,7 +14,7 @@ id="svg2677" sodipodi:version="0.32" inkscape:version="0.46" - sodipodi:docname="timeline.svg" + sodipodi:docname="timeline-panel.svg" version="1.0" inkscape:output_extension="org.inkscape.output.svg.inkscape" inkscape:export-filename="/home/joel/workspace/lumiera/lumiera/icons/timeline.png" @@ -331,16 +331,84 @@ y1="9" x2="16" y2="9" /> + + + + + + + + id="mask2463"> + height="16" + x="0" + y="0" /> - + - - + d="M 0 4 L 0 5 L 0 6 L 0 10 L 0 11 L 0 12 L 16 12 L 16 11 L 15 11 L 15 10 L 16 10 L 16 6 L 15 6 L 15 5 L 16 5 L 16 4 L 0 4 z M 1 5 L 2 5 L 2 6 L 1 6 L 1 5 z M 3 5 L 4 5 L 4 6 L 3 6 L 3 5 z M 5 5 L 6 5 L 6 6 L 5 6 L 5 5 z M 7 5 L 8 5 L 8 6 L 7 6 L 7 5 z M 9 5 L 10 5 L 10 6 L 9 6 L 9 5 z M 11 5 L 12 5 L 12 6 L 11 6 L 11 5 z M 13 5 L 14 5 L 14 6 L 13 6 L 13 5 z M 1 10 L 2 10 L 2 11 L 1 11 L 1 10 z M 3 10 L 4 10 L 4 11 L 3 11 L 3 10 z M 5 10 L 6 10 L 6 11 L 5 11 L 5 10 z M 7 10 L 8 10 L 8 11 L 7 11 L 7 10 z M 9 10 L 10 10 L 10 11 L 9 11 L 9 10 z M 11 10 L 12 10 L 12 11 L 11 11 L 11 10 z M 13 10 L 14 10 L 14 11 L 13 11 L 13 10 z " + style="fill:url(#linearGradient2444);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" /> + style="fill:url(#linearGradient2433);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" /> add(Action::create("ViewMenu", _("_View"))); - actionGroup->add(Action::create("ViewViewer", Gtk::StockID("viewer_panel")), - sigc::mem_fun(*this, &Actions::on_menu_view_viewer)); + actionGroup->add(Action::create("ViewAssets", Gtk::StockID("assets_panel")), + sigc::mem_fun(*this, &Actions::on_menu_view_assets)); actionGroup->add(Action::create("ViewTimeline", Gtk::StockID("timeline_panel")), sigc::mem_fun(*this, &Actions::on_menu_view_timeline)); + actionGroup->add(Action::create("ViewViewer", Gtk::StockID("viewer_panel")), + sigc::mem_fun(*this, &Actions::on_menu_view_viewer)); + // Help Menu actionGroup->add(Action::create("HelpMenu", _("_Help")) ); @@ -80,8 +83,9 @@ namespace workspace { Actions::register_stock_items() { RefPtr factory = IconFactory::create(); - add_stock_item(factory, "viewer-panel.png", "viewer_panel", _("_Viewer")); + add_stock_item(factory, "assets-panel.png", "assets_panel", _("_Assets")); add_stock_item(factory, "timeline-panel.png", "timeline_panel", _("_Timeline")); + add_stock_item(factory, "viewer-panel.png", "viewer_panel", _("_Viewer")); factory->add_default(); //Add factory to list of factories. } @@ -147,9 +151,9 @@ namespace workspace { } void - Actions::on_menu_view_viewer() + Actions::on_menu_view_assets() { - //workspaceWindow.viewer_panel.show(); + //workspaceWindow.timeline_panel.show(); } void @@ -158,6 +162,12 @@ namespace workspace { //workspaceWindow.timeline_panel.show(); } + void + Actions::on_menu_view_viewer() + { + //workspaceWindow.viewer_panel.show(); + } + void Actions::on_menu_help_about() { diff --git a/src/gui/workspace/actions.hpp b/src/gui/workspace/actions.hpp index 9b9092250..1c2c2ff05 100644 --- a/src/gui/workspace/actions.hpp +++ b/src/gui/workspace/actions.hpp @@ -66,8 +66,9 @@ class WorkspaceWindow; void on_menu_edit_preferences(); - void on_menu_view_viewer(); + void on_menu_view_assets(); void on_menu_view_timeline(); + void on_menu_view_viewer(); void on_menu_help_about(); diff --git a/src/gui/workspace/workspace-window.cpp b/src/gui/workspace/workspace-window.cpp index c203c7584..c2c46d61b 100644 --- a/src/gui/workspace/workspace-window.cpp +++ b/src/gui/workspace/workspace-window.cpp @@ -91,8 +91,9 @@ namespace workspace { " " "
" " " - " " + " " " " + " " " " " " " " From 88fc2f6099cc1be48de1ab94d079f5e2ff41a486 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 17 May 2008 04:34:46 +0200 Subject: [PATCH 070/245] WIP reworked to replace boost::variant by a custom solution Not a big simplification, but at least the actual codepath is shorter, while it's not so general as boost::variant (and not threadsafe!) --- src/common/typelistutil.hpp | 2 +- src/tool/try.cpp | 212 +++++++++- .../proc/mobject/builder/buildertooltest.cpp | 400 +++++++++++++++++- 3 files changed, 588 insertions(+), 26 deletions(-) diff --git a/src/common/typelistutil.hpp b/src/common/typelistutil.hpp index 4e382df3d..f7a716024 100644 --- a/src/common/typelistutil.hpp +++ b/src/common/typelistutil.hpp @@ -136,7 +136,7 @@ namespace lumiera > { public: - typedef InstantiateChained Next; + typedef InstantiateChained Next; typedef _X_ Unit; }; diff --git a/src/tool/try.cpp b/src/tool/try.cpp index da5ca97c0..85a3286a0 100644 --- a/src/tool/try.cpp +++ b/src/tool/try.cpp @@ -9,35 +9,235 @@ // 1/08 - check 64bit longs // 4/08 - comparison operators on shared_ptr // 4/08 - conversions on the value_type used for boost::any +// 5/08 - how to guard a downcasting access, so it is compiled in only if the involved types are convertible #include #include #include -#include +#include +#include +#include +#include +#include +#include using std::string; using std::cout; +using std::ostream; + + + using boost::remove_pointer; + using boost::remove_reference; + using boost::is_convertible; + using boost::is_polymorphic; + using boost::is_base_of; + using boost::enable_if; + + template + struct can_cast : boost::false_type {}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + + template + struct has_RTTI + { + typedef typename remove_pointer< + typename remove_reference::type>::type TPlain; + + enum { value = is_polymorphic::value }; + }; + + template + struct use_dynamic_downcast + { + enum { value = can_cast::value + && has_RTTI::value + && has_RTTI::value + }; + }; + + template + struct use_static_downcast + { + enum { value = can_cast::value + && ( !has_RTTI::value + || !has_RTTI::value + ) + }; + }; + + template + struct use_conversion + { + enum { value = is_convertible::value + && !( use_static_downcast::value + ||use_dynamic_downcast::value + ) + }; + }; + + + template + struct EmptyVal + { + static X create() + { + cout << " NULL() " << __PRETTY_FUNCTION__ <<"\n"; + return X(); + } + }; + template + struct EmptyVal + { + static X*& create() + { + cout << " NULL & " << __PRETTY_FUNCTION__ <<"\n"; + static X* null(0); + return null; + } + }; + + + template + struct NullAccessor + { + typedef RET Ret; + + static RET access (...) { return ifEmpty(); } + static RET ifEmpty () { return EmptyVal::create(); } + }; + + template + struct AccessCasted : NullAccessor + { + using NullAccessor::access; + + template + static typename enable_if< use_dynamic_downcast, TAR>::type + access (ELM& elem) + { + cout << " dynamic " << __PRETTY_FUNCTION__ <<"\n"; + return dynamic_cast (elem); + } + + template + static typename enable_if< use_static_downcast, TAR>::type + access (ELM& elem) + { + cout << " static " << __PRETTY_FUNCTION__ <<"\n"; + return static_cast (elem); + } + + template + static typename enable_if< use_conversion, TAR>::type + access (ELM& elem) + { + cout << " convert " << __PRETTY_FUNCTION__ <<"\n"; + return elem; + } + + }; + -using boost::any; -using boost::any_cast; struct B {}; struct D : B {}; -int main (int argc, char* argv[]) +struct E : D + { + virtual ~E() {}; + }; +struct F : E {}; + + +ostream& operator<< (ostream& s, const B& b) { return s << "B{} adr="<<&b; } +ostream& operator<< (ostream& s, const D& d) { return s << "D{} adr="<<&d; } +ostream& operator<< (ostream& s, const E& e) { return s << "E{} adr="<<&e; } +ostream& operator<< (ostream& s, const F& f) { return s << "F{} adr="<<&f; } + +int +main (int argc, char* argv[]) { NOBUG_INIT; D d; D* pD =&d; + B* pB =pD; + D& rD = *pD; + B& rB = *pB; + + D*& rpD = pD; + B*& rpB = pB; + + F f; + E& rE = f; + E* pE = &f; + D* pDE = pE; - any aD (pD); - any_cast (aD); + cout << "is_base_of = " << is_base_of::value << "\n"; + cout << "is_base_of = " << is_base_of::value << "\n"; + cout << "is_base_of = " << is_base_of::value << "\n"; + + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + + cout << "has_RTTI = " << has_RTTI::value << "\n"; + cout << "has_RTTI = " << has_RTTI::value << "\n"; + cout << "has_RTTI = " << has_RTTI::value << "\n"; + + + cout << "use_dynamic_downcast = " << use_dynamic_downcast::value << "\n"; + cout << "use_static_downcast = " << use_static_downcast::value << "\n"; + cout << "use_conversion = " << use_conversion::value << "\n"; + + cout << "use_static_downcast = " << use_static_downcast::value << "\n"; + cout << "use_static_downcast = " << use_static_downcast::value << "\n"; + cout << "use_dynamic_downcast = " << use_dynamic_downcast::value << "\n"; + + + cout << "Access(D as D&) --->" << AccessCasted::access(d) << "\n"; + cout << "Access(D& as D&) --->" << AccessCasted::access(rD) << "\n"; + cout << "Access(B& as D&) --->" << AccessCasted::access(rB) << "\n"; + cout << "Access(D* as D*) --->" << AccessCasted::access(pD) << "\n"; + cout << "Access(B* as D*) --->" << AccessCasted::access(pB) << "\n"; + cout << "Access(D*& as D*&) --->" << AccessCasted::access(rpD) << "\n"; + cout << "Access(B*& as D*&) --->" << AccessCasted::access(rpB) << "\n"; + + cout << "Access(D as B&) --->" << AccessCasted::access(d) << "\n"; + cout << "Access(D& as B&) --->" << AccessCasted::access(rD) << "\n"; + cout << "Access(B& as B&) --->" << AccessCasted::access(rB) << "\n"; + cout << "Access(D* as B*) --->" << AccessCasted::access(pD) << "\n"; + cout << "Access(B* as B*) --->" << AccessCasted::access(pB) << "\n"; + cout << "Access(D*& as B*&) --->" << AccessCasted::access(rpD) << "\n"; + cout << "Access(B*& as B*&) --->" << AccessCasted::access(rpB) << "\n"; + + cout << "Access(D as E&) --->" << AccessCasted::access(d) << "\n"; + cout << "Access(E& as F&) --->" << AccessCasted::access(rE) << "\n"; + cout << "Access(D(E)* as E*) --->" << AccessCasted::access(pDE) << "\n"; + cout << "Access(D(E)* as F*) --->" << AccessCasted::access(pDE) << "\n"; + cout << "Access(E* as F*) --->" << AccessCasted::access(pE) << "\n"; + cout << "\ngulp\n"; diff --git a/tests/components/proc/mobject/builder/buildertooltest.cpp b/tests/components/proc/mobject/builder/buildertooltest.cpp index f9adc1308..6495bb795 100644 --- a/tests/components/proc/mobject/builder/buildertooltest.cpp +++ b/tests/components/proc/mobject/builder/buildertooltest.cpp @@ -32,7 +32,15 @@ #include "proc/mobject/placement.hpp" #include "proc/mobject/explicitplacement.hpp" //////////TODO -#include +#include "common/typelistutil.hpp" + +#include +#include +#include +#include +#include + +//#include #include using std::string; using std::cout; @@ -65,8 +73,359 @@ namespace mobject - vieleicht einen allgemeinen Argument-Adapter nutzen? - Zielobjekt oder Wrapper als Argumenttyp? */ - struct Nothing {}; + + using boost::enable_if; + using boost::is_convertible; + + using lumiera::typelist::Types; + using lumiera::typelist::Node; + using lumiera::typelist::NullType; +// using lumiera::typelist::count; +// using lumiera::typelist::maxSize; + using lumiera::typelist::InstantiateChained; + + template + < class TYPES // List of Types + , template class _X_ // your-template-goes-here + , class BASE = NullType // Base class at end of chain + , uint i = 0 // incremented on each instantiaton + > + class InstantiateWithIndex; + + + template< template class _X_ + , class BASE + , uint i + > + class InstantiateWithIndex + : public BASE + { + public: + typedef BASE Unit; + typedef NullType Next; + enum{ COUNT = i }; + }; + + template + < class TY, typename TYPES + , template class _X_ + , class BASE + , uint i + > + class InstantiateWithIndex, _X_, BASE, i> + : public _X_< TY + , InstantiateWithIndex + , i + > + { + public: + typedef InstantiateWithIndex Next; + typedef _X_ Unit; + enum{ COUNT = Next::COUNT }; + }; + + template + struct count; + template<> + struct count + { + enum{ value = 0 }; + }; + template + struct count > + { + enum{ value = 1 + count::value }; + }; + + template + struct maxSize; + template<> + struct maxSize + { + enum{ value = 0 }; + }; + template + struct maxSize > + { + enum{ nextval = maxSize::value + , thisval = sizeof(TY) + , value = nextval > thisval? nextval:thisval + }; + }; + + + + template + struct Holder + { + T content; + + Holder (T const& src) : T(src) {} + + template + TAR get () { return static_cast (content); } + }; + + typedef Types < Placement* + , P* + > ::List + WrapperTypes; + + template + struct EmptyVal + { + static X create() + { + return X(); + } + }; + template + struct EmptyVal + { + static X*& create() + { + static X* null(0); + return null; + } + }; + + + const uint TYPECNT = count::value; + const size_t SIZE = maxSize::value; + + struct Buffer + { + char buffer_[SIZE]; + uint which; + + Buffer() : which(TYPECNT) {} + + void* + put (void) + { + deleteCurrent(); + return 0; + } + + void + deleteCurrent (); // depends on the Deleter, see below + }; + + template + struct Storage : BASE + { + T& + put (T const& toStore) + { + BASE::deleteCurrent(); // remove old content, if any + + T& storedObj = *new(BASE::buffer_) T (toStore); + this->which = idx; // remember the actual type selected + return storedObj; + } + + using BASE::put; + }; + + + + template + struct CaseSelect + { + typedef typename FUNCTOR::Ret Ret; + typedef Ret (*Func)(Buffer&); + + Func table_[TYPECNT]; + + CaseSelect () + { + for (uint i=0; i + static Ret + trampoline (Buffer& storage) + { + T& content = reinterpret_cast (storage.buffer_); + return FUNCTOR::access (content); + } + + template + void + create_thunk (uint idx) + { + Func thunk = &trampoline; + table_[idx] = thunk; + } + + Ret + invoke (Buffer& storage) + { + if (TYPECNT <= storage.which) + return FUNCTOR::ifEmpty (); + else + return (*table_[storage.which]) (storage); + } + }; + + + template< class T, class BASE, uint i > + struct CasePrepare + : BASE + { + CasePrepare () : BASE() + { +// BASE::table_[i] = &(BASE::template trampoline); + BASE::template create_thunk(i); + } + }; + + + template + typename FUNCTOR::Ret + access (Buffer& buf) + { + typedef InstantiateWithIndex< WrapperTypes + , CasePrepare + , CaseSelect + > + Accessor; + static Accessor select_case; + return select_case.invoke(buf); + } + + + struct Deleter + { + typedef void Ret; + + template + static void access (T& elem) { elem.~T(); } + + static void ifEmpty () { } + }; + + + void + Buffer::deleteCurrent () + { + access(*this); // remove old content, if any + which = TYPECNT; // mark as empty + } + + + + + + + using boost::remove_pointer; + using boost::remove_reference; + using boost::is_convertible; + using boost::is_polymorphic; + using boost::is_base_of; + using boost::enable_if; + + template + struct can_cast : boost::false_type {}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + + template + struct has_RTTI + { + typedef typename remove_pointer< + typename remove_reference::type>::type TPlain; + + enum { value = is_polymorphic::value }; + }; + + template + struct use_dynamic_downcast + { + enum { value = can_cast::value + && has_RTTI::value + && has_RTTI::value + }; + }; + + template + struct use_static_downcast + { + enum { value = can_cast::value + && ( !has_RTTI::value + || !has_RTTI::value + ) + }; + }; + + template + struct use_conversion + { + enum { value = is_convertible::value + && !( use_static_downcast::value + ||use_dynamic_downcast::value + ) + }; + }; + + + + + + template + struct NullAccessor + { + typedef RET Ret; + + static RET access (...) { return ifEmpty(); } + static RET ifEmpty () { return EmptyVal::create(); } + }; + + template + struct AccessCasted : NullAccessor + { + using NullAccessor::access; + + template + static typename enable_if< use_dynamic_downcast, TAR>::type + access (ELM& elem) + { + return dynamic_cast (elem); + } + + template + static typename enable_if< use_static_downcast, TAR>::type + access (ELM& elem) + { + return static_cast (elem); + } + + template + static typename enable_if< use_conversion, TAR>::type + access (ELM& elem) + { + return elem; + } + + }; + + + + + + + + /** * helper to treat various sorts of smart-ptrs uniformly. * Implemented as a variant-type value object, it is preconfigured @@ -80,32 +439,33 @@ namespace mobject class WrapperPtr // NONCOPYABLE!! { - template - struct accessor; - - template class WRA, class TAR> - struct accessor< WRA > - : public boost::static_visitor*> - { - template WRA* operator() (X&) { return 0; } - template WRA* operator() (WRA& stored) { return static_cast*> (stored); } - }; private: + typedef InstantiateWithIndex< WrapperTypes + , Storage + , Buffer + > + VariantHolder; + /** storage: buffer holding either and "empty" marker, * or one of the configured pointer to wrapper types */ - boost::variant*, P*> holder_; + VariantHolder holder_; public: - void reset () { holder_ = Nothing(); } + void + reset () + { + access (holder_); + holder_.which = TYPECNT; + } template WrapperPtr& operator= (WRA* src) ///< store a ptr to the given wrapper, after casting to base { - if (src) holder_ = src; - else holder_ = Nothing(); + if (src) holder_.put (src); + else reset(); return *this; } @@ -113,8 +473,8 @@ namespace mobject WRA* get () ///< retrieve ptr and try to downcast to type WRA { - accessor acc; - WRA* res = boost::apply_visitor(acc, this->holder_); + typedef AccessCasted AccessWraP; + WRA* res = access(this->holder_); return res; } }; @@ -244,7 +604,8 @@ namespace mobject void treat (Clip& c) { Placement& pC = getPlacement(); - cout << "media is: "<< str(pC->getMedia()) <<"\n"; + cout << "media is: "<< str(pC->getMedia()) <<"\n" + << "Placement(adr) " << &pC <<"\n"; } void treat (AbstractMO&) { @@ -291,6 +652,7 @@ namespace mobject Placement clip = asset::Media::create("test-1", asset::VIDEO)->createClip(); + cout << "Placement(adr) " << &clip <<"\n"; apply (tool, clip); cout << "Placement(adr) " << &dumm <<"\n"; apply (tool, dummy); From df5c40fd6302397d90a82b57353ed449873e272a Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 17 May 2008 11:20:49 +0100 Subject: [PATCH 071/245] Panels can now be show and hidden More documentation added to Panel --- src/gui/panels/assets-panel.cpp | 2 +- src/gui/panels/panel.cpp | 21 ++++++++++++--- src/gui/panels/panel.hpp | 31 +++++++++++++++++++++- src/gui/panels/timeline-panel.cpp | 2 +- src/gui/panels/viewer-panel.cpp | 2 +- src/gui/workspace/actions.cpp | 44 ++++++++++++++++++++++++------- src/gui/workspace/actions.hpp | 21 ++++++++++++--- 7 files changed, 104 insertions(+), 19 deletions(-) diff --git a/src/gui/panels/assets-panel.cpp b/src/gui/panels/assets-panel.cpp index 81d449ffb..47aeb5379 100644 --- a/src/gui/panels/assets-panel.cpp +++ b/src/gui/panels/assets-panel.cpp @@ -27,7 +27,7 @@ namespace gui { namespace panels { AssetsPanel::AssetsPanel() : - Panel("assets", "Assets", "assets_panel"), + Panel("assets", _("Assets"), "assets_panel"), placeholder("Placeholder label. Is this supposed to be titled assets\nas in the proc layer? or resources\nas in cinelerra?") { pack_start(placeholder); diff --git a/src/gui/panels/panel.cpp b/src/gui/panels/panel.cpp index efe3f3b38..81dbf9092 100644 --- a/src/gui/panels/panel.cpp +++ b/src/gui/panels/panel.cpp @@ -41,15 +41,30 @@ Panel::Panel(const gchar *name, const gchar *long_name, const gchar *stock_id, Panel::~Panel() { - + #warning Im not sure that dock_item is freed - is it self deleting? } -GdlDockItem* Panel::get_dock_item() const +GdlDockItem* +Panel::get_dock_item() const { return dock_item; } -void Panel::internal_setup() +void +Panel::show(bool show) +{ + if(show) gdl_dock_item_show_item (dock_item); + else gdl_dock_item_hide_item (dock_item); +} + +bool +Panel::is_shown() const +{ + return GTK_WIDGET_VISIBLE((GtkWidget*)dock_item); +} + +void +Panel::internal_setup() { gtk_container_add ((GtkContainer*)dock_item, (GtkWidget*)gobj()); gtk_widget_show ((GtkWidget*)dock_item); diff --git a/src/gui/panels/panel.hpp b/src/gui/panels/panel.hpp index 05e180e77..6769f32d7 100644 --- a/src/gui/panels/panel.hpp +++ b/src/gui/panels/panel.hpp @@ -40,18 +40,47 @@ namespace panels { class Panel : public Gtk::VBox { protected: - + /** + * Constructs a panel object + * @param name The internal name of this panel + * @param long_name The name to display on the caption + * @param behavior The GDL behaviour of this item + */ Panel(const gchar *name, const gchar *long_name, GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL); + + /** + * Constructs a panel object with a stock item for a caption + * @param name The internal name of this panel + * @param long_name The name to display on the caption + * @param stock_id The id of the stock item to display on the caption + * @param behavior The GDL behaviour of this item + */ Panel(const gchar *name, const gchar *long_name, const gchar *stock_id, GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL); + ~Panel(); public: + /** + * Returns a pointer to the underlying GdlDockItem structure + */ GdlDockItem* get_dock_item() const; + /** + * Shows or hides the panel. + * @param show A value of true will show the panel, + * false will hide it. */ + void show(bool show = true); + + /** + * Returns true if the panel is currently visible. + */ + bool is_shown() const; + private: /** + * @internal Used by both constructors * The internal constructor for this class, whose purpose * is to set up the internal container widgets. */ diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index 06e6187e0..a7a8b2b46 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -27,7 +27,7 @@ namespace gui { namespace panels { TimelinePanel::TimelinePanel() : - Panel("timeline", "Timeline", "timeline_panel") + Panel("timeline", _("Timeline"), "timeline_panel") { pack_start(timeline_widget); } diff --git a/src/gui/panels/viewer-panel.cpp b/src/gui/panels/viewer-panel.cpp index c5a64f781..223d1a572 100644 --- a/src/gui/panels/viewer-panel.cpp +++ b/src/gui/panels/viewer-panel.cpp @@ -30,7 +30,7 @@ namespace gui { namespace panels { ViewerPanel::ViewerPanel() : - Panel("viewer", "Viewer", "viewer_panel"), + Panel("viewer", _("Viewer"), "viewer_panel"), previousButton(Stock::MEDIA_PREVIOUS), rewindButton(Stock::MEDIA_REWIND), playPauseButton(Stock::MEDIA_PLAY), diff --git a/src/gui/workspace/actions.cpp b/src/gui/workspace/actions.cpp index bb1c75a35..0e939f356 100644 --- a/src/gui/workspace/actions.cpp +++ b/src/gui/workspace/actions.cpp @@ -65,18 +65,29 @@ namespace workspace { // View Menu actionGroup->add(Action::create("ViewMenu", _("_View"))); - actionGroup->add(Action::create("ViewAssets", Gtk::StockID("assets_panel")), - sigc::mem_fun(*this, &Actions::on_menu_view_assets)); - actionGroup->add(Action::create("ViewTimeline", Gtk::StockID("timeline_panel")), - sigc::mem_fun(*this, &Actions::on_menu_view_timeline)); - actionGroup->add(Action::create("ViewViewer", Gtk::StockID("viewer_panel")), - sigc::mem_fun(*this, &Actions::on_menu_view_viewer)); + + assetsPanelAction = ToggleAction::create("ViewAssets", Gtk::StockID("assets_panel")); + assetsPanelAction->signal_toggled().connect( + sigc::mem_fun(*this, &Actions::on_menu_view_assets)); + actionGroup->add(assetsPanelAction); + + timelinePanelAction = ToggleAction::create("ViewTimeline", Gtk::StockID("timeline_panel")); + timelinePanelAction->signal_toggled().connect( + sigc::mem_fun(*this, &Actions::on_menu_view_timeline)); + actionGroup->add(timelinePanelAction); + viewerPanelAction = ToggleAction::create("ViewViewer", Gtk::StockID("viewer_panel")); + viewerPanelAction->signal_toggled().connect( + sigc::mem_fun(*this, &Actions::on_menu_view_viewer)); + actionGroup->add(viewerPanelAction); // Help Menu actionGroup->add(Action::create("HelpMenu", _("_Help")) ); actionGroup->add(Action::create("HelpAbout", Stock::ABOUT), sigc::mem_fun(*this, &Actions::on_menu_help_about) ); + + // Refresh the UI state + update_action_state(); } void @@ -116,6 +127,14 @@ namespace workspace { Gtk::Stock::add(Gtk::StockItem(stock_id, label)); } + void + Actions::update_action_state() + { + assetsPanelAction->set_active(workspaceWindow.assets_panel.is_shown()); + timelinePanelAction->set_active(workspaceWindow.timeline_panel.is_shown()); + viewerPanelAction->set_active(workspaceWindow.viewer_panel.is_shown()); + } + /* ===== File Menu Event Handlers ===== */ void @@ -143,6 +162,8 @@ namespace workspace { workspaceWindow.hide(); // Closes the main window to stop the Gtk::Main::run(). } + /* ===== Edit Menu Event Handlers ===== */ + void Actions::on_menu_edit_preferences() { @@ -150,22 +171,27 @@ namespace workspace { dialog.run(); } + /* ===== View Menu Event Handlers ===== */ + void Actions::on_menu_view_assets() { - //workspaceWindow.timeline_panel.show(); + workspaceWindow.assets_panel.show(!workspaceWindow.assets_panel.is_shown()); + update_action_state(); } void Actions::on_menu_view_timeline() { - //workspaceWindow.timeline_panel.show(); + workspaceWindow.timeline_panel.show(!workspaceWindow.timeline_panel.is_shown()); + update_action_state(); } void Actions::on_menu_view_viewer() { - //workspaceWindow.viewer_panel.show(); + workspaceWindow.viewer_panel.show(!workspaceWindow.viewer_panel.is_shown()); + update_action_state(); } void diff --git a/src/gui/workspace/actions.hpp b/src/gui/workspace/actions.hpp index 1c2c2ff05..c68ce8de4 100644 --- a/src/gui/workspace/actions.hpp +++ b/src/gui/workspace/actions.hpp @@ -46,12 +46,22 @@ class WorkspaceWindow; private: Actions(WorkspaceWindow &workspace_window); - void register_stock_items(); + /* ===== Internals ===== */ + private: + /** + * Registers application stock items: icons and + * labels associated with IDs */ + static void register_stock_items(); - void add_stock_item(const Glib::RefPtr& factory, + static void add_stock_item(const Glib::RefPtr& factory, const Glib::ustring& filepath, const Glib::ustring& id, const Glib::ustring& label); + /** + * Updates the state of the menu/toolbar actions + * to reflect the current state of the workspace */ + void update_action_state(); + /** * A reference to the MainWindow which owns * this helper */ @@ -75,9 +85,14 @@ class WorkspaceWindow; // Temporary Junk void on_menu_others(); + /* ===== Actions ===== */ + private: Glib::RefPtr actionGroup; - Glib::RefPtr m_refChoiceOne, m_refChoiceTwo; + + Glib::RefPtr assetsPanelAction; + Glib::RefPtr timelinePanelAction; + Glib::RefPtr viewerPanelAction; friend class WorkspaceWindow; }; From 5f8c9a2a1259a7e34ba8b02037cfd7fec6739b63 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 17 May 2008 18:12:07 +0100 Subject: [PATCH 072/245] Corrected 3 build errors --- src/gui/panels/assets-panel.cpp | 1 + src/gui/panels/timeline-panel.cpp | 1 + src/gui/panels/viewer-panel.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/src/gui/panels/assets-panel.cpp b/src/gui/panels/assets-panel.cpp index 47aeb5379..431b92019 100644 --- a/src/gui/panels/assets-panel.cpp +++ b/src/gui/panels/assets-panel.cpp @@ -20,6 +20,7 @@ * *****************************************************/ +#include "../gtk-lumiera.hpp" #include "assets-panel.hpp" namespace lumiera { diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index a7a8b2b46..f2a29fd61 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -20,6 +20,7 @@ * *****************************************************/ +#include "../gtk-lumiera.hpp" #include "timeline-panel.hpp" namespace lumiera { diff --git a/src/gui/panels/viewer-panel.cpp b/src/gui/panels/viewer-panel.cpp index 223d1a572..ff64138ed 100644 --- a/src/gui/panels/viewer-panel.cpp +++ b/src/gui/panels/viewer-panel.cpp @@ -20,6 +20,7 @@ * *****************************************************/ +#include "../gtk-lumiera.hpp" #include "viewer-panel.hpp" using namespace lumiera::gui::widgets; From 19fd89d13ddd392e6c244c2a3889f361896317bf Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Sat, 17 May 2008 20:00:05 +0200 Subject: [PATCH 073/245] cleanup and add more configure checks * GNU_SOURCE by default now * improved use of ACX_PTHREAD, replaces $CC and others * all checks for mandatory things instantly exit for now in future this might produce an report at the end * ported checks from scons over here --- configure.ac | 59 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 72c616a17..b72b7dfee 100644 --- a/configure.ac +++ b/configure.ac @@ -23,6 +23,8 @@ AC_COPYRIGHT([ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ]) +AC_GNU_SOURCE + # # Required programs # @@ -39,6 +41,10 @@ AC_PROG_LIBTOOL AC_STDC_HEADERS ACX_PTHREAD +LIBS="$PTHREAD_LIBS $LIBS" +CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +CC="$PTHREAD_CC" + ##AM_CONDITIONAL([HAVE_THREADING], [test x"$acx_pthread_ok" = xyes]) @@ -68,15 +74,62 @@ AC_ARG_ENABLE(release, AC_HELP_STRING([--enable-release], [select NoBug RELEASE nobug_level=alpha AC_DEFINE(EBUG_ALPHA) )])]) +# END NoBug + +# C headers and libraries +AC_LANG_PUSH([C]) + +AC_CHECK_HEADER([nobug.h], + AC_DEFINE(HAVE_NOBUG_H), + AC_MSG_ERROR([NoBug header missing (http://www.pipapo.org/pipawiki/NoBug)]) + ) +AC_CHECK_LIB([nobugmt], nobug_thread_id_get, + , + AC_MSG_ERROR([NoBug multithreading library missing (http://www.pipapo.org/pipawiki/NoBug)]) + ) -AC_CHECK_HEADER([nobug.h], AC_DEFINE(HAVE_NOBUG_H)) AC_CHECK_HEADER([execinfo.h], AC_DEFINE(HAVE_EXECINFO_H)) # there is a warning in nobug, disabled til fixed AC_CHECK_HEADER([valgrind/valgrind.h], AC_DEFINE(HAVE_VALGRIND_VALGRIND_H)) +AC_LANG_POP([C]) -AC_MSG_RESULT([NoBug build level: $nobug_level]) -# END NoBug +# C++ headers and libraries +AC_LANG_PUSH([C++]) + +AC_CHECK_HEADER([tr1/memory], + , + AC_MSG_ERROR([std::tr1 proposed standard extension for shared_ptr missing]) + ) + +AC_CHECK_HEADER([boost/shared_ptr.hpp], + , + AC_MSG_ERROR([boost::shared_ptr missing (http://www.boost.org/)]) + ) + +AC_CHECK_HEADER([boost/program_options.hpp], + , + AC_MSG_ERROR([boost::program_options missing (http://www.boost.org/)]) + ) +# checking for library left out, name contains compiler version here (libboost_program_options-gcc42-mt-1_34_1.so.1.34.1) any ides how to use that? + +AC_CHECK_HEADER([boost/regex.hpp], + , + AC_MSG_ERROR([boost::regex missing (http://www.boost.org/)]) + ) + +AC_LANG_POP([C++]) + + +# Print a summary +AC_MSG_RESULT([ +Configuration Summary:]) +AC_MSG_RESULT([ NoBug build level: $nobug_level]) +# Add more summary results here + +AC_MSG_RESULT([ +Configuration complete, you can now build Lumiera with 'make' +]) AC_CONFIG_FILES(Makefile) AC_OUTPUT From 2cbfeda4df2ab5de06d8094124a52fccd53f10cc Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Thu, 10 Apr 2008 06:20:51 +0200 Subject: [PATCH 074/245] correct return types in condition.h --- src/lib/condition.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/condition.h b/src/lib/condition.h index 066c6b267..ffc00523c 100644 --- a/src/lib/condition.h +++ b/src/lib/condition.h @@ -167,7 +167,7 @@ lumiera_conditionacquirer_wait (LumieraConditionacquirer self) * a conditionacquirer must be unlocked before leaving scope * @param self conditionacquirer associated with a condition variable */ -static inline int +static inline void lumiera_conditionacquirer_unlock (LumieraConditionacquirer self) { REQUIRE (self); @@ -195,7 +195,7 @@ lumiera_conditionacquirer_signal (LumieraConditionacquirer self) * signal all waiting threads * @param self conditionacquirer associated with the condition variable to be signaled */ -static inline int +static inline void lumiera_conditionacquirer_broadcast (LumieraConditionacquirer self) { REQUIRE (self); From 249c6d5eda5c8ccbf4bc9f575c80b048812e6954 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Sat, 17 May 2008 23:33:21 +0200 Subject: [PATCH 075/245] Remove _GNU_SOURCE from certain files GNU_SOURCE is globally activated in configure.ac --- admin/vgsuppression.c | 1 - src/lib/rwlock.c | 2 -- src/lib/safeclib.c | 2 -- 3 files changed, 5 deletions(-) diff --git a/admin/vgsuppression.c b/admin/vgsuppression.c index 0e1f41fca..cad026e52 100644 --- a/admin/vgsuppression.c +++ b/admin/vgsuppression.c @@ -18,7 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define _GNU_SOURCE /* just place any problematic calls where valgrind whines about in main (with comments please) diff --git a/src/lib/rwlock.c b/src/lib/rwlock.c index 0862aa808..092c7b54b 100644 --- a/src/lib/rwlock.c +++ b/src/lib/rwlock.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define _GNU_SOURCE - #include #include "lib/rwlock.h" diff --git a/src/lib/safeclib.c b/src/lib/safeclib.c index 71e347ab7..a0b562643 100644 --- a/src/lib/safeclib.c +++ b/src/lib/safeclib.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define _GNU_SOURCE - #include "error.h" #include From e8164062a29d8e68951678f58ae8935637471c59 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Sun, 18 May 2008 00:01:51 +0200 Subject: [PATCH 076/245] integrate proc into automake * all files in src/proc are build into libs * TODO: -Werror still missing * TODO: Tests are not yet compiled --- Makefile.am | 1 + src/proc/Makefile.am | 263 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 src/proc/Makefile.am diff --git a/Makefile.am b/Makefile.am index 69cc34288..eb67e0a23 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,6 +33,7 @@ SUBDIRS = include $(top_srcdir)/admin/Makefile.am # core +include $(top_srcdir)/src/proc/Makefile.am include $(top_srcdir)/src/lib/Makefile.am #include $(top_srcdir)/src/backend/Makefile.am diff --git a/src/proc/Makefile.am b/src/proc/Makefile.am new file mode 100644 index 000000000..612ffc2d6 --- /dev/null +++ b/src/proc/Makefile.am @@ -0,0 +1,263 @@ +# Copyright (C) Lumiera.org +# 2008, Christian Thaeter +# +# This program 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 2 of the +# License, or (at your option) any later version. +# +# This program 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. +# Copyright (C) Lumiera.org +# 2008, Christian Thaeter +# +# This program 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 2 of the +# License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +# TODO use -Wextra -Werror + +liblumiproc_a_srcdir = $(top_srcdir)/src/proc +noinst_LIBRARIES += liblumiproc.a + +liblumiproc_a_CXXFLAGS = $(CXXFLAGS) -Wall +liblumiproc_a_CPPFLAGS = -I$(top_srcdir)/src/ + +liblumiproc_a_SOURCES = \ + $(liblumiproc_a_srcdir)/controllerfacade.cpp \ + $(liblumiproc_a_srcdir)/frame.cpp \ + $(liblumiproc_a_srcdir)/stateproxy.cpp \ + $(liblumiproc_a_srcdir)/asset.cpp \ + $(liblumiproc_a_srcdir)/assetmanager.cpp \ + $(liblumiproc_a_srcdir)/nobugcfg.cpp + + + +liblumiprocasset_a_srcdir = $(top_srcdir)/src/proc/asset +noinst_LIBRARIES += liblumiprocasset.a + +liblumiprocasset_a_CXXFLAGS = $(CXXFLAGS) -Wall +liblumiprocasset_a_CPPFLAGS = -I$(top_srcdir)/src/ + +liblumiprocasset_a_SOURCES = \ + $(liblumiprocasset_a_srcdir)/codec.cpp \ + $(liblumiprocasset_a_srcdir)/compoundmedia.cpp \ + $(liblumiprocasset_a_srcdir)/dataset.cpp \ + $(liblumiprocasset_a_srcdir)/effect.cpp \ + $(liblumiprocasset_a_srcdir)/preview.cpp \ + $(liblumiprocasset_a_srcdir)/unknown.cpp \ + $(liblumiprocasset_a_srcdir)/clip.cpp \ + $(liblumiprocasset_a_srcdir)/meta.cpp \ + $(liblumiprocasset_a_srcdir)/category.cpp \ + $(liblumiprocasset_a_srcdir)/media.cpp \ + $(liblumiprocasset_a_srcdir)/pipe.cpp \ + $(liblumiprocasset_a_srcdir)/proc.cpp \ + $(liblumiprocasset_a_srcdir)/procpatt.cpp \ + $(liblumiprocasset_a_srcdir)/struct.cpp \ + $(liblumiprocasset_a_srcdir)/track.cpp + + + +liblumiprocengine_a_srcdir = $(top_srcdir)/src/proc/engine +noinst_LIBRARIES += liblumiprocengine.a + +liblumiprocengine_a_CXXFLAGS = $(CXXFLAGS) -Wall +liblumiprocengine_a_CPPFLAGS = -I$(top_srcdir)/src/ + +liblumiprocengine_a_SOURCES = \ + $(liblumiprocengine_a_srcdir)/aframe.cpp \ + $(liblumiprocengine_a_srcdir)/arender.cpp \ + $(liblumiprocengine_a_srcdir)/codecadapter.cpp \ + $(liblumiprocengine_a_srcdir)/exitnode.cpp \ + $(liblumiprocengine_a_srcdir)/glbuf.cpp \ + $(liblumiprocengine_a_srcdir)/glpipe.cpp \ + $(liblumiprocengine_a_srcdir)/glrender.cpp \ + $(liblumiprocengine_a_srcdir)/hub.cpp \ + $(liblumiprocengine_a_srcdir)/link.cpp \ + $(liblumiprocengine_a_srcdir)/mask.cpp \ + $(liblumiprocengine_a_srcdir)/pluginadapter.cpp \ + $(liblumiprocengine_a_srcdir)/processor.cpp \ + $(liblumiprocengine_a_srcdir)/procnode.cpp \ + $(liblumiprocengine_a_srcdir)/projector.cpp \ + $(liblumiprocengine_a_srcdir)/renderengine.cpp \ + $(liblumiprocengine_a_srcdir)/source.cpp \ + $(liblumiprocengine_a_srcdir)/trafo.cpp \ + $(liblumiprocengine_a_srcdir)/vframe.cpp \ + $(liblumiprocengine_a_srcdir)/vrender.cpp + + + +liblumiprocmobject_a_srcdir = $(top_srcdir)/src/proc/mobject +noinst_LIBRARIES += liblumiprocmobject.a + +liblumiprocmobject_a_CXXFLAGS = $(CXXFLAGS) -Wall +liblumiprocmobject_a_CPPFLAGS = -I$(top_srcdir)/src/ + +liblumiprocmobject_a_SOURCES = \ + $(liblumiprocmobject_a_srcdir)/builderfacade.cpp \ + $(liblumiprocmobject_a_srcdir)/interpolator.cpp \ + $(liblumiprocmobject_a_srcdir)/mobject.cpp \ + $(liblumiprocmobject_a_srcdir)/parameter.cpp \ + $(liblumiprocmobject_a_srcdir)/paramprovider.cpp \ + $(liblumiprocmobject_a_srcdir)/placement.cpp + + + +liblumiprocmobjectbuilder_a_srcdir = $(top_srcdir)/src/proc/mobject/builder +noinst_LIBRARIES += liblumiprocmobjectbuilder.a + +liblumiprocmobjectbuilder_a_CXXFLAGS = $(CXXFLAGS) -Wall +liblumiprocmobjectbuilder_a_CPPFLAGS = -I$(top_srcdir)/src/ + +liblumiprocmobjectbuilder_a_SOURCES = \ + $(liblumiprocmobjectbuilder_a_srcdir)/assembler.cpp \ + $(liblumiprocmobjectbuilder_a_srcdir)/conmanager.cpp \ + $(liblumiprocmobjectbuilder_a_srcdir)/nodecreatertool.cpp \ + $(liblumiprocmobjectbuilder_a_srcdir)/segmentationtool.cpp \ + $(liblumiprocmobjectbuilder_a_srcdir)/toolfactory.cpp + + +liblumiprocmobjectcontroller_a_srcdir = $(top_srcdir)/src/proc/mobject/controller +noinst_LIBRARIES += liblumiprocmobjectcontroller.a + +liblumiprocmobjectcontroller_a_CXXFLAGS = $(CXXFLAGS) -Wall +liblumiprocmobjectcontroller_a_CPPFLAGS = -I$(top_srcdir)/src/ + +liblumiprocmobjectcontroller_a_SOURCES = \ + $(liblumiprocmobjectcontroller_a_srcdir)/pathmanager.cpp \ + $(liblumiprocmobjectcontroller_a_srcdir)/renderstate.cpp + + +liblumiprocmobjectsession_a_srcdir = $(top_srcdir)/src/proc/mobject/session +noinst_LIBRARIES += liblumiprocmobjectsession.a + +liblumiprocmobjectsession_a_CXXFLAGS = $(CXXFLAGS) -Wall +liblumiprocmobjectsession_a_CPPFLAGS = -I$(top_srcdir)/src/ + +liblumiprocmobjectsession_a_SOURCES = \ + $(liblumiprocmobjectsession_a_srcdir)/abstractmo.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/allocation.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/auto.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/compoundclip.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/effect.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/fixedlocation.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/label.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/meta.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/relativelocation.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/segment.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/simpleclip.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/plug.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/sessionimpl.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/sessmanagerimpl.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/edl.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/session.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/track.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/clip.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/constraint.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/defsmanager.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/fixture.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/locatingpin.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/mobjectfactory.cpp \ + $(liblumiprocmobjectsession_a_srcdir)/wish.cpp + + + + +noinst_HEADERS += \ + $(liblumiproc_a_srcdir)/asset/category.hpp \ + $(liblumiproc_a_srcdir)/asset/clip.hpp \ + $(liblumiproc_a_srcdir)/asset/codec.hpp \ + $(liblumiproc_a_srcdir)/asset/compoundmedia.hpp \ + $(liblumiproc_a_srcdir)/asset/dataset.hpp \ + $(liblumiproc_a_srcdir)/asset/effect.hpp \ + $(liblumiproc_a_srcdir)/asset/preview.hpp \ + $(liblumiproc_a_srcdir)/asset/db.hpp \ + $(liblumiproc_a_srcdir)/asset/buildinstruct.hpp \ + $(liblumiproc_a_srcdir)/asset/media.hpp \ + $(liblumiproc_a_srcdir)/asset/meta.hpp \ + $(liblumiproc_a_srcdir)/asset/pipe.hpp \ + $(liblumiproc_a_srcdir)/asset/proc.hpp \ + $(liblumiproc_a_srcdir)/asset/procpatt.hpp \ + $(liblumiproc_a_srcdir)/asset/struct.hpp \ + $(liblumiproc_a_srcdir)/asset/structfactoryimpl.hpp \ + $(liblumiproc_a_srcdir)/asset/track.hpp \ + $(liblumiproc_a_srcdir)/asset/unknown.hpp \ + $(liblumiproc_a_srcdir)/controllerfacade.hpp \ + $(liblumiproc_a_srcdir)/engine/aframe.hpp \ + $(liblumiproc_a_srcdir)/engine/arender.hpp \ + $(liblumiproc_a_srcdir)/engine/codecadapter.hpp \ + $(liblumiproc_a_srcdir)/engine/exitnode.hpp \ + $(liblumiproc_a_srcdir)/engine/glbuf.hpp \ + $(liblumiproc_a_srcdir)/engine/glpipe.hpp \ + $(liblumiproc_a_srcdir)/engine/glrender.hpp \ + $(liblumiproc_a_srcdir)/engine/hub.hpp \ + $(liblumiproc_a_srcdir)/engine/link.hpp \ + $(liblumiproc_a_srcdir)/engine/mask.hpp \ + $(liblumiproc_a_srcdir)/engine/pluginadapter.hpp \ + $(liblumiproc_a_srcdir)/engine/procnode.hpp \ + $(liblumiproc_a_srcdir)/engine/projector.hpp \ + $(liblumiproc_a_srcdir)/engine/renderengine.hpp \ + $(liblumiproc_a_srcdir)/engine/source.hpp \ + $(liblumiproc_a_srcdir)/engine/trafo.hpp \ + $(liblumiproc_a_srcdir)/engine/vframe.hpp \ + $(liblumiproc_a_srcdir)/engine/vrender.hpp \ + $(liblumiproc_a_srcdir)/engine/processor.hpp \ + $(liblumiproc_a_srcdir)/frame.hpp \ + $(liblumiproc_a_srcdir)/mobject/builder/assembler.hpp \ + $(liblumiproc_a_srcdir)/mobject/builder/buildertool.hpp \ + $(liblumiproc_a_srcdir)/mobject/builder/conmanager.hpp \ + $(liblumiproc_a_srcdir)/mobject/builder/nodecreatertool.hpp \ + $(liblumiproc_a_srcdir)/mobject/builder/segmentationtool.hpp \ + $(liblumiproc_a_srcdir)/mobject/builder/toolfactory.hpp \ + $(liblumiproc_a_srcdir)/mobject/builderfacade.hpp \ + $(liblumiproc_a_srcdir)/mobject/controller/pathmanager.hpp \ + $(liblumiproc_a_srcdir)/mobject/controller/renderstate.hpp \ + $(liblumiproc_a_srcdir)/mobject/interpolator.hpp \ + $(liblumiproc_a_srcdir)/mobject/parameter.hpp \ + $(liblumiproc_a_srcdir)/mobject/paramprovider.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/abstractmo.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/allocation.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/auto.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/compoundclip.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/effect.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/fixedlocation.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/label.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/meta.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/relativelocation.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/simpleclip.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/mobjectfactory.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/segment.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/track.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/wish.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/clip.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/constraint.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/defsmanager.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/edl.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/fixture.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/locatingpin.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/plug.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/sessionimpl.hpp \ + $(liblumiproc_a_srcdir)/mobject/session/defsregistry.hpp \ + $(liblumiproc_a_srcdir)/mobject/explicitplacement.hpp \ + $(liblumiproc_a_srcdir)/mobject/mobject.hpp \ + $(liblumiproc_a_srcdir)/mobject/placement.hpp \ + $(liblumiproc_a_srcdir)/mobject/session.hpp \ + $(liblumiproc_a_srcdir)/stateproxy.hpp \ + $(liblumiproc_a_srcdir)/asset.hpp \ + $(liblumiproc_a_srcdir)/assetmanager.hpp \ + $(liblumiproc_a_srcdir)/lumiera.hpp \ + $(liblumiproc_a_srcdir)/nobugcfg.hpp + From 662678f8d14ce3e68e7ba75117dec4281798221c Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 18 May 2008 05:08:11 +0200 Subject: [PATCH 077/245] WIP refactored in preparation of splitting into several lib modules --- .../proc/mobject/builder/buildertooltest.cpp | 711 +++++++++--------- 1 file changed, 372 insertions(+), 339 deletions(-) diff --git a/tests/components/proc/mobject/builder/buildertooltest.cpp b/tests/components/proc/mobject/builder/buildertooltest.cpp index 6495bb795..7a427f51c 100644 --- a/tests/components/proc/mobject/builder/buildertooltest.cpp +++ b/tests/components/proc/mobject/builder/buildertooltest.cpp @@ -34,55 +34,137 @@ #include "common/typelistutil.hpp" +#include #include #include #include #include #include -//#include #include using std::string; using std::cout; -namespace mobject - { +namespace util { + using boost::remove_pointer; + using boost::remove_reference; + using boost::is_convertible; + using boost::is_polymorphic; + using boost::is_base_of; + using boost::enable_if; - DEFINE_SPECIALIZED_PLACEMENT (session::AbstractMO); + template + struct can_cast : boost::false_type {}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; - namespace builder + template + struct has_RTTI { - namespace test - { - - using session::Clip; - using session::AbstractMO; - -/////////////////////////////////////////////////////TODO: move to buildertool.hpp - - using lumiera::P; - -// Problem -/* - - brauche Laufzeittyp des Zielobjektes - - an wen wird die Dispatcher-Tabelle gebunden? - - falls an den Wrapper: Gefahr, zur Laufzeit nicht die Tabelle zu bekommen, in die das Trampolin registriert wurde - - falls an das Zielobjekt: wie gebe ich Referenz und konkreten Typ des Wrappers an den Funktionsaufruf im Tool? - - vieleicht einen allgemeinen Argument-Adapter nutzen? - - Zielobjekt oder Wrapper als Argumenttyp? -*/ - - using boost::enable_if; - using boost::is_convertible; + typedef typename remove_pointer< + typename remove_reference::type>::type TPlain; - using lumiera::typelist::Types; - using lumiera::typelist::Node; - using lumiera::typelist::NullType; -// using lumiera::typelist::count; -// using lumiera::typelist::maxSize; - using lumiera::typelist::InstantiateChained; + enum { value = is_polymorphic::value }; + }; + + template + struct use_dynamic_downcast + { + enum { value = can_cast::value + && has_RTTI::value + && has_RTTI::value + }; + }; + + template + struct use_static_downcast + { + enum { value = can_cast::value + && ( !has_RTTI::value + || !has_RTTI::value + ) + }; + }; + + template + struct use_conversion + { + enum { value = is_convertible::value + && !( use_static_downcast::value + ||use_dynamic_downcast::value + ) + }; + }; + + + + template + struct EmptyVal + { + static X create() { return X(); } + }; + template + struct EmptyVal + { + static X*& create() { static X* nullP(0); return nullP; } + }; + + + + + + template + struct NullAccessor + { + typedef RET Ret; + + static RET access (...) { return ifEmpty(); } + static RET ifEmpty () { return EmptyVal::create(); } + }; + + template + struct AccessCasted : NullAccessor + { + using NullAccessor::access; + + template + static typename enable_if< use_dynamic_downcast, TAR>::type + access (ELM& elem) + { + return dynamic_cast (elem); + } + + template + static typename enable_if< use_static_downcast, TAR>::type + access (ELM& elem) + { + return static_cast (elem); + } + + template + static typename enable_if< use_conversion, TAR>::type + access (ELM& elem) + { + return elem; + } + }; + + +} + +namespace lumiera { + + namespace typelist { + template < class TYPES // List of Types @@ -124,7 +206,7 @@ namespace mobject typedef _X_ Unit; enum{ COUNT = Next::COUNT }; }; - + template struct count; template<> @@ -153,279 +235,270 @@ namespace mobject , value = nextval > thisval? nextval:thisval }; }; + + } // namespace typelist - - - template + + + + + namespace variant { + + using lumiera::typelist::count; + using lumiera::typelist::maxSize; + using lumiera::typelist::InstantiateWithIndex; + + /** + * internal helper used to build a variant storage wrapper. + * Parametrized with a collection of types, it provides functionality + * to copy a value of one of these types into an internal buffer, while + * remembering which of these types was used to place this copy. + * The value can be later on extracted using a visitation like mechanism, + * which takes a functor object and invokes a function \c access(T&) with + * the type matching the current value in storage + */ + template struct Holder { - T content; - Holder (T const& src) : T(src) {} + enum { TYPECNT = count::value + , SIZE = maxSize::value + }; - template - TAR get () { return static_cast (content); } + + /** Storage to hold the actual value */ + struct Buffer + { + char buffer_[SIZE]; + uint which; + + Buffer() : which(TYPECNT) {} + + void* + put (void) + { + deleteCurrent(); + return 0; + } + + void + deleteCurrent (); // depends on the Deleter, see below + }; + + template + struct PlacementAdapter : BASE + { + T& + put (T const& toStore) + { + BASE::deleteCurrent(); // remove old content, if any + + T& storedObj = *new(BASE::buffer_) T (toStore); + this->which = idx; // remember the actual type selected + return storedObj; + } + + using BASE::put; + }; + + typedef InstantiateWithIndex< TYPES + , PlacementAdapter + , Buffer + > + Storage; + + + + /** provide a dispatcher table based visitation mechanism */ + template + struct CaseSelect + { + typedef typename FUNCTOR::Ret Ret; + typedef Ret (*Func)(Buffer&); + + Func table_[TYPECNT]; + + CaseSelect () + { + for (uint i=0; i + static Ret + trampoline (Buffer& storage) + { + T& content = reinterpret_cast (storage.buffer_); + return FUNCTOR::access (content); + } + + Ret + invoke (Buffer& storage) + { + if (TYPECNT <= storage.which) + return FUNCTOR::ifEmpty (); + else + return (*table_[storage.which]) (storage); + } + }; + + + template< class T, class BASE, uint i > + struct CasePrepare + : BASE + { + CasePrepare () : BASE() + { + BASE::table_[i] = &BASE::template trampoline; + } + }; + + + template + static typename FUNCTOR::Ret + access (Buffer& buf) + { + typedef InstantiateWithIndex< TYPES + , CasePrepare + , CaseSelect + > + Accessor; + static Accessor select_case; + return select_case.invoke(buf); + } + + + struct Deleter + { + typedef void Ret; + + template + static void access (T& elem) { elem.~T(); } + + static void ifEmpty () { } + }; }; + + + template + void + Holder::Buffer::deleteCurrent () + { + access(*this); // remove old content, if any + which = TYPECNT; // mark as empty + } + + } // namespace variant + + + + + + + + + + + + /** + * A variant wrapper (typesafe union) capable of holding a value of any + * of a bounded collection of types. The value is stored in a local buffer + * directly within the object and may be accessed by a typesafe visitation. + * + * \par + * This utility class is similar to boost::variant and indeed was implemented + * (5/08) in an effort to replace the latter in a draft solution for the problem + * of typesafe access to the correct wrapper class from within some builder tool. + * Well -- after finisihng this "exercise" I must admit that it is not really + * much more simple than what boost::variant does internally. At least we are + * pulling in fewer headers and the actual code path is shorter compared with + * boost::variant, at the price of beeing not so generic, not caring for + * alignment issues within the buffer and being not threadsafe + * + * @param TYPES collection of possible types to be stored in this variant object + * @param Access policy how to access the stored value + */ + template< typename TYPES + , template class Access = util::AccessCasted + > + class Variant + : boost::noncopyable + { + + typedef variant::Holder Holder; + typedef typename Holder::Deleter Deleter; + + + /** storage: buffer holding either and "empty" marker, + * or one of the configured pointer to wrapper types */ + typename Holder::Storage holder_; + + + public: + void reset () { holder_.deleteCurrent();} + + /** store a copy of the given argument within the + * variant holder buffer, thereby typically casting + * or converting the given source type to the best + * suited (base) type (out of the collection of possible + * types for this Variant instance) + */ + template + Variant& + operator= (SRC src) + { + if (src) holder_.put (src); // see Holder::PlacementAdaptor::put + else reset(); + return *this; + } + + /** retrieve current content of the variant, + * trying to cast or convert it to the given type. + * Actually, the function \c access(T&) on the + * Access-policy (template param) is invoked with the + * type currently stored in the holder buffer. + * May return NULL if conversion fails. + */ + template + TAR + get () + { + typedef Access Extractor; + return Holder::template access (this->holder_); + } + }; + +} // namespace lumiera + + + +namespace mobject + { + + DEFINE_SPECIALIZED_PLACEMENT (session::AbstractMO); + + + namespace builder + { + namespace test + { + + using session::Clip; + using session::AbstractMO; + +/////////////////////////////////////////////////////TODO: move to buildertool.hpp + + using lumiera::P; + using lumiera::typelist::Types; + + + typedef Types < Placement* , P* > ::List WrapperTypes; - - template - struct EmptyVal - { - static X create() - { - return X(); - } - }; - template - struct EmptyVal - { - static X*& create() - { - static X* null(0); - return null; - } - }; - - const uint TYPECNT = count::value; - const size_t SIZE = maxSize::value; - - struct Buffer - { - char buffer_[SIZE]; - uint which; - - Buffer() : which(TYPECNT) {} - - void* - put (void) - { - deleteCurrent(); - return 0; - } - - void - deleteCurrent (); // depends on the Deleter, see below - }; - - template - struct Storage : BASE - { - T& - put (T const& toStore) - { - BASE::deleteCurrent(); // remove old content, if any - - T& storedObj = *new(BASE::buffer_) T (toStore); - this->which = idx; // remember the actual type selected - return storedObj; - } - - using BASE::put; - }; - - - - template - struct CaseSelect - { - typedef typename FUNCTOR::Ret Ret; - typedef Ret (*Func)(Buffer&); - - Func table_[TYPECNT]; - - CaseSelect () - { - for (uint i=0; i - static Ret - trampoline (Buffer& storage) - { - T& content = reinterpret_cast (storage.buffer_); - return FUNCTOR::access (content); - } - - template - void - create_thunk (uint idx) - { - Func thunk = &trampoline; - table_[idx] = thunk; - } - - Ret - invoke (Buffer& storage) - { - if (TYPECNT <= storage.which) - return FUNCTOR::ifEmpty (); - else - return (*table_[storage.which]) (storage); - } - }; - - - template< class T, class BASE, uint i > - struct CasePrepare - : BASE - { - CasePrepare () : BASE() - { -// BASE::table_[i] = &(BASE::template trampoline); - BASE::template create_thunk(i); - } - }; - - - template - typename FUNCTOR::Ret - access (Buffer& buf) - { - typedef InstantiateWithIndex< WrapperTypes - , CasePrepare - , CaseSelect - > - Accessor; - static Accessor select_case; - return select_case.invoke(buf); - } - - - struct Deleter - { - typedef void Ret; - - template - static void access (T& elem) { elem.~T(); } - - static void ifEmpty () { } - }; - - - void - Buffer::deleteCurrent () - { - access(*this); // remove old content, if any - which = TYPECNT; // mark as empty - } - - - - - - - using boost::remove_pointer; - using boost::remove_reference; - using boost::is_convertible; - using boost::is_polymorphic; - using boost::is_base_of; - using boost::enable_if; - - template - struct can_cast : boost::false_type {}; - - template - struct can_cast { enum { value = is_base_of::value };}; - - template - struct can_cast { enum { value = is_base_of::value };}; - - template - struct can_cast { enum { value = is_base_of::value };}; - - - template - struct has_RTTI - { - typedef typename remove_pointer< - typename remove_reference::type>::type TPlain; - - enum { value = is_polymorphic::value }; - }; - - template - struct use_dynamic_downcast - { - enum { value = can_cast::value - && has_RTTI::value - && has_RTTI::value - }; - }; - - template - struct use_static_downcast - { - enum { value = can_cast::value - && ( !has_RTTI::value - || !has_RTTI::value - ) - }; - }; - - template - struct use_conversion - { - enum { value = is_convertible::value - && !( use_static_downcast::value - ||use_dynamic_downcast::value - ) - }; - }; - - - - - - template - struct NullAccessor - { - typedef RET Ret; - - static RET access (...) { return ifEmpty(); } - static RET ifEmpty () { return EmptyVal::create(); } - }; - - template - struct AccessCasted : NullAccessor - { - using NullAccessor::access; - - template - static typename enable_if< use_dynamic_downcast, TAR>::type - access (ELM& elem) - { - return dynamic_cast (elem); - } - - template - static typename enable_if< use_static_downcast, TAR>::type - access (ELM& elem) - { - return static_cast (elem); - } - - template - static typename enable_if< use_conversion, TAR>::type - access (ELM& elem) - { - return elem; - } - - }; - - - - - - - - /** * helper to treat various sorts of smart-ptrs uniformly. * Implemented as a variant-type value object, it is preconfigured @@ -436,48 +509,8 @@ namespace mobject * error reporting is similar to the bahaviour of dynamic_cast: when retrieving * a pointer, in case of mismatch NULL is returned. */ - class WrapperPtr // NONCOPYABLE!! - { - - - - private: - typedef InstantiateWithIndex< WrapperTypes - , Storage - , Buffer - > - VariantHolder; - - /** storage: buffer holding either and "empty" marker, - * or one of the configured pointer to wrapper types */ - VariantHolder holder_; - - public: - void - reset () - { - access (holder_); - holder_.which = TYPECNT; - } - - template - WrapperPtr& - operator= (WRA* src) ///< store a ptr to the given wrapper, after casting to base - { - if (src) holder_.put (src); - else reset(); - return *this; - } - - template - WRA* - get () ///< retrieve ptr and try to downcast to type WRA - { - typedef AccessCasted AccessWraP; - WRA* res = access(this->holder_); - return res; - } - }; + typedef lumiera::Variant WrapperPtr; + class BuTuul @@ -503,7 +536,7 @@ namespace mobject Placement& getPlacement () { - Placement* pPlacement = currentWrapper_.get >(); + Placement* pPlacement = currentWrapper_.get*>(); return *pPlacement; } ExplicitPlacement @@ -515,7 +548,7 @@ namespace mobject P getPtr () { - P* pP = currentWrapper_.get >(); + P* pP = currentWrapper_.get*>(); return *pP; } }; From b6bd181ca8bd05d736ed215f2945562c3a39dd14 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 19 May 2008 01:48:02 +0200 Subject: [PATCH 078/245] correct pasting glitch and copyright header date --- src/proc/Makefile.am | 12 ------------ tests/Makefile.am | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/proc/Makefile.am b/src/proc/Makefile.am index 612ffc2d6..603f4d825 100644 --- a/src/proc/Makefile.am +++ b/src/proc/Makefile.am @@ -10,18 +10,6 @@ # 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. -# Copyright (C) Lumiera.org -# 2008, Christian Thaeter -# -# This program 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 2 of the -# License, or (at your option) any later version. -# -# This program 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 this program; if not, write to the Free Software diff --git a/tests/Makefile.am b/tests/Makefile.am index a6ccae010..1dce33db8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,5 +1,5 @@ # Copyright (C) Lumiera.org -# 2007, Christian Thaeter +# 2007-2008, Christian Thaeter # Hermann Vosseler # # This program is free software; you can redistribute it and/or From 3b6713b23c2612f8ecfe19ff647e8395ced23ee5 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 19 May 2008 01:50:53 +0200 Subject: [PATCH 079/245] build common and (re-)enable backend build (C++ part) - not (yet) merged backend C parts are commented out for now --- Makefile.am | 3 +- src/backend/Makefile.am | 25 +++++++++------- src/common/Makefile.am | 65 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 src/common/Makefile.am diff --git a/Makefile.am b/Makefile.am index eb67e0a23..2ea3aba54 100644 --- a/Makefile.am +++ b/Makefile.am @@ -34,8 +34,9 @@ include $(top_srcdir)/admin/Makefile.am # core include $(top_srcdir)/src/proc/Makefile.am +include $(top_srcdir)/src/common/Makefile.am include $(top_srcdir)/src/lib/Makefile.am -#include $(top_srcdir)/src/backend/Makefile.am +include $(top_srcdir)/src/backend/Makefile.am # plugins #include $(top_srcdir)/src... diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index 5f693f8bf..3d70a09d5 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -22,16 +22,21 @@ liblumibackend_a_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror liblumibackend_a_CPPFLAGS = -I$(top_srcdir)/src/ liblumibackend_a_SOURCES = \ - $(liblumibackend_a_srcdir)/backend.c \ - $(liblumibackend_a_srcdir)/file.c \ - $(liblumibackend_a_srcdir)/filehandle.c \ - $(liblumibackend_a_srcdir)/filedescriptor.c \ - $(liblumibackend_a_srcdir)/filehandlecache.c + $(liblumibackend_a_srcdir)/mediaaccessfacade.cpp + +# $(liblumibackend_a_srcdir)/backend.c \ +# $(liblumibackend_a_srcdir)/file.c \ +# $(liblumibackend_a_srcdir)/filehandle.c \ +# $(liblumibackend_a_srcdir)/filedescriptor.c \ +# $(liblumibackend_a_srcdir)/filehandlecache.c + noinst_HEADERS += \ - $(liblumibackend_a_srcdir)/backend.h \ - $(liblumibackend_a_srcdir)/file.h \ - $(liblumibackend_a_srcdir)/filehandle.h \ - $(liblumibackend_a_srcdir)/filedescriptor.h \ - $(liblumibackend_a_srcdir)/filehandlecache.h + $(liblumibackend_a_srcdir)mediaaccessfacade.cpp + +# $(liblumibackend_a_srcdir)/backend.h \ +# $(liblumibackend_a_srcdir)/file.h \ +# $(liblumibackend_a_srcdir)/filehandle.h \ +# $(liblumibackend_a_srcdir)/filedescriptor.h \ +# $(liblumibackend_a_srcdir)/filehandlecache.h diff --git a/src/common/Makefile.am b/src/common/Makefile.am new file mode 100644 index 000000000..06082da31 --- /dev/null +++ b/src/common/Makefile.am @@ -0,0 +1,65 @@ +# Copyright (C) Lumiera.org +# 2008, Christian Thaeter +# +# This program 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 2 of the +# License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +# TODO use -Wextra -Werror + +liblumicommon_a_srcdir = $(top_srcdir)/src/common +noinst_LIBRARIES += liblumicommon.a + +liblumicommon_a_CXXFLAGS = $(CXXFLAGS) -Wall +liblumicommon_a_CPPFLAGS = -I$(top_srcdir)/src/ + +liblumicommon_a_SOURCES = \ + $(liblumicommon_a_srcdir)/time.cpp \ + $(liblumicommon_a_srcdir)/util.cpp \ + $(liblumicommon_a_srcdir)/visitor.cpp \ + $(liblumicommon_a_srcdir)/cmdline.cpp \ + $(liblumicommon_a_srcdir)/configrules.cpp \ + $(liblumicommon_a_srcdir)/error.cpp \ + $(liblumicommon_a_srcdir)/query.cpp \ + $(liblumicommon_a_srcdir)/query/mockconfigrules.cpp \ + $(liblumicommon_a_srcdir)/test/suite.cpp \ + $(liblumicommon_a_srcdir)/test/testoption.cpp + + +noinst_HEADERS += \ + $(liblumicommon_a_srcdir)/cmdline.hpp \ + $(liblumicommon_a_srcdir)/factory.hpp \ + $(liblumicommon_a_srcdir)/singleton.hpp \ + $(liblumicommon_a_srcdir)/singletonpolicies.hpp \ + $(liblumicommon_a_srcdir)/singletonpreconfigure.hpp \ + $(liblumicommon_a_srcdir)/time.hpp \ + $(liblumicommon_a_srcdir)/typelist.hpp \ + $(liblumicommon_a_srcdir)/visitor.hpp \ + $(liblumicommon_a_srcdir)/visitordispatcher.hpp \ + $(liblumicommon_a_srcdir)/visitorpolicies.hpp \ + $(liblumicommon_a_srcdir)/configrules.hpp \ + $(liblumicommon_a_srcdir)/error.hpp \ + $(liblumicommon_a_srcdir)/multithread.hpp \ + $(liblumicommon_a_srcdir)/p.hpp \ + $(liblumicommon_a_srcdir)/query.hpp \ + $(liblumicommon_a_srcdir)/query/mockconfigrules.hpp \ + $(liblumicommon_a_srcdir)/singletonfactory.hpp \ + $(liblumicommon_a_srcdir)/singletonsubclass.hpp \ + $(liblumicommon_a_srcdir)/typelistutil.hpp \ + $(liblumicommon_a_srcdir)/util.hpp \ + $(liblumicommon_a_srcdir)/test/mockinjector.hpp \ + $(liblumicommon_a_srcdir)/test/suite.hpp \ + $(liblumicommon_a_srcdir)/test/testoption.hpp \ + $(liblumicommon_a_srcdir)/test/run.hpp + From 5ae909e2a0f7b9e445a95329d7cc15b09cfef912 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 19 May 2008 01:51:34 +0200 Subject: [PATCH 080/245] add C++ parts to lib build --- src/lib/Makefile.am | 50 +++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 0e0c2f22e..ffdb9a176 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -21,28 +21,30 @@ noinst_LIBRARIES += liblumi.a liblumi_a_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror liblumi_a_CPPFLAGS = -I$(top_srcdir)/src/ -liblumi_a_SOURCES = \ - $(liblumi_a_srcdir)/plugin.c \ - $(liblumi_a_srcdir)/error.c \ - $(liblumi_a_srcdir)/mutex.c \ - $(liblumi_a_srcdir)/rwlock.c \ - $(liblumi_a_srcdir)/condition.c \ - $(liblumi_a_srcdir)/references.c \ - $(liblumi_a_srcdir)/uuid.c \ - $(liblumi_a_srcdir)/safeclib.c \ - $(liblumi_a_srcdir)/cuckoo.c \ - $(liblumi_a_srcdir)/mrucache.c +liblumi_a_SOURCES = \ + $(liblumi_a_srcdir)/plugin.c \ + $(liblumi_a_srcdir)/error.c \ + $(liblumi_a_srcdir)/mutex.c \ + $(liblumi_a_srcdir)/rwlock.c \ + $(liblumi_a_srcdir)/condition.c \ + $(liblumi_a_srcdir)/references.c \ + $(liblumi_a_srcdir)/uuid.c \ + $(liblumi_a_srcdir)/safeclib.c \ + $(liblumi_a_srcdir)/cuckoo.c \ + $(liblumi_a_srcdir)/mrucache.c \ + $(liblumi_a_srcdir)/appconfig.cpp - -noinst_HEADERS += \ - $(liblumi_a_srcdir)/plugin.h \ - $(liblumi_a_srcdir)/error.h \ - $(liblumi_a_srcdir)/locking.h \ - $(liblumi_a_srcdir)/mutex.h \ - $(liblumi_a_srcdir)/rwlock.h \ - $(liblumi_a_srcdir)/condition.h \ - $(liblumi_a_srcdir)/references.h \ - $(liblumi_a_srcdir)/uuid.h \ - $(liblumi_a_srcdir)/safeclib.h \ - $(liblumi_a_srcdir)/cuckoo.h \ - $(liblumi_a_srcdir)/mrucache.h +noinst_HEADERS += \ + $(liblumi_a_srcdir)/plugin.h \ + $(liblumi_a_srcdir)/error.h \ + $(liblumi_a_srcdir)/locking.h \ + $(liblumi_a_srcdir)/mutex.h \ + $(liblumi_a_srcdir)/rwlock.h \ + $(liblumi_a_srcdir)/condition.h \ + $(liblumi_a_srcdir)/references.h \ + $(liblumi_a_srcdir)/uuid.h \ + $(liblumi_a_srcdir)/safeclib.h \ + $(liblumi_a_srcdir)/cuckoo.h \ + $(liblumi_a_srcdir)/mrucache.h \ + $(liblumi_a_srcdir)/appconfig.hpp \ + $(liblumi_a_srcdir)/lifecycleregistry.hpp From 8ba3df3b31f34580e199bb306f0726a21e22f69c Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 19 May 2008 01:54:40 +0200 Subject: [PATCH 081/245] missing slash --- src/backend/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index 3d70a09d5..eb5853d5f 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -32,7 +32,7 @@ liblumibackend_a_SOURCES = \ noinst_HEADERS += \ - $(liblumibackend_a_srcdir)mediaaccessfacade.cpp + $(liblumibackend_a_srcdir)/mediaaccessfacade.cpp # $(liblumibackend_a_srcdir)/backend.h \ # $(liblumibackend_a_srcdir)/file.h \ From d6d6a1040499e59274fe027fdf5c536a3562395f Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 19 May 2008 01:55:05 +0200 Subject: [PATCH 082/245] add components test build --- Makefile.am | 1 + tests/components/Makefile.am | 72 ++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 tests/components/Makefile.am diff --git a/Makefile.am b/Makefile.am index 2ea3aba54..79d054de2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,6 +42,7 @@ include $(top_srcdir)/src/backend/Makefile.am #include $(top_srcdir)/src... # tests +include $(top_srcdir)/tests/components/Makefile.am include $(top_srcdir)/tests/Makefile.am include $(top_srcdir)/tests/plugin/Makefile.am diff --git a/tests/components/Makefile.am b/tests/components/Makefile.am new file mode 100644 index 000000000..5e8d1e070 --- /dev/null +++ b/tests/components/Makefile.am @@ -0,0 +1,72 @@ +# Copyright (C) Lumiera.org +# 2007, Christian Thaeter +# Hermann Vosseler +# +# This program 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 2 of the +# License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +testcomponents_srcdir = $(top_srcdir)/tests/components + +check_PROGRAMS += test-components +test_components_CPPFLAGS = $(AM_CPPFLAGS) -Wall -I$(top_srcdir)/src -I$(testcomponents_srcdir) +test_components_LDADD = \ + liblumiproc.a \ + liblumiprocengine.a \ + liblumiprocmobjectbuilder.a \ + liblumiprocmobjectsession.a \ + liblumiprocasset.a \ + liblumiprocmobject.a \ + liblumiprocmobjectcontroller.a \ + liblumi.a \ + liblumicommon.a \ + liblumibackend.a \ + -lnobugmt -lpthread -ldl -lboost_program_options-mt -lboost_regex-mt + +test_components_SOURCES = \ + $(testcomponents_srcdir)/backend/mediaaccessmock.cpp \ + $(testcomponents_srcdir)/backend/mediaaccessmocktest.cpp \ + $(testcomponents_srcdir)/proc/asset/assetcategorytest.cpp \ + $(testcomponents_srcdir)/proc/asset/compoundmediatest.cpp \ + $(testcomponents_srcdir)/proc/asset/deleteassettest.cpp \ + $(testcomponents_srcdir)/proc/asset/identityofassetstest.cpp \ + $(testcomponents_srcdir)/proc/asset/mediastructurequerytest.cpp \ + $(testcomponents_srcdir)/proc/asset/basicpipetest.cpp \ + $(testcomponents_srcdir)/proc/asset/createassettest.cpp \ + $(testcomponents_srcdir)/proc/asset/dependantassetstest.cpp \ + $(testcomponents_srcdir)/proc/asset/makecliptest.cpp \ + $(testcomponents_srcdir)/proc/asset/orderingofassetstest.cpp \ + $(testcomponents_srcdir)/proc/asset/testasset.cpp \ + $(testcomponents_srcdir)/proc/engine/sourcenodetest.cpp \ + $(testcomponents_srcdir)/proc/mobject/builder/buildertooltest.cpp \ + $(testcomponents_srcdir)/proc/mobject/builder/buildsegmenttest.cpp \ + $(testcomponents_srcdir)/proc/mobject/controller/rendersegmenttest.cpp \ + $(testcomponents_srcdir)/proc/mobject/placementbasictest.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/addcliptest.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/deletecliptest.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/rebuildfixturetest.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/sessionmanagertest.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/testclip.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/defsmanagerimpltest.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/defsmanagertest.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/defsregistryimpltest.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/sessionstructuretest.cpp \ + $(testcomponents_srcdir)/mainsuite.cpp + +noinst_HEADERS += \ + $(testcomponents_srcdir)/backend/mediaaccessmock.hpp \ + $(testcomponents_srcdir)/proc/asset/testclipasset.hpp \ + $(testcomponents_srcdir)/proc/asset/assetdiagnostics.hpp \ + $(testcomponents_srcdir)/proc/asset/testasset.hpp \ + $(testcomponents_srcdir)/proc/mobject/session/testclip.hpp \ + $(testcomponents_srcdir)/proc/mobject/session/testsession1.hpp From 86162ad314d291f7b190fa17a64b2dc584255067 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 19 May 2008 08:38:13 +0200 Subject: [PATCH 083/245] moved new code into library modules and adapted BuilderTool to use it. BuilderTool_test now passed. --- src/common/accesscasted.hpp | 168 +++++ src/common/typelistutil.hpp | 93 ++- src/common/variant.hpp | 276 +++++++ src/common/wrapperptr.hpp | 63 ++ .../builder/applicablebuildertargettypes.hpp | 70 ++ src/proc/mobject/builder/buildertool.hpp | 134 +++- src/proc/mobject/builder/nodecreatertool.cpp | 7 +- src/proc/mobject/builder/nodecreatertool.hpp | 23 +- src/proc/mobject/builder/segmentationtool.cpp | 6 +- src/proc/mobject/builder/segmentationtool.hpp | 22 +- src/proc/mobject/explicitplacement.hpp | 18 +- src/proc/mobject/mobject.hpp | 5 +- src/proc/mobject/placement.cpp | 32 +- src/proc/mobject/placement.hpp | 21 +- src/proc/mobject/session/clip.hpp | 4 +- src/proc/mobject/session/effect.hpp | 2 +- src/proc/mobject/session/meta.hpp | 2 +- src/proc/mobject/session/track.hpp | 2 +- tests/54builder.tests | 8 +- .../proc/mobject/builder/buildertooltest.cpp | 706 +++--------------- 20 files changed, 953 insertions(+), 709 deletions(-) create mode 100644 src/common/accesscasted.hpp create mode 100644 src/common/variant.hpp create mode 100644 src/common/wrapperptr.hpp create mode 100644 src/proc/mobject/builder/applicablebuildertargettypes.hpp diff --git a/src/common/accesscasted.hpp b/src/common/accesscasted.hpp new file mode 100644 index 000000000..58f2e2dbc --- /dev/null +++ b/src/common/accesscasted.hpp @@ -0,0 +1,168 @@ +/* + ACCESSCASTED.hpp - util template to access a value using conversion or cast as appropriate + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @file accesscasted.hpp + ** Helper for accessing a value employing either conversion or downcast + ** depending on the relation of the source type (type of the original value) + ** and the target type (type we need within the usage context). + ** When instantiating AcessCasted, we get a template static function + ** \c AcessCasted::access(SRC& elm), but the actual implementation + ** is choosed using boost::type_traits. If no viable implementatino can be + ** selected, \c EmptyVal::create() is invoked instead, which by default + ** creates a NULL value or similar by using the no-argument ctor of the + ** type TAR. Alternatively, you may define an specialisation fo EmptyVal, + ** e.g. throwing an exception instead of creating a NULL value. + ** + ** @see lumiera::WrapperPtr usage example to access a variant record + ** + */ + + +#ifndef UTIL_ACCESSCASTED_H +#define UTIL_ACCESSCASTED_H + +#include +#include +#include +#include +#include +#include + + + +namespace util { + using boost::remove_pointer; + using boost::remove_reference; + using boost::is_convertible; + using boost::is_polymorphic; + using boost::is_base_of; + using boost::enable_if; + + + template + struct can_cast : boost::false_type {}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + + template + struct has_RTTI + { + typedef typename remove_pointer< + typename remove_reference::type>::type TPlain; + + enum { value = is_polymorphic::value }; + }; + + template + struct use_dynamic_downcast + { + enum { value = can_cast::value + && has_RTTI::value + && has_RTTI::value + }; + }; + + template + struct use_static_downcast + { + enum { value = can_cast::value + && ( !has_RTTI::value + || !has_RTTI::value + ) + }; + }; + + template + struct use_conversion + { + enum { value = is_convertible::value + && !( use_static_downcast::value + ||use_dynamic_downcast::value + ) + }; + }; + + + + template + struct EmptyVal + { + static X create() { return X(); } + }; + template + struct EmptyVal + { + static X*& create() { static X* nullP(0); return nullP; } + }; + + + + + + template + struct NullAccessor + { + typedef RET Ret; + + static RET access (...) { return ifEmpty(); } + static RET ifEmpty () { return EmptyVal::create(); } + }; + + template + struct AccessCasted : NullAccessor + { + using NullAccessor::access; + + template + static typename enable_if< use_dynamic_downcast, TAR>::type + access (ELM& elem) + { + return dynamic_cast (elem); + } + + template + static typename enable_if< use_static_downcast, TAR>::type + access (ELM& elem) + { + return static_cast (elem); + } + + template + static typename enable_if< use_conversion, TAR>::type + access (ELM& elem) + { + return elem; + } + }; + + +} // namespace util +#endif diff --git a/src/common/typelistutil.hpp b/src/common/typelistutil.hpp index f7a716024..3fb6a531e 100644 --- a/src/common/typelistutil.hpp +++ b/src/common/typelistutil.hpp @@ -40,7 +40,10 @@ This code is heavily inspired by /** @file typelistutil.hpp ** Helpers for working with lumiera::typelist::Types (i.e. lists-of-types). - ** + ** The main purpose is to build interfaces and polymorphic implementations + ** (using virtual functions) based on templated Types or Collections of types, + ** which is not possible without Template Metaprogrmming. + ** ** @see lumiera::query::ConfigRules usage example ** @see typelist.hpp ** @@ -141,6 +144,94 @@ namespace lumiera }; + + /** + * A Variation of InstantiateChained providing an incremented + * Index value template parameter. This index can e.g. be used + * to store pointers in a dispatcher table in the Base class. + * Similar to InstantiateChained, this template builds a linear + * chain of inheritance. The user-provided template, which is + * to be instantiated for all types in the Typelist, now has to + * accept an additional third parameter (uint i). + */ + template + < class TYPES // List of Types + , template class _X_ // your-template-goes-here + , class BASE = NullType // Base class at end of chain + , uint i = 0 // incremented on each instantiaton + > + class InstantiateWithIndex; + + + template< template class _X_ + , class BASE + , uint i + > + class InstantiateWithIndex + : public BASE + { + public: + typedef BASE Unit; + typedef NullType Next; + enum{ COUNT = i }; + }; + + + template + < class TY, typename TYPES + , template class _X_ + , class BASE + , uint i + > + class InstantiateWithIndex, _X_, BASE, i> + : public _X_< TY + , InstantiateWithIndex + , i + > + { + public: + typedef InstantiateWithIndex Next; + typedef _X_ Unit; + enum{ COUNT = Next::COUNT }; + }; + + + /** + * Metafunction counting the number of Types in the collection + */ + template + struct count; + template<> + struct count + { + enum{ value = 0 }; + }; + template + struct count > + { + enum{ value = 1 + count::value }; + }; + + /** + * Metafunction " max( sizeof(T) ) for T in TYPES " + */ + template + struct maxSize; + template<> + struct maxSize + { + enum{ value = 0 }; + }; + template + struct maxSize > + { + enum{ thisval = sizeof(TY) + , nextval = maxSize::value + , value = nextval > thisval? nextval:thisval + }; + }; + + } // namespace typelist } // namespace lumiera diff --git a/src/common/variant.hpp b/src/common/variant.hpp new file mode 100644 index 000000000..561b7149c --- /dev/null +++ b/src/common/variant.hpp @@ -0,0 +1,276 @@ +/* + VARIANT.hpp - simple variant wrapper (typesafe union) + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @file variant.hpp + ** This file defines a simple alternative to boost::variant. + ** It pulls in fewer headers and has a shorter code path, but also + ** doesn't deal with alignement issues and is not threadsafe. + ** + ** Values can be stored using \c operator= . In order to access the value + ** stored in lumiera::Variant, you additionally need to define a "functor" + **
  • with a typedef "Ret" for the return type
  • + **
  • providing a static Ret access(ELM&) function + ** for each of the types used in the Variant
  • + **
+ ** + ** @see wrapperptr.hpp usage example + */ + + +#ifndef LUMIERA_VARIANT_H +#define LUMIERA_VARIANT_H + + +#include "common/typelistutil.hpp" + +#include + + + +namespace lumiera { + + namespace variant { + + using lumiera::typelist::count; + using lumiera::typelist::maxSize; + using lumiera::typelist::InstantiateWithIndex; + + /** + * internal helper used to build a variant storage wrapper. + * Parametrized with a collection of types, it provides functionality + * to copy a value of one of these types into an internal buffer, while + * remembering which of these types was used to place this copy. + * The value can be later on extracted using a visitation like mechanism, + * which takes a functor class and invokes a function \c access(T&) with + * the type matching the current value in storage + */ + template + struct Holder + { + + enum { TYPECNT = count::value + , SIZE = maxSize::value + }; + + + /** Storage to hold the actual value */ + struct Buffer + { + char buffer_[SIZE]; + uint which_; + + Buffer() : which_(TYPECNT) {} + + void* + put (void) + { + deleteCurrent(); + return 0; + } + + void + deleteCurrent (); // depends on the Deleter, see below + }; + + template + struct PlacementAdapter : BASE + { + T& + put (T const& toStore) + { + BASE::deleteCurrent(); // remove old content, if any + + T& storedObj = *new(BASE::buffer_) T (toStore); + BASE::which_ = idx; // remember the actual type selected + return storedObj; + } + + using BASE::put; + }; + + typedef InstantiateWithIndex< TYPES + , PlacementAdapter + , Buffer + > + Storage; + + + + /** provide a dispatcher table based visitation mechanism */ + template + struct CaseSelect + { + typedef typename FUNCTOR::Ret Ret; + typedef Ret (*Func)(Buffer&); + + Func table_[TYPECNT]; + + CaseSelect () + { + for (uint i=0; i + static Ret + trampoline (Buffer& storage) + { + T& content = reinterpret_cast (storage.buffer_); + return FUNCTOR::access (content); + } + + Ret + invoke (Buffer& storage) + { + if (TYPECNT <= storage.which_) + return FUNCTOR::ifEmpty (); + else + return (*table_[storage.which_]) (storage); + } + }; + + + template< class T, class BASE, uint i > + struct CasePrepare + : BASE + { + CasePrepare () : BASE() + { + BASE::table_[i] = &BASE::template trampoline; + } + }; + + + template + static typename FUNCTOR::Ret + access (Buffer& buf) + { + typedef InstantiateWithIndex< TYPES + , CasePrepare + , CaseSelect + > + Accessor; + static Accessor select_case; + return select_case.invoke(buf); + } + + + struct Deleter + { + typedef void Ret; + + template + static void access (T& elem) { elem.~T(); } + + static void ifEmpty () { } + }; + }; + + + template + inline void + Holder::Buffer::deleteCurrent () + { + access(*this); // remove old content, if any + which_ = TYPECNT; // mark as empty + } + + } // namespace variant + + + + + + + + + /** + * A variant wrapper (typesafe union) capable of holding a value of any + * of a bounded collection of types. The value is stored in a local buffer + * directly within the object and may be accessed by a typesafe visitation. + * + * \par + * This utility class is similar to boost::variant and indeed was implemented + * (5/08) in an effort to replace the latter in a draft solution for the problem + * of typesafe access to the correct wrapper class from within some builder tool. + * Well -- after finisihng this "exercise" I must admit that it is not really + * much more simple than what boost::variant does internally. At least we are + * pulling in fewer headers and the actual code path is shorter compared with + * boost::variant, at the price of beeing not so generic, not caring for + * alignment issues within the buffer and being not threadsafe + * + * @param TYPES collection of possible types to be stored in this variant object + * @param Access policy how to access the stored value + */ + template< typename TYPES + , template class Access + > + class Variant + : boost::noncopyable + { + + typedef variant::Holder Holder; + typedef typename Holder::Deleter Deleter; + + + /** storage: buffer holding either and "empty" marker, + * or one of the configured pointer to wrapper types */ + typename Holder::Storage holder_; + + + public: + void reset () { holder_.deleteCurrent();} + + /** store a copy of the given argument within the + * variant holder buffer, thereby typically casting + * or converting the given source type to the best + * suited (base) type (out of the collection of possible + * types for this Variant instance) + */ + template + Variant& + operator= (SRC src) + { + if (src) holder_.put (src); // see Holder::PlacementAdaptor::put + else reset(); + return *this; + } + + /** retrieve current content of the variant, + * trying to cast or convert it to the given type. + * Actually, the function \c access(T&) on the + * Access-policy (template param) is invoked with the + * type currently stored in the holder buffer. + * May return NULL if conversion fails. + */ + template + TAR + get () + { + typedef Access Extractor; + return Holder::template access (this->holder_); + } + }; + +} // namespace lumiera +#endif diff --git a/src/common/wrapperptr.hpp b/src/common/wrapperptr.hpp new file mode 100644 index 000000000..e17963eff --- /dev/null +++ b/src/common/wrapperptr.hpp @@ -0,0 +1,63 @@ +/* + WRAPPERPTR.hpp - variant record able to hold a pointer to some smart-ptr/wrapper types, providing conversions + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + + +#ifndef LUMIERA_WRAPPERPTR_H +#define LUMIERA_WRAPPERPTR_H + + +#include "common/variant.hpp" +#include "common/accesscasted.hpp" + +#include "common/typelist.hpp" +#include "proc/mobject/placement.hpp" +#include "common/p.hpp" + + +namespace asset { class Asset; } +namespace mobject { class MObject; } + +namespace lumiera { + + + typedef typelist::Types < mobject::Placement* + , P* + > ::List + WrapperTypes; + + /** + * helper to treat various sorts of smart-ptrs uniformly. + * Implemented as a variant-type value object, it is preconfigured + * with the possible hierarchy-base classes used within this application. + * Thus, when passing in an arbitrary smart-ptr, the best fitting smart-ptr + * type pointing to the corresponding base class is selected for internal storage. + * Later on, stored values can be retrieved either utilitzing static or dynamic casts; + * error reporting is similar to the bahaviour of dynamic_cast: when retrieving + * a pointer, in case of mismatch NULL is returned. + */ + typedef lumiera::Variant WrapperPtr; + + + +} // namespace lumiera +#endif diff --git a/src/proc/mobject/builder/applicablebuildertargettypes.hpp b/src/proc/mobject/builder/applicablebuildertargettypes.hpp new file mode 100644 index 000000000..e51fa1251 --- /dev/null +++ b/src/proc/mobject/builder/applicablebuildertargettypes.hpp @@ -0,0 +1,70 @@ +/* + ApplicableBuilderTargetTypes - definitinon header specifying all types treated by builder tools + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#ifndef MOBJECT_BUILDER_APPLICABLEBUILDERTARGETTYPES_H +#define MOBJECT_BUILDER_APPLICABLEBUILDERTARGETTYPES_H + +#include "proc/mobject/builder/buildertool.hpp" + + + +namespace mobject { + namespace session { + + class Clip; + class Effect; + class AbstractMO; + template class Auto; + // Forward declarations sufficient here... + // actual definitions necessary only in the + // implementation file (*cpp) of the builder tool. + } + + namespace builder { + + typedef Types< session::Clip, + session::Effect, + session::AbstractMO + > ::List + BuilderTargetTypes; + + + /** + * Marker used to declare some visiting Tool class to be actually a + * mobject::builder::BuilderTool and to possibly accept and treat the + * common selection of types to be handled by any such builder tool. + * The actual BuilderTool impl should inherit from this template by + * feeding back its type (CRTP), this causes a dispatcher table entry + * be generated for this concrete BuilderTool implementation. + */ + template + struct ApplicableBuilderTargetTypes + : Applicable + { }; + + + + } // namespace mobject::builder + +} // namespace mobject +#endif diff --git a/src/proc/mobject/builder/buildertool.hpp b/src/proc/mobject/builder/buildertool.hpp index 0985567d1..1801bc2ef 100644 --- a/src/proc/mobject/builder/buildertool.hpp +++ b/src/proc/mobject/builder/buildertool.hpp @@ -20,20 +20,54 @@ */ +/** @file buildertool.hpp + ** Visiting-tool mechanism configured specifically for the Builder. + ** The Builder creates the render nodes network by applying several Builder Tools + ** to the objects found in the Session, EDL and Fixture. These BuilderTool instances + ** contain the details of the builder implementation. + ** + ** As the objects to be treated are normally handled by smart-ptrs, BuilderTool provides + ** a special facility for dealing with these wrapped objects. There are some liabilities. + **
  • each concrete Buildable subtype to be treated specifically needs to + ** declare \c DEFINE_PROCESSABLE_BY(BuilderTool)
  • + **
  • at the same time, the concrete BuilderTool subclass has to declare + ** being Applicable to this concrete Buildable subtype. The recommended way + ** of ensuring this, is to add an entry to applicablebuildertargettypes.hpp + ** and then derive the concrete BuilderTool subclass from + ** ApplicableBuilderTargetTypes
  • + **
  • when accessing the wrapper from within a \c treat() function, a suitable + ** concrete wrapper type has to be specified. If the wrapper type used for + ** invoking the BuilderTool (function \c apply(BuilderTool&l, WrappedObject&) ) + ** can not be converted to this type requested from within the call, an + ** assertion failure (or segmentation fault in a release build) will result.
  • + **
+ ** + ** @see visitor.hpp + ** @see applicablebuildertargettypes.hpp + ** @see buildertooltest.hpp + ** @see nodecreatertool.hpp + */ + + #ifndef MOBJECT_BUILDER_TOOL_H #define MOBJECT_BUILDER_TOOL_H #include "common/visitor.hpp" +#include "common/wrapperptr.hpp" + +#include "common/p.hpp" +#include "proc/mobject/placement.hpp" +#include "proc/mobject/explicitplacement.hpp" +namespace mobject { -namespace mobject - { class Buildable; - namespace builder - { + namespace builder { + + using lumiera::P; /** * Policy invoking an catch-all function for processing @@ -49,19 +83,79 @@ namespace mobject virtual RET onUnknown (Buildable& target) = 0; }; - - + + /** * Base class of all BuilderTools, used according to the visitor pattern: * each Tool contains the concrete implementation for one task to be done * to the various MObject classes. The concrete builder tool implementation * should not diretcly inherit from this base interface, but rather through * an instantiation of the "Applicable" template parametrized with all - * concrete Buildable classes, for which it wants calls to be dispatched. + * concrete Buildable classes, for which it wants calls to be dispatched. + * \par + * In addition to lumiera::visitor::Tool, BuilderTool adds support for dealing + * with objects normally handled by means of smart-pointers or similar + * wrappers, most notably mobject::Placement. The visitaion is initiated + * by calling the stand-alone function \c (BuilderTool& tool, WRA& wrappedTargetObj) , + * which forwards to the visitation mechanism supported by the type contained + * in the wrapper, but stores away a pointer to the wrapped object, which can + * be retrieved in a typesafe manner from within the \c treat(ConcreteType&) + * function. + * @note retrieving the wrapper is not threadsafe and not reentrant, + * as we simply store a pointer within the BuilderTool instance. */ - typedef lumiera::visitor::Tool BuilderTool; + class BuilderTool + : public lumiera::visitor::Tool + { + lumiera::WrapperPtr currentWrapper_; + + public: + + template class WRA, class TAR> + void rememberWrapper (WRA* ptr_toWrappedTarget) + { + currentWrapper_ = ptr_toWrappedTarget; + } + + void forgetWrapper () + { + currentWrapper_.reset(); + } + + + protected: /* == interface for accessing the wrapper from within tool application == */ + + template + Placement& + getPlacement () + { + Placement* pPlacement = currentWrapper_.get*>(); + ENSURE (pPlacement, "wrong target type when invoking %s", __PRETTY_FUNCTION__); + return *pPlacement; + } + + ExplicitPlacement + getExplicitPlacement () + { + return getPlacement().resolve(); + } + + template + lumiera::P + getPtr () + { + P* pP = currentWrapper_.get*>(); + ENSURE (pP, "wrong target type when invoking %s", __PRETTY_FUNCTION__); + return *pP; + } + }; + + /** + * declare the concrete types a BuilderTool may recievee and treat. + * @note it is recommended to use ApplicableBuilderTargetTypes + */ template < class TOOLImpl, // concrete BuilderTool implementation class TYPELIST // list of all concrete Buildables to be treated @@ -71,17 +165,33 @@ namespace mobject { } ; - using lumiera::typelist::Types; // convienience for the users of "Applicable" - + using lumiera::typelist::Types; // convenience for the users of "Applicable" + } // namespace mobject::builder /** - * Marker Interface for classes Visitable by Builder tools. + * Marker Interface for classes visitable by Builder tools. */ class Buildable : public lumiera::visitor::Visitable { }; - + + + + + namespace builder { // to be found by ADL + + template + inline Buildable::ReturnType + apply (BuilderTool& tool, WRA& wrappedTargetObj) + { + tool.rememberWrapper(&wrappedTargetObj); + wrappedTargetObj->apply (tool); // dispatch to suitable treat() function + tool.forgetWrapper(); + } + + } // namespace mobject::builder + } // namespace mobject #endif diff --git a/src/proc/mobject/builder/nodecreatertool.cpp b/src/proc/mobject/builder/nodecreatertool.cpp index 89a35fa46..93362ef25 100644 --- a/src/proc/mobject/builder/nodecreatertool.cpp +++ b/src/proc/mobject/builder/nodecreatertool.cpp @@ -31,11 +31,8 @@ using mobject::session::Clip; using mobject::session::Effect; using mobject::session::Auto; -namespace mobject - { - - namespace builder - { +namespace mobject { + namespace builder { diff --git a/src/proc/mobject/builder/nodecreatertool.hpp b/src/proc/mobject/builder/nodecreatertool.hpp index 26a033d26..e37d0d14f 100644 --- a/src/proc/mobject/builder/nodecreatertool.hpp +++ b/src/proc/mobject/builder/nodecreatertool.hpp @@ -24,23 +24,15 @@ #ifndef MOBJECT_BUILDER_NODECREATERTOOL_H #define MOBJECT_BUILDER_NODECREATERTOOL_H -#include "proc/mobject/builder/buildertool.hpp" + +#include "proc/mobject/builder/applicablebuildertargettypes.hpp" + #include "proc/engine/processor.hpp" -namespace mobject - { - namespace session - { - // Forward declarations - class Effect; - class Clip; - template class Auto; - } - - namespace builder - { +namespace mobject { + namespace builder { @@ -52,11 +44,10 @@ namespace mobject * render engine under construction such as to reflect the properties * of the MObject in the actual render. */ - class NodeCreatorTool : public BuilderTool + class NodeCreatorTool + : public ApplicableBuilderTargetTypes { - //////////////////////////////////////////////TODO: switch to acyclic visitior!!!!!!!!!!!!! - public: virtual void treat (mobject::session::Clip& clip) ; virtual void treat (mobject::session::Effect& effect) ; diff --git a/src/proc/mobject/builder/segmentationtool.cpp b/src/proc/mobject/builder/segmentationtool.cpp index 6f07e7d4f..7b6c29747 100644 --- a/src/proc/mobject/builder/segmentationtool.cpp +++ b/src/proc/mobject/builder/segmentationtool.cpp @@ -31,10 +31,8 @@ using mobject::session::Clip; using mobject::session::Effect; -namespace mobject - { - namespace builder - { +namespace mobject { + namespace builder { diff --git a/src/proc/mobject/builder/segmentationtool.hpp b/src/proc/mobject/builder/segmentationtool.hpp index aa09d80d3..eaf74c1c6 100644 --- a/src/proc/mobject/builder/segmentationtool.hpp +++ b/src/proc/mobject/builder/segmentationtool.hpp @@ -24,26 +24,18 @@ #ifndef MOBJECT_BUILDER_SEGMENTATIONTOOL_H #define MOBJECT_BUILDER_SEGMENTATIONTOOL_H -#include -#include "proc/mobject/builder/buildertool.hpp" +#include "proc/mobject/builder/applicablebuildertargettypes.hpp" + #include "proc/mobject/session/segment.hpp" +#include using std::list; -namespace mobject - { - namespace session - { - // Forward declarations - class Clip; - class Effect; - } - - namespace builder - { +namespace mobject { + namespace builder { /** @@ -53,10 +45,10 @@ namespace mobject * can be represented by automation solely, without the need * to change the node connections. */ - class SegmentationTool : public BuilderTool + class SegmentationTool + : public ApplicableBuilderTargetTypes { - //////////////////////////////////////////////TODO: switch to acyclic visitior!!!!!!!!!!!!! public: void treat (mobject::session::Clip& clip) ; diff --git a/src/proc/mobject/explicitplacement.hpp b/src/proc/mobject/explicitplacement.hpp index cb5e424b5..0e5b20bfd 100644 --- a/src/proc/mobject/explicitplacement.hpp +++ b/src/proc/mobject/explicitplacement.hpp @@ -30,9 +30,9 @@ namespace mobject { - - - + + + /** * Special kind of Placement, where the location of the * MObject has been nailed down to a fixed position. @@ -51,7 +51,7 @@ namespace mobject const Pipe pipe; typedef std::pair SolutionData; //TODO (ichthyo consideres better passing of solution by subclass) - + /** no need to resolve any further, as this ExplicitPlacement * already \e is the result of a resolve()-call. */ @@ -61,9 +61,7 @@ namespace mobject return *this; } - /** */ /////////////////////////////////////////////////////////////TODO: wip-wip... - DEFINE_PROCESSABLE_BY (builder::BuilderTool); - + protected: /* @todo ichthyo considers a much more elegant implementation utilizing a subclass * of FixedLocation, which would serve as Placement::LocatingSolution, and @@ -82,8 +80,8 @@ namespace mobject /** copying prohibited, ExplicitPlacement is effectively const! */ ExplicitPlacement& operator= (const ExplicitPlacement&); }; - - - + + + } // namespace mobject #endif diff --git a/src/proc/mobject/mobject.hpp b/src/proc/mobject/mobject.hpp index 28ab788ed..eb481489f 100644 --- a/src/proc/mobject/mobject.hpp +++ b/src/proc/mobject/mobject.hpp @@ -88,9 +88,10 @@ namespace mobject virtual bool operator== (const MObject& oo) const =0; }; + - - + + typedef Placement PMO; diff --git a/src/proc/mobject/placement.cpp b/src/proc/mobject/placement.cpp index 452528627..58e145e72 100644 --- a/src/proc/mobject/placement.cpp +++ b/src/proc/mobject/placement.cpp @@ -23,25 +23,39 @@ #include "proc/mobject/placement.hpp" #include "proc/mobject/explicitplacement.hpp" +#include "proc/mobject/mobject.hpp" + +#include +using boost::str; namespace mobject { - /** @note we know we need only this single - * specialisation, because we define - * the Placements of more specific - * MObject kinds to be subclasses - * of Placement, so they - * will inherit this function. - */ - template<> + template ExplicitPlacement - Placement::resolve () const + Placement::resolve () const { return ExplicitPlacement (*this, chain.resolve()); } + + /** @note we know we need only this single specialisation, + * because we define the Placements of more specific + * MObject kinds to be subclasses of Placement, + * so they will inherit this function. + */ + template ExplicitPlacement Placement::resolve() const; + + template<> + Placement::operator string () const + { + static boost::format fmt("Placement<%s> %|50T.| use-cnt=%x adr=%x pointee=%x"); + return str(fmt % typeid(*get()).name() % use_count() % this % get() ); + } + + + } // namespace mobject diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index 7bd3a9ce4..df71f0d75 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -58,12 +58,10 @@ #define MOBJECT_PLACEMENT_H #include "pre.hpp" -#include "proc/mobject/mobject.hpp" #include "proc/mobject/session/locatingpin.hpp" #include "proc/asset/pipe.hpp" #include -using std::tr1::shared_ptr; namespace mobject @@ -72,6 +70,7 @@ namespace mobject class ExplicitPlacement; + using std::tr1::shared_ptr; @@ -82,9 +81,10 @@ namespace mobject * be within the Session/EDL */ template - class Placement : public Buildable, protected shared_ptr + class Placement : protected shared_ptr { protected: + typedef shared_ptr Base; typedef lumiera::Time Time; typedef asset::shared_ptr Pipe; @@ -99,13 +99,14 @@ namespace mobject operator-> () const { ENSURE (*this); - return shared_ptr::operator-> (); + return Base::operator-> (); } + operator string() const ; + size_t use_count() const { return Base::use_count(); } + virtual ~Placement() {}; - /** */ /////////////////////////////////////////////////////////////TODO: totmachen? - DEFINE_PROCESSABLE_BY (builder::BuilderTool); /** interface for defining the kind of placement @@ -128,20 +129,19 @@ namespace mobject friend class session::MObjectFactory; }; - typedef Placement PMO; /* === defining specialisations to be subclasses === */ -#define DEFINE_SPECIALIZED_PLACEMENT(SUBCLASS) \ +#define DEFINE_SPECIALIZED_PLACEMENT(SUBCLASS, BASE) \ template<> \ - class Placement : public Placement \ + class Placement : public Placement \ { \ protected: \ Placement (SUBCLASS & m, void (*moKiller)(MObject*)) \ - : Placement::Placement (m, moKiller) \ + : Placement::Placement (m, moKiller) \ { }; \ friend class session::MObjectFactory; \ \ @@ -154,7 +154,6 @@ namespace mobject (shared_ptr::operator-> ()); \ } \ }; - // DEFINE_PROCESSABLE_BY (builder::BuilderTool); /* a note to the maintainer: please don't add any fields or methods to * these subclasses which aren't also present in Placement! diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp index 7f1fe23c0..174a86cbf 100644 --- a/src/proc/mobject/session/clip.hpp +++ b/src/proc/mobject/session/clip.hpp @@ -66,7 +66,7 @@ namespace mobject and the unlink() function of the asset should take it into account when breaking circular references. */ -public: ////////////////////////////////////TODO: temporarily for buildertooltest + const Media & mediaDef_; const asset::Clip & clipDef_; @@ -99,7 +99,7 @@ public: ////////////////////////////////////TODO: temporarily for buildertoolt } // namespace mobject::session /** Placement defined to be subclass of Placement */ - DEFINE_SPECIALIZED_PLACEMENT (session::Clip); + DEFINE_SPECIALIZED_PLACEMENT (session::Clip, MObject); } // namespace mobject diff --git a/src/proc/mobject/session/effect.hpp b/src/proc/mobject/session/effect.hpp index 5831098d4..e4cdbee16 100644 --- a/src/proc/mobject/session/effect.hpp +++ b/src/proc/mobject/session/effect.hpp @@ -51,7 +51,7 @@ namespace mobject } // namespace mobject::session /** Placement defined to be subclass of Placement */ - DEFINE_SPECIALIZED_PLACEMENT (session::Effect); + DEFINE_SPECIALIZED_PLACEMENT (session::Effect, MObject); } // namespace mobject #endif diff --git a/src/proc/mobject/session/meta.hpp b/src/proc/mobject/session/meta.hpp index b45d30eb5..db679a904 100644 --- a/src/proc/mobject/session/meta.hpp +++ b/src/proc/mobject/session/meta.hpp @@ -50,7 +50,7 @@ namespace mobject } // namespace mobject::session /** Placement defined to be subclass of Placement */ - DEFINE_SPECIALIZED_PLACEMENT (session::Meta); + DEFINE_SPECIALIZED_PLACEMENT (session::Meta, MObject); } // namespace mobject #endif diff --git a/src/proc/mobject/session/track.hpp b/src/proc/mobject/session/track.hpp index 2b9801273..f8b2c0017 100644 --- a/src/proc/mobject/session/track.hpp +++ b/src/proc/mobject/session/track.hpp @@ -83,7 +83,7 @@ namespace mobject } // namespace mobject::session /** Placement defined to be subclass of Placement */ - DEFINE_SPECIALIZED_PLACEMENT (session::Track); + DEFINE_SPECIALIZED_PLACEMENT (session::Track, session::Meta); } // namespace mobject #endif diff --git a/tests/54builder.tests b/tests/54builder.tests index 3b6825651..3ec3bd325 100644 --- a/tests/54builder.tests +++ b/tests/54builder.tests @@ -4,8 +4,12 @@ TESTING "Component Test Suite: Builder" ./test-components --group=builder TEST "BuilderTool_test" BuilderTool_test < -#include -#include -#include -#include -#include +#include "common/util.hpp" #include + +using util::cStr; using std::string; using std::cout; -namespace util { - using boost::remove_pointer; - using boost::remove_reference; - using boost::is_convertible; - using boost::is_polymorphic; - using boost::is_base_of; - using boost::enable_if; - - template - struct can_cast : boost::false_type {}; - template - struct can_cast { enum { value = is_base_of::value };}; - - template - struct can_cast { enum { value = is_base_of::value };}; - - template - struct can_cast { enum { value = is_base_of::value };}; - - - template - struct has_RTTI - { - typedef typename remove_pointer< - typename remove_reference::type>::type TPlain; - - enum { value = is_polymorphic::value }; - }; - - template - struct use_dynamic_downcast - { - enum { value = can_cast::value - && has_RTTI::value - && has_RTTI::value - }; - }; - - template - struct use_static_downcast - { - enum { value = can_cast::value - && ( !has_RTTI::value - || !has_RTTI::value - ) - }; - }; - - template - struct use_conversion - { - enum { value = is_convertible::value - && !( use_static_downcast::value - ||use_dynamic_downcast::value - ) - }; - }; - - - - template - struct EmptyVal - { - static X create() { return X(); } - }; - template - struct EmptyVal - { - static X*& create() { static X* nullP(0); return nullP; } - }; - - - - - - template - struct NullAccessor - { - typedef RET Ret; - - static RET access (...) { return ifEmpty(); } - static RET ifEmpty () { return EmptyVal::create(); } - }; - - template - struct AccessCasted : NullAccessor - { - using NullAccessor::access; - - template - static typename enable_if< use_dynamic_downcast, TAR>::type - access (ELM& elem) - { - return dynamic_cast (elem); - } - - template - static typename enable_if< use_static_downcast, TAR>::type - access (ELM& elem) - { - return static_cast (elem); - } - - template - static typename enable_if< use_conversion, TAR>::type - access (ELM& elem) - { - return elem; - } - }; - - -} - -namespace lumiera { - - namespace typelist { - - - template - < class TYPES // List of Types - , template class _X_ // your-template-goes-here - , class BASE = NullType // Base class at end of chain - , uint i = 0 // incremented on each instantiaton - > - class InstantiateWithIndex; - - - template< template class _X_ - , class BASE - , uint i - > - class InstantiateWithIndex - : public BASE - { - public: - typedef BASE Unit; - typedef NullType Next; - enum{ COUNT = i }; - }; - - - template - < class TY, typename TYPES - , template class _X_ - , class BASE - , uint i - > - class InstantiateWithIndex, _X_, BASE, i> - : public _X_< TY - , InstantiateWithIndex - , i - > - { - public: - typedef InstantiateWithIndex Next; - typedef _X_ Unit; - enum{ COUNT = Next::COUNT }; - }; - - template - struct count; - template<> - struct count - { - enum{ value = 0 }; - }; - template - struct count > - { - enum{ value = 1 + count::value }; - }; - - template - struct maxSize; - template<> - struct maxSize - { - enum{ value = 0 }; - }; - template - struct maxSize > - { - enum{ nextval = maxSize::value - , thisval = sizeof(TY) - , value = nextval > thisval? nextval:thisval - }; - }; - - } // namespace typelist - - - - - - namespace variant { - - using lumiera::typelist::count; - using lumiera::typelist::maxSize; - using lumiera::typelist::InstantiateWithIndex; - - /** - * internal helper used to build a variant storage wrapper. - * Parametrized with a collection of types, it provides functionality - * to copy a value of one of these types into an internal buffer, while - * remembering which of these types was used to place this copy. - * The value can be later on extracted using a visitation like mechanism, - * which takes a functor object and invokes a function \c access(T&) with - * the type matching the current value in storage - */ - template - struct Holder - { - - enum { TYPECNT = count::value - , SIZE = maxSize::value - }; - - - /** Storage to hold the actual value */ - struct Buffer - { - char buffer_[SIZE]; - uint which; - - Buffer() : which(TYPECNT) {} - - void* - put (void) - { - deleteCurrent(); - return 0; - } - - void - deleteCurrent (); // depends on the Deleter, see below - }; - - template - struct PlacementAdapter : BASE - { - T& - put (T const& toStore) - { - BASE::deleteCurrent(); // remove old content, if any - - T& storedObj = *new(BASE::buffer_) T (toStore); - this->which = idx; // remember the actual type selected - return storedObj; - } - - using BASE::put; - }; - - typedef InstantiateWithIndex< TYPES - , PlacementAdapter - , Buffer - > - Storage; - - - - /** provide a dispatcher table based visitation mechanism */ - template - struct CaseSelect - { - typedef typename FUNCTOR::Ret Ret; - typedef Ret (*Func)(Buffer&); - - Func table_[TYPECNT]; - - CaseSelect () - { - for (uint i=0; i - static Ret - trampoline (Buffer& storage) - { - T& content = reinterpret_cast (storage.buffer_); - return FUNCTOR::access (content); - } - - Ret - invoke (Buffer& storage) - { - if (TYPECNT <= storage.which) - return FUNCTOR::ifEmpty (); - else - return (*table_[storage.which]) (storage); - } - }; - - - template< class T, class BASE, uint i > - struct CasePrepare - : BASE - { - CasePrepare () : BASE() - { - BASE::table_[i] = &BASE::template trampoline; - } - }; - - - template - static typename FUNCTOR::Ret - access (Buffer& buf) - { - typedef InstantiateWithIndex< TYPES - , CasePrepare - , CaseSelect - > - Accessor; - static Accessor select_case; - return select_case.invoke(buf); - } - - - struct Deleter - { - typedef void Ret; - - template - static void access (T& elem) { elem.~T(); } - - static void ifEmpty () { } - }; - }; - - - template - void - Holder::Buffer::deleteCurrent () - { - access(*this); // remove old content, if any - which = TYPECNT; // mark as empty - } - - } // namespace variant - - - - - - - - - - - - - /** - * A variant wrapper (typesafe union) capable of holding a value of any - * of a bounded collection of types. The value is stored in a local buffer - * directly within the object and may be accessed by a typesafe visitation. - * - * \par - * This utility class is similar to boost::variant and indeed was implemented - * (5/08) in an effort to replace the latter in a draft solution for the problem - * of typesafe access to the correct wrapper class from within some builder tool. - * Well -- after finisihng this "exercise" I must admit that it is not really - * much more simple than what boost::variant does internally. At least we are - * pulling in fewer headers and the actual code path is shorter compared with - * boost::variant, at the price of beeing not so generic, not caring for - * alignment issues within the buffer and being not threadsafe - * - * @param TYPES collection of possible types to be stored in this variant object - * @param Access policy how to access the stored value - */ - template< typename TYPES - , template class Access = util::AccessCasted - > - class Variant - : boost::noncopyable - { - - typedef variant::Holder Holder; - typedef typename Holder::Deleter Deleter; - - - /** storage: buffer holding either and "empty" marker, - * or one of the configured pointer to wrapper types */ - typename Holder::Storage holder_; - - - public: - void reset () { holder_.deleteCurrent();} - - /** store a copy of the given argument within the - * variant holder buffer, thereby typically casting - * or converting the given source type to the best - * suited (base) type (out of the collection of possible - * types for this Variant instance) - */ - template - Variant& - operator= (SRC src) - { - if (src) holder_.put (src); // see Holder::PlacementAdaptor::put - else reset(); - return *this; - } - - /** retrieve current content of the variant, - * trying to cast or convert it to the given type. - * Actually, the function \c access(T&) on the - * Access-policy (template param) is invoked with the - * type currently stored in the holder buffer. - * May return NULL if conversion fails. - */ - template - TAR - get () - { - typedef Access Extractor; - return Holder::template access (this->holder_); - } - }; - -} // namespace lumiera - - - -namespace mobject - { - - DEFINE_SPECIALIZED_PLACEMENT (session::AbstractMO); - - - namespace builder - { - namespace test - { +namespace mobject { + namespace builder { + namespace test { using session::Clip; using session::AbstractMO; - -/////////////////////////////////////////////////////TODO: move to buildertool.hpp - - using lumiera::P; - using lumiera::typelist::Types; - - - - typedef Types < Placement* - , P* - > ::List - WrapperTypes; - - /** - * helper to treat various sorts of smart-ptrs uniformly. - * Implemented as a variant-type value object, it is preconfigured - * with the possible hierarchy-base classes used within this application. - * Thus, when passing in an arbitrary smart-ptr, the best fitting smart-ptr - * type pointing to the corresponding base class is selected for internal storage. - * Later on, stored values can be retrieved either utilitzing static or dynamic casts; - * error reporting is similar to the bahaviour of dynamic_cast: when retrieving - * a pointer, in case of mismatch NULL is returned. - */ - typedef lumiera::Variant WrapperPtr; - - - - class BuTuul - : public lumiera::visitor::Tool - { - WrapperPtr currentWrapper_; - - public: - - template class WRA, class TAR> - void rememberWrapper (WRA* argument) - { - currentWrapper_ = argument; - } - - void forgetWrapper () - { - currentWrapper_.reset(); - } - template - Placement& - getPlacement () - { - Placement* pPlacement = currentWrapper_.get*>(); - return *pPlacement; - } - ExplicitPlacement - getExplicitPlacement () - { - return getPlacement().resolve(); - } - template - P - getPtr () - { - P* pP = currentWrapper_.get*>(); - return *pP; - } - }; - - - - - - - - template - < class TOOLImpl, // concrete BuilderTool implementation - class TYPELIST // list of all concrete Buildables to be treated - > - class Appli - : public lumiera::visitor::Applicable - { } - ; - - using lumiera::typelist::Types; // convienience for the users of "Applicable" - - class BDable : public lumiera::visitor::Visitable - { - - }; -/////////////////////////////////////////////////////TODO: move to buildertool.hpp - - class DummyMO : public AbstractMO, public BDable + /** + * Test MObject subclass, which, contrary to any real MObject, + * can be created directly without involving MObjectFactory. + */ + class TestMO : public AbstractMO { public: - DummyMO() { }; - virtual bool isValid() const { return true;} -// DEFINE_PROCESSABLE_BY (BuilderTool); + TestMO() { }; - static void killDummy (MObject* dum) { delete (DummyMO*)dum; } - - virtual void - apply (BuTuul& tool) - { - return BDable::dispatchOp (*this, tool); - } + DEFINE_PROCESSABLE_BY (BuilderTool); + virtual bool isValid() const { return true;} + static void killDummy (MObject* dum) { delete (TestMO*)dum; } }; - class Clop : public Clip, public BDable - { - Clop (Clip& base) : Clip (base.clipDef_, base.mediaDef_) {} - - virtual void - apply (BuTuul& tool) - { - return BDable::dispatchOp (*this, tool); - } + /** + * Subclass-1 is \em not defined "processable", + * thus will always be handled as TestMO... + */ + class TestSubMO1 : public TestMO + { }; + + /** + * Subclass-2 \em is defined "processable", + * but we omit the necessary "applicable" definition in TestTool, + * resulting in an invocation of the error (catch-all) function... + */ + class TestSubMO2 : public TestMO + { + DEFINE_PROCESSABLE_BY (BuilderTool); }; - template - inline BDable::ReturnType - apply (BuTuul& tool, WRA& wrappedTargetObj) - { - WRA* ptr = &wrappedTargetObj; - (*ptr)->isValid(); - tool.rememberWrapper(ptr); - wrappedTargetObj->apply (tool); - tool.forgetWrapper(); - } - - //////////////////////////////////////////////////////TODO: wip-wip - - class DummyPlacement : public Placement + template + class TestPlacement : public Placement { public: - DummyPlacement() - : Placement::Placement(*new DummyMO, &DummyMO::killDummy) + TestPlacement(TestMO& testObject) + : Placement::Placement(testObject, &TestMO::killDummy) { } }; - //////////////////////////////////////////////////////TODO: wip-wip - + /** + * BuilderTool implementation for checking the invokation of the correct + * \c treat() function and for accessing the original Placement from + * within this invocation. It is declared to be applicable to Clip + * and TestMO objects (wrapped into any acceptable shared-ptr). + * Intentionally, we omit to declare it applicable to TestSubMO2 instances. + * In reality this would be a case of misconfiguration, because TestSubMO2 + * is defined to be processable and consequently has an \apply() function, + * which, due to this ommission can't find a dispatcher entry when invoked, + * so it will call the \c onUnknown(Buildable&) instead + */ class TestTool - : public Appli::List> + : public Applicable::List> { public: + string log_; + void treat (Clip& c) { Placement& pC = getPlacement(); - cout << "media is: "<< str(pC->getMedia()) <<"\n" - << "Placement(adr) " << &pC <<"\n"; + cout << "Clip on media : "<< str(pC->getMedia()) <<"\n"; + log_ = string (pC); } void treat (AbstractMO&) { - Placement& placement = getPlacement(); - cout << "unspecific MO; Placement(adr) " << &placement <<"\n"; + cout << "treat (AbstractMO&);\n"; + log_ = string (getPlacement()); } - void onUnknown (Buildable&) + void onUnknown (Buildable& bxx) { - cout << "catch-all-function called.\n"; + cout << "catch-all-function called...\n"; + log_ = string (getPlacement()); } }; - - - /******************************************************************* - * @test the generic visitor pattern specialized for treating - * MObjects in the builder. Because the generic visitor - * implementation is already covered by - * \link VisitingTool_test, it is sufficient to test - * the specialisation to the builder. - * \par + + + + + /************************************************************************************* + * @test the generic visitor pattern specialized for treating MObjects in the builder. * Besides using existing MObject types (at the moment session::Clip), - * we create inline a yet-unknown new MObject subclass. When passing - * such to any BuilderTool subclass, the compiler enforces the definition - * of a catch-all function, which is called, when there is no other - * applicable \c treat(MO&) function. Note further, whithin the specific - * treat-functions we get direct references, whithout interfering with - * Placements and memory management. (Is this a good idea? it allows - * client code to bypass the Placement (Handle). At least, I think - * it is not really a problem...) + * we create a yet-unknown new MObject subclass. When passing such to any + * BuilderTool subclass, the compiler enforces the definition of a catch-all + * function, which is called, when there is no other applicable \c treat(MO&) + * function. Note further, whithin the specific treat-functions we get direct + * references, whithout interfering with Placements and memory management. + * But from within the \c treat() function, we may access the wrapper object + * (i.e. shared_ptr, or lumiera::P or Placement) used when invoking the + * BuilderTool by using the protected interface on BuilderTool. + * + * @see VisitingTool_test for checking general visitor functionality */ class BuilderTool_test : public Test { @@ -677,18 +150,27 @@ namespace mobject { TestTool t1; - BuTuul& tool (t1); + BuilderTool& tool = t1; - DummyPlacement dumm; - Placement& dummy(dumm); - Placement clip = asset::Media::create("test-1", asset::VIDEO)->createClip(); + TestPlacement test1(*new TestSubMO1); + TestPlacement test2(*new TestSubMO2); - cout << "Placement(adr) " << &clip <<"\n"; + cout << "apply (tool, clip);\n"; apply (tool, clip); - cout << "Placement(adr) " << &dumm <<"\n"; - apply (tool, dummy); + INFO (test, "got Wrapper = %s", t1.log_.c_str()); + ASSERT (t1.log_ == string(clip)); + + cout << "apply (tool, test1);\n"; + apply (tool, test1); + INFO (test, "got Wrapper = %s", t1.log_.c_str()); + ASSERT (t1.log_ == string(test1)); + + cout << "apply (tool, test2);\n"; + apply (tool, test2); + INFO (test, "got Wrapper = %s", t1.log_.c_str()); + ASSERT (t1.log_ == string(test2)); } }; @@ -702,14 +184,4 @@ namespace mobject } // namespace builder - //////////////////////////////////////////////////////TODO: wip-wip -/* template<> - ExplicitPlacement - Placement::resolve () const - { - UNIMPLEMENTED ("just a test"); - } -*/ //////////////////////////////////////////////////////TODO: wip-wip - - } // namespace mobject From 6b1be6b7e7cd95b6c85a19e1cb2c625dc68ebc17 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 19 May 2008 08:46:19 +0200 Subject: [PATCH 084/245] Refactorings regarding use of smart-ptr, Placement and BuilderTool --- src/common/accesscasted.hpp | 168 +++++++++++ src/common/configrules.hpp | 8 +- src/common/query/mockconfigrules.hpp | 2 +- src/common/typelistutil.hpp | 95 +++++- src/common/variant.hpp | 276 ++++++++++++++++++ src/common/visitor.hpp | 2 +- src/common/visitorpolicies.hpp | 2 +- src/common/wrapperptr.hpp | 63 ++++ src/proc/asset/buildinstruct.hpp | 5 +- src/proc/asset/clip.hpp | 2 +- src/proc/asset/db.hpp | 2 +- src/proc/asset/media.cpp | 2 +- src/proc/asset/media.hpp | 11 +- src/proc/asset/meta.hpp | 2 +- src/proc/asset/pipe.hpp | 3 +- src/proc/asset/proc.hpp | 4 +- src/proc/asset/procpatt.cpp | 2 +- src/proc/asset/procpatt.hpp | 8 +- src/proc/asset/struct.cpp | 12 +- src/proc/asset/struct.hpp | 6 +- src/proc/asset/track.hpp | 2 +- src/proc/assetmanager.cpp | 32 +- src/proc/assetmanager.hpp | 6 +- src/proc/lumiera.hpp | 1 + .../builder/applicablebuildertargettypes.hpp | 70 +++++ src/proc/mobject/builder/buildertool.hpp | 134 ++++++++- src/proc/mobject/builder/nodecreatertool.cpp | 7 +- src/proc/mobject/builder/nodecreatertool.hpp | 23 +- src/proc/mobject/builder/segmentationtool.cpp | 6 +- src/proc/mobject/builder/segmentationtool.hpp | 22 +- src/proc/mobject/explicitplacement.hpp | 17 +- src/proc/mobject/mobject.hpp | 20 +- src/proc/mobject/placement.cpp | 32 +- src/proc/mobject/placement.hpp | 19 +- src/proc/mobject/session/abstractmo.cpp | 10 +- src/proc/mobject/session/abstractmo.hpp | 2 + src/proc/mobject/session/clip.hpp | 7 +- src/proc/mobject/session/defsmanager.cpp | 20 +- src/proc/mobject/session/defsmanager.hpp | 14 +- src/proc/mobject/session/defsregistry.hpp | 37 +-- src/proc/mobject/session/effect.hpp | 2 +- src/proc/mobject/session/locatingpin.hpp | 5 +- src/proc/mobject/session/meta.hpp | 2 +- src/proc/mobject/session/mobjectfactory.hpp | 2 +- src/proc/mobject/session/track.hpp | 8 +- src/tool/try.cpp | 213 +++++++++++++- tests/54builder.tests | 8 +- .../proc/mobject/builder/buildertooltest.cpp | 158 +++++++--- .../mobject/session/defsregistryimpltest.cpp | 11 +- 49 files changed, 1329 insertions(+), 236 deletions(-) create mode 100644 src/common/accesscasted.hpp create mode 100644 src/common/variant.hpp create mode 100644 src/common/wrapperptr.hpp create mode 100644 src/proc/mobject/builder/applicablebuildertargettypes.hpp diff --git a/src/common/accesscasted.hpp b/src/common/accesscasted.hpp new file mode 100644 index 000000000..58f2e2dbc --- /dev/null +++ b/src/common/accesscasted.hpp @@ -0,0 +1,168 @@ +/* + ACCESSCASTED.hpp - util template to access a value using conversion or cast as appropriate + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @file accesscasted.hpp + ** Helper for accessing a value employing either conversion or downcast + ** depending on the relation of the source type (type of the original value) + ** and the target type (type we need within the usage context). + ** When instantiating AcessCasted, we get a template static function + ** \c AcessCasted::access(SRC& elm), but the actual implementation + ** is choosed using boost::type_traits. If no viable implementatino can be + ** selected, \c EmptyVal::create() is invoked instead, which by default + ** creates a NULL value or similar by using the no-argument ctor of the + ** type TAR. Alternatively, you may define an specialisation fo EmptyVal, + ** e.g. throwing an exception instead of creating a NULL value. + ** + ** @see lumiera::WrapperPtr usage example to access a variant record + ** + */ + + +#ifndef UTIL_ACCESSCASTED_H +#define UTIL_ACCESSCASTED_H + +#include +#include +#include +#include +#include +#include + + + +namespace util { + using boost::remove_pointer; + using boost::remove_reference; + using boost::is_convertible; + using boost::is_polymorphic; + using boost::is_base_of; + using boost::enable_if; + + + template + struct can_cast : boost::false_type {}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + + template + struct has_RTTI + { + typedef typename remove_pointer< + typename remove_reference::type>::type TPlain; + + enum { value = is_polymorphic::value }; + }; + + template + struct use_dynamic_downcast + { + enum { value = can_cast::value + && has_RTTI::value + && has_RTTI::value + }; + }; + + template + struct use_static_downcast + { + enum { value = can_cast::value + && ( !has_RTTI::value + || !has_RTTI::value + ) + }; + }; + + template + struct use_conversion + { + enum { value = is_convertible::value + && !( use_static_downcast::value + ||use_dynamic_downcast::value + ) + }; + }; + + + + template + struct EmptyVal + { + static X create() { return X(); } + }; + template + struct EmptyVal + { + static X*& create() { static X* nullP(0); return nullP; } + }; + + + + + + template + struct NullAccessor + { + typedef RET Ret; + + static RET access (...) { return ifEmpty(); } + static RET ifEmpty () { return EmptyVal::create(); } + }; + + template + struct AccessCasted : NullAccessor + { + using NullAccessor::access; + + template + static typename enable_if< use_dynamic_downcast, TAR>::type + access (ELM& elem) + { + return dynamic_cast (elem); + } + + template + static typename enable_if< use_static_downcast, TAR>::type + access (ELM& elem) + { + return static_cast (elem); + } + + template + static typename enable_if< use_conversion, TAR>::type + access (ELM& elem) + { + return elem; + } + }; + + +} // namespace util +#endif diff --git a/src/common/configrules.hpp b/src/common/configrules.hpp index 81da041ae..0968c88d4 100644 --- a/src/common/configrules.hpp +++ b/src/common/configrules.hpp @@ -46,6 +46,7 @@ #ifndef LUMIERA_CONFIGRULES_H #define LUMIERA_CONFIGRULES_H +#include "common/p.hpp" #include "common/query.hpp" #include "common/typelistutil.hpp" #include "common/singletonsubclass.hpp" @@ -57,14 +58,13 @@ #include "proc/asset/track.hpp" #include -#include namespace lumiera { using std::string; - using std::tr1::shared_ptr; + using lumiera::P; @@ -148,13 +148,13 @@ namespace lumiera * @query any goals to be fulfilled by the solution. * @return false if resolution failed. In this case, solution ptr is empty. */ - virtual bool resolve (shared_ptr& solution, const Query& q) = 0; + virtual bool resolve (P& solution, const Query& q) = 0; }; // TODO: the Idea is to provide specialisations for the concrete types // we want to participate in the ConfigRules system.... // Thus we get the possibility to create a specific return type, - // e.g. return a shared_ptr but a Placement, using the appropriate factory. + // e.g. return a P but a Placement, using the appropriate factory. // Of course then the definitions need to be split up in separate headers. diff --git a/src/common/query/mockconfigrules.hpp b/src/common/query/mockconfigrules.hpp index f5bea3264..f56519ed6 100644 --- a/src/common/query/mockconfigrules.hpp +++ b/src/common/query/mockconfigrules.hpp @@ -74,7 +74,7 @@ namespace lumiera /** a traits-class to define the smart-ptr to wrap the result */ template - struct WrapReturn { typedef shared_ptr Wrapper; }; + struct WrapReturn { typedef P Wrapper; }; template<> struct WrapReturn { typedef PProcPatt Wrapper; }; diff --git a/src/common/typelistutil.hpp b/src/common/typelistutil.hpp index 4e382df3d..3fb6a531e 100644 --- a/src/common/typelistutil.hpp +++ b/src/common/typelistutil.hpp @@ -40,7 +40,10 @@ This code is heavily inspired by /** @file typelistutil.hpp ** Helpers for working with lumiera::typelist::Types (i.e. lists-of-types). - ** + ** The main purpose is to build interfaces and polymorphic implementations + ** (using virtual functions) based on templated Types or Collections of types, + ** which is not possible without Template Metaprogrmming. + ** ** @see lumiera::query::ConfigRules usage example ** @see typelist.hpp ** @@ -136,11 +139,99 @@ namespace lumiera > { public: - typedef InstantiateChained Next; + typedef InstantiateChained Next; typedef _X_ Unit; }; + + /** + * A Variation of InstantiateChained providing an incremented + * Index value template parameter. This index can e.g. be used + * to store pointers in a dispatcher table in the Base class. + * Similar to InstantiateChained, this template builds a linear + * chain of inheritance. The user-provided template, which is + * to be instantiated for all types in the Typelist, now has to + * accept an additional third parameter (uint i). + */ + template + < class TYPES // List of Types + , template class _X_ // your-template-goes-here + , class BASE = NullType // Base class at end of chain + , uint i = 0 // incremented on each instantiaton + > + class InstantiateWithIndex; + + + template< template class _X_ + , class BASE + , uint i + > + class InstantiateWithIndex + : public BASE + { + public: + typedef BASE Unit; + typedef NullType Next; + enum{ COUNT = i }; + }; + + + template + < class TY, typename TYPES + , template class _X_ + , class BASE + , uint i + > + class InstantiateWithIndex, _X_, BASE, i> + : public _X_< TY + , InstantiateWithIndex + , i + > + { + public: + typedef InstantiateWithIndex Next; + typedef _X_ Unit; + enum{ COUNT = Next::COUNT }; + }; + + + /** + * Metafunction counting the number of Types in the collection + */ + template + struct count; + template<> + struct count + { + enum{ value = 0 }; + }; + template + struct count > + { + enum{ value = 1 + count::value }; + }; + + /** + * Metafunction " max( sizeof(T) ) for T in TYPES " + */ + template + struct maxSize; + template<> + struct maxSize + { + enum{ value = 0 }; + }; + template + struct maxSize > + { + enum{ thisval = sizeof(TY) + , nextval = maxSize::value + , value = nextval > thisval? nextval:thisval + }; + }; + + } // namespace typelist } // namespace lumiera diff --git a/src/common/variant.hpp b/src/common/variant.hpp new file mode 100644 index 000000000..561b7149c --- /dev/null +++ b/src/common/variant.hpp @@ -0,0 +1,276 @@ +/* + VARIANT.hpp - simple variant wrapper (typesafe union) + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @file variant.hpp + ** This file defines a simple alternative to boost::variant. + ** It pulls in fewer headers and has a shorter code path, but also + ** doesn't deal with alignement issues and is not threadsafe. + ** + ** Values can be stored using \c operator= . In order to access the value + ** stored in lumiera::Variant, you additionally need to define a "functor" + **
  • with a typedef "Ret" for the return type
  • + **
  • providing a static Ret access(ELM&) function + ** for each of the types used in the Variant
  • + **
+ ** + ** @see wrapperptr.hpp usage example + */ + + +#ifndef LUMIERA_VARIANT_H +#define LUMIERA_VARIANT_H + + +#include "common/typelistutil.hpp" + +#include + + + +namespace lumiera { + + namespace variant { + + using lumiera::typelist::count; + using lumiera::typelist::maxSize; + using lumiera::typelist::InstantiateWithIndex; + + /** + * internal helper used to build a variant storage wrapper. + * Parametrized with a collection of types, it provides functionality + * to copy a value of one of these types into an internal buffer, while + * remembering which of these types was used to place this copy. + * The value can be later on extracted using a visitation like mechanism, + * which takes a functor class and invokes a function \c access(T&) with + * the type matching the current value in storage + */ + template + struct Holder + { + + enum { TYPECNT = count::value + , SIZE = maxSize::value + }; + + + /** Storage to hold the actual value */ + struct Buffer + { + char buffer_[SIZE]; + uint which_; + + Buffer() : which_(TYPECNT) {} + + void* + put (void) + { + deleteCurrent(); + return 0; + } + + void + deleteCurrent (); // depends on the Deleter, see below + }; + + template + struct PlacementAdapter : BASE + { + T& + put (T const& toStore) + { + BASE::deleteCurrent(); // remove old content, if any + + T& storedObj = *new(BASE::buffer_) T (toStore); + BASE::which_ = idx; // remember the actual type selected + return storedObj; + } + + using BASE::put; + }; + + typedef InstantiateWithIndex< TYPES + , PlacementAdapter + , Buffer + > + Storage; + + + + /** provide a dispatcher table based visitation mechanism */ + template + struct CaseSelect + { + typedef typename FUNCTOR::Ret Ret; + typedef Ret (*Func)(Buffer&); + + Func table_[TYPECNT]; + + CaseSelect () + { + for (uint i=0; i + static Ret + trampoline (Buffer& storage) + { + T& content = reinterpret_cast (storage.buffer_); + return FUNCTOR::access (content); + } + + Ret + invoke (Buffer& storage) + { + if (TYPECNT <= storage.which_) + return FUNCTOR::ifEmpty (); + else + return (*table_[storage.which_]) (storage); + } + }; + + + template< class T, class BASE, uint i > + struct CasePrepare + : BASE + { + CasePrepare () : BASE() + { + BASE::table_[i] = &BASE::template trampoline; + } + }; + + + template + static typename FUNCTOR::Ret + access (Buffer& buf) + { + typedef InstantiateWithIndex< TYPES + , CasePrepare + , CaseSelect + > + Accessor; + static Accessor select_case; + return select_case.invoke(buf); + } + + + struct Deleter + { + typedef void Ret; + + template + static void access (T& elem) { elem.~T(); } + + static void ifEmpty () { } + }; + }; + + + template + inline void + Holder::Buffer::deleteCurrent () + { + access(*this); // remove old content, if any + which_ = TYPECNT; // mark as empty + } + + } // namespace variant + + + + + + + + + /** + * A variant wrapper (typesafe union) capable of holding a value of any + * of a bounded collection of types. The value is stored in a local buffer + * directly within the object and may be accessed by a typesafe visitation. + * + * \par + * This utility class is similar to boost::variant and indeed was implemented + * (5/08) in an effort to replace the latter in a draft solution for the problem + * of typesafe access to the correct wrapper class from within some builder tool. + * Well -- after finisihng this "exercise" I must admit that it is not really + * much more simple than what boost::variant does internally. At least we are + * pulling in fewer headers and the actual code path is shorter compared with + * boost::variant, at the price of beeing not so generic, not caring for + * alignment issues within the buffer and being not threadsafe + * + * @param TYPES collection of possible types to be stored in this variant object + * @param Access policy how to access the stored value + */ + template< typename TYPES + , template class Access + > + class Variant + : boost::noncopyable + { + + typedef variant::Holder Holder; + typedef typename Holder::Deleter Deleter; + + + /** storage: buffer holding either and "empty" marker, + * or one of the configured pointer to wrapper types */ + typename Holder::Storage holder_; + + + public: + void reset () { holder_.deleteCurrent();} + + /** store a copy of the given argument within the + * variant holder buffer, thereby typically casting + * or converting the given source type to the best + * suited (base) type (out of the collection of possible + * types for this Variant instance) + */ + template + Variant& + operator= (SRC src) + { + if (src) holder_.put (src); // see Holder::PlacementAdaptor::put + else reset(); + return *this; + } + + /** retrieve current content of the variant, + * trying to cast or convert it to the given type. + * Actually, the function \c access(T&) on the + * Access-policy (template param) is invoked with the + * type currently stored in the holder buffer. + * May return NULL if conversion fails. + */ + template + TAR + get () + { + typedef Access Extractor; + return Holder::template access (this->holder_); + } + }; + +} // namespace lumiera +#endif diff --git a/src/common/visitor.hpp b/src/common/visitor.hpp index 837ddf713..3d22f11e6 100644 --- a/src/common/visitor.hpp +++ b/src/common/visitor.hpp @@ -105,7 +105,7 @@ namespace lumiera typedef RET ReturnType; ///< Tool function invocation return type typedef Tool ToolBase; ///< for templating the Tag and Dispatcher - virtual ~Tool () { }; ///< use RTTI for all visiting tools + virtual ~Tool () { }; ///< use RTTI for all visiting tools /** allows discovery of the concrete Tool type when dispatching a * visitor call. Can be implemented by inheriting from ToolTag */ diff --git a/src/common/visitorpolicies.hpp b/src/common/visitorpolicies.hpp index e59a2f5b2..829dd5546 100644 --- a/src/common/visitorpolicies.hpp +++ b/src/common/visitorpolicies.hpp @@ -23,7 +23,7 @@ /** @file visitorpolicies.hpp ** Policies usable for configuring the lumiera::visitor::Tool for different kinds of error handling. - ** @see buildertool.hpp for another flavor (calling and catch-all-function) + ** @see buildertool.hpp for another flavour (calling an catch-all-function there) ** */ diff --git a/src/common/wrapperptr.hpp b/src/common/wrapperptr.hpp new file mode 100644 index 000000000..e17963eff --- /dev/null +++ b/src/common/wrapperptr.hpp @@ -0,0 +1,63 @@ +/* + WRAPPERPTR.hpp - variant record able to hold a pointer to some smart-ptr/wrapper types, providing conversions + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + + +#ifndef LUMIERA_WRAPPERPTR_H +#define LUMIERA_WRAPPERPTR_H + + +#include "common/variant.hpp" +#include "common/accesscasted.hpp" + +#include "common/typelist.hpp" +#include "proc/mobject/placement.hpp" +#include "common/p.hpp" + + +namespace asset { class Asset; } +namespace mobject { class MObject; } + +namespace lumiera { + + + typedef typelist::Types < mobject::Placement* + , P* + > ::List + WrapperTypes; + + /** + * helper to treat various sorts of smart-ptrs uniformly. + * Implemented as a variant-type value object, it is preconfigured + * with the possible hierarchy-base classes used within this application. + * Thus, when passing in an arbitrary smart-ptr, the best fitting smart-ptr + * type pointing to the corresponding base class is selected for internal storage. + * Later on, stored values can be retrieved either utilitzing static or dynamic casts; + * error reporting is similar to the bahaviour of dynamic_cast: when retrieving + * a pointer, in case of mismatch NULL is returned. + */ + typedef lumiera::Variant WrapperPtr; + + + +} // namespace lumiera +#endif diff --git a/src/proc/asset/buildinstruct.hpp b/src/proc/asset/buildinstruct.hpp index 577a108c1..8b1162103 100644 --- a/src/proc/asset/buildinstruct.hpp +++ b/src/proc/asset/buildinstruct.hpp @@ -41,12 +41,13 @@ using std::string; namespace asset { + using lumiera::P; class Proc; class ProcPatt; - typedef shared_ptr PProc; - typedef shared_ptr PProcPatt; + typedef P PProc; + typedef P PProcPatt; static Symbol CURRENT = "current"; diff --git a/src/proc/asset/clip.hpp b/src/proc/asset/clip.hpp index f5e1ea629..53a74faa5 100644 --- a/src/proc/asset/clip.hpp +++ b/src/proc/asset/clip.hpp @@ -53,7 +53,7 @@ namespace asset }; - typedef shared_ptr PClipAsset; + typedef P PClipAsset; const string CLIP_SUBFOLDER = "clips"; // TODO: handling of hard-wired constants.... diff --git a/src/proc/asset/db.hpp b/src/proc/asset/db.hpp index cb32868d7..f35785e5e 100644 --- a/src/proc/asset/db.hpp +++ b/src/proc/asset/db.hpp @@ -100,7 +100,7 @@ namespace asset bool del (ID hash) { return table.erase (hash); } template - shared_ptr + P get (ID hash) const { return dynamic_pointer_cast (find (hash)); diff --git a/src/proc/asset/media.cpp b/src/proc/asset/media.cpp index a91e8284b..68fcb0b56 100644 --- a/src/proc/asset/media.cpp +++ b/src/proc/asset/media.cpp @@ -219,7 +219,7 @@ namespace asset * @throw Invalid if the given media asset is not top-level, * but rather part or a multichannel (compound) media */ - shared_ptr + P MediaFactory::operator() (asset::Media& mediaref) throw(lumiera::error::Invalid) { if (mediaref.checkCompound()) diff --git a/src/proc/asset/media.hpp b/src/proc/asset/media.hpp index 4e122cd53..b14399ce5 100644 --- a/src/proc/asset/media.hpp +++ b/src/proc/asset/media.hpp @@ -52,6 +52,7 @@ namespace asset class MediaFactory; class ProcPatt; + using lumiera::P; using lumiera::Time; @@ -74,9 +75,9 @@ namespace asset const Time len_; public: - typedef shared_ptr PMedia; - typedef shared_ptr PClip; - typedef shared_ptr PProcPatt; + typedef P PMedia; + typedef P PClip; + typedef P PProcPatt; typedef mobject::session::PClipMO PClipMO; @@ -142,7 +143,7 @@ namespace asset class MediaFactory : public lumiera::Factory { public: - typedef shared_ptr PType; + typedef P PType; PType operator() (Asset::Ident& key, const string& file=""); PType operator() (const string& file, const Category& cat); @@ -152,7 +153,7 @@ namespace asset PType operator() (const char* file, const Category& cat); PType operator() (const char* file, asset::Kind); - shared_ptr + P operator() (asset::Media& mediaref) throw(lumiera::error::Invalid); }; diff --git a/src/proc/asset/meta.hpp b/src/proc/asset/meta.hpp index 02be992db..c15f14fbf 100644 --- a/src/proc/asset/meta.hpp +++ b/src/proc/asset/meta.hpp @@ -95,7 +95,7 @@ namespace asset class MetaFactory : public lumiera::Factory { public: - typedef shared_ptr PType; + typedef P PType; PType operator() (Asset::Ident& key); ////////////TODO define actual operation diff --git a/src/proc/asset/pipe.hpp b/src/proc/asset/pipe.hpp index 110dd1975..c2a9a8ff0 100644 --- a/src/proc/asset/pipe.hpp +++ b/src/proc/asset/pipe.hpp @@ -31,9 +31,10 @@ namespace asset { + using lumiera::P; class Pipe; - typedef shared_ptr PPipe; + typedef P PPipe; template<> diff --git a/src/proc/asset/proc.hpp b/src/proc/asset/proc.hpp index 05eca4ddf..724c8a786 100644 --- a/src/proc/asset/proc.hpp +++ b/src/proc/asset/proc.hpp @@ -48,7 +48,7 @@ namespace asset class Proc; class ProcFactory; - typedef shared_ptr PProc; + typedef P PProc; @@ -97,7 +97,7 @@ namespace asset class ProcFactory : public lumiera::Factory { public: - typedef shared_ptr PType; + typedef P PType; PType operator() (Asset::Ident& key); ////////////TODO define actual operation diff --git a/src/proc/asset/procpatt.cpp b/src/proc/asset/procpatt.cpp index 1adf8736c..d5173b9ea 100644 --- a/src/proc/asset/procpatt.cpp +++ b/src/proc/asset/procpatt.cpp @@ -60,7 +60,7 @@ namespace asset * some ProcPatt as a template for creating more * spezialized patterns. */ - shared_ptr + P ProcPatt::newCopy (string newID) const { TODO ("implement the Pattern-ID within the propDescriptor!"); diff --git a/src/proc/asset/procpatt.hpp b/src/proc/asset/procpatt.hpp index 6c8cf37e0..65f832b41 100644 --- a/src/proc/asset/procpatt.hpp +++ b/src/proc/asset/procpatt.hpp @@ -35,13 +35,14 @@ using std::vector; namespace asset { + using lumiera::P; using lumiera::Symbol; class Proc; class ProcPatt; class BuildInstruct; - typedef shared_ptr PProc; - typedef shared_ptr PProcPatt; + typedef P PProc; + typedef P PProcPatt; typedef vector InstructionSequence; @@ -61,14 +62,13 @@ namespace asset friend class StructFactoryImpl; public: - shared_ptr newCopy (string newID) const; + P newCopy (string newID) const; ProcPatt& attach (Symbol where, PProc& node); ProcPatt& operator+= (PProcPatt& toReuse); }; - typedef shared_ptr PProcPatt; diff --git a/src/proc/asset/struct.cpp b/src/proc/asset/struct.cpp index 6e85c50c2..5813ce339 100644 --- a/src/proc/asset/struct.cpp +++ b/src/proc/asset/struct.cpp @@ -89,10 +89,10 @@ namespace asset * created as a side effect of calling the concrete Struct subclass ctor. */ template - shared_ptr + P StructFactory::operator() (const Query& capabilities) { - shared_ptr res; + P res; QueryHandler& typeHandler = ConfigRules::instance(); typeHandler.resolve (res, capabilities); @@ -117,7 +117,7 @@ namespace asset * @see ProcPatt * @see DefaultsManager */ - shared_ptr + P StructFactory::operator() (string pipeID, string streamID) { normalizeID (pipeID); @@ -147,9 +147,9 @@ namespace asset namespace asset { - template shared_ptr StructFactory::operator() (const Query& query); - template shared_ptr StructFactory::operator() (const Query& query); - template PProcPatt StructFactory::operator() (const Query& query); + template P StructFactory::operator() (const Query& query); + template P StructFactory::operator() (const Query& query); + template PProcPatt StructFactory::operator() (const Query& query); } // namespace asset diff --git a/src/proc/asset/struct.hpp b/src/proc/asset/struct.hpp index 7c4c4367b..5941bd13a 100644 --- a/src/proc/asset/struct.hpp +++ b/src/proc/asset/struct.hpp @@ -120,12 +120,12 @@ namespace asset public: - typedef shared_ptr PType; + typedef P PType; template - shared_ptr operator() (const Query& query); ////////////TODO actually do something sensible here + P operator() (const Query& query); ////////////TODO actually do something sensible here - shared_ptr operator() (string pipeID, string streamID); + P operator() (string pipeID, string streamID); }; diff --git a/src/proc/asset/track.hpp b/src/proc/asset/track.hpp index a36a6242c..01abe5e8e 100644 --- a/src/proc/asset/track.hpp +++ b/src/proc/asset/track.hpp @@ -48,7 +48,7 @@ namespace asset }; - typedef shared_ptr PTrack; + typedef P PTrack; diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp index fcdf45dc0..9acb29daa 100644 --- a/src/proc/assetmanager.cpp +++ b/src/proc/assetmanager.cpp @@ -130,11 +130,11 @@ namespace asset * of the stored object differs and can't be casted. */ template - shared_ptr + P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid) { - if (shared_ptr obj = registry.get (id)) + if (P obj = registry.get (id)) return obj; else if (known (id)) // provide Ident tuple of existing Asset @@ -143,14 +143,14 @@ namespace asset throw UnknownID (id); } - /** convienience shortcut for fetching the registered shared_ptr + /** convienience shortcut for fetching the registered smart-ptr * which is in charge of the given asset instance. By querying * directly asset.id (of type ID), the call to registry.get() * can bypass the dynamic cast, because the type of the asset * is explicitely given by type KIND. */ template - shared_ptr + P AssetManager::wrap (const KIND& asset) { ENSURE (instance().known(asset.id), @@ -169,7 +169,7 @@ namespace asset { return ( registry.get (ID(id)) ); } // query most general Asset ID-kind and use implicit - // conversion from shared_ptr to bool (test if empty) + // conversion from smart-ptr to bool (test if empty) /** @@ -245,18 +245,18 @@ namespace asset template ID AssetManager::reg (Asset* obj, const Asset::Ident& idi); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); + template P AssetManager::getAsset (const ID& id) throw(lumiera::error::Invalid); - template shared_ptr AssetManager::wrap (const Asset& asset); - template shared_ptr AssetManager::wrap (const Media& asset); - template shared_ptr AssetManager::wrap (const Clip& asset); - template shared_ptr AssetManager::wrap (const Track& asset); - template shared_ptr AssetManager::wrap (const Pipe& asset); - template shared_ptr AssetManager::wrap (const ProcPatt& asset); + template P AssetManager::wrap (const Asset& asset); + template P AssetManager::wrap (const Media& asset); + template P AssetManager::wrap (const Clip& asset); + template P AssetManager::wrap (const Track& asset); + template P AssetManager::wrap (const Pipe& asset); + template P AssetManager::wrap (const ProcPatt& asset); } // namespace asset diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp index 22138065d..3f62d2ecd 100644 --- a/src/proc/assetmanager.hpp +++ b/src/proc/assetmanager.hpp @@ -73,13 +73,13 @@ namespace asset /** provide the unique ID for given Asset::Ident tuple */ static ID getID (const Asset::Ident&); - /** retrieve the registerd shared_ptr for any asset */ + /** retrieve the registerd smart-ptr for any asset */ template - static shared_ptr wrap (const KIND& asset); + static P wrap (const KIND& asset); /** find and return corresponging object */ template - shared_ptr getAsset (const ID& id) throw(lumiera::error::Invalid); + P getAsset (const ID& id) throw(lumiera::error::Invalid); /** @return true if the given id is registered in the internal asset DB */ diff --git a/src/proc/lumiera.hpp b/src/proc/lumiera.hpp index b56ab69b6..c00a70254 100644 --- a/src/proc/lumiera.hpp +++ b/src/proc/lumiera.hpp @@ -30,6 +30,7 @@ /* common types frequently used... */ +#include "common/p.hpp" #include "common/util.hpp" #include "common/time.hpp" #include "common/error.hpp" ///< pulls in NoBug via nobugcfg.hpp diff --git a/src/proc/mobject/builder/applicablebuildertargettypes.hpp b/src/proc/mobject/builder/applicablebuildertargettypes.hpp new file mode 100644 index 000000000..e51fa1251 --- /dev/null +++ b/src/proc/mobject/builder/applicablebuildertargettypes.hpp @@ -0,0 +1,70 @@ +/* + ApplicableBuilderTargetTypes - definitinon header specifying all types treated by builder tools + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#ifndef MOBJECT_BUILDER_APPLICABLEBUILDERTARGETTYPES_H +#define MOBJECT_BUILDER_APPLICABLEBUILDERTARGETTYPES_H + +#include "proc/mobject/builder/buildertool.hpp" + + + +namespace mobject { + namespace session { + + class Clip; + class Effect; + class AbstractMO; + template class Auto; + // Forward declarations sufficient here... + // actual definitions necessary only in the + // implementation file (*cpp) of the builder tool. + } + + namespace builder { + + typedef Types< session::Clip, + session::Effect, + session::AbstractMO + > ::List + BuilderTargetTypes; + + + /** + * Marker used to declare some visiting Tool class to be actually a + * mobject::builder::BuilderTool and to possibly accept and treat the + * common selection of types to be handled by any such builder tool. + * The actual BuilderTool impl should inherit from this template by + * feeding back its type (CRTP), this causes a dispatcher table entry + * be generated for this concrete BuilderTool implementation. + */ + template + struct ApplicableBuilderTargetTypes + : Applicable + { }; + + + + } // namespace mobject::builder + +} // namespace mobject +#endif diff --git a/src/proc/mobject/builder/buildertool.hpp b/src/proc/mobject/builder/buildertool.hpp index 0985567d1..1801bc2ef 100644 --- a/src/proc/mobject/builder/buildertool.hpp +++ b/src/proc/mobject/builder/buildertool.hpp @@ -20,20 +20,54 @@ */ +/** @file buildertool.hpp + ** Visiting-tool mechanism configured specifically for the Builder. + ** The Builder creates the render nodes network by applying several Builder Tools + ** to the objects found in the Session, EDL and Fixture. These BuilderTool instances + ** contain the details of the builder implementation. + ** + ** As the objects to be treated are normally handled by smart-ptrs, BuilderTool provides + ** a special facility for dealing with these wrapped objects. There are some liabilities. + **
  • each concrete Buildable subtype to be treated specifically needs to + ** declare \c DEFINE_PROCESSABLE_BY(BuilderTool)
  • + **
  • at the same time, the concrete BuilderTool subclass has to declare + ** being Applicable to this concrete Buildable subtype. The recommended way + ** of ensuring this, is to add an entry to applicablebuildertargettypes.hpp + ** and then derive the concrete BuilderTool subclass from + ** ApplicableBuilderTargetTypes
  • + **
  • when accessing the wrapper from within a \c treat() function, a suitable + ** concrete wrapper type has to be specified. If the wrapper type used for + ** invoking the BuilderTool (function \c apply(BuilderTool&l, WrappedObject&) ) + ** can not be converted to this type requested from within the call, an + ** assertion failure (or segmentation fault in a release build) will result.
  • + **
+ ** + ** @see visitor.hpp + ** @see applicablebuildertargettypes.hpp + ** @see buildertooltest.hpp + ** @see nodecreatertool.hpp + */ + + #ifndef MOBJECT_BUILDER_TOOL_H #define MOBJECT_BUILDER_TOOL_H #include "common/visitor.hpp" +#include "common/wrapperptr.hpp" + +#include "common/p.hpp" +#include "proc/mobject/placement.hpp" +#include "proc/mobject/explicitplacement.hpp" +namespace mobject { -namespace mobject - { class Buildable; - namespace builder - { + namespace builder { + + using lumiera::P; /** * Policy invoking an catch-all function for processing @@ -49,19 +83,79 @@ namespace mobject virtual RET onUnknown (Buildable& target) = 0; }; - - + + /** * Base class of all BuilderTools, used according to the visitor pattern: * each Tool contains the concrete implementation for one task to be done * to the various MObject classes. The concrete builder tool implementation * should not diretcly inherit from this base interface, but rather through * an instantiation of the "Applicable" template parametrized with all - * concrete Buildable classes, for which it wants calls to be dispatched. + * concrete Buildable classes, for which it wants calls to be dispatched. + * \par + * In addition to lumiera::visitor::Tool, BuilderTool adds support for dealing + * with objects normally handled by means of smart-pointers or similar + * wrappers, most notably mobject::Placement. The visitaion is initiated + * by calling the stand-alone function \c (BuilderTool& tool, WRA& wrappedTargetObj) , + * which forwards to the visitation mechanism supported by the type contained + * in the wrapper, but stores away a pointer to the wrapped object, which can + * be retrieved in a typesafe manner from within the \c treat(ConcreteType&) + * function. + * @note retrieving the wrapper is not threadsafe and not reentrant, + * as we simply store a pointer within the BuilderTool instance. */ - typedef lumiera::visitor::Tool BuilderTool; + class BuilderTool + : public lumiera::visitor::Tool + { + lumiera::WrapperPtr currentWrapper_; + + public: + + template class WRA, class TAR> + void rememberWrapper (WRA* ptr_toWrappedTarget) + { + currentWrapper_ = ptr_toWrappedTarget; + } + + void forgetWrapper () + { + currentWrapper_.reset(); + } + + + protected: /* == interface for accessing the wrapper from within tool application == */ + + template + Placement& + getPlacement () + { + Placement* pPlacement = currentWrapper_.get*>(); + ENSURE (pPlacement, "wrong target type when invoking %s", __PRETTY_FUNCTION__); + return *pPlacement; + } + + ExplicitPlacement + getExplicitPlacement () + { + return getPlacement().resolve(); + } + + template + lumiera::P + getPtr () + { + P* pP = currentWrapper_.get*>(); + ENSURE (pP, "wrong target type when invoking %s", __PRETTY_FUNCTION__); + return *pP; + } + }; + + /** + * declare the concrete types a BuilderTool may recievee and treat. + * @note it is recommended to use ApplicableBuilderTargetTypes + */ template < class TOOLImpl, // concrete BuilderTool implementation class TYPELIST // list of all concrete Buildables to be treated @@ -71,17 +165,33 @@ namespace mobject { } ; - using lumiera::typelist::Types; // convienience for the users of "Applicable" - + using lumiera::typelist::Types; // convenience for the users of "Applicable" + } // namespace mobject::builder /** - * Marker Interface for classes Visitable by Builder tools. + * Marker Interface for classes visitable by Builder tools. */ class Buildable : public lumiera::visitor::Visitable { }; - + + + + + namespace builder { // to be found by ADL + + template + inline Buildable::ReturnType + apply (BuilderTool& tool, WRA& wrappedTargetObj) + { + tool.rememberWrapper(&wrappedTargetObj); + wrappedTargetObj->apply (tool); // dispatch to suitable treat() function + tool.forgetWrapper(); + } + + } // namespace mobject::builder + } // namespace mobject #endif diff --git a/src/proc/mobject/builder/nodecreatertool.cpp b/src/proc/mobject/builder/nodecreatertool.cpp index 89a35fa46..93362ef25 100644 --- a/src/proc/mobject/builder/nodecreatertool.cpp +++ b/src/proc/mobject/builder/nodecreatertool.cpp @@ -31,11 +31,8 @@ using mobject::session::Clip; using mobject::session::Effect; using mobject::session::Auto; -namespace mobject - { - - namespace builder - { +namespace mobject { + namespace builder { diff --git a/src/proc/mobject/builder/nodecreatertool.hpp b/src/proc/mobject/builder/nodecreatertool.hpp index 26a033d26..e37d0d14f 100644 --- a/src/proc/mobject/builder/nodecreatertool.hpp +++ b/src/proc/mobject/builder/nodecreatertool.hpp @@ -24,23 +24,15 @@ #ifndef MOBJECT_BUILDER_NODECREATERTOOL_H #define MOBJECT_BUILDER_NODECREATERTOOL_H -#include "proc/mobject/builder/buildertool.hpp" + +#include "proc/mobject/builder/applicablebuildertargettypes.hpp" + #include "proc/engine/processor.hpp" -namespace mobject - { - namespace session - { - // Forward declarations - class Effect; - class Clip; - template class Auto; - } - - namespace builder - { +namespace mobject { + namespace builder { @@ -52,11 +44,10 @@ namespace mobject * render engine under construction such as to reflect the properties * of the MObject in the actual render. */ - class NodeCreatorTool : public BuilderTool + class NodeCreatorTool + : public ApplicableBuilderTargetTypes { - //////////////////////////////////////////////TODO: switch to acyclic visitior!!!!!!!!!!!!! - public: virtual void treat (mobject::session::Clip& clip) ; virtual void treat (mobject::session::Effect& effect) ; diff --git a/src/proc/mobject/builder/segmentationtool.cpp b/src/proc/mobject/builder/segmentationtool.cpp index 6f07e7d4f..7b6c29747 100644 --- a/src/proc/mobject/builder/segmentationtool.cpp +++ b/src/proc/mobject/builder/segmentationtool.cpp @@ -31,10 +31,8 @@ using mobject::session::Clip; using mobject::session::Effect; -namespace mobject - { - namespace builder - { +namespace mobject { + namespace builder { diff --git a/src/proc/mobject/builder/segmentationtool.hpp b/src/proc/mobject/builder/segmentationtool.hpp index aa09d80d3..eaf74c1c6 100644 --- a/src/proc/mobject/builder/segmentationtool.hpp +++ b/src/proc/mobject/builder/segmentationtool.hpp @@ -24,26 +24,18 @@ #ifndef MOBJECT_BUILDER_SEGMENTATIONTOOL_H #define MOBJECT_BUILDER_SEGMENTATIONTOOL_H -#include -#include "proc/mobject/builder/buildertool.hpp" +#include "proc/mobject/builder/applicablebuildertargettypes.hpp" + #include "proc/mobject/session/segment.hpp" +#include using std::list; -namespace mobject - { - namespace session - { - // Forward declarations - class Clip; - class Effect; - } - - namespace builder - { +namespace mobject { + namespace builder { /** @@ -53,10 +45,10 @@ namespace mobject * can be represented by automation solely, without the need * to change the node connections. */ - class SegmentationTool : public BuilderTool + class SegmentationTool + : public ApplicableBuilderTargetTypes { - //////////////////////////////////////////////TODO: switch to acyclic visitior!!!!!!!!!!!!! public: void treat (mobject::session::Clip& clip) ; diff --git a/src/proc/mobject/explicitplacement.hpp b/src/proc/mobject/explicitplacement.hpp index 388a0ac82..0e5b20bfd 100644 --- a/src/proc/mobject/explicitplacement.hpp +++ b/src/proc/mobject/explicitplacement.hpp @@ -30,9 +30,9 @@ namespace mobject { - - - + + + /** * Special kind of Placement, where the location of the * MObject has been nailed down to a fixed position. @@ -51,7 +51,7 @@ namespace mobject const Pipe pipe; typedef std::pair SolutionData; //TODO (ichthyo consideres better passing of solution by subclass) - + /** no need to resolve any further, as this ExplicitPlacement * already \e is the result of a resolve()-call. */ @@ -60,7 +60,8 @@ namespace mobject { return *this; } - + + protected: /* @todo ichthyo considers a much more elegant implementation utilizing a subclass * of FixedLocation, which would serve as Placement::LocatingSolution, and @@ -79,8 +80,8 @@ namespace mobject /** copying prohibited, ExplicitPlacement is effectively const! */ ExplicitPlacement& operator= (const ExplicitPlacement&); }; - - - + + + } // namespace mobject #endif diff --git a/src/proc/mobject/mobject.hpp b/src/proc/mobject/mobject.hpp index a8c02c761..eb481489f 100644 --- a/src/proc/mobject/mobject.hpp +++ b/src/proc/mobject/mobject.hpp @@ -26,17 +26,18 @@ #include "pre.hpp" -#include -#include #include "proc/lumiera.hpp" #include "proc/mobject/builder/buildertool.hpp" #include "proc/mobject/placement.hpp" #include "proc/asset.hpp" // TODO finally not needed? +#include +#include +#include + using std::list; -using std::tr1::shared_ptr; #include "proc/assetmanager.hpp" using proc_interface::IDA; // TODO finally not needed? @@ -45,6 +46,7 @@ using proc_interface::AssetManager; namespace mobject { + using lumiera::P; namespace session { @@ -58,7 +60,10 @@ namespace mobject * manipulated and finally rendered within Lumiera's EDL * are MObjects. */ - class MObject : public Buildable + class MObject + : public Buildable, + boost::noncopyable, + boost::equality_comparable< MObject > { protected: typedef lumiera::Time Time; @@ -79,11 +84,14 @@ namespace mobject virtual bool isValid() const =0; virtual Time& getLength() =0; ///< @todo how to deal with the time/length field?? + + virtual bool operator== (const MObject& oo) const =0; }; + - - + + typedef Placement PMO; diff --git a/src/proc/mobject/placement.cpp b/src/proc/mobject/placement.cpp index 452528627..58e145e72 100644 --- a/src/proc/mobject/placement.cpp +++ b/src/proc/mobject/placement.cpp @@ -23,25 +23,39 @@ #include "proc/mobject/placement.hpp" #include "proc/mobject/explicitplacement.hpp" +#include "proc/mobject/mobject.hpp" + +#include +using boost::str; namespace mobject { - /** @note we know we need only this single - * specialisation, because we define - * the Placements of more specific - * MObject kinds to be subclasses - * of Placement, so they - * will inherit this function. - */ - template<> + template ExplicitPlacement - Placement::resolve () const + Placement::resolve () const { return ExplicitPlacement (*this, chain.resolve()); } + + /** @note we know we need only this single specialisation, + * because we define the Placements of more specific + * MObject kinds to be subclasses of Placement, + * so they will inherit this function. + */ + template ExplicitPlacement Placement::resolve() const; + + template<> + Placement::operator string () const + { + static boost::format fmt("Placement<%s> %|50T.| use-cnt=%x adr=%x pointee=%x"); + return str(fmt % typeid(*get()).name() % use_count() % this % get() ); + } + + + } // namespace mobject diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index c5d56169d..df71f0d75 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -58,12 +58,10 @@ #define MOBJECT_PLACEMENT_H #include "pre.hpp" -#include "proc/mobject/mobject.hpp" #include "proc/mobject/session/locatingpin.hpp" #include "proc/asset/pipe.hpp" #include -using std::tr1::shared_ptr; namespace mobject @@ -72,6 +70,7 @@ namespace mobject class ExplicitPlacement; + using std::tr1::shared_ptr; @@ -85,6 +84,7 @@ namespace mobject class Placement : protected shared_ptr { protected: + typedef shared_ptr Base; typedef lumiera::Time Time; typedef asset::shared_ptr Pipe; @@ -99,13 +99,14 @@ namespace mobject operator-> () const { ENSURE (*this); - return shared_ptr::operator-> (); + return Base::operator-> (); } + operator string() const ; + size_t use_count() const { return Base::use_count(); } + virtual ~Placement() {}; - /** */ /////////////////////////////////////////////////////////////TODO: totmachen? - // DEFINE_PROCESSABLE_BY (builder::BuilderTool); /** interface for defining the kind of placement @@ -128,20 +129,19 @@ namespace mobject friend class session::MObjectFactory; }; - typedef Placement PMO; /* === defining specialisations to be subclasses === */ -#define DEFINE_SPECIALIZED_PLACEMENT(SUBCLASS) \ +#define DEFINE_SPECIALIZED_PLACEMENT(SUBCLASS, BASE) \ template<> \ - class Placement : public Placement \ + class Placement : public Placement \ { \ protected: \ Placement (SUBCLASS & m, void (*moKiller)(MObject*)) \ - : Placement::Placement (m, moKiller) \ + : Placement::Placement (m, moKiller) \ { }; \ friend class session::MObjectFactory; \ \ @@ -154,7 +154,6 @@ namespace mobject (shared_ptr::operator-> ()); \ } \ }; - // DEFINE_PROCESSABLE_BY (builder::BuilderTool); /* a note to the maintainer: please don't add any fields or methods to * these subclasses which aren't also present in Placement! diff --git a/src/proc/mobject/session/abstractmo.cpp b/src/proc/mobject/session/abstractmo.cpp index e484eee6e..e3ebffd4f 100644 --- a/src/proc/mobject/session/abstractmo.cpp +++ b/src/proc/mobject/session/abstractmo.cpp @@ -28,8 +28,14 @@ namespace mobject namespace session { - /** */ - + /** default/fallback implementation of equality + * using literal object identity (same address) + */ + bool + AbstractMO::operator== (const MObject& oo) const + { + return (this == &oo); + } } // namespace mobject::session diff --git a/src/proc/mobject/session/abstractmo.hpp b/src/proc/mobject/session/abstractmo.hpp index 45942986d..5de61737f 100644 --- a/src/proc/mobject/session/abstractmo.hpp +++ b/src/proc/mobject/session/abstractmo.hpp @@ -49,6 +49,8 @@ namespace mobject DEFINE_PROCESSABLE_BY (builder::BuilderTool); + virtual bool operator== (const MObject& oo) const; + }; diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp index 75cac3ef7..174a86cbf 100644 --- a/src/proc/mobject/session/clip.hpp +++ b/src/proc/mobject/session/clip.hpp @@ -38,8 +38,8 @@ namespace mobject namespace session { using asset::Media; - typedef shared_ptr PMedia; - typedef shared_ptr PClipAsset; + typedef P PMedia; + typedef P PClipAsset; /** @@ -66,6 +66,7 @@ namespace mobject and the unlink() function of the asset should take it into account when breaking circular references. */ + const Media & mediaDef_; const asset::Clip & clipDef_; @@ -98,7 +99,7 @@ namespace mobject } // namespace mobject::session /** Placement defined to be subclass of Placement */ - DEFINE_SPECIALIZED_PLACEMENT (session::Clip); + DEFINE_SPECIALIZED_PLACEMENT (session::Clip, MObject); } // namespace mobject diff --git a/src/proc/mobject/session/defsmanager.cpp b/src/proc/mobject/session/defsmanager.cpp index c84e5116d..b60e38064 100644 --- a/src/proc/mobject/session/defsmanager.cpp +++ b/src/proc/mobject/session/defsmanager.cpp @@ -39,7 +39,7 @@ namespace mobject { namespace session { - using std::tr1::shared_ptr; + using lumiera::P; @@ -52,10 +52,10 @@ namespace mobject template - shared_ptr + P DefsManager::search (const Query& capabilities) { - shared_ptr res; + P res; QueryHandler& typeHandler = ConfigRules::instance(); for (DefsRegistry::Iter i = defsRegistry->candidates(capabilities); res = *i ; ++i ) @@ -69,10 +69,10 @@ namespace mobject template - shared_ptr + P DefsManager::create (const Query& capabilities) { - shared_ptr res; + P res; QueryHandler& typeHandler = ConfigRules::instance(); typeHandler.resolve (res, capabilities); if (res) @@ -83,9 +83,9 @@ namespace mobject template bool - DefsManager::define (const shared_ptr& defaultObj, const Query& capabilities) + DefsManager::define (const P& defaultObj, const Query& capabilities) { - shared_ptr candidate (defaultObj); + P candidate (defaultObj); QueryHandler& typeHandler = ConfigRules::instance(); typeHandler.resolve (candidate, capabilities); if (!candidate) @@ -97,17 +97,17 @@ namespace mobject template bool - DefsManager::forget (const shared_ptr& defaultObj) + DefsManager::forget (const P& defaultObj) { return defsRegistry->forget (defaultObj); } template - shared_ptr + P DefsManager::operator() (const Query& capabilities) { - shared_ptr res (search (capabilities)); + P res (search (capabilities)); if (res) return res; else diff --git a/src/proc/mobject/session/defsmanager.hpp b/src/proc/mobject/session/defsmanager.hpp index 753b452d2..eb2ca1502 100644 --- a/src/proc/mobject/session/defsmanager.hpp +++ b/src/proc/mobject/session/defsmanager.hpp @@ -25,11 +25,11 @@ #define MOBJECT_SESSION_DEFSMANAGER_H +#include "common/p.hpp" #include "common/query.hpp" #include #include -#include @@ -37,7 +37,7 @@ namespace mobject { namespace session { - using std::tr1::shared_ptr; + using lumiera::P; using boost::scoped_ptr; class DefsRegistry; @@ -69,14 +69,14 @@ namespace mobject * is considered \e misconfiguration. */ template - shared_ptr operator() (const lumiera::Query&); + P operator() (const lumiera::Query&); /** search through the registered defaults, never create anything. * @return object fulfilling the query, \c empty ptr if not found. */ template - shared_ptr search (const lumiera::Query&); + P search (const lumiera::Query&); /** retrieve an object fulfilling the query and register it as default. * The resolution is delegated to the ConfigQuery system (which may cause @@ -84,7 +84,7 @@ namespace mobject * @return object fulfilling the query, \c empty ptr if no solution. */ template - shared_ptr create (const lumiera::Query&); + P create (const lumiera::Query&); /** register the given object as default, after ensuring it fulfills the * query. The latter may cause some properties of the object to be set, @@ -93,13 +93,13 @@ namespace mobject * @note only a weak ref to the object is stored */ template - bool define (const shared_ptr&, const lumiera::Query&); + bool define (const P&, const lumiera::Query&); /** remove the defaults registration of the given object, if there was such * @return false if nothing has been changed because the object wasn't registered */ template - bool forget (const shared_ptr&); + bool forget (const P&); // Q: can we have something along the line of...? diff --git a/src/proc/mobject/session/defsregistry.hpp b/src/proc/mobject/session/defsregistry.hpp index 4aca10868..7d7589110 100644 --- a/src/proc/mobject/session/defsregistry.hpp +++ b/src/proc/mobject/session/defsregistry.hpp @@ -28,6 +28,7 @@ #include "common/multithread.hpp" #include "common/query.hpp" #include "common/util.hpp" +#include "common/p.hpp" #include #include @@ -41,10 +42,10 @@ namespace mobject { namespace session { - using std::tr1::shared_ptr; - using std::tr1::weak_ptr; - using lumiera::Thread; + using lumiera::P; using lumiera::Query; + using lumiera::Thread; + using std::tr1::weak_ptr; using std::string; using boost::format; @@ -60,7 +61,7 @@ namespace mobject /** we maintain an independent defaults registry * for every participating kind of objects */ - typedef std::vector > Table; + typedef std::vector< P > Table; uint maxSlots (0); ///< number of different registered Types @@ -76,7 +77,7 @@ namespace mobject Query query; weak_ptr objRef; - Record (const Query& q, const shared_ptr& obj) + Record (const Query& q, const P& obj) : degree (lumiera::query::countPraed (q)), query (q), objRef (obj) @@ -85,15 +86,15 @@ namespace mobject struct Search ///< Functor searching for a specific object { - Search (const shared_ptr& obj) + Search (const P& obj) : obj_(obj) { } - const shared_ptr& obj_; + const P& obj_; bool operator() (const Record& rec) { - shared_ptr storedObj (rec.objRef.lock()); + P storedObj (rec.objRef.lock()); return storedObj && (storedObj == obj_); } }; @@ -110,7 +111,7 @@ namespace mobject }; operator string () const { return str (dumpRecord % degree % query % dumpObj()); } - string dumpObj () const { shared_ptr o (objRef.lock()); return o? string(*o):"dead"; } + string dumpObj () const { P o (objRef.lock()); return o? string(*o):"dead"; } }; /** every new kind of object (Type) creates a new @@ -186,7 +187,7 @@ namespace mobject typedef typename Slot::Registry::iterator II; II p,i,e; - shared_ptr next, ptr; + P next, ptr; Iter (II from, II to) ///< just ennumerates the given range : p(from), i(from), e(to) @@ -201,7 +202,7 @@ namespace mobject operator++ (); // init to first element (or to null if emty) } - shared_ptr findNext () throw() + P findNext () throw() { while (!next) { @@ -214,9 +215,9 @@ namespace mobject public: - shared_ptr operator* () { return ptr; } - bool hasNext () { return next || findNext(); } - Iter operator++ (int) { Iter tmp=*this; operator++(); return tmp; } + P operator* () { return ptr; } + bool hasNext () { return next || findNext(); } + Iter operator++ (int) { Iter tmp=*this; operator++(); return tmp; } Iter& operator++ () { ptr=findNext(); @@ -237,7 +238,7 @@ namespace mobject template Iter candidates (const Query& query) { - shared_ptr dummy; + P dummy; Record entry (query, dummy); typedef typename Slot::Registry Registry; Registry& registry = Slot::access(table_); @@ -261,7 +262,7 @@ namespace mobject * case, also the param obj shared-ptr is rebound! */ template - bool put (shared_ptr& obj, const Query& query) + bool put (P& obj, const Query& query) { Record entry (query, obj); typedef typename Slot::Registry Registry; @@ -272,7 +273,7 @@ namespace mobject if ( pos!=registry.end() && pos->query == query) { - shared_ptr storedObj (pos->objRef.lock()); + P storedObj (pos->objRef.lock()); if (storedObj) return (storedObj == obj); else @@ -290,7 +291,7 @@ namespace mobject * @return false if the object wasn't registered at all. */ template - bool forget (const shared_ptr& obj) + bool forget (const P& obj) { typedef typename Slot::Registry Registry; typedef typename Record::Search SearchFunc; diff --git a/src/proc/mobject/session/effect.hpp b/src/proc/mobject/session/effect.hpp index 5831098d4..e4cdbee16 100644 --- a/src/proc/mobject/session/effect.hpp +++ b/src/proc/mobject/session/effect.hpp @@ -51,7 +51,7 @@ namespace mobject } // namespace mobject::session /** Placement defined to be subclass of Placement */ - DEFINE_SPECIALIZED_PLACEMENT (session::Effect); + DEFINE_SPECIALIZED_PLACEMENT (session::Effect, MObject); } // namespace mobject #endif diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp index f978d4f4e..ecd82ab30 100644 --- a/src/proc/mobject/session/locatingpin.hpp +++ b/src/proc/mobject/session/locatingpin.hpp @@ -111,9 +111,12 @@ namespace mobject virtual LocatingPin* clone () const; virtual ~LocatingPin() {}; - protected: +// protected: LocatingPin () {}; +//TODO (for working out the buildable interface; ctor should be protected) +protected: + friend class Placement; /** diff --git a/src/proc/mobject/session/meta.hpp b/src/proc/mobject/session/meta.hpp index b45d30eb5..db679a904 100644 --- a/src/proc/mobject/session/meta.hpp +++ b/src/proc/mobject/session/meta.hpp @@ -50,7 +50,7 @@ namespace mobject } // namespace mobject::session /** Placement defined to be subclass of Placement */ - DEFINE_SPECIALIZED_PLACEMENT (session::Meta); + DEFINE_SPECIALIZED_PLACEMENT (session::Meta, MObject); } // namespace mobject #endif diff --git a/src/proc/mobject/session/mobjectfactory.hpp b/src/proc/mobject/session/mobjectfactory.hpp index cff884ca7..427385194 100644 --- a/src/proc/mobject/session/mobjectfactory.hpp +++ b/src/proc/mobject/session/mobjectfactory.hpp @@ -45,7 +45,7 @@ namespace mobject class Track; class Effect; - typedef shared_ptr PTrackAsset; + typedef P PTrackAsset; class MObjectFactory diff --git a/src/proc/mobject/session/track.hpp b/src/proc/mobject/session/track.hpp index 2b8f090b9..f8b2c0017 100644 --- a/src/proc/mobject/session/track.hpp +++ b/src/proc/mobject/session/track.hpp @@ -34,11 +34,13 @@ namespace mobject { namespace session { + using lumiera::P; + class Track; typedef asset::Track TrackAsset; - typedef shared_ptr PTrack; - typedef shared_ptr PTrackAsset; + typedef P PTrack; + typedef P PTrackAsset; /** @@ -81,7 +83,7 @@ namespace mobject } // namespace mobject::session /** Placement defined to be subclass of Placement */ - DEFINE_SPECIALIZED_PLACEMENT (session::Track); + DEFINE_SPECIALIZED_PLACEMENT (session::Track, session::Meta); } // namespace mobject #endif diff --git a/src/tool/try.cpp b/src/tool/try.cpp index 90bdfadf8..85a3286a0 100644 --- a/src/tool/try.cpp +++ b/src/tool/try.cpp @@ -8,25 +8,236 @@ // 1/08 - working out a static initialisation problem for Visitor (Tag creation) // 1/08 - check 64bit longs // 4/08 - comparison operators on shared_ptr +// 4/08 - conversions on the value_type used for boost::any +// 5/08 - how to guard a downcasting access, so it is compiled in only if the involved types are convertible #include #include #include +#include +#include +#include +#include +#include +#include using std::string; using std::cout; +using std::ostream; + + + using boost::remove_pointer; + using boost::remove_reference; + using boost::is_convertible; + using boost::is_polymorphic; + using boost::is_base_of; + using boost::enable_if; + + template + struct can_cast : boost::false_type {}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + template + struct can_cast { enum { value = is_base_of::value };}; + + + template + struct has_RTTI + { + typedef typename remove_pointer< + typename remove_reference::type>::type TPlain; + + enum { value = is_polymorphic::value }; + }; + + template + struct use_dynamic_downcast + { + enum { value = can_cast::value + && has_RTTI::value + && has_RTTI::value + }; + }; + + template + struct use_static_downcast + { + enum { value = can_cast::value + && ( !has_RTTI::value + || !has_RTTI::value + ) + }; + }; + + template + struct use_conversion + { + enum { value = is_convertible::value + && !( use_static_downcast::value + ||use_dynamic_downcast::value + ) + }; + }; + + + template + struct EmptyVal + { + static X create() + { + cout << " NULL() " << __PRETTY_FUNCTION__ <<"\n"; + return X(); + } + }; + template + struct EmptyVal + { + static X*& create() + { + cout << " NULL & " << __PRETTY_FUNCTION__ <<"\n"; + static X* null(0); + return null; + } + }; + + + template + struct NullAccessor + { + typedef RET Ret; + + static RET access (...) { return ifEmpty(); } + static RET ifEmpty () { return EmptyVal::create(); } + }; + + template + struct AccessCasted : NullAccessor + { + using NullAccessor::access; + + template + static typename enable_if< use_dynamic_downcast, TAR>::type + access (ELM& elem) + { + cout << " dynamic " << __PRETTY_FUNCTION__ <<"\n"; + return dynamic_cast (elem); + } + + template + static typename enable_if< use_static_downcast, TAR>::type + access (ELM& elem) + { + cout << " static " << __PRETTY_FUNCTION__ <<"\n"; + return static_cast (elem); + } + + template + static typename enable_if< use_conversion, TAR>::type + access (ELM& elem) + { + cout << " convert " << __PRETTY_FUNCTION__ <<"\n"; + return elem; + } + + }; -int main (int argc, char* argv[]) +struct B {}; +struct D : B {}; + +struct E : D + { + virtual ~E() {}; + }; +struct F : E {}; + + +ostream& operator<< (ostream& s, const B& b) { return s << "B{} adr="<<&b; } +ostream& operator<< (ostream& s, const D& d) { return s << "D{} adr="<<&d; } +ostream& operator<< (ostream& s, const E& e) { return s << "E{} adr="<<&e; } +ostream& operator<< (ostream& s, const F& f) { return s << "F{} adr="<<&f; } + +int +main (int argc, char* argv[]) { NOBUG_INIT; + D d; + D* pD =&d; + B* pB =pD; + D& rD = *pD; + B& rB = *pB; + + D*& rpD = pD; + B*& rpB = pB; + + F f; + E& rE = f; + E* pE = &f; + D* pDE = pE; + + cout << "is_base_of = " << is_base_of::value << "\n"; + cout << "is_base_of = " << is_base_of::value << "\n"; + cout << "is_base_of = " << is_base_of::value << "\n"; + + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + + cout << "can_cast = " << can_cast::value << "\n"; + cout << "can_cast = " << can_cast::value << "\n"; + + cout << "has_RTTI = " << has_RTTI::value << "\n"; + cout << "has_RTTI = " << has_RTTI::value << "\n"; + cout << "has_RTTI = " << has_RTTI::value << "\n"; + + + cout << "use_dynamic_downcast = " << use_dynamic_downcast::value << "\n"; + cout << "use_static_downcast = " << use_static_downcast::value << "\n"; + cout << "use_conversion = " << use_conversion::value << "\n"; + + cout << "use_static_downcast = " << use_static_downcast::value << "\n"; + cout << "use_static_downcast = " << use_static_downcast::value << "\n"; + cout << "use_dynamic_downcast = " << use_dynamic_downcast::value << "\n"; + + + cout << "Access(D as D&) --->" << AccessCasted::access(d) << "\n"; + cout << "Access(D& as D&) --->" << AccessCasted::access(rD) << "\n"; + cout << "Access(B& as D&) --->" << AccessCasted::access(rB) << "\n"; + cout << "Access(D* as D*) --->" << AccessCasted::access(pD) << "\n"; + cout << "Access(B* as D*) --->" << AccessCasted::access(pB) << "\n"; + cout << "Access(D*& as D*&) --->" << AccessCasted::access(rpD) << "\n"; + cout << "Access(B*& as D*&) --->" << AccessCasted::access(rpB) << "\n"; + + cout << "Access(D as B&) --->" << AccessCasted::access(d) << "\n"; + cout << "Access(D& as B&) --->" << AccessCasted::access(rD) << "\n"; + cout << "Access(B& as B&) --->" << AccessCasted::access(rB) << "\n"; + cout << "Access(D* as B*) --->" << AccessCasted::access(pD) << "\n"; + cout << "Access(B* as B*) --->" << AccessCasted::access(pB) << "\n"; + cout << "Access(D*& as B*&) --->" << AccessCasted::access(rpD) << "\n"; + cout << "Access(B*& as B*&) --->" << AccessCasted::access(rpB) << "\n"; + + cout << "Access(D as E&) --->" << AccessCasted::access(d) << "\n"; + cout << "Access(E& as F&) --->" << AccessCasted::access(rE) << "\n"; + cout << "Access(D(E)* as E*) --->" << AccessCasted::access(pDE) << "\n"; + cout << "Access(D(E)* as F*) --->" << AccessCasted::access(pDE) << "\n"; + cout << "Access(E* as F*) --->" << AccessCasted::access(pE) << "\n"; + cout << "\ngulp\n"; diff --git a/tests/54builder.tests b/tests/54builder.tests index 3b6825651..3ec3bd325 100644 --- a/tests/54builder.tests +++ b/tests/54builder.tests @@ -4,8 +4,12 @@ TESTING "Component Test Suite: Builder" ./test-components --group=builder TEST "BuilderTool_test" BuilderTool_test < @@ -22,63 +22,127 @@ #include "common/test/run.hpp" + #include "proc/mobject/builder/buildertool.hpp" +#include "proc/mobject/placement.hpp" #include "proc/asset/category.hpp" #include "proc/asset/media.hpp" #include "proc/mobject/session/clip.hpp" +#include "common/util.hpp" #include + +using util::cStr; using std::string; using std::cout; -namespace mobject - { - namespace builder - { - namespace test - { + +namespace mobject { + namespace builder { + namespace test { using session::Clip; using session::AbstractMO; - - class DummyMO : public AbstractMO + + + /** + * Test MObject subclass, which, contrary to any real MObject, + * can be created directly without involving MObjectFactory. + */ + class TestMO : public AbstractMO { public: - DummyMO() { }; - virtual bool isValid() const { return true;} + TestMO() { }; + + DEFINE_PROCESSABLE_BY (BuilderTool); + + virtual bool isValid() const { return true;} + static void killDummy (MObject* dum) { delete (TestMO*)dum; } + }; + + /** + * Subclass-1 is \em not defined "processable", + * thus will always be handled as TestMO... + */ + class TestSubMO1 : public TestMO + { }; + + /** + * Subclass-2 \em is defined "processable", + * but we omit the necessary "applicable" definition in TestTool, + * resulting in an invocation of the error (catch-all) function... + */ + class TestSubMO2 : public TestMO + { DEFINE_PROCESSABLE_BY (BuilderTool); }; - - class TestTool - : public Applicable::List> + + + template + class TestPlacement : public Placement { public: - void treat (Clip& c) { cout << "media is: "<< str(c.getMedia()) <<"\n"; } - void treat (AbstractMO&){ cout << "unspecific MO.\n"; } - void onUnknown (Buildable&){ cout << "catch-all-function called.\n"; } + TestPlacement(TestMO& testObject) + : Placement::Placement(testObject, &TestMO::killDummy) + { } }; - - - /******************************************************************* - * @test the generic visitor pattern specialized for treating - * MObjects in the builder. Because the generic visitor - * implementation is already covered by - * \link VisitingTool_test, it is sufficient to test - * the specialisation to the builder. - * \par + /** + * BuilderTool implementation for checking the invokation of the correct + * \c treat() function and for accessing the original Placement from + * within this invocation. It is declared to be applicable to Clip + * and TestMO objects (wrapped into any acceptable shared-ptr). + * Intentionally, we omit to declare it applicable to TestSubMO2 instances. + * In reality this would be a case of misconfiguration, because TestSubMO2 + * is defined to be processable and consequently has an \apply() function, + * which, due to this ommission can't find a dispatcher entry when invoked, + * so it will call the \c onUnknown(Buildable&) instead + */ + class TestTool + : public Applicable::List> + { + public: + string log_; + + void treat (Clip& c) + { + Placement& pC = getPlacement(); + cout << "Clip on media : "<< str(pC->getMedia()) <<"\n"; + log_ = string (pC); + } + void treat (AbstractMO&) + { + cout << "treat (AbstractMO&);\n"; + log_ = string (getPlacement()); + } + void onUnknown (Buildable& bxx) + { + cout << "catch-all-function called...\n"; + log_ = string (getPlacement()); + } + }; + + + + + + + /************************************************************************************* + * @test the generic visitor pattern specialized for treating MObjects in the builder. * Besides using existing MObject types (at the moment session::Clip), - * we create inline a yet-unknown new MObject subclass. When passing - * such to any BuilderTool subclass, the compiler enforces the definition - * of a catch-all function, which is called, when there is no other - * applicable \c treat(MO&) function. Note further, whithin the specific - * treat-functions we get direct references, whithout interfering with - * Placements and memory management. (Is this a good idea? it allows - * client code to bypass the Placement (Handle). At least, I think - * it is not really a problem...) + * we create a yet-unknown new MObject subclass. When passing such to any + * BuilderTool subclass, the compiler enforces the definition of a catch-all + * function, which is called, when there is no other applicable \c treat(MO&) + * function. Note further, whithin the specific treat-functions we get direct + * references, whithout interfering with Placements and memory management. + * But from within the \c treat() function, we may access the wrapper object + * (i.e. shared_ptr, or lumiera::P or Placement) used when invoking the + * BuilderTool by using the protected interface on BuilderTool. + * + * @see VisitingTool_test for checking general visitor functionality */ class BuilderTool_test : public Test { @@ -86,13 +150,27 @@ namespace mobject { TestTool t1; - BuilderTool& tool (t1); + BuilderTool& tool = t1; - DummyMO dumm; - PMO clip = asset::Media::create("test-1", asset::VIDEO)->createClip(); + Placement clip = asset::Media::create("test-1", asset::VIDEO)->createClip(); + TestPlacement test1(*new TestSubMO1); + TestPlacement test2(*new TestSubMO2); + - clip->apply (tool); - dumm.apply (tool); + cout << "apply (tool, clip);\n"; + apply (tool, clip); + INFO (test, "got Wrapper = %s", t1.log_.c_str()); + ASSERT (t1.log_ == string(clip)); + + cout << "apply (tool, test1);\n"; + apply (tool, test1); + INFO (test, "got Wrapper = %s", t1.log_.c_str()); + ASSERT (t1.log_ == string(test1)); + + cout << "apply (tool, test2);\n"; + apply (tool, test2); + INFO (test, "got Wrapper = %s", t1.log_.c_str()); + ASSERT (t1.log_ == string(test2)); } }; @@ -105,5 +183,5 @@ namespace mobject } // namespace test } // namespace builder - + } // namespace mobject diff --git a/tests/components/proc/mobject/session/defsregistryimpltest.cpp b/tests/components/proc/mobject/session/defsregistryimpltest.cpp index 0aae90b3a..e605880a1 100644 --- a/tests/components/proc/mobject/session/defsregistryimpltest.cpp +++ b/tests/components/proc/mobject/session/defsregistryimpltest.cpp @@ -27,6 +27,7 @@ #include "proc/mobject/session/defsregistry.hpp" #include "common/factory.hpp" #include "common/query.hpp" +#include "common/p.hpp" #include "../common/query/querydiagnostics.hpp" @@ -35,11 +36,11 @@ #include #include +using lumiera::P; using lumiera::Query; using lumiera::query::test::garbage_query; using util::isnil; -using std::tr1::shared_ptr; using boost::scoped_ptr; using boost::format; using std::string; @@ -75,7 +76,9 @@ namespace mobject { static string name; string instanceID; - operator string () const { return instanceID; } + operator string () const { return instanceID; } + bool operator== (const Dummy& odu) const { return this == &odu; } + Dummy () : instanceID (newID (name)) {} }; @@ -99,8 +102,8 @@ namespace mobject { scoped_ptr reg_; - typedef shared_ptr > O; - typedef shared_ptr > P; + typedef P > O; + typedef P > P; typedef Query > Q13; typedef Query > Q23; From e1b8849d0c23896d5bd18fceeb1fda1c0057e643 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 19 May 2008 13:30:20 +0200 Subject: [PATCH 085/245] build 'common' tests --- Makefile.am | 1 + tests/common/Makefile.am | 61 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 tests/common/Makefile.am diff --git a/Makefile.am b/Makefile.am index 79d054de2..e6f29bf97 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,6 +42,7 @@ include $(top_srcdir)/src/backend/Makefile.am #include $(top_srcdir)/src... # tests +include $(top_srcdir)/tests/common/Makefile.am include $(top_srcdir)/tests/components/Makefile.am include $(top_srcdir)/tests/Makefile.am include $(top_srcdir)/tests/plugin/Makefile.am diff --git a/tests/common/Makefile.am b/tests/common/Makefile.am new file mode 100644 index 000000000..cc027e477 --- /dev/null +++ b/tests/common/Makefile.am @@ -0,0 +1,61 @@ +# Copyright (C) Lumiera.org +# 2008, Christian Thaeter +# Hermann Vosseler +# +# This program 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 2 of the +# License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +testcommon_srcdir = $(top_srcdir)/tests/common + +check_PROGRAMS += test-common +test_common_CPPFLAGS = $(AM_CPPFLAGS) -Wall -I$(top_srcdir)/src -I$(testcommon_srcdir) +test_common_LDADD = \ + liblumiproc.a \ + liblumiprocengine.a \ + liblumiprocmobjectbuilder.a \ + liblumiprocmobjectsession.a \ + liblumiprocasset.a \ + liblumiprocmobject.a \ + liblumiprocmobjectcontroller.a \ + liblumi.a \ + liblumicommon.a \ + liblumibackend.a \ + -lnobugmt -lpthread -ldl -lboost_program_options-mt -lboost_regex-mt + +test_common_SOURCES = \ + $(testcommon_srcdir)/appconfigtest.cpp \ + $(testcommon_srcdir)/customsharedptrtest.cpp \ + $(testcommon_srcdir)/exceptionerrortest.cpp \ + $(testcommon_srcdir)/factoryspecialtest.cpp \ + $(testcommon_srcdir)/factorytest.cpp \ + $(testcommon_srcdir)/helloworldtest.cpp \ + $(testcommon_srcdir)/lifecycletest.cpp \ + $(testcommon_srcdir)/mainsuite.cpp \ + $(testcommon_srcdir)/query/queryutilstest.cpp \ + $(testcommon_srcdir)/removefromsettest.cpp \ + $(testcommon_srcdir)/sanitizedidentifiertest.cpp \ + $(testcommon_srcdir)/singletonsubclasstest.cpp \ + $(testcommon_srcdir)/singletontest.cpp \ + $(testcommon_srcdir)/singletontestmocktest.cpp \ + $(testcommon_srcdir)/test/cmdlinewrappertest.cpp \ + $(testcommon_srcdir)/test/testoptiontest.cpp \ + $(testcommon_srcdir)/typelisttest.cpp \ + $(testcommon_srcdir)/typelistutiltest.cpp \ + $(testcommon_srcdir)/visitingtoolconcept.cpp \ + $(testcommon_srcdir)/visitingtoolextendedtest.cpp \ + $(testcommon_srcdir)/visitingtooltest.cpp + +noinst_HEADERS += \ + $(testcommon_srcdir)/query/querydiagnostics.hpp \ + $(testcommon_srcdir)/testtargetobj.hpp From bc436d1d6a0cf75c66050f317020b366dba69b44 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 19 May 2008 13:30:55 +0200 Subject: [PATCH 086/245] fix typo in component test --- tests/50components.tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/50components.tests b/tests/50components.tests index 2bac409cb..18f04ee4b 100644 --- a/tests/50components.tests +++ b/tests/50components.tests @@ -62,7 +62,7 @@ out: caught error::Logic: LUMIERA_ERROR_FATAL:floundered (test-2). out: caught error::Invalid: LUMIERA_ERROR_INVALID:invalid input or parameters (test-3). out: caught lumiera::Error: LUMIERA_ERROR_EXTERNAL:failure in external service (test-4). out: caught std::runtime_error: test-5 -out: caught std::exception: St9exception +out: caught std::exception: std::exception out: intermediate handler caught: LUMIERA_ERROR_EXTERNAL:failure in external service (test-7).....will rethrow as error::State out: caught lumiera::Error: LUMIERA_ERROR_STATE:unforseen state -- caused by: LUMIERA_ERROR_EXTERNAL:failure in external service (test-7). out: intermediate handler caught: LUMIERA_ERROR_EXTERNAL:failure in external service (test-8).....will rethrow as error::State From 5659219e55c3348b7ea1aab8e7c3b823c172aaf4 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 19 May 2008 13:31:18 +0200 Subject: [PATCH 087/245] correct date in copyright header --- tests/components/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/components/Makefile.am b/tests/components/Makefile.am index 5e8d1e070..088dbe668 100644 --- a/tests/components/Makefile.am +++ b/tests/components/Makefile.am @@ -1,5 +1,5 @@ # Copyright (C) Lumiera.org -# 2007, Christian Thaeter +# 2008, Christian Thaeter # Hermann Vosseler # # This program is free software; you can redistribute it and/or From b4183ed44456c830e61a848e09b3a34fd6c70b9f Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 1 Apr 2008 07:55:20 +0200 Subject: [PATCH 088/245] safeclib improvements * add lumiera_calloc() * improve cleanup functions for tmpbuf --- src/lib/safeclib.c | 40 ++++++++++++++++++++++++++-------------- src/lib/safeclib.h | 1 - 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/lib/safeclib.c b/src/lib/safeclib.c index a0b562643..934c3ff5b 100644 --- a/src/lib/safeclib.c +++ b/src/lib/safeclib.c @@ -1,7 +1,7 @@ /* safe_clib.c - Portable and safe wrapers around some clib functions and some tools - Copyright (C) CinelerraCV + Copyright (C) Lumiera.org 2008, Christian Thaeter This program is free software; you can redistribute it and/or @@ -39,9 +39,26 @@ LUMIERA_ERROR_DEFINE (NO_MEMORY, "Out of Memory!"); * @return pointer to the allocated memory */ void* -lumiera_malloc (size_t sz) +lumiera_malloc (size_t size) { - void* o = sz? malloc (sz) : NULL; + void* o = size ? malloc (size) : NULL; + if (!o) + LUMIERA_DIE (NO_MEMORY); + return o; +} + + +/** + * Allocate cleared memory for an array. + * always succeeds or dies + * @param n number of elements + * @param size memory to be allocated + * @return pointer to the allocated memory + */ +void* +lumiera_calloc (size_t n, size_t size) +{ + void* o = (n&&size)? calloc (n, size) : NULL; if (!o) LUMIERA_DIE (NO_MEMORY); return o; @@ -120,7 +137,6 @@ static void lumiera_tmpbuf_destroy (void* buf) { lumiera_tmpbuf_freeall (); - free (buf); } static void @@ -139,17 +155,13 @@ lumiera_tmpbuf_freeall (void) { pthread_once (&lumiera_tmpbuf_tls_once, lumiera_tmpbuf_init); struct lumiera_tmpbuf_struct* buf = pthread_getspecific (lumiera_tmpbuf_tls_key); - if (!buf) - pthread_setspecific (lumiera_tmpbuf_tls_key, - buf = lumiera_malloc (sizeof (struct lumiera_tmpbuf_struct))); - - for (buf->idx = 0; buf->idx < 64; ++buf->idx) + if (buf) { - free (buf->buffers[buf->idx]); - buf->buffers[buf->idx] = NULL; - buf->sizes[buf->idx] = 0; + pthread_setspecific (lumiera_tmpbuf_tls_key, NULL); + for (int idx = 0; idx < 64; ++idx) + free (buf->buffers[idx]); + free (buf); } - buf->idx = 0; } @@ -165,7 +177,7 @@ lumiera_tmpbuf_provide (size_t size) struct lumiera_tmpbuf_struct* buf = pthread_getspecific (lumiera_tmpbuf_tls_key); if (!buf) pthread_setspecific (lumiera_tmpbuf_tls_key, - buf = lumiera_malloc (sizeof (struct lumiera_tmpbuf_struct))); + buf = lumiera_calloc (1, sizeof (struct lumiera_tmpbuf_struct))); buf->idx = (buf->idx + 1) & 0x3f; diff --git a/src/lib/safeclib.h b/src/lib/safeclib.h index 02d931cb7..1aa806fd1 100644 --- a/src/lib/safeclib.h +++ b/src/lib/safeclib.h @@ -84,7 +84,6 @@ lumiera_streq (const char* a, const char* b); void lumiera_tmpbuf_freeall (void); - /** * Query a thread local tmpbuf. * @param size minimal needed size for the tmpbuf From 293b872b5d89e7a32dbfbd8b998c7476b5cd3a3e Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Fri, 4 Apr 2008 07:58:11 +0200 Subject: [PATCH 089/245] extend the MUTEX_SECTION macro with NoBug resource tracking LUMIERA_MUTEX_SECTION takes now a nobug flag as first argument and a nobug resource-handle as second argument. This change works forward for the NoBug resource tracker and deadlock detector. --- src/lib/mutex.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lib/mutex.h b/src/lib/mutex.h index 9381c3ca1..ca48ea592 100644 --- a/src/lib/mutex.h +++ b/src/lib/mutex.h @@ -27,12 +27,15 @@ /** * @file Mutual exclusion locking, header. */ - -#define LUMIERA_MUTEX_SECTION(mutex) \ +#define LUMIERA_MUTEX_SECTION(flag, handle, mutex) \ +RESOURCE_HANDLE (rh_##__LINE__##_); \ lumiera_mutexacquirer lock_##__LINE__##_; \ +RESOURCE_ENTER (flag, handle, "acquire mutex", &lock_##__LINE__##_, \ + NOBUG_RESOURCE_EXCLUSIVE, rh_##__LINE__##_); \ for (lumiera_mutexacquirer_init_mutex (&lock_##__LINE__##_, mutex, LUMIERA_LOCKED); \ lock_##__LINE__##_.state == LUMIERA_LOCKED; \ - lumiera_mutexacquirer_unlock (&lock_##__LINE__##_)) + lumiera_mutexacquirer_unlock (&lock_##__LINE__##_), \ + ({RESOURCE_LEAVE(flag, rh_##__LINE__##_);})) /** From b909c2247d3ef8c545c96e534db6d025038ec445 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 7 Apr 2008 05:43:40 +0200 Subject: [PATCH 090/245] add a cuckoo_nelements function Query the number of elements stored in a hash, useful for debugging. --- src/lib/cuckoo.c | 7 +++++++ src/lib/cuckoo.h | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/lib/cuckoo.c b/src/lib/cuckoo.c index 0d0b4efef..bbcb0e71a 100644 --- a/src/lib/cuckoo.c +++ b/src/lib/cuckoo.c @@ -208,6 +208,13 @@ cuckoo_insert_internal_ (Cuckoo self, void* item) } +size_t +cuckoo_nelements (Cuckoo self) +{ + return self->elements; +} + + static void cuckoo_rehash (Cuckoo self) { diff --git a/src/lib/cuckoo.h b/src/lib/cuckoo.h index db1d33da3..63b6d260d 100644 --- a/src/lib/cuckoo.h +++ b/src/lib/cuckoo.h @@ -105,6 +105,13 @@ cuckoo_destroy (Cuckoo self); void cuckoo_free (Cuckoo self); +/** + * Get the number of elements stored in a hash. + * @return number of elements, 0 when empty + */ +size_t +cuckoo_nelements (Cuckoo self); + /** * Insert an element into a hash. * amortized O(1) complexity because it may rarely rehash the tables or even grow them. From 0996c386bbab0250fda9fcde0061ecc8c8f26156 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 7 Apr 2008 06:38:05 +0200 Subject: [PATCH 091/245] Mrucache update * Fix: unlinking at destroy * rename add/remove to checkin/checkout * add a drop function which moves a node to the end for fast reuse --- src/lib/mrucache.c | 1 + src/lib/mrucache.h | 30 +++++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/lib/mrucache.c b/src/lib/mrucache.c index d98976184..b05169db8 100644 --- a/src/lib/mrucache.c +++ b/src/lib/mrucache.c @@ -43,6 +43,7 @@ lumiera_mrucache_destroy (LumieraMruCache self) { LLIST_WHILE_TAIL (&self->cache_list, node) { + llist_unlink (node); if (self->destructor_cb) free (self->destructor_cb (node)); else diff --git a/src/lib/mrucache.h b/src/lib/mrucache.h index 8af7434d9..4644abe8d 100644 --- a/src/lib/mrucache.h +++ b/src/lib/mrucache.h @@ -67,7 +67,7 @@ lumiera_mrucache_destroy (LumieraMruCache self); * add an element to a mrucache */ static inline void -lumiera_mrucache_add (LumieraMruCache self, LList node) +lumiera_mrucache_checkin (LumieraMruCache self, LList node) { REQUIRE (self); REQUIRE (node && llist_is_empty (node)); @@ -76,11 +76,34 @@ lumiera_mrucache_add (LumieraMruCache self, LList node) } +/** + * place an element at the tail of a mrucache, to be reused as first + */ +static inline void +lumiera_mrucache_drop (LumieraMruCache self, LList node) +{ + REQUIRE (self); + REQUIRE (node); + + if (llist_is_empty (node)) + { + /* was not in list, we need to count it */ + ++self->cached; + } + else + { + /* speedup loop warning :P, this check is costly */ + REQUIRE (llist_is_member (&self->cache_list, node), "node must be empty or member of cache"); + } + llist_insert_tail (&self->cache_list, node); +} + + /** * Remove an element from a mrucache. */ static inline void -lumiera_mrucache_remove (LumieraMruCache self, LList node) +lumiera_mrucache_checkout (LumieraMruCache self, LList node) { REQUIRE (self); REQUIRE (node && llist_is_member (&self->cache_list, node)); /* speedup loop warning :P, this check is costly */ @@ -88,6 +111,7 @@ lumiera_mrucache_remove (LumieraMruCache self, LList node) --self->cached; } + /** * destroy the oldest element and return a pointer to it for reuse. */ @@ -98,7 +122,7 @@ lumiera_mrucache_pop (LumieraMruCache self) if (llist_is_empty (&self->cache_list)) return NULL; - LList node = llist_tail (&self->cache_list); + LList node = llist_tail (&self->cache_list); llist_unlink (node); --self->cached; From ff6ce603a4b683210449efc92dc14257f70fdfb4 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 7 Apr 2008 19:21:52 +0200 Subject: [PATCH 092/245] tmpbuf_sprintf renamed to tmpbuf_snprintf --- src/lib/safeclib.c | 2 +- src/lib/safeclib.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/safeclib.c b/src/lib/safeclib.c index 934c3ff5b..1240cb673 100644 --- a/src/lib/safeclib.c +++ b/src/lib/safeclib.c @@ -206,7 +206,7 @@ lumiera_tmpbuf_strndup (const char* src, size_t size) char* -lumiera_tmpbuf_sprintf (size_t size, const char* fmt, ...) +lumiera_tmpbuf_snprintf (size_t size, const char* fmt, ...) { va_list args; diff --git a/src/lib/safeclib.h b/src/lib/safeclib.h index 1aa806fd1..2c835c8c2 100644 --- a/src/lib/safeclib.h +++ b/src/lib/safeclib.h @@ -109,5 +109,5 @@ lumiera_tmpbuf_strndup (const char* src, size_t size); * @return temporary buffer containing the constructed of the string */ char* -lumiera_tmpbuf_sprintf (size_t size, const char* fmt, ...); +lumiera_tmpbuf_snprintf (size_t size, const char* fmt, ...); From dc0cbf0ad8ef18b329ef4ae163b07712a363e762 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 7 Apr 2008 20:36:24 +0200 Subject: [PATCH 093/245] Fix: off by one allocation error in tmpbuf_snprintf() --- src/lib/safeclib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/safeclib.c b/src/lib/safeclib.c index 1240cb673..0e82e2dc0 100644 --- a/src/lib/safeclib.c +++ b/src/lib/safeclib.c @@ -215,9 +215,9 @@ lumiera_tmpbuf_snprintf (size_t size, const char* fmt, ...) va_end (args); len = len > size ? size : len; - char* buf = lumiera_tmpbuf_provide (len); + char* buf = lumiera_tmpbuf_provide (len+1); va_start (args, fmt); - vsnprintf (buf, len, fmt, args); + vsnprintf (buf, len+1, fmt, args); va_end (args); return buf; From 63c07d12749dafa3dac7a18a3d8580a949729612 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 9 Apr 2008 07:57:03 +0200 Subject: [PATCH 094/245] doxydocing mrucache --- src/lib/mrucache.c | 10 ---------- src/lib/mrucache.h | 50 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/lib/mrucache.c b/src/lib/mrucache.c index b05169db8..0f9bb86df 100644 --- a/src/lib/mrucache.c +++ b/src/lib/mrucache.c @@ -21,12 +21,6 @@ #include "lib/mrucache.h" -/** - * @file Most recent used cache - * Elements (addressed by a LList node) are either in the cache and thereby subject of aging - * or checked out under control of the user. - */ - LumieraMruCache lumiera_mrucache_init (LumieraMruCache self, lumiera_cache_destructor_fn destructor_cb) @@ -53,10 +47,6 @@ lumiera_mrucache_destroy (LumieraMruCache self) return self; } - -/** - * destroy and free the nelem oldest elements - */ int lumiera_mrucache_age (LumieraMruCache self, int nelem) { diff --git a/src/lib/mrucache.h b/src/lib/mrucache.h index 4644abe8d..3edb680f0 100644 --- a/src/lib/mrucache.h +++ b/src/lib/mrucache.h @@ -28,8 +28,9 @@ /** * @file Most recent used cache - * Elements (addressed by a LList node) are either in the cache and thereby subject of aging - * or checked out under control of the user. + * Elements (addressed by a LList node) are either checked in the cache and thereby subject of aging + * or checked out under control of the user. Most operations require that the chache is locked. This locking + * must be done from elsewhere. */ /** @@ -50,21 +51,31 @@ typedef struct lumiera_mrucache_struct lumiera_mrucache; typedef lumiera_mrucache* LumieraMruCache; /** - * Initialize a mrucache + * Initialize a cache. + * @param self cache to be initialized + * @param destructor_cb function for destructing a cache node, preparing for reuse. + * @return self */ LumieraMruCache lumiera_mrucache_init (LumieraMruCache self, lumiera_cache_destructor_fn destructor_cb); - /** - * Destroy a mrucache + * Destroy a cache. + * frees all checked in items. + * @param self cache to be destroyed + * @return self */ LumieraMruCache lumiera_mrucache_destroy (LumieraMruCache self); /** - * add an element to a mrucache + * Add an element to a mrucache. + * When added the element is subject of aging and must not be accessed anymore. + * To acces elements they have to be checked out again. + * Checkin and checkout operations must be protected by a lock over the cache. + * @param self cache where to checkin + * @param node a llist member in the cached data which is used as queue in the cache */ static inline void lumiera_mrucache_checkin (LumieraMruCache self, LList node) @@ -77,7 +88,13 @@ lumiera_mrucache_checkin (LumieraMruCache self, LList node) /** - * place an element at the tail of a mrucache, to be reused as first + * Schedule an element for fast aging. + * When an element is not longer needed it can be placed at the end of the chache + * aging queue and thus become the first one to be reused when a new element is queried. + * This can be done on a checked out element as well as on an element which is in the cache. + * The cache must be locked for this operation. + * @param self cache + * @param node a llist member in the cached data which is used as queue in the cache */ static inline void lumiera_mrucache_drop (LumieraMruCache self, LList node) @@ -100,7 +117,12 @@ lumiera_mrucache_drop (LumieraMruCache self, LList node) /** - * Remove an element from a mrucache. + * Checkout an element from a cache. + * A checked out element is not under cache control anymore until is gets checked in again. + * The code which checked the element out takes ownership of the element. + * The cache must be locked for this operation. + * @param self cache + * @param node a llist member in the cached data which is used as queue in the cache */ static inline void lumiera_mrucache_checkout (LumieraMruCache self, LList node) @@ -113,7 +135,11 @@ lumiera_mrucache_checkout (LumieraMruCache self, LList node) /** - * destroy the oldest element and return a pointer to it for reuse. + * Destroy the oldest element from the cache and return it. + * This function is used to get a new element by deleting the oldest least used one from the cache. + * The cache must be locked for this operation. + * @param self cache + * @return pointer to the uninitialized memory ready for being reused */ static inline void* lumiera_mrucache_pop (LumieraMruCache self) @@ -134,7 +160,11 @@ lumiera_mrucache_pop (LumieraMruCache self) /** - * destroy and free the nelem oldest elements + * Destroy and free the nelem oldest elements. + * Used to free up resources and memory. + * @param self cache where to free elements. + * @param nelem number of elements wished to be freed + * @return nelem-(numer of elements which got freed), that is 0 if all requested elements got freed */ int lumiera_mrucache_age (LumieraMruCache self, int nelem); From 03ed87051d8c8377a22f8767e61414660efa4349 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Fri, 2 May 2008 23:58:12 +0200 Subject: [PATCH 095/245] fix missing declaration of lumiera_calloc() in safeclib.h --- src/lib/safeclib.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/lib/safeclib.h b/src/lib/safeclib.h index 2c835c8c2..f486ed056 100644 --- a/src/lib/safeclib.h +++ b/src/lib/safeclib.h @@ -38,6 +38,17 @@ void* lumiera_malloc (size_t sz); +/** + * Allocate cleared memory for an array. + * always succeeds or dies + * @param n number of elements + * @param size memory to be allocated + * @return pointer to the allocated memory + */ +void* +lumiera_calloc (size_t n, size_t size); + + /** * Duplicate a C string. * always succeeds or dies From 94e075d2c2ea02042b809eb48c8635203d9c8f75 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Fri, 2 May 2008 23:59:26 +0200 Subject: [PATCH 096/245] fix: mrucache_drop() must call the element destructor --- src/lib/mrucache.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/mrucache.h b/src/lib/mrucache.h index 3edb680f0..c81bd7599 100644 --- a/src/lib/mrucache.h +++ b/src/lib/mrucache.h @@ -35,7 +35,8 @@ /** * Callback function used to destruct/cleanup aged elements. - * shall clean the element sufficiently up to be ready for being freed or reused + * shall clean the element sufficiently up to be ready for being freed or reused, + * this callback function must be reentrant and prepared to be called twice. * @param node the llist node used to link cache elements (will be empty at call) * @return pointer to the begin of the element. */ @@ -113,6 +114,9 @@ lumiera_mrucache_drop (LumieraMruCache self, LList node) REQUIRE (llist_is_member (&self->cache_list, node), "node must be empty or member of cache"); } llist_insert_tail (&self->cache_list, node); + + if (self->destructor_cb) + self->destructor_cb (node); } From 791f42c10474cd26f096c070a0feba51e4c72706 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Sun, 30 Mar 2008 04:31:32 +0200 Subject: [PATCH 097/245] WIP: Low level file management We have 'File' which associates a name with a file and will be used to offer an interface for the application. Posix 'Filehandles' which are managed in a 'Filehandlecache' to utilize a limited number of fd's at optimum. Internally we use 'Filedescriptor's which manage files, mapping and all kinds of metadata. Filedescriptors weak referenced by a registry and freed when the last user vanishes. --- src/backend/Makefile.am | 15 ++- src/backend/file.c | 64 +++++++++++ src/backend/file.h | 90 +++++++++++++++ src/backend/filedescriptor.c | 199 ++++++++++++++++++++++++++++++++++ src/backend/filedescriptor.h | 58 ++++++++++ src/backend/filehandle.h | 51 +++++++++ src/backend/filehandlecache.c | 83 ++++++++++++++ src/backend/filehandlecache.h | 97 +++++++++++++++++ 8 files changed, 649 insertions(+), 8 deletions(-) create mode 100644 src/backend/file.c create mode 100644 src/backend/file.h create mode 100644 src/backend/filedescriptor.c create mode 100644 src/backend/filedescriptor.h create mode 100644 src/backend/filehandle.h create mode 100644 src/backend/filehandlecache.c create mode 100644 src/backend/filehandlecache.h diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index eb5853d5f..45ce555a8 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -31,12 +31,11 @@ liblumibackend_a_SOURCES = \ # $(liblumibackend_a_srcdir)/filehandlecache.c -noinst_HEADERS += \ - $(liblumibackend_a_srcdir)/mediaaccessfacade.cpp - -# $(liblumibackend_a_srcdir)/backend.h \ -# $(liblumibackend_a_srcdir)/file.h \ -# $(liblumibackend_a_srcdir)/filehandle.h \ -# $(liblumibackend_a_srcdir)/filedescriptor.h \ -# $(liblumibackend_a_srcdir)/filehandlecache.h +noinst_HEADERS += \ + $(liblumibackend_a_srcdir)/mediaaccessfacade.cpp \ + $(liblumibackend_a_srcdir)/backend.h \ + $(liblumibackend_a_srcdir)/file.h \ + $(liblumibackend_a_srcdir)/filehandle.h \ + $(liblumibackend_a_srcdir)/filedescriptor.h \ + $(liblumibackend_a_srcdir)/filehandlecache.h diff --git a/src/backend/file.c b/src/backend/file.c new file mode 100644 index 000000000..7a4aa5050 --- /dev/null +++ b/src/backend/file.c @@ -0,0 +1,64 @@ +/* + file.c - file handling + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "lib/mutex.h" +#include "lib/safeclib.h" + +#include "backend/file.h" +#include "backend/filedescriptor.h" + +#include + + +NOBUG_DEFINE_FLAG (lumiera_file); + +LumieraFile +lumiera_file_init (LumieraFile self, const char* name, int flags) +{ + if (!lumiera_filedescriptor_acquire (&self->descriptor, name, flags)) + return NULL; + self->name = lumiera_strndup (name, PATH_MAX); + + return self; +} + +LumieraFile +lumiera_file_destroy (LumieraFile self) +{ + lumiera_reference_destroy (&self->descriptor); + free ((void*)self->name); + return self; +} + + +LumieraFile +lumiera_file_new (const char* name, int flags) +{ + LumieraFile self = lumiera_malloc (sizeof (lumiera_file)); + return lumiera_file_init (self, name, flags); +} + +void +lumiera_file_delete (LumieraFile self) +{ + free (lumiera_file_destroy (self)); +} + diff --git a/src/backend/file.h b/src/backend/file.h new file mode 100644 index 000000000..5018d321a --- /dev/null +++ b/src/backend/file.h @@ -0,0 +1,90 @@ +/* + file.h - interface to files by filename + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef LUMIERA_FILE_H +#define LUMIERA_FILE_H + + +#include "lib/mutex.h" +#include "lib/llist.h" +#include "lib/error.h" +#include "lib/references.h" + +/** + * @file File management + * Handling Files is splitted into different classes: + * 1. The 'lumiera_file' class which acts as interface to the outside for managing files. + * 'lumiera_file' is addressed by the name of the file. Since files can have more than one name (hardlinks) + * many 'lumiera_file' can point to a single 'lumiera_filedescriptor' + * 2. The 'lumiera_filedescriptor' class which does the real work managing the file in the back. + * 3. Since OS-filehandles are a limited resource we access the lazily as 'lumiera_filehandle' which are + * managed in a 'lumiera_filehandlecache' + */ + +typedef struct lumiera_file_struct lumiera_file; +typedef lumiera_file* LumieraFile; + + +#include "backend/filehandle.h" +#include "backend/filedescriptor.h" + + + +NOBUG_DECLARE_FLAG (lumiera_file); + +#define LUMIERA_FILE_READONLY (O_RDONLY | O_LARGEFILE | O_NOATIME) +#define LUMIERA_FILE_READWRITE (O_RDWR | O_LARGEFILE | O_NOATIME) +#define LUMIERA_FILE_CREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_EXCL) +#define LUMIERA_FILE_RECREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_TRUNC) + +struct lumiera_file_struct +{ + const char* name; + struct lumiera_reference_struct descriptor; +}; + +/** + * + */ +LumieraFile +lumiera_file_init (LumieraFile self, const char* name, int flags); + +/** + * + */ +LumieraFile +lumiera_file_destroy (LumieraFile self); + +/** + * + */ +LumieraFile +lumiera_file_new (const char* name, int flags); + +/** + * + */ +void +lumiera_file_delete (LumieraFile self); + + +#endif + diff --git a/src/backend/filedescriptor.c b/src/backend/filedescriptor.c new file mode 100644 index 000000000..fdb22ffb3 --- /dev/null +++ b/src/backend/filedescriptor.c @@ -0,0 +1,199 @@ +/* + filedescriptor.c - file handling + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "lib/mutex.h" +#include "lib/safeclib.h" +#include "lib/cuckoo.h" + +#include "backend/filedescriptor.h" + +#include +#include +#include +#include + + +NOBUG_DEFINE_FLAG (filedescriptor); + +static Cuckoo registry = NULL; +static lumiera_mutex registry_mutex = {PTHREAD_MUTEX_INITIALIZER}; + + +static size_t +h1 (const void* item, const uint32_t r) +{ + const LumieraFiledescriptor i = (const LumieraFiledescriptor) item; + return i->stat.st_dev^i->stat.st_ino^i->flags^((i->stat.st_dev^i->stat.st_ino^i->flags)>>7)^r; +} + +static size_t +h2 (const void* item, const uint32_t r) +{ + const LumieraFiledescriptor i = (const LumieraFiledescriptor) item; + return i->stat.st_dev^i->stat.st_ino^i->flags^((i->stat.st_dev^i->stat.st_ino^i->flags)>>5)^r; +} + +static size_t +h3 (const void* item, const uint32_t r) +{ + const LumieraFiledescriptor i = (const LumieraFiledescriptor) item; + return i->stat.st_dev^i->stat.st_ino^i->flags^((i->stat.st_dev^i->stat.st_ino^i->flags)>>3)^r; +} + + +static int +cmp (const void* keya, const void* keyb) +{ + const LumieraFiledescriptor a = (const LumieraFiledescriptor) keya; + const LumieraFiledescriptor b = (const LumieraFiledescriptor) keyb; + return a->stat.st_dev == b->stat.st_dev && a->stat.st_ino == b->stat.st_ino && a->flags == b->flags; +} + + +static Cuckoo +lumiera_filedescriptor_registry_new (void) +{ + NOBUG_INIT_FLAG (filedescriptor); + + Cuckoo registry = cuckoo_new (h1, h2, h3, cmp, + sizeof (struct lumiera_reference_struct), + 3); + if (!registry) + LUMIERA_DIE (NO_MEMORY); + + return registry; +} + +/** + * Find existing filedescriptor or create one + * @param descriptor strong reference to be initialized with the filedescriptor, + * a filedescriptor will be deleted when its last string reference gets deleted. + * @param name name of the file + * @param flags opening flags for the filedescriptor + * @return descriptor on success or NULL on error + */ +LumieraReference +lumiera_filedescriptor_acquire (LumieraReference descriptor, const char* name, int flags) +{ + UNCHECKED; + lumiera_mutexacquirer registry_lock; + lumiera_mutexacquirer_init_mutex (®istry_lock, ®istry_mutex, LUMIERA_LOCKED); + + if (!registry) + registry = lumiera_filedescriptor_registry_new (); + + struct lumiera_filedescriptor_struct findme; + findme.flags = flags; + + for (int retry = 0; !retry; ++retry) + { + if (stat (name, &findme.stat) == 0) + break; + else + { + if (errno == ENOENT && flags&O_CREAT) + { + TRACE (filedescriptor, "try creating file: %s", name); + char* slash = lumiera_tmpbuf_strndup (name, PATH_MAX); + + while ((slash = strchr (slash+1, '/'))) + { + *slash = '\0'; + if (mkdir (name, 0777) == -1) + { + LUMIERA_ERROR_SET (filedescriptor, ERRNO); + goto efile; + } + *slash = '/'; + } + + int fd; + fd = creat (name, 0777); + if (fd == -1) + { + LUMIERA_ERROR_SET (filedescriptor, ERRNO); + goto efile; + } + close (fd); + /* will now retry the fstat once */ + } + else + { + LUMIERA_ERROR_SET (filedescriptor, ERRNO); + goto efile; + } + } + } + + /* lookup/create descriptor */ + LumieraReference elem = cuckoo_find (registry, &findme); + + if (!elem) + { + TRACE (filedescriptor, "Descriptor not found"); + + lumiera_reference_strong_init_once (descriptor, + lumiera_filedescriptor_new (&findme), + (void(*)(void*))lumiera_filedescriptor_delete); + + if (!lumiera_reference_get (descriptor)) + goto ecreate; + + lumiera_reference weak_descriptor; + lumiera_reference_weak_init (&weak_descriptor, descriptor); + cuckoo_insert (registry, &weak_descriptor); + } + else + { + lumiera_reference_strong_init (descriptor, elem); + } + lumiera_mutexacquirer_unlock (®istry_lock); + + return descriptor; + + efile: + ecreate: + lumiera_mutexacquirer_unlock (®istry_lock); + return NULL; +} + + +/** + * Allocate a new filedescriptor cloned from a template + * @param template the source filedescriptor + * @return the constrccted filedescriptor + */ +LumieraFiledescriptor +lumiera_filedescriptor_new (LumieraFiledescriptor template) +{ + UNIMPLEMENTED(""); + return NULL; +} + +/** + * delete a filedescriptor and free its resources + * @param descriptor filedescriptor to be freed + */ +void +lumiera_filedescriptor_delete (LumieraFiledescriptor descriptor) +{ + UNIMPLEMENTED(""); +} diff --git a/src/backend/filedescriptor.h b/src/backend/filedescriptor.h new file mode 100644 index 000000000..060839d0a --- /dev/null +++ b/src/backend/filedescriptor.h @@ -0,0 +1,58 @@ +/* + filedescriptor.h - file handling + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef LUMIERA_FILEDESCRIPTOR_H +#define LUMIERA_FILEDESCRIPTOR_H + +#include "lib/mutex.h" + +#include + +typedef struct lumiera_filedescriptor_struct lumiera_filedescriptor; +typedef lumiera_filedescriptor* LumieraFiledescriptor; + + +#include "backend/filehandle.h" +#include "backend/file.h" + + +struct lumiera_filedescriptor_struct +{ + struct stat stat; /* create after first open, maintained metadata, MUST BE FIRST! */ + int flags; /* open flags, must be masked for reopen */ + lumiera_mutex lock; /* locks operations on this file descriptor */ + unsigned reopened; /* count for reopens 0=not yet opened, 1=first, 2..=reopened*/ + //LumieraFileMap mappings; + //LumieraWriteBuffer writebuffer; +}; + + +LumieraReference +lumiera_filedescriptor_acquire (LumieraReference descriptor, const char* name, int flags); + +LumieraFiledescriptor +lumiera_filedescriptor_new (LumieraFiledescriptor template); + +void +lumiera_filedescriptor_delete (LumieraFiledescriptor self); + + +#endif diff --git a/src/backend/filehandle.h b/src/backend/filehandle.h new file mode 100644 index 000000000..00b4737c9 --- /dev/null +++ b/src/backend/filehandle.h @@ -0,0 +1,51 @@ +/* + filehandle - filehandle management and caching + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#ifndef LUMIERA_FILEHANDLE_H +#define LUMIERA_FILEHANDLE_H + +#include "lib/error.h" +#include "lib/llist.h" + +/** + * @file Filehandles + */ + + +/** + * File handles + */ +struct lumiera_filehandle_struct +{ + llist cachenode; + int handle; + //LumieraFile file; + //lumiera_mutex lock; +}; +typedef struct lumiera_filehandle_struct lumiera_filehandle; +typedef lumiera_filehandle* LumieraFilehandle; + +LumieraFilehandle +lumiera_filehandle_new (); + +void* +lumiera_filehandle_destroy_node (LList node); + +#endif diff --git a/src/backend/filehandlecache.c b/src/backend/filehandlecache.c new file mode 100644 index 000000000..98ebdddc9 --- /dev/null +++ b/src/backend/filehandlecache.c @@ -0,0 +1,83 @@ +/* + filehandlecache - filehandle management and caching + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "backend/filehandlecache.h" + +NOBUG_DEFINE_FLAG (lumiera_filehandlecache); + +/* errors */ + +LUMIERA_ERROR_DEFINE (FILEHANDLECACHE_NOHANDLE, "No filehandle available"); + + +/**/ + +LumieraFilehandlecache +lumiera_filehandlecache_init (LumieraFilehandlecache self, int max_entries) +{ + lumiera_mrucache_init (&self->cache, lumiera_filehandle_destroy_node); + self->available =max_entries; + lumiera_mutex_init (&self->lock); + return self; +} + +LumieraFilehandlecache +lumiera_filehandlecache_destroy (LumieraFilehandlecache self) +{ + self->available += self->cache.cached; + lumiera_mrucache_destroy (&self->cache); + lumiera_mutex_destroy (&self->lock); + return self; +} + + +LumieraFilehandle +lumiera_filehandlecache_filehandle_acquire (LumieraFilehandlecache self) +{ + LumieraFilehandle ret; + LUMIERA_MUTEX_SECTION (&self->lock) + { + if (self->available <= 0 && self->cache.cached) + { + /* pop a filehandle from cache */ + ret = lumiera_mrucache_pop (&self->cache); + if (self->available < 0) + /* try to free overallocated filehandles */ + self->available -= self->available + lumiera_mrucache_age (&self->cache, -self->available); + } + else + { + /* allocate new filehandle if we are below the limit or no cached handles where available (overallocating) */ + ret = lumiera_filehandle_new (); + if (!ret) + LUMIERA_ERROR_SET (lumiera_filehandlecache, FILEHANDLECACHE_NOHANDLE); + else + --self->available; + } + } + return ret; +} + +void +lumiera_filehandlecache_add (LumieraFilehandlecache self, LumieraFilehandle handle) +{ + UNIMPLEMENTED (""); +} diff --git a/src/backend/filehandlecache.h b/src/backend/filehandlecache.h new file mode 100644 index 000000000..40386defe --- /dev/null +++ b/src/backend/filehandlecache.h @@ -0,0 +1,97 @@ +/* + filehandlecache - filehandle management and caching + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#ifndef LUMIERA_FILEHANDLECACHE_H +#define LUMIERA_FILEHANDLECACHE_H + +#include "lib/error.h" +#include "lib/mrucache.h" +#include "lib/mutex.h" + +#include "backend/filehandle.h" + +/** + * @file Filehandle management and caching + * The number of filehandles a program can held open is usually limited, since we want to support + * using a less limited number of files and closing/opening for each operation is expensive, we + * provide a cache to keep the most frequent used files open and gracefully close/recycle unused filehandles. + */ + + + +/* + File handle cache manages file handles + */ +struct lumiera_filehandlecache_struct +{ + lumiera_mrucache cache; + int available; + lumiera_mutex lock; +}; +typedef struct lumiera_filehandlecache_struct lumiera_filehandlecache; +typedef lumiera_filehandlecache* LumieraFilehandlecache; + + +/** + * Initializes a filehandle cache. + * @param self pointer to the cache to be initialized + * @param max_entries number how much filehandles shall be managed + * @return self as given + * The number of elements the cache can hold is static and should be + * determined by sysconf (_SC_OPEN_MAX) minus some safety margin. + */ +LumieraFilehandlecache +lumiera_filehandlecache_init (LumieraFilehandlecache self, int max_entries); + +/** + * Destroy a filehandle cache. + * @param self the cache to be destroyed + * @return self as given to the now uninitialized! cache + * No filehandles in the cache must be locked, this would be a fatal error. + * The handles are closed automatically. + */ +LumieraFilehandlecache +lumiera_filehandlecache_destroy (LumieraFilehandlecache self); + +/** + * Get a fresh filehandle. + * @param self pointer to the cache + * @return the new filehandle + * one must call lumiera_mutexacquirer_unlock (&lock) to free the lock on the handle when done + */ +LumieraFilehandle +lumiera_filehandlecache_filehandle_acquire (LumieraFilehandlecache self); + +/** + * Add filehande back to cache. + * @param self pointer to the cache + * @param handle filehandle to be put back + */ +void +lumiera_filehandlecache_add (LumieraFilehandlecache self, LumieraFilehandle handle); + +/** + * + */ +LumieraFilehandle +lumiera_filehandlecache_remove (LumieraFilehandlecache self, int fd); + + +#endif From 7a266f22ba1dc41fd0519f8a47b86570cb891582 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 31 Mar 2008 02:28:25 +0200 Subject: [PATCH 098/245] integrate filedescriptor tests --- tests/20filedescriptor.tests | 20 ++++++++ tests/Makefile.am | 5 ++ tests/backend/test-filedescriptors.c | 70 ++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 tests/20filedescriptor.tests create mode 100644 tests/backend/test-filedescriptors.c diff --git a/tests/20filedescriptor.tests b/tests/20filedescriptor.tests new file mode 100644 index 000000000..703a3351e --- /dev/null +++ b/tests/20filedescriptor.tests @@ -0,0 +1,20 @@ + +TESTING "Filedescriptor management" ./test-filedescriptors + +echo testdata > ,tmp_testfile + +TEST "acquire existing file" acquire_existing < + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#define _GNU_SOURCE + +#include "lib/references.h" +#include "lib/safeclib.h" + +#include "backend/filedescriptor.h" + +#include "tests/test.h" + +TESTS_BEGIN + + +TEST ("acquire_existing") +{ + lumiera_reference descriptor; + if (lumiera_filedescriptor_acquire (&descriptor, ",tmp_testfile", LUMIERA_FILE_READONLY)) + { + lumiera_reference_destroy (&descriptor); + return 0; + } + else + return 1; +} + +TEST ("acquire_create") +{ + lumiera_reference descriptor; + if (lumiera_filedescriptor_acquire (&descriptor, ",tmp_testfile", LUMIERA_FILE_CREATE)) + { + lumiera_reference_destroy (&descriptor); + return 0; + } + else + return 1; +} + +TEST ("acquire_create_dir") +{ + lumiera_reference descriptor; + if (lumiera_filedescriptor_acquire (&descriptor, ",tmp_testdir/,tmp_testfile", LUMIERA_FILE_CREATE)) + { + lumiera_reference_destroy (&descriptor); + return 0; + } + else + return 1; +} + + +TESTS_END From e2e94884badc0e58606f0841dfd91d3368b051f6 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 1 Apr 2008 19:20:17 +0200 Subject: [PATCH 099/245] some refinements to the todo wiki --- wiki/todo.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wiki/todo.html b/wiki/todo.html index d6caf66be..e66ec929f 100644 --- a/wiki/todo.html +++ b/wiki/todo.html @@ -3344,7 +3344,11 @@ Someone might pickup a Doxygen-Maintainer. This is not writing actual documentat
Use the backend, gmerlin/avdecoder and a Player widget to playback videos. This should be a small application which can open and playback many videos from one instance in parallel. Later on scrubbing for this videos might be supported.
 
-The idea here is to show and measure backend and scheduler performance and beeing a proof of concept for the design. It will run independent of the Proc layer but needs quite some work on the backend to be done.
+The idea here is to show and measure backend and scheduler performance + and beeing a proof of concept for the design. It will run + independent of the Proc layer but needs quite some work on the + backend to be done. +
From 52868388866c6c038cbeba9286092ee65d1f3ed6 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 1 Apr 2008 22:32:35 +0200 Subject: [PATCH 100/245] filedescriptor handling basics working, including some tests It is now possible to acquire/release filedescriptors for existing files and files to be created. Filedescriptors are managed in a registry by refcounts, they get automatically destructed when the last user releases them. --- src/backend/filedescriptor.c | 123 ++++++++++++++++++--------- src/backend/filedescriptor.h | 14 ++- tests/20filedescriptor.tests | 8 +- tests/backend/test-filedescriptors.c | 35 +++++--- 4 files changed, 125 insertions(+), 55 deletions(-) diff --git a/src/backend/filedescriptor.c b/src/backend/filedescriptor.c index fdb22ffb3..6db2882c9 100644 --- a/src/backend/filedescriptor.c +++ b/src/backend/filedescriptor.c @@ -33,28 +33,35 @@ NOBUG_DEFINE_FLAG (filedescriptor); +/* + Filedescriptor registry + + This registry stores all acquired filedescriptors for lookup, they will be freed when not referenced anymore. + */ static Cuckoo registry = NULL; static lumiera_mutex registry_mutex = {PTHREAD_MUTEX_INITIALIZER}; - +/* + * setup hashing and compare functions for cuckoo hashing + */ static size_t h1 (const void* item, const uint32_t r) { - const LumieraFiledescriptor i = (const LumieraFiledescriptor) item; + const LumieraFiledescriptor i = *(const LumieraFiledescriptor*)item; return i->stat.st_dev^i->stat.st_ino^i->flags^((i->stat.st_dev^i->stat.st_ino^i->flags)>>7)^r; } static size_t h2 (const void* item, const uint32_t r) { - const LumieraFiledescriptor i = (const LumieraFiledescriptor) item; + const LumieraFiledescriptor i = *(const LumieraFiledescriptor*)item; return i->stat.st_dev^i->stat.st_ino^i->flags^((i->stat.st_dev^i->stat.st_ino^i->flags)>>5)^r; } static size_t h3 (const void* item, const uint32_t r) { - const LumieraFiledescriptor i = (const LumieraFiledescriptor) item; + const LumieraFiledescriptor i = *(const LumieraFiledescriptor*)item; return i->stat.st_dev^i->stat.st_ino^i->flags^((i->stat.st_dev^i->stat.st_ino^i->flags)>>3)^r; } @@ -62,19 +69,18 @@ h3 (const void* item, const uint32_t r) static int cmp (const void* keya, const void* keyb) { - const LumieraFiledescriptor a = (const LumieraFiledescriptor) keya; - const LumieraFiledescriptor b = (const LumieraFiledescriptor) keyb; + const LumieraFiledescriptor a = *(const LumieraFiledescriptor*)keya; + const LumieraFiledescriptor b = *(const LumieraFiledescriptor*)keyb; return a->stat.st_dev == b->stat.st_dev && a->stat.st_ino == b->stat.st_ino && a->flags == b->flags; } - static Cuckoo lumiera_filedescriptor_registry_new (void) { NOBUG_INIT_FLAG (filedescriptor); Cuckoo registry = cuckoo_new (h1, h2, h3, cmp, - sizeof (struct lumiera_reference_struct), + sizeof (LumieraFiledescriptor), 3); if (!registry) LUMIERA_DIE (NO_MEMORY); @@ -82,6 +88,12 @@ lumiera_filedescriptor_registry_new (void) return registry; } +static void +lumiera_filedescriptor_registry_delete (void) +{ + cuckoo_free (registry); +} + /** * Find existing filedescriptor or create one * @param descriptor strong reference to be initialized with the filedescriptor, @@ -90,34 +102,40 @@ lumiera_filedescriptor_registry_new (void) * @param flags opening flags for the filedescriptor * @return descriptor on success or NULL on error */ -LumieraReference -lumiera_filedescriptor_acquire (LumieraReference descriptor, const char* name, int flags) +LumieraFiledescriptor +lumiera_filedescriptor_acquire (const char* name, int flags) { + TRACE (filedescriptor); UNCHECKED; lumiera_mutexacquirer registry_lock; lumiera_mutexacquirer_init_mutex (®istry_lock, ®istry_mutex, LUMIERA_LOCKED); if (!registry) - registry = lumiera_filedescriptor_registry_new (); + { + registry = lumiera_filedescriptor_registry_new (); + atexit (lumiera_filedescriptor_registry_delete); + } - struct lumiera_filedescriptor_struct findme; - findme.flags = flags; + lumiera_filedescriptor fdesc; + fdesc.flags = flags; for (int retry = 0; !retry; ++retry) { - if (stat (name, &findme.stat) == 0) + if (stat (name, &fdesc.stat) == 0) break; else { if (errno == ENOENT && flags&O_CREAT) { - TRACE (filedescriptor, "try creating file: %s", name); - char* slash = lumiera_tmpbuf_strndup (name, PATH_MAX); + INFO (filedescriptor, "try creating file: %s %d", name, PATH_MAX); + char* dir = lumiera_tmpbuf_strndup (name, PATH_MAX); + char* slash = dir; while ((slash = strchr (slash+1, '/'))) { *slash = '\0'; - if (mkdir (name, 0777) == -1) + INFO (filedescriptor, "try creating dir: %s", dir); + if (mkdir (dir, 0777) == -1) { LUMIERA_ERROR_SET (filedescriptor, ERRNO); goto efile; @@ -133,41 +151,37 @@ lumiera_filedescriptor_acquire (LumieraReference descriptor, const char* name, i goto efile; } close (fd); - /* will now retry the fstat once */ - } - else - { - LUMIERA_ERROR_SET (filedescriptor, ERRNO); - goto efile; + continue; /* will now retry the fstat once */ } } + /* finally, no luck */ + LUMIERA_ERROR_SET (filedescriptor, ERRNO); + goto efile; } /* lookup/create descriptor */ - LumieraReference elem = cuckoo_find (registry, &findme); + LumieraFiledescriptor dest = &fdesc; + LumieraFiledescriptor* found = cuckoo_find (registry, &dest); - if (!elem) + if (!found) { TRACE (filedescriptor, "Descriptor not found"); - lumiera_reference_strong_init_once (descriptor, - lumiera_filedescriptor_new (&findme), - (void(*)(void*))lumiera_filedescriptor_delete); - - if (!lumiera_reference_get (descriptor)) + dest = lumiera_filedescriptor_new (&fdesc); + if (!dest) goto ecreate; - lumiera_reference weak_descriptor; - lumiera_reference_weak_init (&weak_descriptor, descriptor); - cuckoo_insert (registry, &weak_descriptor); + cuckoo_insert (registry, &dest); } else { - lumiera_reference_strong_init (descriptor, elem); + TRACE (filedescriptor, "Descriptor already existing"); + dest = *found; + ++dest->refcount; } - lumiera_mutexacquirer_unlock (®istry_lock); - return descriptor; + lumiera_mutexacquirer_unlock (®istry_lock); + return dest; efile: ecreate: @@ -175,6 +189,13 @@ lumiera_filedescriptor_acquire (LumieraReference descriptor, const char* name, i return NULL; } +void +lumiera_filedescriptor_release (LumieraFiledescriptor self) +{ + TRACE (filedescriptor); + if (!--self->refcount) + lumiera_filedescriptor_delete (self); +} /** * Allocate a new filedescriptor cloned from a template @@ -184,8 +205,17 @@ lumiera_filedescriptor_acquire (LumieraReference descriptor, const char* name, i LumieraFiledescriptor lumiera_filedescriptor_new (LumieraFiledescriptor template) { - UNIMPLEMENTED(""); - return NULL; + LumieraFiledescriptor self = lumiera_malloc (sizeof (lumiera_filedescriptor)); + TRACE (filedescriptor, "at %p", self); + + self->stat = template->stat; + + self->flags = template->flags; + lumiera_mutex_init (&self->lock); + self->reopened = 0; + self->refcount = 1; + + return self; } /** @@ -193,7 +223,20 @@ lumiera_filedescriptor_new (LumieraFiledescriptor template) * @param descriptor filedescriptor to be freed */ void -lumiera_filedescriptor_delete (LumieraFiledescriptor descriptor) +lumiera_filedescriptor_delete (LumieraFiledescriptor self) { - UNIMPLEMENTED(""); + TRACE (filedescriptor, "%p", self); + lumiera_mutexacquirer registry_lock; + lumiera_mutexacquirer_init_mutex (®istry_lock, ®istry_mutex, LUMIERA_LOCKED); + + REQUIRE (self->refcount == 0); + + cuckoo_remove (registry, cuckoo_find (registry, &self)); + + TODO ("destruct other members (WIP)"); + + lumiera_mutex_destroy (&self->lock); + free (self); + + lumiera_mutexacquirer_unlock (®istry_lock); } diff --git a/src/backend/filedescriptor.h b/src/backend/filedescriptor.h index 060839d0a..59c4eacef 100644 --- a/src/backend/filedescriptor.h +++ b/src/backend/filedescriptor.h @@ -24,7 +24,10 @@ #include "lib/mutex.h" + +#include #include +#include typedef struct lumiera_filedescriptor_struct lumiera_filedescriptor; typedef lumiera_filedescriptor* LumieraFiledescriptor; @@ -39,14 +42,19 @@ struct lumiera_filedescriptor_struct struct stat stat; /* create after first open, maintained metadata, MUST BE FIRST! */ int flags; /* open flags, must be masked for reopen */ lumiera_mutex lock; /* locks operations on this file descriptor */ - unsigned reopened; /* count for reopens 0=not yet opened, 1=first, 2..=reopened*/ + unsigned reopened; /* count for reopens 0=not yet opened, 1=first, 2..=reopened */ + unsigned refcount; /* reference counter, all users sans registry */ + //LumieraFileMap mappings; //LumieraWriteBuffer writebuffer; }; -LumieraReference -lumiera_filedescriptor_acquire (LumieraReference descriptor, const char* name, int flags); +LumieraFiledescriptor +lumiera_filedescriptor_acquire (const char* name, int flags); + +void +lumiera_filedescriptor_release (LumieraFiledescriptor self); LumieraFiledescriptor lumiera_filedescriptor_new (LumieraFiledescriptor template); diff --git a/tests/20filedescriptor.tests b/tests/20filedescriptor.tests index 703a3351e..78639e7b8 100644 --- a/tests/20filedescriptor.tests +++ b/tests/20filedescriptor.tests @@ -4,17 +4,23 @@ TESTING "Filedescriptor management" ./test-filedescriptors echo testdata > ,tmp_testfile TEST "acquire existing file" acquire_existing < Date: Fri, 4 Apr 2008 08:01:59 +0200 Subject: [PATCH 101/245] add nobug resource tracking to filedescriptors --- src/backend/filedescriptor.c | 8 ++++++++ src/backend/filedescriptor.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/src/backend/filedescriptor.c b/src/backend/filedescriptor.c index 6db2882c9..51b536e56 100644 --- a/src/backend/filedescriptor.c +++ b/src/backend/filedescriptor.c @@ -214,6 +214,9 @@ lumiera_filedescriptor_new (LumieraFiledescriptor template) lumiera_mutex_init (&self->lock); self->reopened = 0; self->refcount = 1; + self->handle = 0; + + RESOURCE_ANNOUNCE (filedescriptor, "mutex", "filedescriptor", self, self->rh); return self; } @@ -231,10 +234,15 @@ lumiera_filedescriptor_delete (LumieraFiledescriptor self) REQUIRE (self->refcount == 0); + RESOURCE_FORGET (filedescriptor, self->rh); + cuckoo_remove (registry, cuckoo_find (registry, &self)); TODO ("destruct other members (WIP)"); + + TODO ("release filehandle"); + lumiera_mutex_destroy (&self->lock); free (self); diff --git a/src/backend/filedescriptor.h b/src/backend/filedescriptor.h index 59c4eacef..48d0cd21c 100644 --- a/src/backend/filedescriptor.h +++ b/src/backend/filedescriptor.h @@ -45,8 +45,11 @@ struct lumiera_filedescriptor_struct unsigned reopened; /* count for reopens 0=not yet opened, 1=first, 2..=reopened */ unsigned refcount; /* reference counter, all users sans registry */ + LumieraFilehandle handle; //LumieraFileMap mappings; //LumieraWriteBuffer writebuffer; + + RESOURCE_HANDLE (rh); }; From b11ff40fbe33846b3f12f38bac35bf00029a85f8 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 7 Apr 2008 05:51:32 +0200 Subject: [PATCH 102/245] Filedescriptor updates * make registry initialization singleton, no parameters. * remove registry init from all functions, has to be called explicitly. * some nobug improvements --- src/backend/filedescriptor.c | 36 ++++++++++++++++++------------------ src/backend/filedescriptor.h | 6 +++++- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/backend/filedescriptor.c b/src/backend/filedescriptor.c index 51b536e56..0a3d6e048 100644 --- a/src/backend/filedescriptor.c +++ b/src/backend/filedescriptor.c @@ -31,7 +31,7 @@ #include -NOBUG_DEFINE_FLAG (filedescriptor); +NOBUG_DEFINE_FLAG_PARENT (filedescriptor, file_all); /* Filedescriptor registry @@ -74,26 +74,28 @@ cmp (const void* keya, const void* keyb) return a->stat.st_dev == b->stat.st_dev && a->stat.st_ino == b->stat.st_ino && a->flags == b->flags; } -static Cuckoo -lumiera_filedescriptor_registry_new (void) +void +lumiera_filedescriptor_registry_init (void) { NOBUG_INIT_FLAG (filedescriptor); + TRACE (filedescriptor); - Cuckoo registry = cuckoo_new (h1, h2, h3, cmp, - sizeof (LumieraFiledescriptor), - 3); + registry = cuckoo_new (h1, h2, h3, cmp, + sizeof (LumieraFiledescriptor), + 3); if (!registry) LUMIERA_DIE (NO_MEMORY); - - return registry; } -static void -lumiera_filedescriptor_registry_delete (void) +void +lumiera_filedescriptor_registry_destroy (void) { + TRACE (filedescriptor); + REQUIRE (!cuckoo_nelements (registry)); cuckoo_free (registry); } + /** * Find existing filedescriptor or create one * @param descriptor strong reference to be initialized with the filedescriptor, @@ -106,18 +108,13 @@ LumieraFiledescriptor lumiera_filedescriptor_acquire (const char* name, int flags) { TRACE (filedescriptor); + REQUIRE (registry, "not initialized"); UNCHECKED; lumiera_mutexacquirer registry_lock; lumiera_mutexacquirer_init_mutex (®istry_lock, ®istry_mutex, LUMIERA_LOCKED); - if (!registry) - { - registry = lumiera_filedescriptor_registry_new (); - atexit (lumiera_filedescriptor_registry_delete); - } - lumiera_filedescriptor fdesc; - fdesc.flags = flags; + fdesc.flags = flags&LUMIERA_FILE_MASK; for (int retry = 0; !retry; ++retry) { @@ -216,7 +213,10 @@ lumiera_filedescriptor_new (LumieraFiledescriptor template) self->refcount = 1; self->handle = 0; - RESOURCE_ANNOUNCE (filedescriptor, "mutex", "filedescriptor", self, self->rh); + const char* type = "mutex"; + const char* name = "filedescriptor"; + + RESOURCE_ANNOUNCE (filedescriptor, type, name, self, self->rh); return self; } diff --git a/src/backend/filedescriptor.h b/src/backend/filedescriptor.h index 48d0cd21c..817e8bc13 100644 --- a/src/backend/filedescriptor.h +++ b/src/backend/filedescriptor.h @@ -52,6 +52,11 @@ struct lumiera_filedescriptor_struct RESOURCE_HANDLE (rh); }; +void +lumiera_filedescriptor_registry_init (void); + +void +lumiera_filedescriptor_registry_destroy (void); LumieraFiledescriptor lumiera_filedescriptor_acquire (const char* name, int flags); @@ -65,5 +70,4 @@ lumiera_filedescriptor_new (LumieraFiledescriptor template); void lumiera_filedescriptor_delete (LumieraFiledescriptor self); - #endif From 232afe77e9aefb10cf9832aa678aa2e4b11f620a Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 7 Apr 2008 06:47:57 +0200 Subject: [PATCH 103/245] Filehandling * add 'backend' for backend global initialization/destruction and common functions. * WIP: 'file' acts as interface to named files, provides posix filehandles with and acquire/release function pair. * 'filehandle' manages posix filehandles internally, refcounted. * WIP: 'filehandlecache' keeps unused filehandles in a MRU cache * WIP: test for filehandle management * improved filedescriptor test --- src/backend/backend.c | 53 ++++++++++++++ src/backend/backend.h | 36 ++++++++++ src/backend/file.c | 53 ++++++++++++-- src/backend/file.h | 17 +++-- src/backend/filedescriptor.c | 4 ++ src/backend/filehandle.c | 70 ++++++++++++++++++ src/backend/filehandle.h | 16 +++-- src/backend/filehandlecache.c | 102 +++++++++++++++++++++------ src/backend/filehandlecache.h | 41 ++++++----- tests/20filehandle.tests | 7 ++ tests/Makefile.am | 8 +-- tests/backend/test-filedescriptors.c | 10 ++- tests/backend/test-filehandles.c | 58 +++++++++++++++ 13 files changed, 415 insertions(+), 60 deletions(-) create mode 100644 src/backend/backend.c create mode 100644 src/backend/backend.h create mode 100644 src/backend/filehandle.c create mode 100644 tests/20filehandle.tests create mode 100644 tests/backend/test-filehandles.c diff --git a/src/backend/backend.c b/src/backend/backend.c new file mode 100644 index 000000000..024f7e6f8 --- /dev/null +++ b/src/backend/backend.c @@ -0,0 +1,53 @@ +/* + backend - common lumiera backend things + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "backend/backend.h" +#include "backend/filehandlecache.h" +#include "backend/filedescriptor.h" + +//NOBUG_DEFINE_FLAG_PARENT (backend, lumiera); TODO +NOBUG_DEFINE_FLAG (backend); +NOBUG_DEFINE_FLAG_PARENT (file_all, backend); + +int +lumiera_backend_init (void) +{ + NOBUG_INIT_FLAG (backend); + NOBUG_INIT_FLAG (file_all); + NOBUG_INIT_FLAG (file); + TRACE (backend); + lumiera_filedescriptor_registry_init (); + + int max_entries = 10; TODO("determine by sysconf (_SC_OPEN_MAX) minus some (big) safety margin " + "add some override to run tests with few filehandles"); + + lumiera_filehandlecache_new (max_entries); + + return 0; +} + +void +lumiera_backend_destroy (void) +{ + TRACE (backend); + lumiera_filedescriptor_registry_destroy (); + lumiera_filehandlecache_delete (); +} diff --git a/src/backend/backend.h b/src/backend/backend.h new file mode 100644 index 000000000..bd4c86815 --- /dev/null +++ b/src/backend/backend.h @@ -0,0 +1,36 @@ +/* + backend - common lumiera backend things + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#ifndef LUMIERA_BACKEND_H +#define LUMIERA_BACKEND_H + +#include + +NOBUG_DECLARE_FLAG (backend); +NOBUG_DECLARE_FLAG (file_all); +NOBUG_DECLARE_FLAG (file); + +int +lumiera_backend_init (void); + +void +lumiera_backend_destroy (void); + +#endif diff --git a/src/backend/file.c b/src/backend/file.c index 7a4aa5050..e9cd208dc 100644 --- a/src/backend/file.c +++ b/src/backend/file.c @@ -23,17 +23,18 @@ #include "lib/safeclib.h" #include "backend/file.h" +#include "backend/filehandlecache.h" #include "backend/filedescriptor.h" #include - -NOBUG_DEFINE_FLAG (lumiera_file); +NOBUG_DEFINE_FLAG_PARENT (file, file_all); LumieraFile lumiera_file_init (LumieraFile self, const char* name, int flags) { - if (!lumiera_filedescriptor_acquire (&self->descriptor, name, flags)) + TRACE (file); + if (!(self->descriptor = lumiera_filedescriptor_acquire (name, flags))) return NULL; self->name = lumiera_strndup (name, PATH_MAX); @@ -43,7 +44,8 @@ lumiera_file_init (LumieraFile self, const char* name, int flags) LumieraFile lumiera_file_destroy (LumieraFile self) { - lumiera_reference_destroy (&self->descriptor); + TRACE (file); + lumiera_filedescriptor_release (self->descriptor); free ((void*)self->name); return self; } @@ -52,6 +54,7 @@ lumiera_file_destroy (LumieraFile self) LumieraFile lumiera_file_new (const char* name, int flags) { + TRACE (file); LumieraFile self = lumiera_malloc (sizeof (lumiera_file)); return lumiera_file_init (self, name, flags); } @@ -59,6 +62,48 @@ lumiera_file_new (const char* name, int flags) void lumiera_file_delete (LumieraFile self) { + TRACE (file); free (lumiera_file_destroy (self)); } + +int +lumiera_file_handle_acquire (LumieraFile self) +{ + TRACE (file); + REQUIRE (self); + REQUIRE (self->descriptor); + REQUIRE (fhcache); + + LUMIERA_MUTEX_SECTION (file, self->descriptor->rh, &self->descriptor->lock) + { + if (!self->descriptor->handle) + /* no handle yet, get a new one */ + lumiera_filehandlecache_handle_acquire (fhcache, self->descriptor); + else + lumiera_filehandlecache_checkout (fhcache, self->descriptor->handle); + + if (self->descriptor->handle->fd == -1) + { + TODO ("stat handling/update"); + self->descriptor->handle->fd = open (self->name, self->descriptor->flags); + if (self->descriptor->handle->fd == -1) + { + LUMIERA_ERROR_SET (file, ERRNO); + } + } + } + + return self->descriptor->handle->fd; +} + +void +lumiera_file_handle_release (LumieraFile self) +{ + TRACE (file); + + LUMIERA_MUTEX_SECTION (file, self->descriptor->rh, &self->descriptor->lock) + { + lumiera_filehandlecache_checkin (fhcache, self->descriptor->handle); + } +} diff --git a/src/backend/file.h b/src/backend/file.h index 5018d321a..60c35447c 100644 --- a/src/backend/file.h +++ b/src/backend/file.h @@ -26,7 +26,8 @@ #include "lib/mutex.h" #include "lib/llist.h" #include "lib/error.h" -#include "lib/references.h" + +NOBUG_DECLARE_FLAG (file); /** * @file File management @@ -47,18 +48,18 @@ typedef lumiera_file* LumieraFile; #include "backend/filedescriptor.h" - -NOBUG_DECLARE_FLAG (lumiera_file); - #define LUMIERA_FILE_READONLY (O_RDONLY | O_LARGEFILE | O_NOATIME) #define LUMIERA_FILE_READWRITE (O_RDWR | O_LARGEFILE | O_NOATIME) #define LUMIERA_FILE_CREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_EXCL) #define LUMIERA_FILE_RECREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_TRUNC) +/* creat and excl flags will be masked out for descriptor lookup */ +#define LUMIERA_FILE_MASK ~(O_CREAT | O_EXCL) + struct lumiera_file_struct { const char* name; - struct lumiera_reference_struct descriptor; + LumieraFiledescriptor descriptor; }; /** @@ -86,5 +87,11 @@ void lumiera_file_delete (LumieraFile self); +int +lumiera_file_handle_acquire (LumieraFile self); + +void +lumiera_file_handle_release (LumieraFile self); + #endif diff --git a/src/backend/filedescriptor.c b/src/backend/filedescriptor.c index 0a3d6e048..be166d9c7 100644 --- a/src/backend/filedescriptor.c +++ b/src/backend/filedescriptor.c @@ -23,7 +23,10 @@ #include "lib/safeclib.h" #include "lib/cuckoo.h" +#include "backend/file.h" #include "backend/filedescriptor.h" +#include "backend/filehandle.h" +#include "backend/filehandlecache.h" #include #include @@ -141,6 +144,7 @@ lumiera_filedescriptor_acquire (const char* name, int flags) } int fd; + INFO (filedescriptor, "try creating file: %s", name); fd = creat (name, 0777); if (fd == -1) { diff --git a/src/backend/filehandle.c b/src/backend/filehandle.c new file mode 100644 index 000000000..60d54cf82 --- /dev/null +++ b/src/backend/filehandle.c @@ -0,0 +1,70 @@ +/* + filehandle - filehandle management and caching + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "lib/llist.h" +#include "lib/safeclib.h" + +#include "backend/file.h" +#include "backend/filehandle.h" +#include "backend/filedescriptor.h" + +#include + +NOBUG_DEFINE_FLAG_PARENT (filehandle, file_all); + +LumieraFilehandle +lumiera_filehandle_new () +{ + LumieraFilehandle self = lumiera_malloc (sizeof (lumiera_filehandle)); + TRACE (filehandle, "%p", self); + + llist_init (&self->cachenode); + self->fd = -1; + self->use_cnt = 1; + self->descriptor = NULL; + + return self; +} + + +void* +lumiera_filehandle_destroy_node (LList node) +{ + TRACE (filehandle); + REQUIRE (llist_is_empty (node)); + LumieraFilehandle self = (LumieraFilehandle)node; + REQUIRE (self->use_cnt == 0); + + if (self->fd >= 0) + close (self->fd); + self->fd = -1; + self->descriptor = NULL; + return self; +} + + +int +lumiera_filehandle_get (LumieraFilehandle self) +{ + REQUIRE (self->descriptor); + return -1; +} + diff --git a/src/backend/filehandle.h b/src/backend/filehandle.h index 00b4737c9..54e4d6936 100644 --- a/src/backend/filehandle.h +++ b/src/backend/filehandle.h @@ -24,6 +24,11 @@ #include "lib/error.h" #include "lib/llist.h" +typedef struct lumiera_filehandle_struct lumiera_filehandle; +typedef lumiera_filehandle* LumieraFilehandle; + +#include "backend/filedescriptor.h" + /** * @file Filehandles */ @@ -35,16 +40,17 @@ struct lumiera_filehandle_struct { llist cachenode; - int handle; - //LumieraFile file; - //lumiera_mutex lock; + int fd; + unsigned use_cnt; + LumieraFiledescriptor descriptor; }; -typedef struct lumiera_filehandle_struct lumiera_filehandle; -typedef lumiera_filehandle* LumieraFilehandle; LumieraFilehandle lumiera_filehandle_new (); +int +lumiera_filehandle_get (LumieraFilehandle self); + void* lumiera_filehandle_destroy_node (LList node); diff --git a/src/backend/filehandlecache.c b/src/backend/filehandlecache.c index 98ebdddc9..c629f765b 100644 --- a/src/backend/filehandlecache.c +++ b/src/backend/filehandlecache.c @@ -19,41 +19,60 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "lib/safeclib.h" + +#include "backend/file.h" #include "backend/filehandlecache.h" -NOBUG_DEFINE_FLAG (lumiera_filehandlecache); +NOBUG_DEFINE_FLAG_PARENT (filehandlecache, file_all); /* errors */ LUMIERA_ERROR_DEFINE (FILEHANDLECACHE_NOHANDLE, "No filehandle available"); -/**/ +LumieraFilehandlecache fhcache = NULL; -LumieraFilehandlecache -lumiera_filehandlecache_init (LumieraFilehandlecache self, int max_entries) + +void +lumiera_filehandlecache_new (int max_entries) { - lumiera_mrucache_init (&self->cache, lumiera_filehandle_destroy_node); - self->available =max_entries; - lumiera_mutex_init (&self->lock); - return self; + if (!fhcache) + { + NOBUG_INIT_FLAG (filehandlecache); + fhcache = lumiera_malloc (sizeof (lumiera_filehandlecache)); + lumiera_mrucache_init (&fhcache->cache, lumiera_filehandle_destroy_node); + fhcache->available = max_entries; + fhcache->checked_out = 0; + lumiera_mutex_init (&fhcache->lock); + RESOURCE_ANNOUNCE (filehandlecache, "mutex", "filehandlecache", fhcache, fhcache->rh); + } + else + NOTREACHED; } -LumieraFilehandlecache -lumiera_filehandlecache_destroy (LumieraFilehandlecache self) + +void +lumiera_filehandlecache_delete (void) { - self->available += self->cache.cached; - lumiera_mrucache_destroy (&self->cache); - lumiera_mutex_destroy (&self->lock); - return self; + if (fhcache) + { + REQUIRE (!fhcache->checked_out, "Filehandles in use at shutdown"); + RESOURCE_FORGET (filehandlecache, fhcache->rh); + lumiera_mrucache_destroy (&fhcache->cache); + lumiera_mutex_destroy (&fhcache->lock); + free (fhcache); + fhcache = NULL; + } } LumieraFilehandle -lumiera_filehandlecache_filehandle_acquire (LumieraFilehandlecache self) +lumiera_filehandlecache_handle_acquire (LumieraFilehandlecache self, LumieraFiledescriptor desc) { - LumieraFilehandle ret; - LUMIERA_MUTEX_SECTION (&self->lock) + TRACE (filehandlecache); + LumieraFilehandle ret = NULL; + LUMIERA_MUTEX_SECTION (filehandlecache, self->rh, &self->lock) { if (self->available <= 0 && self->cache.cached) { @@ -65,19 +84,58 @@ lumiera_filehandlecache_filehandle_acquire (LumieraFilehandlecache self) } else { - /* allocate new filehandle if we are below the limit or no cached handles where available (overallocating) */ + /* allocate new filehandle if we are below the limit or no cached handles are available (overallocating) */ ret = lumiera_filehandle_new (); if (!ret) - LUMIERA_ERROR_SET (lumiera_filehandlecache, FILEHANDLECACHE_NOHANDLE); + LUMIERA_ERROR_SET (filehandlecache, FILEHANDLECACHE_NOHANDLE); else --self->available; } + ret->use_cnt = 1; + ret->descriptor = desc; + desc->handle = ret; + ++self->checked_out; } return ret; } -void -lumiera_filehandlecache_add (LumieraFilehandlecache self, LumieraFilehandle handle) + +LumieraFilehandle +lumiera_filehandlecache_checkout (LumieraFilehandlecache self, LumieraFilehandle handle) { - UNIMPLEMENTED (""); + REQUIRE (self); + REQUIRE (handle); + /* This function is called with the associated descriptor locked, nothing can modify 'handle' */ + if (!handle->use_cnt) + { + /* lock cache and checkout */ + LUMIERA_MUTEX_SECTION (filehandlecache, self->rh, &self->lock) + { + lumiera_mrucache_checkout (&self->cache, &handle->cachenode); + } + } + ++handle->use_cnt; + ++self->checked_out; + + return handle; } + +void +lumiera_filehandlecache_checkin (LumieraFilehandlecache self, LumieraFilehandle handle) +{ + REQUIRE (self); + REQUIRE (handle); + REQUIRE (handle->use_cnt); + + /* This function is called with the associated descriptor locked, nothing can modify 'self' */ + if (!--handle->use_cnt) + { + /* lock cache and checin */ + LUMIERA_MUTEX_SECTION (filehandlecache, self->rh, &self->lock) + { + --self->checked_out; + lumiera_mrucache_checkin (&self->cache, &handle->cachenode); + } + } +} + diff --git a/src/backend/filehandlecache.h b/src/backend/filehandlecache.h index 40386defe..8d8de44cb 100644 --- a/src/backend/filehandlecache.h +++ b/src/backend/filehandlecache.h @@ -25,6 +25,9 @@ #include "lib/mrucache.h" #include "lib/mutex.h" +typedef struct lumiera_filehandlecache_struct lumiera_filehandlecache; +typedef lumiera_filehandlecache* LumieraFilehandlecache; + #include "backend/filehandle.h" /** @@ -43,55 +46,55 @@ struct lumiera_filehandlecache_struct { lumiera_mrucache cache; int available; + int checked_out; lumiera_mutex lock; + RESOURCE_HANDLE (rh); }; -typedef struct lumiera_filehandlecache_struct lumiera_filehandlecache; -typedef lumiera_filehandlecache* LumieraFilehandlecache; +extern LumieraFilehandlecache fhcache; /** - * Initializes a filehandle cache. - * @param self pointer to the cache to be initialized + * Initializes the filehandle cache. * @param max_entries number how much filehandles shall be managed - * @return self as given * The number of elements the cache can hold is static and should be - * determined by sysconf (_SC_OPEN_MAX) minus some safety margin. + * determined by sysconf (_SC_OPEN_MAX) minus some (big) safety margin. */ -LumieraFilehandlecache -lumiera_filehandlecache_init (LumieraFilehandlecache self, int max_entries); +void +lumiera_filehandlecache_new (int max_entries); /** - * Destroy a filehandle cache. - * @param self the cache to be destroyed - * @return self as given to the now uninitialized! cache + * Delete the filehandle cache. * No filehandles in the cache must be locked, this would be a fatal error. * The handles are closed automatically. */ -LumieraFilehandlecache -lumiera_filehandlecache_destroy (LumieraFilehandlecache self); +void +lumiera_filehandlecache_delete (void); /** * Get a fresh filehandle. * @param self pointer to the cache * @return the new filehandle - * one must call lumiera_mutexacquirer_unlock (&lock) to free the lock on the handle when done */ LumieraFilehandle -lumiera_filehandlecache_filehandle_acquire (LumieraFilehandlecache self); +lumiera_filehandlecache_handle_acquire (LumieraFilehandlecache self, LumieraFiledescriptor desc); /** - * Add filehande back to cache. + * Add filehande back to cache, the filehandle becomes subject of aging. * @param self pointer to the cache * @param handle filehandle to be put back */ void -lumiera_filehandlecache_add (LumieraFilehandlecache self, LumieraFilehandle handle); +lumiera_filehandlecache_add_filehandle (LumieraFilehandlecache self, LumieraFilehandle handle); /** - * + * Remove a filehandle from cache aging + * Filehandles which are subject of cache aging must be checked out before they can be used + * */ LumieraFilehandle -lumiera_filehandlecache_remove (LumieraFilehandlecache self, int fd); +lumiera_filehandlecache_checkout (LumieraFilehandlecache self, LumieraFilehandle handle); +void +lumiera_filehandlecache_checkin (LumieraFilehandlecache self, LumieraFilehandle handle); #endif diff --git a/tests/20filehandle.tests b/tests/20filehandle.tests new file mode 100644 index 000000000..068304f54 --- /dev/null +++ b/tests/20filehandle.tests @@ -0,0 +1,7 @@ + +TESTING "Filehandle management" ./test-filehandles + + +TEST "basic filehandle usage" basic < + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#define _GNU_SOURCE + +#include "lib/llist.h" + +#include "backend/backend.h" +#include "backend/filehandlecache.h" + +#include "tests/test.h" + +TESTS_BEGIN + +TEST ("basic") +{ + lumiera_backend_init (); + LumieraFile file = lumiera_file_new (",tmp_testfile", LUMIERA_FILE_CREATE); + + /* get the filehandle */ + int fd = lumiera_file_handle_acquire (file); + + /* we now 'own'it and can use it */ + ENSURE (fd > -1); + printf ("got filehandle #%d\n", fd); + + /* put it into aging, can't use anymore */ + lumiera_file_handle_release (file); + + lumiera_file_delete (file); + lumiera_backend_destroy (); +} + + +TEST ("more") +{ + lumiera_backend_init (); + lumiera_backend_destroy (); +} + +TESTS_END From dd63a0e1902a8a49f3b730b3729046e42097abdd Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 8 Apr 2008 07:46:25 +0200 Subject: [PATCH 104/245] filedescriptor cleanup and fixes basically working now, flag masking is not complete yet. --- src/backend/filedescriptor.c | 58 ++++++++++++++------------------ tests/20filehandle.tests | 6 ++++ tests/backend/test-filehandles.c | 31 +++++++++++++++++ 3 files changed, 63 insertions(+), 32 deletions(-) diff --git a/src/backend/filedescriptor.c b/src/backend/filedescriptor.c index be166d9c7..0df739670 100644 --- a/src/backend/filedescriptor.c +++ b/src/backend/filedescriptor.c @@ -110,54 +110,48 @@ lumiera_filedescriptor_registry_destroy (void) LumieraFiledescriptor lumiera_filedescriptor_acquire (const char* name, int flags) { - TRACE (filedescriptor); + TRACE (filedescriptor, "%s", name); REQUIRE (registry, "not initialized"); - UNCHECKED; + lumiera_mutexacquirer registry_lock; lumiera_mutexacquirer_init_mutex (®istry_lock, ®istry_mutex, LUMIERA_LOCKED); lumiera_filedescriptor fdesc; fdesc.flags = flags&LUMIERA_FILE_MASK; - for (int retry = 0; !retry; ++retry) + if (stat (name, &fdesc.stat) != 0) { - if (stat (name, &fdesc.stat) == 0) - break; - else + if (errno == ENOENT && flags&O_CREAT) { - if (errno == ENOENT && flags&O_CREAT) + char* dir = lumiera_tmpbuf_strndup (name, PATH_MAX); + char* slash = dir; + while ((slash = strchr (slash+1, '/'))) { - INFO (filedescriptor, "try creating file: %s %d", name, PATH_MAX); - char* dir = lumiera_tmpbuf_strndup (name, PATH_MAX); - char* slash = dir; - - while ((slash = strchr (slash+1, '/'))) - { - *slash = '\0'; - INFO (filedescriptor, "try creating dir: %s", dir); - if (mkdir (dir, 0777) == -1) - { - LUMIERA_ERROR_SET (filedescriptor, ERRNO); - goto efile; - } - *slash = '/'; - } - - int fd; - INFO (filedescriptor, "try creating file: %s", name); - fd = creat (name, 0777); - if (fd == -1) + *slash = '\0'; + INFO (filedescriptor, "try creating dir: %s", dir); + if (mkdir (dir, 0777) == -1 && errno != EEXIST) { LUMIERA_ERROR_SET (filedescriptor, ERRNO); goto efile; } - close (fd); - continue; /* will now retry the fstat once */ + *slash = '/'; + } + int fd; + INFO (filedescriptor, "try creating file: %s", name); + fd = creat (name, 0777); + if (fd == -1) + { + LUMIERA_ERROR_SET (filedescriptor, ERRNO); + goto efile; + } + close (fd); + if (stat (name, &fdesc.stat) != 0) + { + /* finally, no luck */ + LUMIERA_ERROR_SET (filedescriptor, ERRNO); + goto efile; } } - /* finally, no luck */ - LUMIERA_ERROR_SET (filedescriptor, ERRNO); - goto efile; } /* lookup/create descriptor */ diff --git a/tests/20filehandle.tests b/tests/20filehandle.tests index 068304f54..0365bbffc 100644 --- a/tests/20filehandle.tests +++ b/tests/20filehandle.tests @@ -5,3 +5,9 @@ TESTING "Filehandle management" ./test-filehandles TEST "basic filehandle usage" basic < -1); + printf ("got filehandle #%d\n", fds[i]); + } + + /* put them into aging, can't use anymore */ + for (int i=0; i<100; ++i) + { + lumiera_file_handle_release (files[i]); + } + + /* cleanup */ + for (int i=0; i<100; ++i) + { + lumiera_file_delete (files[i]); + } + lumiera_backend_destroy (); } From 8311316a9210ff719c1c061d5899c07cfff76447 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 9 Apr 2008 07:56:39 +0200 Subject: [PATCH 105/245] Doxydocing for the filehandling stuff --- src/backend/file.h | 34 +++++++++++++++++++++++++----- src/backend/filedescriptor.c | 25 +++++++--------------- src/backend/filedescriptor.h | 39 +++++++++++++++++++++++++++++++++++ src/backend/filehandle.h | 15 ++++++++++++-- src/backend/filehandlecache.h | 13 +++++++++--- 5 files changed, 98 insertions(+), 28 deletions(-) diff --git a/src/backend/file.h b/src/backend/file.h index 60c35447c..9e774b94d 100644 --- a/src/backend/file.h +++ b/src/backend/file.h @@ -63,33 +63,57 @@ struct lumiera_file_struct }; /** - * + * Initialize a file structure. + * @param self pointer to the file structure + * @param name filename + * @param flags open flags + * @return self */ LumieraFile lumiera_file_init (LumieraFile self, const char* name, int flags); /** - * + * Destroy a file structure. + * frees all associated resources, releases the filedescriptor etc. + * @param self file structure to be destroyed + * @return self */ LumieraFile lumiera_file_destroy (LumieraFile self); /** - * + * Allocate a new file structure. + * @param name filename + * @param flags open flags + * @return new file structure */ LumieraFile lumiera_file_new (const char* name, int flags); /** - * + * Frees a file structure. + * @param self file structure to be freed */ void lumiera_file_delete (LumieraFile self); - +/** + * Get a POSIX filehandle for a file. + * Filehandles are opened on demand and must be acquired for use. + * Using filehandles is refcounted and might be nested. + * After using them they must be released which puts them back into filehandlecache aging. + * @param self file structure + * @return POSIX filehandle or -1 on error, check lumiera_error() to retrieve the errorcode + * Currently only LUMIERA_ERROR_ERRNO will be raised but this might change in future. + * Opening files can fail for many reasons and at any time! + */ int lumiera_file_handle_acquire (LumieraFile self); +/** + * Put filehandle back into cache aging. + * @param self file which handle to be released + */ void lumiera_file_handle_release (LumieraFile self); diff --git a/src/backend/filedescriptor.c b/src/backend/filedescriptor.c index 0df739670..5a513a7b4 100644 --- a/src/backend/filedescriptor.c +++ b/src/backend/filedescriptor.c @@ -82,6 +82,7 @@ lumiera_filedescriptor_registry_init (void) { NOBUG_INIT_FLAG (filedescriptor); TRACE (filedescriptor); + REQUIRE (!registry); registry = cuckoo_new (h1, h2, h3, cmp, sizeof (LumieraFiledescriptor), @@ -95,18 +96,12 @@ lumiera_filedescriptor_registry_destroy (void) { TRACE (filedescriptor); REQUIRE (!cuckoo_nelements (registry)); - cuckoo_free (registry); + if (registry) + cuckoo_free (registry); + registry = NULL; } -/** - * Find existing filedescriptor or create one - * @param descriptor strong reference to be initialized with the filedescriptor, - * a filedescriptor will be deleted when its last string reference gets deleted. - * @param name name of the file - * @param flags opening flags for the filedescriptor - * @return descriptor on success or NULL on error - */ LumieraFiledescriptor lumiera_filedescriptor_acquire (const char* name, int flags) { @@ -184,6 +179,7 @@ lumiera_filedescriptor_acquire (const char* name, int flags) return NULL; } + void lumiera_filedescriptor_release (LumieraFiledescriptor self) { @@ -192,11 +188,7 @@ lumiera_filedescriptor_release (LumieraFiledescriptor self) lumiera_filedescriptor_delete (self); } -/** - * Allocate a new filedescriptor cloned from a template - * @param template the source filedescriptor - * @return the constrccted filedescriptor - */ + LumieraFiledescriptor lumiera_filedescriptor_new (LumieraFiledescriptor template) { @@ -219,10 +211,7 @@ lumiera_filedescriptor_new (LumieraFiledescriptor template) return self; } -/** - * delete a filedescriptor and free its resources - * @param descriptor filedescriptor to be freed - */ + void lumiera_filedescriptor_delete (LumieraFiledescriptor self) { diff --git a/src/backend/filedescriptor.h b/src/backend/filedescriptor.h index 817e8bc13..8ae19a04d 100644 --- a/src/backend/filedescriptor.h +++ b/src/backend/filedescriptor.h @@ -36,6 +36,12 @@ typedef lumiera_filedescriptor* LumieraFiledescriptor; #include "backend/filehandle.h" #include "backend/file.h" +/** + * @file Filedescriptors + * Filedescriptors are the underlying working horse in accessing files. + */ + + struct lumiera_filedescriptor_struct { @@ -52,21 +58,54 @@ struct lumiera_filedescriptor_struct RESOURCE_HANDLE (rh); }; +/** + * Initialize the global filedescriptor registry. + * All filedescriptors are looked up by dev/ino/open-flags in a hashtable. Opening hardlinked + * files will be targeted to the same filedescriptor. + * This function never fails but dies on error. + */ void lumiera_filedescriptor_registry_init (void); +/** + * Destroy and free the global filedescriptor registry. + * Never fails. + */ void lumiera_filedescriptor_registry_destroy (void); + +/** + * Find existing filedescriptor or create one + * @param name name of the file + * @param flags opening flags for the filedescriptor + * @return descriptor on success or NULL on error + */ LumieraFiledescriptor lumiera_filedescriptor_acquire (const char* name, int flags); + +/** + * Release a filedescriptor. + * @param self filedescriptor to be released + */ void lumiera_filedescriptor_release (LumieraFiledescriptor self); + +/** + * Allocate a new filedescriptor cloned from a template + * @param template the source filedescriptor + * @return the constrccted filedescriptor + */ LumieraFiledescriptor lumiera_filedescriptor_new (LumieraFiledescriptor template); +/** + * Delete a filedescriptor + * Called whenever its reference count drops to zero. + * @param self the filedescriptor to be deleted + */ void lumiera_filedescriptor_delete (LumieraFiledescriptor self); diff --git a/src/backend/filehandle.h b/src/backend/filehandle.h index 54e4d6936..47fd0f3a7 100644 --- a/src/backend/filehandle.h +++ b/src/backend/filehandle.h @@ -31,6 +31,9 @@ typedef lumiera_filehandle* LumieraFilehandle; /** * @file Filehandles + * Filehandles manage the underlying POSIX filehandle for a filedescriptor. + * Since we want to support handling of more files than POSIX filehandles are available on a common system + * the filehandles are opened, cached and closed on demand, see 'filehandlecache'. */ @@ -45,12 +48,20 @@ struct lumiera_filehandle_struct LumieraFiledescriptor descriptor; }; +/** + * Allocate a new filehandle structure. + * @return new filehandle structure + */ LumieraFilehandle lumiera_filehandle_new (); -int -lumiera_filehandle_get (LumieraFilehandle self); +/** + * destroy the resources associated eith a filehandle structure. + * This function is used by the filehandlecache to recycle filehandle structs. + * @param node pointer to the cachenode member of a struct filehandle + * @return pointer to the start of the memory of the destroyed filehandle + */ void* lumiera_filehandle_destroy_node (LList node); diff --git a/src/backend/filehandlecache.h b/src/backend/filehandlecache.h index 8d8de44cb..fd6ddfd13 100644 --- a/src/backend/filehandlecache.h +++ b/src/backend/filehandlecache.h @@ -35,10 +35,10 @@ typedef lumiera_filehandlecache* LumieraFilehandlecache; * The number of filehandles a program can held open is usually limited, since we want to support * using a less limited number of files and closing/opening for each operation is expensive, we * provide a cache to keep the most frequent used files open and gracefully close/recycle unused filehandles. + * The filehandlecache defined here protects all operations on the cache with a mutex. */ - /* File handle cache manages file handles */ @@ -88,12 +88,19 @@ lumiera_filehandlecache_add_filehandle (LumieraFilehandlecache self, LumieraFile /** * Remove a filehandle from cache aging - * Filehandles which are subject of cache aging must be checked out before they can be used - * + * Filehandles which are subject of cache aging must be checked out before they can be used. + * @param self the filehandlecache + * @param handle the filehandle to be checked out */ LumieraFilehandle lumiera_filehandlecache_checkout (LumieraFilehandlecache self, LumieraFilehandle handle); +/** + * Put a filehandle into the cache + * Filehandles which are checked in are subject of cache aging and might get destroyed and reused. + * @param self the filehandlecache + * @param handle the filehandle to be checked in + */ void lumiera_filehandlecache_checkin (LumieraFilehandlecache self, LumieraFilehandle handle); From 4ed2fe9e7cf4503b4f94f5b9b2368c07b52acbee Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 9 Apr 2008 07:58:29 +0200 Subject: [PATCH 106/245] few more todos in the wiki, plan for a player in roadmap --- wiki/todo.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wiki/todo.html b/wiki/todo.html index e66ec929f..763c8a80a 100644 --- a/wiki/todo.html +++ b/wiki/todo.html @@ -3350,6 +3350,11 @@ The idea here is to show and measure backend and scheduler performance backend to be done. +
+
Use the backend, gmerlin/avdecoder and a Player widget to playback videos. This should be a small application which can open and playback many videos from on instance in parallel. Later on scrubbing for this videos might be supported.
+
+The idea here is to show and measure backend and scheduler performance and beeing a proof of concept for the design. It will run independent of the Proc layer but needs quite some work on the backend to be done.
+
From 00b9dff106d018c03a704e3b5db1e92467c25f3b Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Thu, 10 Apr 2008 02:40:34 +0200 Subject: [PATCH 107/245] Doxygen config update * set EXPORT_ALL=NO to leave out undcoumented entities. * Fix a lot @file directives --- src/backend/file.h | 3 ++- src/backend/filedescriptor.h | 4 +++- src/backend/filehandle.h | 3 ++- src/backend/filehandlecache.h | 3 ++- src/lib/condition.c | 3 ++- src/lib/condition.h | 3 ++- src/lib/cuckoo.h | 3 ++- src/lib/error.c | 3 ++- src/lib/error.h | 3 ++- src/lib/llist.h | 3 ++- src/lib/locking.h | 3 ++- src/lib/mrucache.h | 3 ++- src/lib/mutex.c | 3 ++- src/lib/mutex.h | 3 ++- src/lib/plugin.c | 3 ++- src/lib/plugin.h | 3 ++- src/lib/references.c | 3 ++- src/lib/references.h | 3 ++- src/lib/rwlock.c | 3 ++- src/lib/rwlock.h | 3 ++- src/lib/safeclib.c | 3 ++- src/lib/safeclib.h | 3 ++- 22 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/backend/file.h b/src/backend/file.h index 9e774b94d..175b93e9d 100644 --- a/src/backend/file.h +++ b/src/backend/file.h @@ -30,7 +30,8 @@ NOBUG_DECLARE_FLAG (file); /** - * @file File management + * @file + * File management * Handling Files is splitted into different classes: * 1. The 'lumiera_file' class which acts as interface to the outside for managing files. * 'lumiera_file' is addressed by the name of the file. Since files can have more than one name (hardlinks) diff --git a/src/backend/filedescriptor.h b/src/backend/filedescriptor.h index 8ae19a04d..4789f9ce2 100644 --- a/src/backend/filedescriptor.h +++ b/src/backend/filedescriptor.h @@ -37,8 +37,10 @@ typedef lumiera_filedescriptor* LumieraFiledescriptor; #include "backend/file.h" /** - * @file Filedescriptors + * @file + * Filedescriptors. * Filedescriptors are the underlying working horse in accessing files. + * All information associated with managing a file is kept here. */ diff --git a/src/backend/filehandle.h b/src/backend/filehandle.h index 47fd0f3a7..e1b02b2e4 100644 --- a/src/backend/filehandle.h +++ b/src/backend/filehandle.h @@ -30,7 +30,8 @@ typedef lumiera_filehandle* LumieraFilehandle; #include "backend/filedescriptor.h" /** - * @file Filehandles + * @file + * Filehandles. * Filehandles manage the underlying POSIX filehandle for a filedescriptor. * Since we want to support handling of more files than POSIX filehandles are available on a common system * the filehandles are opened, cached and closed on demand, see 'filehandlecache'. diff --git a/src/backend/filehandlecache.h b/src/backend/filehandlecache.h index fd6ddfd13..25964f986 100644 --- a/src/backend/filehandlecache.h +++ b/src/backend/filehandlecache.h @@ -31,7 +31,8 @@ typedef lumiera_filehandlecache* LumieraFilehandlecache; #include "backend/filehandle.h" /** - * @file Filehandle management and caching + * @file + * Filehandle management and caching * The number of filehandles a program can held open is usually limited, since we want to support * using a less limited number of files and closing/opening for each operation is expensive, we * provide a cache to keep the most frequent used files open and gracefully close/recycle unused filehandles. diff --git a/src/lib/condition.c b/src/lib/condition.c index 1bfa2ef96..60e8b6f10 100644 --- a/src/lib/condition.c +++ b/src/lib/condition.c @@ -22,7 +22,8 @@ #include "lib/condition.h" /** - * @file Condition variables + * @file + * Condition variables */ LUMIERA_ERROR_DEFINE (CONDITION_DESTROY, "condition destroy failed"); diff --git a/src/lib/condition.h b/src/lib/condition.h index ffc00523c..dd92f326b 100644 --- a/src/lib/condition.h +++ b/src/lib/condition.h @@ -25,7 +25,8 @@ #include "lib/locking.h" /** - * @file Condition variables, header + * @file + * Condition variables, header */ LUMIERA_ERROR_DECLARE (CONDITION_DESTROY); diff --git a/src/lib/cuckoo.h b/src/lib/cuckoo.h index 63b6d260d..323b5cc75 100644 --- a/src/lib/cuckoo.h +++ b/src/lib/cuckoo.h @@ -22,7 +22,8 @@ #define CUCKOO_H /** - * @file Cuckoo hashing + * @file + * Cuckoo hashing * This hashing gives guaranteed O(1) lookup complexity and amortized O(1) insert and remove complexity. * Hash tables by default grow and shrink automatically. It is posible to preallocate entries and turn * automatic shrinking off taking out the memory management factors for insert and remove operations. diff --git a/src/lib/error.c b/src/lib/error.c index 81e24bad8..b2bc390b6 100644 --- a/src/lib/error.c +++ b/src/lib/error.c @@ -24,7 +24,8 @@ #include "lib/error.h" /** - * @file C Error handling in Lumiera. + * @file + * C Error handling in Lumiera. */ diff --git a/src/lib/error.h b/src/lib/error.h index e71c0cdfa..1eeb42dda 100644 --- a/src/lib/error.h +++ b/src/lib/error.h @@ -31,7 +31,8 @@ extern "C" { #include /** - * @file C Error handling in Lumiera, header. + * @file + * C Error handling in Lumiera, header. */ diff --git a/src/lib/llist.h b/src/lib/llist.h index efb3f5202..128a3e826 100644 --- a/src/lib/llist.h +++ b/src/lib/llist.h @@ -27,7 +27,8 @@ #include /** - * @file Intrusive cyclic double linked list + * @file + * Intrusive cyclic double linked list * There is only one node type which contains a forward and a backward pointer. In a empty initialized node, * this pointers point to the node itself. Note that these pointers can never ever become NULL. * This lists are used by using one node as 'root' node where its both pointers are the head/tail pointer to the actual list. diff --git a/src/lib/locking.h b/src/lib/locking.h index f62dd6c29..3c4d497d8 100644 --- a/src/lib/locking.h +++ b/src/lib/locking.h @@ -34,7 +34,8 @@ LUMIERA_ERROR_DECLARE (MUTEX_UNLOCK); LUMIERA_ERROR_DECLARE (MUTEX_DESTROY); /** - * @file Shared declarations for all locking primitives. + * @file + * Shared declarations for all locking primitives. */ /** diff --git a/src/lib/mrucache.h b/src/lib/mrucache.h index c81bd7599..08654754f 100644 --- a/src/lib/mrucache.h +++ b/src/lib/mrucache.h @@ -27,7 +27,8 @@ #include /** - * @file Most recent used cache + * @file + * Most recent used cache * Elements (addressed by a LList node) are either checked in the cache and thereby subject of aging * or checked out under control of the user. Most operations require that the chache is locked. This locking * must be done from elsewhere. diff --git a/src/lib/mutex.c b/src/lib/mutex.c index 009502e5a..b7c5f1844 100644 --- a/src/lib/mutex.c +++ b/src/lib/mutex.c @@ -22,7 +22,8 @@ #include "lib/mutex.h" /** - * @file Mutual exclusion locking. + * @file + * Mutual exclusion locking. */ LUMIERA_ERROR_DEFINE (MUTEX_LOCK, "Mutex locking failed"); diff --git a/src/lib/mutex.h b/src/lib/mutex.h index ca48ea592..f19058e7a 100644 --- a/src/lib/mutex.h +++ b/src/lib/mutex.h @@ -25,7 +25,8 @@ #include "lib/locking.h" /** - * @file Mutual exclusion locking, header. + * @file + * Mutual exclusion locking, header. */ #define LUMIERA_MUTEX_SECTION(flag, handle, mutex) \ RESOURCE_HANDLE (rh_##__LINE__##_); \ diff --git a/src/lib/plugin.c b/src/lib/plugin.c index 8345d9887..1f5e8576e 100644 --- a/src/lib/plugin.c +++ b/src/lib/plugin.c @@ -31,7 +31,8 @@ #include "safeclib.h" /** - * @file Plugin loader. + * @file + * Plugin loader. */ diff --git a/src/lib/plugin.h b/src/lib/plugin.h index f8916ae96..54dad6372 100644 --- a/src/lib/plugin.h +++ b/src/lib/plugin.h @@ -33,7 +33,8 @@ extern "C" { #include "error.h" /** - * @file Plugin loader, header. + * @file + * Plugin loader, header. */ diff --git a/src/lib/references.c b/src/lib/references.c index 3e9d5f260..925258377 100644 --- a/src/lib/references.c +++ b/src/lib/references.c @@ -22,7 +22,8 @@ #include "lib/safeclib.h" /** - * @file Strong and Weak references + * @file + * Strong and Weak references * Strong references keep some object alive while they existing * Weak references become invalidated when the referenced object gets destroyed * diff --git a/src/lib/references.h b/src/lib/references.h index 3e00457e7..6ad65d62f 100644 --- a/src/lib/references.h +++ b/src/lib/references.h @@ -25,7 +25,8 @@ #include /** - * @file Strong and Weak references, header. + * @file + * Strong and Weak references, header. */ diff --git a/src/lib/rwlock.c b/src/lib/rwlock.c index 092c7b54b..077ff9766 100644 --- a/src/lib/rwlock.c +++ b/src/lib/rwlock.c @@ -29,7 +29,8 @@ LUMIERA_ERROR_DEFINE(RWLOCK_RLOCK, "rlock"); LUMIERA_ERROR_DEFINE(RWLOCK_WLOCK, "wlock"); /** - * @file Read/write locks. + * @file + * Read/write locks. */ diff --git a/src/lib/rwlock.h b/src/lib/rwlock.h index 5e121fbcc..d58627dda 100644 --- a/src/lib/rwlock.h +++ b/src/lib/rwlock.h @@ -39,7 +39,8 @@ LUMIERA_ERROR_DECLARE(RWLOCK_RLOCK); LUMIERA_ERROR_DECLARE(RWLOCK_WLOCK); /** - * @file Read/write locks, header. + * @file + * Read/write locks, header. */ diff --git a/src/lib/safeclib.c b/src/lib/safeclib.c index 0e82e2dc0..f500ea71c 100644 --- a/src/lib/safeclib.c +++ b/src/lib/safeclib.c @@ -27,7 +27,8 @@ #include /** - * @file Portable and safe wrapers around some clib functions and some tools + * @file + * Portable and safe wrapers around some clib functions and some tools */ LUMIERA_ERROR_DEFINE (NO_MEMORY, "Out of Memory!"); diff --git a/src/lib/safeclib.h b/src/lib/safeclib.h index f486ed056..6fc532239 100644 --- a/src/lib/safeclib.h +++ b/src/lib/safeclib.h @@ -24,7 +24,8 @@ #include /** - * @file Portable and safe wrapers around some clib functions and some tools + * @file + * Portable and safe wrapers around some clib functions and some tools */ LUMIERA_ERROR_DECLARE(NO_MEMORY); From c4816c39fdc802a4db00e65dfab12077e18970c3 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Thu, 10 Apr 2008 06:03:21 +0200 Subject: [PATCH 108/245] Proper flag and stat handling for files Filedescriptors create files at construction, each later access becomes a reopen on the now existing file. file_handle_acquire() reopens the file to gain a handle when required and checks that the file is really the one we expected (ino and dev num) --- src/backend/file.c | 29 ++++++++++++++++++++++++++--- src/backend/file.h | 3 ++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/backend/file.c b/src/backend/file.c index e9cd208dc..861f3ce21 100644 --- a/src/backend/file.c +++ b/src/backend/file.c @@ -27,9 +27,13 @@ #include "backend/filedescriptor.h" #include +#include NOBUG_DEFINE_FLAG_PARENT (file, file_all); +LUMIERA_ERROR_DEFINE(FILE_CHANGED, "File changed unexpected"); + + LumieraFile lumiera_file_init (LumieraFile self, const char* name, int flags) { @@ -85,12 +89,31 @@ lumiera_file_handle_acquire (LumieraFile self) if (self->descriptor->handle->fd == -1) { - TODO ("stat handling/update"); - self->descriptor->handle->fd = open (self->name, self->descriptor->flags); - if (self->descriptor->handle->fd == -1) + int fd; + fd = open (self->name, self->descriptor->flags & ~(O_EXCL|O_TRUNC|O_CREAT)); + if (fd == -1) { LUMIERA_ERROR_SET (file, ERRNO); + return -1; } + else + { + struct stat st; + if (fstat (fd, &st) == -1) + { + close (fd); + LUMIERA_ERROR_SET (file, ERRNO); + return -1; + } + else if (self->descriptor->stat.st_dev != st.st_dev || self->descriptor->stat.st_ino != st.st_ino) + { + close (fd); + /* Woops this is not the file we expected to use */ + LUMIERA_ERROR_SET (file, FILE_CHANGED); + return -1; + } + } + self->descriptor->handle->fd = fd; } } diff --git a/src/backend/file.h b/src/backend/file.h index 175b93e9d..71ca15751 100644 --- a/src/backend/file.h +++ b/src/backend/file.h @@ -29,6 +29,8 @@ NOBUG_DECLARE_FLAG (file); +LUMIERA_ERROR_DECLARE(FILE_CHANGED); + /** * @file * File management @@ -48,7 +50,6 @@ typedef lumiera_file* LumieraFile; #include "backend/filehandle.h" #include "backend/filedescriptor.h" - #define LUMIERA_FILE_READONLY (O_RDONLY | O_LARGEFILE | O_NOATIME) #define LUMIERA_FILE_READWRITE (O_RDWR | O_LARGEFILE | O_NOATIME) #define LUMIERA_FILE_CREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_EXCL) From 444b142d854ed51c727db86dd2fd280189e107df Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Thu, 10 Apr 2008 06:07:04 +0200 Subject: [PATCH 109/245] Correct File flag masking The hash lookup needs to ignore O_EXCL|O_TRUNC|O_CREAT as well as file reopening must not use this flags. --- src/backend/file.c | 2 +- src/backend/file.h | 2 +- src/backend/filedescriptor.c | 15 +++++++++------ src/backend/filedescriptor.h | 1 - 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/backend/file.c b/src/backend/file.c index 861f3ce21..e315537fc 100644 --- a/src/backend/file.c +++ b/src/backend/file.c @@ -90,7 +90,7 @@ lumiera_file_handle_acquire (LumieraFile self) if (self->descriptor->handle->fd == -1) { int fd; - fd = open (self->name, self->descriptor->flags & ~(O_EXCL|O_TRUNC|O_CREAT)); + fd = open (self->name, self->descriptor->flags & LUMIERA_FILE_MASK); if (fd == -1) { LUMIERA_ERROR_SET (file, ERRNO); diff --git a/src/backend/file.h b/src/backend/file.h index 71ca15751..bba12a167 100644 --- a/src/backend/file.h +++ b/src/backend/file.h @@ -56,7 +56,7 @@ typedef lumiera_file* LumieraFile; #define LUMIERA_FILE_RECREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_TRUNC) /* creat and excl flags will be masked out for descriptor lookup */ -#define LUMIERA_FILE_MASK ~(O_CREAT | O_EXCL) +#define LUMIERA_FILE_MASK ~(O_CREAT | O_EXCL | O_TRUNC) struct lumiera_file_struct { diff --git a/src/backend/filedescriptor.c b/src/backend/filedescriptor.c index 5a513a7b4..b9608984f 100644 --- a/src/backend/filedescriptor.c +++ b/src/backend/filedescriptor.c @@ -51,21 +51,24 @@ static size_t h1 (const void* item, const uint32_t r) { const LumieraFiledescriptor i = *(const LumieraFiledescriptor*)item; - return i->stat.st_dev^i->stat.st_ino^i->flags^((i->stat.st_dev^i->stat.st_ino^i->flags)>>7)^r; + return i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK) + ^((i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK))>>7)^r; } static size_t h2 (const void* item, const uint32_t r) { const LumieraFiledescriptor i = *(const LumieraFiledescriptor*)item; - return i->stat.st_dev^i->stat.st_ino^i->flags^((i->stat.st_dev^i->stat.st_ino^i->flags)>>5)^r; + return i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK) + ^((i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK))>>5)^r; } static size_t h3 (const void* item, const uint32_t r) { const LumieraFiledescriptor i = *(const LumieraFiledescriptor*)item; - return i->stat.st_dev^i->stat.st_ino^i->flags^((i->stat.st_dev^i->stat.st_ino^i->flags)>>3)^r; + return i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK) + ^((i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK))>>3)^r; } @@ -74,7 +77,8 @@ cmp (const void* keya, const void* keyb) { const LumieraFiledescriptor a = *(const LumieraFiledescriptor*)keya; const LumieraFiledescriptor b = *(const LumieraFiledescriptor*)keyb; - return a->stat.st_dev == b->stat.st_dev && a->stat.st_ino == b->stat.st_ino && a->flags == b->flags; + return a->stat.st_dev == b->stat.st_dev && a->stat.st_ino == b->stat.st_ino + && (a->flags&LUMIERA_FILE_MASK) == (b->flags&LUMIERA_FILE_MASK); } void @@ -112,7 +116,7 @@ lumiera_filedescriptor_acquire (const char* name, int flags) lumiera_mutexacquirer_init_mutex (®istry_lock, ®istry_mutex, LUMIERA_LOCKED); lumiera_filedescriptor fdesc; - fdesc.flags = flags&LUMIERA_FILE_MASK; + fdesc.flags = flags; if (stat (name, &fdesc.stat) != 0) { @@ -199,7 +203,6 @@ lumiera_filedescriptor_new (LumieraFiledescriptor template) self->flags = template->flags; lumiera_mutex_init (&self->lock); - self->reopened = 0; self->refcount = 1; self->handle = 0; diff --git a/src/backend/filedescriptor.h b/src/backend/filedescriptor.h index 4789f9ce2..528be41e8 100644 --- a/src/backend/filedescriptor.h +++ b/src/backend/filedescriptor.h @@ -50,7 +50,6 @@ struct lumiera_filedescriptor_struct struct stat stat; /* create after first open, maintained metadata, MUST BE FIRST! */ int flags; /* open flags, must be masked for reopen */ lumiera_mutex lock; /* locks operations on this file descriptor */ - unsigned reopened; /* count for reopens 0=not yet opened, 1=first, 2..=reopened */ unsigned refcount; /* reference counter, all users sans registry */ LumieraFilehandle handle; From 241327bcd423fb27a925a0a25b4195b11e1cdae9 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Fri, 2 May 2008 23:55:14 +0200 Subject: [PATCH 110/245] rename 'fhcache' global var to 'lumiera_fhcache' --- src/backend/file.c | 9 +++++---- src/backend/filehandlecache.c | 37 ++++++++++++++++------------------- src/backend/filehandlecache.h | 2 +- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/backend/file.c b/src/backend/file.c index e315537fc..4a309ed3a 100644 --- a/src/backend/file.c +++ b/src/backend/file.c @@ -77,15 +77,15 @@ lumiera_file_handle_acquire (LumieraFile self) TRACE (file); REQUIRE (self); REQUIRE (self->descriptor); - REQUIRE (fhcache); + REQUIRE (lumiera_fhcache); LUMIERA_MUTEX_SECTION (file, self->descriptor->rh, &self->descriptor->lock) { if (!self->descriptor->handle) /* no handle yet, get a new one */ - lumiera_filehandlecache_handle_acquire (fhcache, self->descriptor); + lumiera_filehandlecache_handle_acquire (lumiera_fhcache, self->descriptor); else - lumiera_filehandlecache_checkout (fhcache, self->descriptor->handle); + lumiera_filehandlecache_checkout (lumiera_fhcache, self->descriptor->handle); if (self->descriptor->handle->fd == -1) { @@ -120,6 +120,7 @@ lumiera_file_handle_acquire (LumieraFile self) return self->descriptor->handle->fd; } + void lumiera_file_handle_release (LumieraFile self) { @@ -127,6 +128,6 @@ lumiera_file_handle_release (LumieraFile self) LUMIERA_MUTEX_SECTION (file, self->descriptor->rh, &self->descriptor->lock) { - lumiera_filehandlecache_checkin (fhcache, self->descriptor->handle); + lumiera_filehandlecache_checkin (lumiera_fhcache, self->descriptor->handle); } } diff --git a/src/backend/filehandlecache.c b/src/backend/filehandlecache.c index c629f765b..181807661 100644 --- a/src/backend/filehandlecache.c +++ b/src/backend/filehandlecache.c @@ -31,38 +31,35 @@ NOBUG_DEFINE_FLAG_PARENT (filehandlecache, file_all); LUMIERA_ERROR_DEFINE (FILEHANDLECACHE_NOHANDLE, "No filehandle available"); -LumieraFilehandlecache fhcache = NULL; +LumieraFilehandlecache lumiera_fhcache = NULL; void lumiera_filehandlecache_new (int max_entries) { - if (!fhcache) - { - NOBUG_INIT_FLAG (filehandlecache); - fhcache = lumiera_malloc (sizeof (lumiera_filehandlecache)); - lumiera_mrucache_init (&fhcache->cache, lumiera_filehandle_destroy_node); - fhcache->available = max_entries; - fhcache->checked_out = 0; - lumiera_mutex_init (&fhcache->lock); - RESOURCE_ANNOUNCE (filehandlecache, "mutex", "filehandlecache", fhcache, fhcache->rh); - } - else - NOTREACHED; + REQUIRE (!lumiera_fhcache, "Filehandlecache already initialized"); + + NOBUG_INIT_FLAG (filehandlecache); + lumiera_fhcache = lumiera_malloc (sizeof (lumiera_filehandlecache)); + lumiera_mrucache_init (&lumiera_fhcache->cache, lumiera_filehandle_destroy_node); + lumiera_fhcache->available = max_entries; + lumiera_fhcache->checked_out = 0; + lumiera_mutex_init (&lumiera_fhcache->lock); + RESOURCE_ANNOUNCE (filehandlecache, "mutex", "filehandlecache", lumiera_fhcache, lumiera_fhcache->rh); } void lumiera_filehandlecache_delete (void) { - if (fhcache) + if (lumiera_fhcache) { - REQUIRE (!fhcache->checked_out, "Filehandles in use at shutdown"); - RESOURCE_FORGET (filehandlecache, fhcache->rh); - lumiera_mrucache_destroy (&fhcache->cache); - lumiera_mutex_destroy (&fhcache->lock); - free (fhcache); - fhcache = NULL; + REQUIRE (!lumiera_fhcache->checked_out, "Filehandles in use at shutdown"); + RESOURCE_FORGET (filehandlecache, lumiera_fhcache->rh); + lumiera_mrucache_destroy (&lumiera_fhcache->cache); + lumiera_mutex_destroy (&lumiera_fhcache->lock); + free (lumiera_fhcache); + lumiera_fhcache = NULL; } } diff --git a/src/backend/filehandlecache.h b/src/backend/filehandlecache.h index 25964f986..37c2a416b 100644 --- a/src/backend/filehandlecache.h +++ b/src/backend/filehandlecache.h @@ -52,7 +52,7 @@ struct lumiera_filehandlecache_struct RESOURCE_HANDLE (rh); }; -extern LumieraFilehandlecache fhcache; +extern LumieraFilehandlecache lumiera_fhcache; /** * Initializes the filehandle cache. From 9ad62d0edc0e7f2bd9ba6f480ec1ea9c18d0f73f Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Fri, 2 May 2008 23:56:49 +0200 Subject: [PATCH 111/245] Fix: one must not return from a mutex section --- src/backend/file.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/backend/file.c b/src/backend/file.c index 4a309ed3a..9af608567 100644 --- a/src/backend/file.c +++ b/src/backend/file.c @@ -94,7 +94,6 @@ lumiera_file_handle_acquire (LumieraFile self) if (fd == -1) { LUMIERA_ERROR_SET (file, ERRNO); - return -1; } else { @@ -103,14 +102,12 @@ lumiera_file_handle_acquire (LumieraFile self) { close (fd); LUMIERA_ERROR_SET (file, ERRNO); - return -1; } else if (self->descriptor->stat.st_dev != st.st_dev || self->descriptor->stat.st_ino != st.st_ino) { close (fd); /* Woops this is not the file we expected to use */ LUMIERA_ERROR_SET (file, FILE_CHANGED); - return -1; } } self->descriptor->handle->fd = fd; From 64e549dc8125f923aab3d9e02d941f1ddca28dee Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Sat, 3 May 2008 16:32:27 +0200 Subject: [PATCH 112/245] headers for the memory mapping backend (WIP) --- src/backend/mmap.h | 88 ++++++++++++++++++++++++++ src/backend/mmapcache.h | 136 ++++++++++++++++++++++++++++++++++++++++ src/backend/mmapings.h | 118 ++++++++++++++++++++++++++++++++++ 3 files changed, 342 insertions(+) create mode 100644 src/backend/mmap.h create mode 100644 src/backend/mmapcache.h create mode 100644 src/backend/mmapings.h diff --git a/src/backend/mmap.h b/src/backend/mmap.h new file mode 100644 index 000000000..608e40133 --- /dev/null +++ b/src/backend/mmap.h @@ -0,0 +1,88 @@ +/* + mmap.h - memory mapped acces to files + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef LUMIERA_MMAP_H +#define LUMIERA_MMAP_H + +#include "lib/llist.h" + + +typedef struct lumiera_mmap_struct lumiera_mmap; +typedef lumiera_mmap* LumieraMMap; + + +#include "backend/filedescriptor.h" + + +#include +#include + +NOBUG_DECLARE_FLAG (mmap); + +/** + * @file + * MMap objects cover a memory maped range in a file + */ + + + +/** + * mmaped area + * + */ +struct lumiera_mmap_struct +{ + /** used for the mrucache when checked in the cache OR for attaching owners when checked out **/ + llist cachenode; + + /** all mmaps of a file are chained in this list, used to find ranges **/ + llist searchnode; + + off_t start; + size_t size; + void* address; + + /** array with refcounters per page **/ + unsigned short* refmap; + + /** 0 when this mmap is in cache, else the count of attached owners **/ + unsigned use_cnt; + //RESOURCE_HANDLE (rh); +}; + + +LumieraMMap +lumiera_mmap_init (LumieraMMap self, LumieraFile file, LList acquirer, off_t start, size_t size, size_t chunksize); + +LumieraMMap +lumiera_mmap_new (LumieraFile file, LList acquirer, off_t start, size_t size, size_t chunksize); + +void* +lumiera_mmap_destroy_node (LList node); + +#endif +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/src/backend/mmapcache.h b/src/backend/mmapcache.h new file mode 100644 index 000000000..ed2efcb43 --- /dev/null +++ b/src/backend/mmapcache.h @@ -0,0 +1,136 @@ +/* + mmapcache.h - handle aging of mmap objects + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef LUMIERA_MMAPCACHE_H +#define LUMIERA_MMAPCACHE_H + +#include "lib/error.h" +#include "lib/mrucache.h" +#include "lib/mutex.h" + + +typedef struct lumiera_mmapcache_struct lumiera_mmapcache; +typedef lumiera_mmapcache* LumieraMMapcache; + +#include "backend/mmap.h" + +#include + +/** + * @file + * Mmapcache stores a MRU cache of all established mmaped memory regions which are currently not in use. + * The mmapcache also manages the upper limit about how much memory can be mmaped. + */ + +struct lumiera_mmapcache_struct +{ + lumiera_mrucache cache; + size_t limit; + size_t total; + size_t cached; + lumiera_mutex lock; + RESOURCE_HANDLE (rh); +}; + +extern LumieraMMapcache lumiera_mcache; + + +/** + * Initializes the mmapcache. + * @param limit the mmapcache will drop elements when the sum of all mmapings gives over limit + */ +void +lumiera_mmapcache_new (size_t limit); + +/** + * Delete the mmap cache. + * No mmaps in the cache must be locked, this would be a fatal error. + * The handles are closed automatically. + */ +void +lumiera_mmapcache_delete (void); + +/** + * Get a fresh mmap object. + * when mmaped_limit is reached, the oldest mmap object gets dropped else a new allocated object + * is returned + * @param self pointer to the cache + * @return the new mmap + */ +LumieraMMap +lumiera_mmapcache_mmap_acquire (LumieraMMapcache self); + + +/** + * Announce a new mmap object to the cache quotas. + * Update the statistics kept in the cache, + * the map object is still considered to be checked out + * @param self pointer to the cache + * @param map object to be announced + */ +void +lumiera_mmapcache_announce (LumieraMMapcache self, LumieraMMap map); + +/** + * Remove a mmap object from the cache quotas. + * Update the statistics kept in the cache, + * called by mmap's destructor only + * @param self pointer to the cache + * @param map object to be removed + */ +void +lumiera_mmapcache_forget (LumieraMMapcache self, LumieraMMap map); + +/** + * Destroy and free the nelem oldest elements. + * Used to free up resources and memory. + * @param self cache where to free elements. + * @return nelem-(numer of elements which got freed), that is 0 if all requested elements got freed + */ +int +lumiera_mmapcache_age (LumieraMMapcache self); + +/** + * Remove a mmap from cache aging + * Mmaps which are subject of cache aging must be checked out before they can be used. + * @param self the mmapcache + * @param handle the mmap to be checked out + */ +LumieraMMap +lumiera_mmapcache_checkout (LumieraMMapcache self, LumieraMMap handle); + +/** + * Put a mmap into the cache + * Mmaps which are checked in are subject of cache aging and might get destroyed and reused. + * @param self the mmapcache + * @param handle the mmap to be checked in + */ +void +lumiera_mmapcache_checkin (LumieraMMapcache self, LumieraMMap handle); + +#endif +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/src/backend/mmapings.h b/src/backend/mmapings.h new file mode 100644 index 000000000..234ab280b --- /dev/null +++ b/src/backend/mmapings.h @@ -0,0 +1,118 @@ +/* + mmapings.h - manage ranges of mmaped areas on a filedescriptor + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef LUMIERA_MMAPINGS_H +#define LUMIERA_MMAPINGS_H + +#include "lib/mutex.h" +#include "lib/llist.h" + +typedef struct lumiera_mmapings_struct lumiera_mmapings; +typedef lumiera_mmapings* LumieraMMapings; + +#include "backend/filedescriptor.h" +#include "backend/mmap.h" + +#include + + +/** + * @file + * Keeps all mmaped areas + * + */ + +struct lumiera_mmapings_struct +{ + /** mmaped ranges are kept in an list sorted by the size of the mmaping, might be improved to a tree someday **/ + llist mmaps; + + /** sum of all mmaped areas, areas might be overlapping **/ + // size_t vsz; + + /** + * chunkssize is the smallest granularity which is used for mmapping files, it + * should reflect the intended file usage, that is 'pagesize' for small or non growing + * files and some MB for media files. Must be a 2's exponent of pagesize. + **/ + size_t chunksize; + + LumieraFiledescriptor descriptor; + lumiera_mutex lock; + RESOURCE_HANDLE (rh); +}; + +/** + * initialize mmapings container + * + */ +LumieraMMapings +lumiera_mmapings_init (LumieraMMapings self, LumieraFile file, size_t chunksize); + +/** + * destroy mmapings container and free all resources. + * + */ +LumieraMMapings +lumiera_mmapings_destroy (LumieraMMapings self); + +/** + * allocate and initialize new mmapings container + * + */ +LumieraMMapings +lumiera_mmapings_new (LumieraFile file, size_t chunksize); + +/** + * destroy and free mmapings container and all its resources + * + */ +void +lumiera_mmapings_delete (LumieraMMapings self); + +/** + * acquire a mmap which covers the given range + * @param self mmapings where to search + * @param acquirer list node of the new owner which will registered in the mmap + * @param start begin of the required range + * @param size requested size + * @return MMap object covering the requested range or NULL on error + */ +LumieraMMap +lumiera_mmapings_mmap_acquire (LumieraMMapings self, LumieraFile file, LList acquirer, off_t start, size_t size); + +/** + * release a previously acquired MMap object + * @param self mmapings to which the map belongs + * @param acquirer holding node + * @param map object to be released + */ +void +lumiera_mmapings_release_mmap (LumieraMMapings self, LList acquirer, LumieraMMap map); + +#endif +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ From f58be32a0563d6a5849fcd528b6aaec416a74b21 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 19 May 2008 16:37:50 +0200 Subject: [PATCH 113/245] Fixes after rebase * remove _GNU_SOURCE from tests * re-enable C source building in backend --- src/backend/Makefile.am | 15 +++++++-------- tests/backend/test-filedescriptors.c | 2 -- tests/backend/test-filehandles.c | 2 -- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index 45ce555a8..8b33df06a 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -21,14 +21,13 @@ noinst_LIBRARIES += liblumibackend.a liblumibackend_a_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror liblumibackend_a_CPPFLAGS = -I$(top_srcdir)/src/ -liblumibackend_a_SOURCES = \ - $(liblumibackend_a_srcdir)/mediaaccessfacade.cpp - -# $(liblumibackend_a_srcdir)/backend.c \ -# $(liblumibackend_a_srcdir)/file.c \ -# $(liblumibackend_a_srcdir)/filehandle.c \ -# $(liblumibackend_a_srcdir)/filedescriptor.c \ -# $(liblumibackend_a_srcdir)/filehandlecache.c +liblumibackend_a_SOURCES = \ + $(liblumibackend_a_srcdir)/mediaaccessfacade.cpp \ + $(liblumibackend_a_srcdir)/backend.c \ + $(liblumibackend_a_srcdir)/file.c \ + $(liblumibackend_a_srcdir)/filehandle.c \ + $(liblumibackend_a_srcdir)/filedescriptor.c \ + $(liblumibackend_a_srcdir)/filehandlecache.c noinst_HEADERS += \ diff --git a/tests/backend/test-filedescriptors.c b/tests/backend/test-filedescriptors.c index 40f516048..3e14ead1d 100644 --- a/tests/backend/test-filedescriptors.c +++ b/tests/backend/test-filedescriptors.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define _GNU_SOURCE - #include "lib/safeclib.h" #include "backend/backend.h" diff --git a/tests/backend/test-filehandles.c b/tests/backend/test-filehandles.c index 71056144e..17c237d4f 100644 --- a/tests/backend/test-filehandles.c +++ b/tests/backend/test-filehandles.c @@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define _GNU_SOURCE - #include "lib/llist.h" #include "lib/safeclib.h" From 287fa119758bbc5238848be8c9d0b6523db45ebb Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 20 May 2008 13:03:05 +0200 Subject: [PATCH 114/245] added protocol of may dev meeting etc... --- wiki/index.html | 150 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 145 insertions(+), 5 deletions(-) diff --git a/wiki/index.html b/wiki/index.html index 1ed553afd..2c34a10d1 100644 --- a/wiki/index.html +++ b/wiki/index.html @@ -635,6 +635,18 @@ ColorPalette SiteUrl +
+
* autotools 1.10 (as of 5/2008) &dash; Question: other versions usable too?
+* the usual procedure, in short
+{{{
+autoreconf -i
+automake
+./configure --enable-alpha
+make
+make check
+}}}
+
+
/***
 |Name|BetterTimelineMacro|
@@ -930,9 +942,10 @@ git push git://git.pipapo.org/lumiera/mob
 
 lumiera/mob is an anonymous account at pipapo.org where everyone can commit changes. 
-
+
We keep a protocol or short summary of each important discussion. The summaries of the monthly developer meetings are posted to the Mailinglist and can be found on pipapo.org too
 
+* [[05-08 developer meeting 8.May.2008|IRC_2008-05-08]]
 * [[04-08 developer meeting 3.Apr.2008|IRC_2008-04-03]]
 * [[03-08 developer meeting 6.Mar.2008|IRC_2008-03-06]]
 * [[1.official developer meeting 1.Feb.2008|IRC_2008-02-01]]
@@ -1187,7 +1200,7 @@ Conclusion:
  Next meeting 3rd april 21:00GMT. But Aussies, please speak up if you want the time changed!
 
-
+
! 3. apr.2008 on #lumiera
 21:00 - 23:30 GMT. __Participants__:
  * cehteh
@@ -1306,7 +1319,7 @@ __Conclusion__: Gmerlin does it the way it fits best for within the decoder, and
 
 ! Next meeting
 
-The next meeting will be at thuesday 8th may 21:00GMT
+The next meeting will be at thursday 8th may 21:00GMT
 
 -----------------------------
 
@@ -1446,6 +1459,133 @@ The next meeting will be at thuesday 8th may 21:00GMT
 01:34 cehteh gmerlin: that should be unified :)
 }}}
 
+
+
+
+
! 8. May.2008 on #lumiera
+__Participants__:
+ * cehteh
+ * joelholdsworth
+ * ichthyo
+ * raffa
+ * ~WesLappy
+ * gmerlin
+
+! Boilerplate
+!! Organization of this meeting
+* cehteh writes the protocol
+
+! Webpage-Infrastructure, Maintenance
+
+Cehteh put this on topic because it's really urgent to bring up some infrastructure to manage the information we produce.
+
+The Lumiera pages on pipapo.org were always meant as intermediary solution. Pipapo.org gets much spam on the moinmoin wiki and cehteh expresses that he wants to move pipapo.org to a new infrastructure based on asciidoc and git he created (see http://git.pipapo.org/uWiki.html). This system is barely useable and needs lots of work to be completed. It would be nice to use it for Lumiera too, if the others agree. Maintaining and extending (scripting) needs someone who knows shell scripting and doesn't need to be done by the core devs freeing their resources to work on Lumiera. Cehteh expresses that none of the people who proposed to help before showed up yet. ~WesLappy tells he might help (addendum not this week, because he is busy).
+
+Next there was a suggestion by cehteh to convert the tiddlywikis to asciidoc. Ichthyo expresses that he likes the tiddlywikis, Joel mentions that they feel a little odd. Generally we all agree that they have some problems in sense of workflow and merging.
+
+Ichthyo makes the suggestion to keep the tiddlywikis as scrapbook and build up 'official' documentation based on their content in whatever-we-use-then (asciidoc) documentation system. All agree on this approach.
+
+Back to the new wiki, cehteh suggests to make stricter access rules to prevent spam: "There will be a group of 'Validated' people which following rules: only Validated people can edit general content and 'Validated' people can add new people to 'Validated' themselves". That means that we can have a lightweight self-administrating authentication where new people have to be introduced by someone who is already there.
+
+Ichthyo suggests to send a reply to Serge G. who send an introduction to the cinelerra mailing list expressing that he would like to help.
+
+Raffa will take care of content/design as much her time/knowledge permits.
+
+__Conclusion__:
+* We really need someone to help with the webpage scripting.
+* Documentation needs to be well organized and moved over.
+* Content of the pipapo.org moinmoin wiki should be moved over.
+* The new website should be well organized with a nice looking frontpage
+* All other documentation should be below that
+
+-----
+
+! Whats pending in DesignProcess
+
+!! MistakestoAvoid
+http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/MistakestoAvoid
+
+rick_777 wrote a "MistakestoAvoid" page which explains some possible gotchas. We basically agree with most points there while we already decided to address some things differently than he suggested. One noteable difference is that we do not intent to provide a windows version of Lumiera, which was explained in serveral places. Cehteh added some comments to the page explaining some things.
+
+
+-----
+
+nothing more to discuss in 'Ideas', we go over to 'Drafts'
+
+!! ArchitectureOverview
+http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/ArchitectureOverview
+
+Cehteh suggests to put that drawing under version control, as .fig. Ichthyo explains that it is already a .SVG and that he does not like .fig.
+
+Conclusion: We agree to keep it as .SVG, add it to the repository and improve/complete it.
+
+!! GitSubmoduleTransistion
+http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/GitSubmoduleTransistion
+
+Another suggestion made by cehteh is to make managing of subprojects within the sourcetree easier. Joel and ichthyo oppose that it is not really needed now and needs more understanding of git. Ichthyo suggests that the documentation might be separated into its own git, he further explains that the things are not settled yet and we don't know if we will some rearrangements and movements of files between modules.
+
+Conclusion: We transform the documentation to a submodule and see how it works. Other things will be decided much later.
+
+
+
+!! GlobalInitialization
+http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/GlobalInitialization
+
+This topic is discussed and agreed on the DesignProcess page already.
+
+__Conclusion__: finalize it
+
+!! MasterRepositorySetup
+http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/MasterRepositorySetup
+
+Setting up an master repository was decided on the last meeting. cehteh now set one up which also does some automatic, but intended fragile merging from subsystem maintainer branches.
+# it updates automatically for the maintainers repo for conflict free fast-forwards
+# it can always be overridden with explicit pushes
+
+The others agree on the setup.
+
+Ichthyo stresses that maintainers shall watch that their 'master' branch should compile cleanly and pass the testsuite always, test which are not operational should be tagged as PLANNED. We all agree...
+
+Then a short discussion about building and synchronizing the docs follows. Problem is that docs build in maintainer branches are different for each branch, rsyncing them up to the server will always change a lot of things. We agree that the 'official' docs shall be build from the LUMIERA/master repository, preferably on the 'devel' vserver which has to be set up.
+
+__Conclusions__: Make this final, setup build environment in the devel server and build docs there.
+
+
+!! NoBugFlags
+http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/NoBugFlags
+
+Defining a debugging control hierarchy. This is work in progress and cehteh explains that he works it out and deploys it, this depends on the GlobalInitialization decided earlier.
+
+__Conclusion__: accepted, finish and finalize it.
+
+
+! Further Technical Discussion
+
+Ichthyo asks how the GUI will be pulled up. Since he didn't attend IRC discussions recently he has no information yet what's going on. We explain him that we already made some discussions. Integrate the GUI into the build system probably linked as library, nothing finally decided yet. Communication will go over the plugin/interface facility (Plain C API). This things should be worked out and documented in DesignProcess.
+
+Cehteh made a small tool {{{./admin/headercheck}}} which will gradually extended to proof that headers are sufficiently selfstanding.
+
+
+! Progress
+
+''Cehteh'' finished low level file handling and working in mmaping and frameprovider next. When thats finished, the finalization of the Plugin loader and interface definition things is the most urgent thing.
+
+''Ichthyo'' works on the builder internals and next on some sort of "connection manager".
+
+''Joel'' goes on with GUI pro9gramming and integrating it into the source tree next.
+
+Gmerlin and cehteh discuss about how to handle the index files which avdecoder uses internally. cehteh would like to manage them in the Lumiera backend to, because filehandles are a precious resource. Gmerlin explains that this index files are just loaded and kept in memory. So this poses no problem for filehandle exhaustion. We will discuss this further via email.
+
+Cehteh suggests that we should think about some kind of preferences/registry sometime next to store default configs.
+
+Following a discussion about how messages are passed between GUI and core. Generally we will use the interfaces defined by the plugin system. Gmerlin says that he uses message queues in 'gmerlin', Joel requests that a lot of things should be done synchronous and he wants to avoid message queues. Cehteh suggests to use use the scheduler for GUI things too. For the parts where the GUI interacts with the high level proc model ichthyo and joel agree on working something (synchronous) out. Ichthyo stresses that the edit core is not threadsafe by design and relies on the backends scheduler. The underlying builder might sometimes to expensive for synchronous calls (ichthyo plans a rule system there) this needs to be worked out.
+
+Ichthyo explains that the builder needs to detect cycles and check if the high level model is translateable into the low level model (in case plugins git removed and so on). Parts in the render graph which are not 'doable' should be flagged as erroneous but not dropped since one doesn't want to loose project information when loading a project on a machine with different installed plugins. In any case it should be possible that the GUI gets immediate synchronous feedback for such things.
+
+
+! Next Meeting
+
+Next meeting is on thursday 5th June 21:00 UTC
 
@@ -1796,7 +1936,7 @@ This distributed wiki might be used instead the pipapo.org wiki, investigate tha Wiki works. It is simple to use and just flexible enough to handle the task. I don't go to install any other software for such tasks on my server. While the design progresses I'd propose to move our work into git repositories and eventually phase this wiki pages out anyways. I'd rather like to start out distributed/git right away .. but git gives us only a fine storage layer, for a design process we need some good presentation layer (later when using git and starting the implementation everyones favorite editor serves for that) I have no better ideas yet to solve the presentation problem other than using this wiki (or maybe Bouml).
-
+
This is the entry point to several [[TiddlyWiki]]-Pages containing the developer and design documentation for Lumiera.
 
 * Cehteh started GitNotes where we will collect some information about git, howto and special setups
@@ -1812,8 +1952,8 @@ to get started, we create design drafts emphasizing different aspects and region
 
 * Cehteh works on the data backend, see [[this page|backend.html]]
 * Ichthyo focuses mainly on Edit operations and Builder, [[see this separate page|renderengine.html]]
+* Joel started with a GUI implementation based on GTK
 * Gmerlin is in charge of [[GAVL|http://gmerlin.sourceforge.net/gavl.html]] for processing of video data
-* as of 4/08 a GuiWorkingGroup is emerging...
 * Some tools which don't fit somewhere else and are used everywhere are put into a [[Support Library|support_library.html]]
 
 !Coding &mdash; Building &mdash; Testing

From b5d2e9486edf405501d94f43e39a4f478fa26b70 Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Tue, 20 May 2008 13:04:22 +0200
Subject: [PATCH 115/245] small adaptions to scons, fix a test

---
 SConstruct                          |  3 ++-
 tests/50components.tests            |  2 +-
 tests/SConscript                    | 10 +++++++++-
 tests/common/exceptionerrortest.cpp |  4 ++--
 tests/test.sh                       |  3 +--
 5 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/SConstruct b/SConstruct
index cef5ebda0..066cd31b0 100644
--- a/SConstruct
+++ b/SConstruct
@@ -33,7 +33,7 @@ CUSTOPTIONSFILE  = 'custom-options'
 SRCDIR           = 'src'
 BINDIR           = 'bin'
 TESTDIR          = 'tests'
-VERSION          = '3+alpha.01'
+VERSION          = '0.1+pre.01'
 #-----------------------------------Configuration
 
 # NOTE: scons -h for help.
@@ -68,6 +68,7 @@ def setupBasicEnvironment():
     RegisterPrecompiledHeader_Builder(env)
     handleNoBugSwitches(env)
     
+    env.Append(CPPDEFINES = '_GNU_SOURCE')
     appendCppDefine(env,'DEBUG','DEBUG', 'NDEBUG')
     appendCppDefine(env,'OPENGL','USE_OPENGL')
     appendVal(env,'ARCHFLAGS', 'CCFLAGS')   # for both C and C++
diff --git a/tests/50components.tests b/tests/50components.tests
index 18f04ee4b..ae15f37c3 100644
--- a/tests/50components.tests
+++ b/tests/50components.tests
@@ -62,7 +62,7 @@ out: caught error::Logic: LUMIERA_ERROR_FATAL:floundered (test-2).
 out: caught error::Invalid: LUMIERA_ERROR_INVALID:invalid input or parameters (test-3).
 out: caught lumiera::Error: LUMIERA_ERROR_EXTERNAL:failure in external service (test-4).
 out: caught std::runtime_error: test-5
-out: caught std::exception: std::exception
+out: caught std::exception. (unspecific)
 out: intermediate handler caught: LUMIERA_ERROR_EXTERNAL:failure in external service (test-7).....will rethrow as error::State
 out: caught lumiera::Error: LUMIERA_ERROR_STATE:unforseen state -- caused by: LUMIERA_ERROR_EXTERNAL:failure in external service (test-7).
 out: intermediate handler caught: LUMIERA_ERROR_EXTERNAL:failure in external service (test-8).....will rethrow as error::State
diff --git a/tests/SConscript b/tests/SConscript
index 7f66b6284..e662ca044 100644
--- a/tests/SConscript
+++ b/tests/SConscript
@@ -9,6 +9,10 @@ from Buildhelper import globRootdirs
 
 Import('env','artifacts','core')
 
+# temp fix to add test.h  -- wouldn't it be better to put this header be into src/lib ?  
+env = env.Clone()
+env.Append(CPPPATH='#/.')  # add Rootdir to Includepath, so test/test.h is found
+# temp fix------------- 
 
 def testExecutable(env,tree, exeName=None, obj=None):
     """ declare all targets needed to create a standalone
@@ -52,7 +56,7 @@ def treatPluginTestcase(env):
 moduledirs = globRootdirs('*')
 
 # but have to treat some subdirs individually.
-specials = ['plugin','locking','library']
+specials = ['plugin','locking','library','backend']
 
 
 
@@ -61,6 +65,10 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in moduledirs
                               + testExecutable(env, 'locking', obj=['test-locking.c','mutex.c','condition.c'])
                               + testExecutable(env, 'library', exeName='test-llist', obj=['test-llist.c'])
                               + testExecutable(env, 'library', exeName='test-references', obj=['test-references.c'])
+                              + testExecutable(env, 'library', exeName='test-safeclib', obj=['test-safeclib.c'])
+                              + testExecutable(env, 'library', exeName='test-uuid',     obj=['test-uuid.c'])
+                              + testExecutable(env, 'backend', exeName='test-filedescriptors', obj=['test-filedescriptors.c'])
+                              + testExecutable(env, 'backend', exeName='test-filehandles', obj=['test-filehandles.c'])
                               ) 
                               
 
diff --git a/tests/common/exceptionerrortest.cpp b/tests/common/exceptionerrortest.cpp
index 6bc97afbb..e1c133e4f 100644
--- a/tests/common/exceptionerrortest.cpp
+++ b/tests/common/exceptionerrortest.cpp
@@ -97,7 +97,7 @@ namespace lumiera
         void throwInvalid (string _) { throw error::Invalid(_); }
         void throwExternal(string _) { throw error::External(_); }
         void throwRuntime (string _) { throw std::runtime_error(_); }
-        void throwExceptn (string _) { throw std::exception(error::State(_)); }
+        void throwExceptn (string _) { throw std::exception(); }
 
         
         /** @test catching, repackaging and rethrowing of errors.
@@ -219,7 +219,7 @@ namespace lumiera
           catch (error::Invalid&e) { cout << "caught error::Invalid: " << e.what() << "\n"; }                
           catch (Error&         e) { cout << "caught lumiera::Error: " << e.what() << "\n"; }                
           catch (runtime_error& e) { cout << "caught std::runtime_error: " << e.what() << "\n"; }                
-          catch (exception&     e) { cout << "caught std::exception: " << e.what() << "\n"; }
+          catch (exception&     e) { cout << "caught std::exception. (unspecific)" << "\n"; }
           catch (...)              { cout << "caught an unknown exception\n"; }
         }
       };
diff --git a/tests/test.sh b/tests/test.sh
index 77bac66bf..d919ed073 100755
--- a/tests/test.sh
+++ b/tests/test.sh
@@ -1,7 +1,6 @@
 #!/bin/bash 
 #  Copyright (C)         Lumiera.org
-#    2007,               Christian Thaeter 
-#                        Hermann Vosseler 
+#    2007 - 2008,        Christian Thaeter 
 #
 #  This program is free software; you can redistribute it and/or
 #  modify it under the terms of the GNU General Public License as

From 686e47220d60227fd89d5d96f5eab597a25e2c8d Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Wed, 21 May 2008 05:30:07 +0200
Subject: [PATCH 116/245] written down basics of the builder's internal
 operation

---
 wiki/renderengine.html | 69 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 60 insertions(+), 9 deletions(-)

diff --git a/wiki/renderengine.html b/wiki/renderengine.html
index 7e922bde6..b076f0d9b 100644
--- a/wiki/renderengine.html
+++ b/wiki/renderengine.html
@@ -578,8 +578,9 @@ The first step towards an solution is to isolate the problem; obviously we //nee
 [img[how to implement Automation|uml/fig129669.png]]
 
-
+
Starting out from the concepts of Objects, Placement to Tracks, render Pipes and connection properties (&rarr; see [[here|TrackPipeEDL]]) within the EDL, we can identify the elementary operations occuring within the Builder. Overall, the Builder is organized as application of //visiting tools// to a collection of objects, so finally we have to consider some object kind appearing in the working function of the given builder tool, which holds at this moment some //context//. The job now is to organize this context such as to create a predictable build process from this //event driven// approach.
+&rarr;see also: BuilderPrimitives for the elementary situations used to cary out the building operations
 
 !Builder working Situations
 # any ''Clip'' (which at this point has been reduced already to a part of a simple elementary media stream &rarr; see [[Fixture]])
@@ -728,7 +729,7 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
 }
 //}}}
-
+
All decisions on //how // the RenderProcess has to be carried out are concentrated in this rather complicated Builder Subsystem. The benefit of this approach is, besides decoupling of subsystems, to keep the actual performance-intensive video processing code as simple and transparent as possible. The price, in terms of increased complexity &mdash; to pay in the Builder &mdash; can be handled by making the Build Process generic to a large degree. Using a Design By Contract approach we can decompose the various decisions into small decision modules without having to trace the actual workings of the Build Process as a whole.
 
 [>img[Outline of the Build Process|uml/fig129413.png]]
@@ -737,8 +738,10 @@ The building itself will be broken down into several small tool application step
 * for each segment: generate a ProcNode for each found MObject and wire them accordingly
 Note, //we still have to work out how exactly building, rendering and playback work// together with the backend-design. The build process as such doesn't overly depend on these decisions. It is easy to reconfigure this process. For example, it would be possible as well to build for each frame separately (as Cinelerra2 does), or to build one segment covering the whole timeline (and handle everything via [[Automation]]
 
+&rarr;see also: [[Builder Overview|Builder]]
 &rarr;see also: BasicBuildingOperations
 &rarr;see also: BuilderStructures
+&rarr;see also: BuilderMechanics
 &rarr;see also: PlanningBuildFixture
 &rarr;see also: PlanningSegementationTool
 &rarr;see also: PlanningNodeCreatorTool
@@ -746,7 +749,7 @@ Note, //we still have to work out how exactly building, rendering and playback w
 [img[Colaborations in the Build Process|uml/fig128517.png]]
 
-
+
The Builder takes some MObject/[[Placement]] information (called Timeline) and generates out of this a Render Engine configuration able to render this Objects. It does all decisions and retrieves the current configuration of all objects and plugins, so the Render Engine can just process them stright forward.
 
 The Builder is the central part of the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]]
@@ -754,12 +757,44 @@ The Builder is the central part of the [[Builder Pattern|http://en.wikipedia.org
 As the builder has to create a render node network implementing most of the features and wiring possible with the various MObject kinds and placement types, it is a rather complicated piece of software. In order to keep it manageable, it is broken down into several specialized sub components:
 * clients access builder functionality via the BuilderFacade
 * the [[Proc-Layer-Controller|Controller]] initiates the BuildProcess and does the overall coordination of scheduling edit operations, rebuilding the fixture and triggering the Builder
-* to carry out the building, we use several tools (SegmentationTool, NodeCreaterTool,...), which are supplied by the [[tool factory|BuilderToolFactory]]
-* the actual building (i.e. the application of those tools to the timeline) is done by the [[Assembler|BuilderAssembler]], which is basically a collection of functions (but has a small amount of global configuration state)
+* to carry out the building, we use several primary tools (SegmentationTool, NodeCreaterTool,...),  together with a BuilderToolKit to be supplied by the [[tool factory|BuilderToolFactory]]
+* //operating the Builder// can be viewed at from two different angles, either emphasizing the [[basic building operations|BasicBuildingOperations]] employed to assemble the render node network, or focussing rather at the [[mechanics|BuilderMechanics]] of cooperating parts while processing.
+* besides, we can identify a small set of elementary situations we call [[builder primitives|BuilderPrimitives]], to be covered by the mentioned BuilderToolKit; by virtue of [[processing patterns|ProcPatt]] they form an [[interface to the rule based configuration|BuilderRulesInterface]].
+* the actual building (i.e. the application of tools to the timeline) is done by the [[Assembler|BuilderAssembler]], which is basically a collection of functions (but has a small amount of global configuration state)
 * any non-trivial wiring of render nodes, tracks, pipes and automation is done by the services of the [[connection manager|ConManager]]
 
-
+
+
The cooperation of several components creates a context of operation for the primary builder working tool, the [[node creator|PlanningNodeCreatorTool]]:
+* the BuilderToolFactory acts as the "builder for the builder tools", i.e. we can assume to be able to retrive all needed primary tools and elementary tools from this factory, completely configured and ready to use.
+* the [[Assembler|BuilderAssembler]] has the ability to consume objects from the high level model and feed them to the node creator (which translates into a dispatch of individual operations suited to the objects to be treated). This involves some sort of scheduling or ordering of the operaions, which is the only means to direct the overall process such as to create a sensible and usable result. //This is an fundamental design decision:// the actual working tools have no hard wired knowledge of the "right process", which makes the whole Builder highly configurable ("open").
+* the [[connection manager|ConManager]] on the contrary is a passive service provider. Fed with [[wiring requests|WiringRequest]], he can determine if a desired connection is possible, and what steps to take to implement it; the latter recursively creates further building requests to satisfy by the assembler, and possibly new wiring requests.
+
+!!pattern of operation
+The working pattern of this builder mechanics can be described as triggering, enqueuing, priorizing, recursing and exhausting. Without the priorizing part, it would be a depth-first call graph without any context state, forcing us to have all cross reference information available at every node or element to be treated. We prefer to avoid this overhead by ordering the operations into several phases and within these phases into correlated entities with the help of a ''weighting function'' and scheduling with a ''priority queue''
+
+
+
While assembling and building up the render engines node network, a small number of primitive building situations is encountered repeatedly. The BuilderToolKit provides a "fitting tool" for each of these situations, typically involving parametrisation and the application of a [[processing pattern|ProcPatt]].
+
+!List of elementary building situations
+!!!inserting an Effect or Plugin
+* participating: a Pipe and an Effect
+* result: Effect appended at the pipe's exit node
+
+!!!building a source connection
+* participating: source port of a clip, media access point, processing pattern
+* result: processing pattern has been //executed//, resulting in a chain of nodes from the source reader to the clip source port
+
+!!!wiring a general connection
+* participating: already verified connection request, providing a Pipe and an exit node; a processing pattern and a Placement
+* result: summation node prepended to the port of the pipe, processing pattern has been //executed// for building the connection from the exit node to the pipe's port, ParamProvider has been setup in accordance to the Placement.
+
+!!!attaching a transition 
+* participating: N pipe's exit nodes, transition
+* result: transition has been attached with the pipe's exit nodes, new wiring requests created attached to the transition's exit node(s)
+
+
+
* the MObjects implement //Buildable//
 * each Buildable can "receive" a Tool object and apply it
 * the different Tool objects are iterated/mapped onto the list of MObjects in the [[Timeline]]
@@ -769,10 +804,26 @@ As the builder has to create a render node network implementing most of the feat
 ** a given Tool instance can carry state while being iterated, so we don't need any global (or object-global) variables to hold the result of the build process
 
 This programming technique is often referred to as [["double dispatch" or "visitor"|VisitorUse]]. We use a specialized library implementation of this pattern &mdash; heavily inspired by the [[Loki library|http://loki-lib.sourceforge.net/]]. We use this approach not only for the builder, but also for carrying out operations on the objects in the EDL in a typesafe manner. 
-For the actual building operations see BasicBuildingOperations {{red{TODO:flesh out the actual Operations}}}
-    
-
+It is the low level foundation of the actual [[building operations|BasicBuildingOperations]] necessary to create render nodes starting from the given high level model. 
 [img[Entities cooperating in the Builder|uml/fig129285.png]]
+
+!Colaborations
+
+While building, the application of such a visiting tool (especially the [[NodeCreatorTool|PlanningNodeCreatorTool]]) is embedded into an execution context formed by the BuilderToolFactory providing our BuilderToolKit, the [[Assembler|BuilderAssembler]] and [[connection manager|ConManager]]. The colaboration of these parts can be seen as the [[mechanics of the builder|BuilderMechanics]] &mdash; sort of the //outward view//, contrary to the //invard aspects// visible when focussing on how the nodes are put together.
+    
+[img[Colaborations in the Build Process|uml/fig128517.png]]
+
+
+
+
+
Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounder several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool". The palette of these fitting tools is called the ''tool kit'' of the builder. It is subject to configuration by rules.
+
+!! {{red{open questions}}}
+* how to address these fitting tools
+* how to type them
+* how to parametrize them
+
+&rarr;see also: BuilderPrimitives for the elementary corresponding to these fitting tools
 
From fe975a701d1a3e6d8b120b850b772e06684cad86 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 22 May 2008 19:19:04 +0100 Subject: [PATCH 117/245] Added some scroll bars --- src/gui/panels/timeline-panel.cpp | 4 +- src/gui/widgets/timeline-widget.cpp | 62 ++++++++++++++--------------- src/gui/widgets/timeline-widget.hpp | 14 +++++-- 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index f2a29fd61..fc4e7387e 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -23,6 +23,8 @@ #include "../gtk-lumiera.hpp" #include "timeline-panel.hpp" +using namespace Gtk; + namespace lumiera { namespace gui { namespace panels { @@ -30,7 +32,7 @@ namespace panels { TimelinePanel::TimelinePanel() : Panel("timeline", _("Timeline"), "timeline_panel") { - pack_start(timeline_widget); + pack_start(timeline_widget, PACK_EXPAND_WIDGET); } } // namespace panels diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index 10eaa3fb0..4e60ba7b8 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -26,45 +26,43 @@ #include "timeline-widget.hpp" +using namespace Gtk; + namespace lumiera { namespace gui { namespace widgets { -TimelineWidget::TimelineWidget() +TimelineWidget::TimelineWidget() : + Table(2, 2), + horizontalAdjustment(0, 200, 400), + verticalAdjustment(0, 200, 400), + horizontalScroll(horizontalAdjustment), + verticalScroll(verticalAdjustment), + rowHeaderViewport(), + label1("label1"), label2("label2"), label3("label3"), label4("label4"), + label5("label5"), label6("label6"), label7("label7"), label8("label8"), + label9("label1"), label10("label10"), label11("label11"), ruler("ruler") { - set_flags(Gtk::NO_WINDOW); - } + rowHeaderBox.pack_start(label1); + rowHeaderBox.pack_start(label2); + rowHeaderBox.pack_start(label3); + rowHeaderBox.pack_start(label4); + rowHeaderBox.pack_start(label5); + rowHeaderBox.pack_start(label6); + rowHeaderBox.pack_start(label7); + rowHeaderBox.pack_start(label8); + rowHeaderBox.pack_start(label9); + rowHeaderBox.pack_start(label10); + rowHeaderBox.pack_start(label11); + rowHeaderViewport.add(rowHeaderBox); -void -TimelineWidget::on_realize() - { - //Call base class: - Gtk::Widget::on_realize(); + rowHeaderViewport.set_hadjustment(horizontalAdjustment); + rowHeaderViewport.set_vadjustment(verticalAdjustment); - } - -bool -TimelineWidget::on_expose_event(GdkEventExpose* event) - { - // This is where we draw on the window - Glib::RefPtr window = get_window(); - if(window) - { - /*Cairo::RefPtr cr = window->create_cairo_context(); - if(event) - { - // clip to the area that needs to be re-exposed so we don't draw any - // more than we need to. - cr->rectangle(event->area.x, event->area.y, - event->area.width, event->area.height); - cr->clip(); - } - - // Paint the background - cr->set_source_rgb(0.0, 0.0, 0.0); - cr->paint();*/ - } - return true; + attach(ruler, 1, 2, 0, 1, FILL|EXPAND, SHRINK); + attach(rowHeaderViewport, 0, 1, 1, 2, SHRINK, FILL|EXPAND); + attach(horizontalScroll, 1, 2, 2, 3, FILL|EXPAND, SHRINK); + attach(verticalScroll, 2, 3, 1, 2, SHRINK, FILL|EXPAND); } diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp index a080d34b2..e89e684e0 100644 --- a/src/gui/widgets/timeline-widget.hpp +++ b/src/gui/widgets/timeline-widget.hpp @@ -32,15 +32,23 @@ namespace lumiera { namespace gui { namespace widgets { - class TimelineWidget : public Gtk::Widget + class TimelineWidget : public Gtk::Table { public: TimelineWidget(); /* ===== Overrides ===== */ protected: - virtual void on_realize(); - virtual bool on_expose_event(GdkEventExpose* event); + Gtk::Adjustment horizontalAdjustment, verticalAdjustment; + Gtk::HScrollbar horizontalScroll; + Gtk::VScrollbar verticalScroll; + + Gtk::Viewport rowHeaderViewport; + Gtk::VBox rowHeaderBox; + Gtk::Label label1, label2, label3, label4; + Gtk::Label label5, label6, label7, label8; + Gtk::Label label9, label10, label11, label12; + Gtk::Label ruler; }; } // namespace widgets From f3d078f93b1cdfacfdf789da650f2a733f2cc9db Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 23 May 2008 07:05:35 +0200 Subject: [PATCH 118/245] add drawing to explain the builder primitives --- doc/devel/draw/builder-primitives.svg | 2115 +++++++++++++++++++++++++ wiki/draw/builder-primitives1.png | Bin 0 -> 4777 bytes wiki/draw/builder-primitives2.png | Bin 0 -> 7087 bytes wiki/draw/builder-primitives3.png | Bin 0 -> 8197 bytes wiki/draw/builder-primitives4.png | Bin 0 -> 13071 bytes wiki/renderengine.html | 29 +- 6 files changed, 2136 insertions(+), 8 deletions(-) create mode 100644 doc/devel/draw/builder-primitives.svg create mode 100644 wiki/draw/builder-primitives1.png create mode 100644 wiki/draw/builder-primitives2.png create mode 100644 wiki/draw/builder-primitives3.png create mode 100644 wiki/draw/builder-primitives4.png diff --git a/doc/devel/draw/builder-primitives.svg b/doc/devel/draw/builder-primitives.svg new file mode 100644 index 000000000..aa1ae5801 --- /dev/null +++ b/doc/devel/draw/builder-primitives.svg @@ -0,0 +1,2115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + style="overflow:visible"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + Transition + + + + + + + + + + + + + + + x + + + + + + + Effect + + + + + + + + + + + + + + + + + + + x + + + + + + + + + + + Effect + + + + + + + + + + + + + + + x + + + + + + + + x + + + + + + + + + + + + + + + + + + + x + + + + + + + Transition + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Clip + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Clip + + + + + + + + + + + + + + + + + + + + + + + Conv + + + + + + + Cam + + + + + + + + + + + + + + + + x + + + + + + + + + + + x + + + + + + + + + Con-Req + + + + + + + + + + Placement + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + x + + + + + + + + ∑ + + + + + + + + + + + + + + + + + + + + Conv + + + + + + + + + + + + + Proj + + + + + + + + + + + + + + + + + + x + + + + + diff --git a/wiki/draw/builder-primitives1.png b/wiki/draw/builder-primitives1.png new file mode 100644 index 0000000000000000000000000000000000000000..986aa4227074a0e48673d1e9d3416062bfd850b7 GIT binary patch literal 4777 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 literal 0 HcmV?d00001 diff --git a/wiki/draw/builder-primitives3.png b/wiki/draw/builder-primitives3.png new file mode 100644 index 0000000000000000000000000000000000000000..f80b1f5c69a1624bbe254b195180f11dfac669d6 GIT binary patch literal 8197 zcmX9@1z1#F*S$yxN=Xi&v;tC6(kUURAP7j;0Ma$U(4e%G)Jun?2uO!?BQ;2uz(`7W z*MIoGd7fc_d*_~W_TFdhwbluJtE@n9kNO@2K?I5~Wz`@EqZj=C9v27v3?Rim0v}ii z8AWwm@bbbn4FP}SIlR5Sx-InvFW?J^T||+R6!S=SU-E@)PKDu{G9pGB4)NB zRjpmEaAH_YVJq&xowaqINHZ-{?MAbyy~O`0@zwb5<3D&Sb-#bfT}A7x`^ zVOdN=&RGg7-tmi#B{lHe5)cv*G3kzcgiiHGaFJk1GvnTQ{89#&L4TZ4)o#A&QK4pW z+dCEUz*rU)la29WRxU2P3RN&l3U9IIjIFdIYHz!K$7F3d_bn@#piQ%B56MFz2k2?M z(jQxCV(=V`mvL{zORB6VOqP4&6U9BBb8v8=*VjMCv%jyNVr6E=f_67bni+X{N#5nX zmX?*p`j1QhUX{-5a;B1!Qs%@)N+jHQxtDzN&ri}1s8mZ;JA3;m$HlI%m6hsGNkS8~ zILs+1C|+|V@TsV%biuOc9y0`d(H$Pm9<{1sWo2#gCz5b$k9f+?jsbn5NB@dunk+ZF z&&$gTK^Mnc8%}Qn0|R$YPV80lCN}o|AO^u>$!^Xknx~mx`TF{@#w#f%5Gms_1n`f< zu|6ijVd|&`pBwplF03cn_F8K%W(RU zd=+22u5c=SNlXS%Un4qt-}Rb(#LZEup$Dsji_r?Sty2{r9MLTpo0DbP?T@~VSv6dr zZ-j)0cLdYq^EF#8B45KPO47QDokdi3&6&9VHojEu; z4GXIL@z$4;YWdO=%hGK-UCCw&!YG#)8B8pLlSPqmaJ`?^YCz;|E)_J78#jdV>R|&-_g;LAu=*DkMMTbqUZjGdiwf%ZTGn= zEl+LjUeIP-d;#lRQC`4di3HVCJ_-)TtdR) z$-Hl{EMseLJo^I}Y!c3Mh|`t$uf+FiBYARiG6~)t8J{FV3pSc>%tK+PrIT)2&)0ZT zZNh>x`fR{oGkjE>Ii_q{pR*=pi8q#p;?^k>Q|dpPQqF-WnQ4 zou7L^eqhCrk)>r1#y{cJDv`7wgnkB3Vw1efD@#iq)@5V(F9xM?8LpzSq;i$>N5FWm z8V%<8liUuvdHd6p^D&_iSw^ntmst8Qq{aQtQ&S(tO6aa_Zi-!|dv0sr^l>*A{p#zp z7Im~^F*P%@1iRO2WiaDrZoF9cy(4O)UQ`(@e=GLik%x=ByL(z#SlG+#A^szJ0qO|0 z#X2*!f;hukhmZC3^)!TZ5*!XF&nu@Va2smBZm3}yjV3;f^1WQ-{`vFgd_Z8}7V6ip zmlm@UtgOHEvxl^*xhSzPcA9Ulmmi6`dabOk3UY99Z5tC2MLD(y6Wy>%O5QBF$Ry&T zpF=dltMBW!{2$2tf|wN*6^Bl`72EIMzyHR)pd4RH*w30V`kM~Gj|%gFay$Y8{ZhNx zx(A}j?MtMsZE^3U7Gv~isB9Jm-qoL<2pJn28*>?%HX5DcYV(ee2efJhqr0HK@zb9f zw}stK=i}AIN%P&zMpBGLv4AS^V>~kijUo z2!AP%Eh4Xl#&ICa6%kC0BoLt-3DBStB1wzwHNGo<))8F5p8ad6OSG#*gBzfu3 za};?t=zGm))*eJ~(+;b^d@GkQipP+%@l9dsh0yAR$c*d1-(Ryf9`~TiK`5-mT+QB} z$l)^NNN4EcC-RIVX?L+4{J@{jBTTT}51m z*&>xAR+iU^=o+`Zh2o*1A^S&SZlwbUAuAyWgKn7TZd>4edkK*CAtr@Ln*;l~q;ACU z@Ni@}wZPLS025q0Ka<04ZEU8Q>(56#l*H`uf6M3eOT3GYd) zMzN-~wuXjT;ak>Gr=JZ!T)aVkt8#OfyG_cpD5p+WaZ^m%Nep*0-VRk>1=;_E-x~l$)k}L4-fBjEkEO} zh6XlZ2XXQ7(u~pcLPD@8iE~!6&p{YR_6>VoQ(*0YO-+36Tu?GJoVVuU;<_`PF=^WJ z>_S%9aiPO6BqT)Kz`%ehB|#KSR90TzN6ckieF#kQCca>yUK_+_8KQWdA#qgzz}#lY z`($?2jr~GVMMV+?OG(Pexas;#&c1ygAK!)#o0cJG6?BQPqT*uC95uFw4E2Y^Jrdv(u_~ql}mH9;gql~ry;LpIsgtnXsPPk!(I%EYE#!4SN7)zjEnq|i9$zM8h<9LF4ynwq)^y4k#0c$GVB z{?GE#5?SNXxGs_HO!Zd#k4+X~VfT4}c;`k=PEKmbPI=s)?vEco2GMApzqv-n#l;yN ztPHpv4k=(j^~jwd0C}ynb%TJ)gqN0@XsOs{29CYrvBX;I#(}A#+M2ghtT)@ikdEq`(f~ryf^S$wDQnn*DR89 zcCIW#;y|qI?A8^H!NGSS^lfjhTdpDO9#iOkA7_9!{_{RAN4x%^YwjS^za+IZ%ghVZ&AY z%XI5h?Cr3mTduDz9*~lbWO)H?n{FJyy}y81o-W0z5K~eHkB+LpP7|prn46fO z1Y!dK{zxwTL?Mp#jm_b|p>)Jb{}cj+4pi1=g;QoIR3^IQd=hLGhfO9I`(g$=DIF9!Gal8p=vZ zK{7Hj4uBAHXqBStLidkn>=m4y`AvDL0CMQ)5jJWxH8lzOUW;)VHvKVi_zm*F<8yiX zd~0K4!}0Rev9`AMA1Xs~etGdk5M%%yDY^|4aakX|9i3Bo4F*pH0y#FK$LYc2SHn9F z21e_|9x-}c3SM4fU=R5X53AMI)yXhgo+jJ+C?4%E_q{2Zot-W7Jh9WOcP*ZI!u6$Z zIV3bx8r%;O?U=omBWOPto|#FnuCD%%O|@Ds+rV=wkq7QY?HL1~F8mN~+!lbRa=RGP zF4)x#u}K~v0&d>k-t{Mk9VR?tVq(cLOA*hy>bzYu0R9lCB04%drHeIdX5>pI;6Ua6 z>g{bCQIRBoh_OD>;N$!lS#z_s<>Y2#quM>;TnnpB0Gj`*eQ>a3mf5lc)(+y4fqVac zeM!v%V}P>(Qv96|5ICDt75SpBV>od9lICj>KPZ= z0Ut8FDFCAr1(Ep8KX2`cv(Fa?>3eLsn3UDNV_^yBdC43jQFZ);0dt7X_mV*wP)npq zl~}BWS9;79FdR0+xSLv*`x25sCDZYm;>t%p?D7Bf$qgU}ga)x(=yI_YhKGY?jNsTm zVO1rO`NjFA$Mnz8kZMX|V(k*T)!&sQwBs|+_+d-aOJ?4|emtoH^(>$TFHUxlrRC*n zc%ND@q&O%J7+wU8ewNMhfIL8#{$*N@F`I(*zvltr@&IUT0g!KDz*VP>p8cYNn=HyM zP*AK$_PjASU+D*o0~?4H{U-^1RS|q+RM4m;e=;@d=XiJbhZdrzIkJGs)EEKDCSz)v zBcDBl3;I3<0lOXl5o47OCr~m|$4@b&hy$2J(zchw!^2&^e*KDAa{38cutW6AoCynl z5vVRr6seZQ?*akmhEjmgVTi8_AF2do>=~5V(D0`y7LEYjxBwVIGuYC&9PI3cw>sA;#fb+)tl+!J35~U z2EPRRc&U*&~bJi znkNh}N(}JNgVxqoC8+LrS`|1-UoavO2K}&^kf1SJ+B*;n3(Fbc2VxPnR@T;E)e6un zE3WNHJ|fw`F^Nq`Smnf(v2=I;NnPx*%$xL@gq+;02GGozWLr!ye`lwH1)Awf%XiwU zs?iCuj6*`g!eg2KvWldHz|6s*eo{!+3FAZcq98P&aR8dA0eRa4m}~-2ca~T24*WF- z?k55$Nj}>$)}6*P8s8%EdJqVIz7MF5j!@FQ;aA))XQy3op!fn?jlL9)trH#?H~&*r z0*LA6cA5w$NZpF{`A8%FJmZSmKPN81ZHdv3V*?Ofv36*9$PXiVh z2B^2&x-j<+UwW&z>>QK5iM=)uRneeHec@FhtNPr|3aaH zN=mqci0I}jOTffh`ugrCB_-_wyXE)S7pgispMmpX0w6??JVC9Xqrv^4^uu6!9^UN8 z$VkdMw?RY5^t8_D#f4xM5Qjjv_{n_rYi^dT)Zyd;*S@|8z5@Ymk*QYT*Cp%4bj7Gz zS6iz!kRj=tU9kAi4hX>Y>GfjqOkm}#UtjDPo&$sA`ov=k2G7P2azMTFVB?p0N$H3p z;^``fE=i&NgM;Yw^vFifleXU8ds6KI8=&+dKS1ID0uj}_Zhcb9ZJTTK#DIVi)cs90 z8@;s^5fFgIp;L)FH8oXQRVAmV_mG5y1cH=uhxH58rvdGxxC6oasig4z1_5h?=y`Y^ zApbZjglVX>wY5Qz^~4W39UW>wD*vvm1l{&1(2!66Wk(UiU?G4GaA=offf#|x*Gs8=hfGz}NWK(nLV!+IPqyMc$|3JPTB{OrsO^s1`*UtI9l zAA=0}so)$L2!rW*fJ${}I!HO;zyGGmC@GnQglgOIW`I`Z8yz3N#iBv61ANe8h`71A zp%wtm5p3`BZu16MyR@t8bHAV}-Z3iyp;f>_Ir8%IgE?Jb$AC?* z4g5S=S=mbA=c^Av*xCjqZ}2l2+{Z^pA;`IZNNCFA1 zT6In8LJ!##Nrr12P_L-q{=lR{*4Nd|`2tG|sB$eGooY)OQc}z=80fOMRthPLGXLXV zpt+%zFAOh|4KV!*3)w+Q;da504h}$X`+yiGkdTrtQo$7=T8!PY`1mnfpnll^em~~q zEFLHe`}{dM5*x~vk7x@eWq}}oxY&@JyL)S`&19-Dq7>du2;8)`)>aIV65!Y>+1u~j zQ~@ELtybV8>b{?YC6!WWwvrxl-tS+J`O%<6!OChqC?Fs}(0=qkL^?J)*Z?<-c=*aW zoQL7rGh*?;J zHvMmE#&T+Nt8fW%s4R6CEJMtlHzqb#mxEkWRTYDdjxO%MYj;{7U{r_Gir2L-0u{RO zZz%h8zmJ;-xvd8mHr_MhP>K@OY9npwNF^3Lx*h~P#|4(?h`-s3q?lK zc_?sN9<Ngf%#x1;>pFEM|nUzDE zO9d2(aHaixlY8oc@|(zhSOpfEpydG)Fpm0}jOjXH5rQX0|M2bd?r|JW_>;1@{ip*_mU+swx*k<>us!3YMJg z?tanL*2bQioWwT{@A2E#UmU5$$!~0I{LJGjmp?-ONW!c34nb5^mD`gHkGPx{KoPhr zMA4=p_!LPjYMYH4l9Ux=zBKiWj8wd4j9%jH%26vI`$X@&aZ;w7zxatB2C4t7t*uNF z*#_GHqSm1i;4bLqJXbtA;s?Jh}^o$}*0E*ZBB2wP%8DQ$@eHYVyUmKRz2# zlGj2h>FE-JqN4R3qh-W09`j%)3HbQyfnL=O$`u!_WVBu>)KL?iV{)vZT|}FB;&d zT-jk$$l$I$MX1E(1mk`313@@J?#x})6~Mt+2EueZG{z%NJOmM0Sy^cd(Dlgae~;?@ zLz?@udm`V=%*?wU2>U>OHi#j>x&II8gCkbYmv(mBD!^OhNj)&|ln(_*WQ@Si;9sx$ zKt@KkbnA2?K8JYhOHhEJ?{;a4Q#aMy3_}H#aUHjw$UxZ^VVMNFjCA@V!wwi z$N_~fJYCy7(q4eRPSd3x?1bCH;DcFT5B~iUzG=`t!>?0N^pN4F=4zbANVHo38PDNc z5xj29bioFhBu&1_9M~x(2gec^U6ZU(HqHDT3RYj?E)Fgh!{Emdt&Jwx0F1`wyBqi> zsZPf48aI{D80VTP$aG*X45K5F6{PX!k1iha10C`~c(_2s->ocy3@|;B!;u z%LHK|A+6=*<-pCE8v77~61thXIiqJ-jfcap0FWdh#=(6kG9D5cP`<%LC;fmF6qJ-0 zP8&4JXS+WEc9xZtlphON2RH~AeJUs@XnJ#f^-jbpHZ}EfGUNf%@vB@l4Fy}UtQsvX zEjK_OME;A9e`8V7)X*TtAuN2x1zh|ON^v=TK!j}eC-M0JgN^|lI_h|OUO0hmX&ugE z0K7_oetMv&x^GoMpic4g!O=Z1r#EjR4g}}D_)tdAv_N+-sH&)_H@CIbFV-w92J3zV zR8t!0=q!Dvu)V=Zt5{ogb@sEU`rEgsH?lNlHJqL*Pnf# zz-{O=s9r`QgA3Kx*YAK9B@M7cDNsgrs?Go$%xb=WFZwEXIP2zayxy$RbDp(!aAXfD M$|=kKkTLr7f7;m5IRF3v literal 0 HcmV?d00001 diff --git a/wiki/draw/builder-primitives4.png b/wiki/draw/builder-primitives4.png new file mode 100644 index 0000000000000000000000000000000000000000..6d60ddf2cc054d6a30d4bb4ab967d05c9bf3df0a GIT binary patch literal 13071 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 literal 0 HcmV?d00001 diff --git a/wiki/renderengine.html b/wiki/renderengine.html index b076f0d9b..93cf42061 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -773,25 +773,38 @@ As the builder has to create a render node network implementing most of the feat !!pattern of operation The working pattern of this builder mechanics can be described as triggering, enqueuing, priorizing, recursing and exhausting. Without the priorizing part, it would be a depth-first call graph without any context state, forcing us to have all cross reference information available at every node or element to be treated. We prefer to avoid this overhead by ordering the operations into several phases and within these phases into correlated entities with the help of a ''weighting function'' and scheduling with a ''priority queue''
-
-
While assembling and building up the render engines node network, a small number of primitive building situations is encountered repeatedly. The BuilderToolKit provides a "fitting tool" for each of these situations, typically involving parametrisation and the application of a [[processing pattern|ProcPatt]].
+
+
While assembling and building up the render engines node network, a small number of primitive building situations is encountered repeatedly. The BuilderToolKit provides a "[[mould|BuilderMould]]" for each of these situations, typically involving parametrisation and the application of a [[processing pattern|ProcPatt]].
 
 !List of elementary building situations
 !!!inserting an Effect or Plugin
+[>img[draw/builder-primitives1.png]]
 * participating: a Pipe and an Effect
 * result: Effect appended at the pipe's exit node
 
+@@clear(right):display(block):@@
+
+
+!!!attaching a transition 
+[>img[draw/builder-primitives2.png]]
+* participating: N pipe's exit nodes, transition
+* result: transition has been attached with the pipe's exit nodes, new wiring requests created attached to the transition's exit node(s)
+
+@@clear(right):display(block):@@
+
 !!!building a source connection
+[>img[draw/builder-primitives3.png]]
 * participating: source port of a clip, media access point, processing pattern
 * result: processing pattern has been //executed//, resulting in a chain of nodes from the source reader to the clip source port
 
+@@clear(right):display(block):@@
+
 !!!wiring a general connection
 * participating: already verified connection request, providing a Pipe and an exit node; a processing pattern and a Placement
 * result: summation node prepended to the port of the pipe, processing pattern has been //executed// for building the connection from the exit node to the pipe's port, ParamProvider has been setup in accordance to the Placement.
+[>img[draw/builder-primitives4.png]]
 
-!!!attaching a transition 
-* participating: N pipe's exit nodes, transition
-* result: transition has been attached with the pipe's exit nodes, new wiring requests created attached to the transition's exit node(s)
+@@clear(right):display(block):@@
 
@@ -815,11 +828,11 @@ While building, the application of such a visiting tool (especially the [[NodeCr
-
-
Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounder several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool". The palette of these fitting tools is called the ''tool kit'' of the builder. It is subject to configuration by rules.
+
+
Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounder several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool" or [[mould|BuilderMould]]. The palette of these moulds is called the ''tool kit'' of the builder. It is subject to configuration by rules.
 
 !! {{red{open questions}}}
-* how to address these fitting tools
+* how to address these moulds
 * how to type them
 * how to parametrize them
 

From 93908cf29ff8f983f38d45ae37b1e244503e56ec Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Sun, 25 May 2008 06:18:58 +0200
Subject: [PATCH 119/245] further planning of implementation details

---
 wiki/renderengine.html | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/wiki/renderengine.html b/wiki/renderengine.html
index 93cf42061..94a0886b7 100644
--- a/wiki/renderengine.html
+++ b/wiki/renderengine.html
@@ -773,35 +773,51 @@ As the builder has to create a render node network implementing most of the feat
 !!pattern of operation
 The working pattern of this builder mechanics can be described as triggering, enqueuing, priorizing, recursing and exhausting. Without the priorizing part, it would be a depth-first call graph without any context state, forcing us to have all cross reference information available at every node or element to be treated. We prefer to avoid this overhead by ordering the operations into several phases and within these phases into correlated entities with the help of a ''weighting function'' and scheduling with a ''priority queue''
-
+
While assembling and building up the render engines node network, a small number of primitive building situations is encountered repeatedly. The BuilderToolKit provides a "[[mould|BuilderMould]]" for each of these situations, typically involving parametrisation and the application of a [[processing pattern|ProcPatt]].
 
+The ''Lifecycle'' of such a mould starts out by arming it with the object references involved into the next building step. After conducting this building step, the resulting render nodes can be found &mdash; depending on the situation &mdash; attached either to the same mould, or to another kind of mould, but in any case ready to included in the next building step. Thus, //effectively//&nbsp; the moulds are //used to handle the nodes being built,// due to the fact that the low-level model (nodes to be built) and the high-level model (objects directing what is to be built) are //never connected directly.//
+
 !List of elementary building situations
 !!!inserting an Effect or Plugin
 [>img[draw/builder-primitives1.png]]
+The __~PipeMould__ is used to chain up the effects attached to a clip (=local pipe) or global pipe (=bus)
 * participating: a Pipe and an Effect
+* point of reference: current exit node of the pipe
 * result: Effect appended at the pipe's exit node
+* returns: ~PipeMould holding onto the new exit node
 
 @@clear(right):display(block):@@
 
 
 !!!attaching a transition 
 [>img[draw/builder-primitives2.png]]
+After having completed N pipe's node chains, a __~CombiningMould__ can be used to join them into a [transition|TransitionsHandling]
 * participating: N pipe's exit nodes, transition
+* point of reference: N exit nodes corresponding to (completed) pipes
 * result: transition has been attached with the pipe's exit nodes, new wiring requests created attached to the transition's exit node(s)
+* returns: ~WiringMould, connected with the created wiring request
+Using this mould implicitly "closes" the involved pipes, which means that we give up any reference to the exit node and can't build any further effect attached to this pipes. Generally speaking, "exit node" isn't a special kind of node, rather it's a node we are currently holding on. Similarly, there is nothing directly correlated to a pipe within the render nodes network after we are done with building the part of the network corresponding to the pipe, which is used as a blueprint for building, but isn't an entity in the resulting low-level model.
+Actually, there is {{red{planned}}} a more general (and complicated) kind of transition, which can be inserted into N data connections without joining them together into one single output, as the standard transitions do. The ~CombiningMould can handle this case too by just returning N wiring moulds as a result.
 
 @@clear(right):display(block):@@
 
 !!!building a source connection
 [>img[draw/builder-primitives3.png]]
+The __~SourceChainMould__ is used as a starting point for any further building, as it results in a local pipe (=clip) rooted at the clip source port. This reflects the fact that the source readers (media access points) are the leaf nodes in the graph
 * participating: source port of a clip, media access point, processing pattern
+* point of reference: //none//
 * result: processing pattern has been //executed//, resulting in a chain of nodes from the source reader to the clip source port
+* returns: ~PipeMould holding onto the new exit node (of a yet-empty pipe)
 
 @@clear(right):display(block):@@
 
 !!!wiring a general connection
+Any wiring (outside the chain of effects within a pipe) is always done from exit nodes to the port of another pipe, requiring an [[wiring request|WiringRequest]] already checked and deemed resolvable. Within the __~WiringMould__ the actual wiring is conducted, possibly adding a summation node (called "overlayer" in case of video) and typically a fader element (the specific setup to be used is subject to configuration by processing patterns)
 * participating: already verified connection request, providing a Pipe and an exit node; a processing pattern and a Placement
+* points of reference: exit node and (optionally) starting point of a pipe's chain (in case there are already other connections)
 * result: summation node prepended to the port of the pipe, processing pattern has been //executed// for building the connection from the exit node to the pipe's port, ParamProvider has been setup in accordance to the Placement.
+* returns: ~PipeMould holding onto the destination pipe's exit node, ~WiringMould holding onto the port side of the same pipe, i.e. the destination where further connections will insert summation nodes. {{red{TODO how to handle the //empty//-case?}}}
 [>img[draw/builder-primitives4.png]]
 
 @@clear(right):display(block):@@
@@ -828,7 +844,7 @@ While building, the application of such a visiting tool (especially the [[NodeCr
 
 
-
+
Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounder several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool" or [[mould|BuilderMould]]. The palette of these moulds is called the ''tool kit'' of the builder. It is subject to configuration by rules.
 
 !! {{red{open questions}}}
@@ -836,7 +852,7 @@ While building, the application of such a visiting tool (especially the [[NodeCr
 * how to type them
 * how to parametrize them
 
-&rarr;see also: BuilderPrimitives for the elementary corresponding to these fitting tools
+&rarr;see also: BuilderPrimitives for the elementary working situations corresponding to these fitting tools
 
@@ -2379,12 +2395,12 @@ The GUI can connect the viewer(s) to some pipe (and moreover can use [[probe poi
-
+
!Identification
 Pipes are distinct objects and can be identified by their asset ~IDs. Besides, as for all [[structural assets|StructAsset]] there are extended query capabilities, including a symbolic pipe-id and a media (stream) type id. Any pipe can accept and deliver exactly one media stream kind (which may be inherently structured though, e.g. spatial sound systems or stereoscopic video)
 
 !creating pipes
-Pipe assets are created automatically by being used and referred. The [[Session]] holds a collection of global pipes, and further pipes can be created by using a new pipe reference in some placement. Moreover, every clip has an (implicit) [[source port|ClipSourcePort]], which will appear as pipe asset when first used (referred) while [[building|BuildProcess]]. Note that creating a new pipe implies using a [[processing pattern|ProcPatt]], which will be queried from the [[Defaults Manager|DefaultsManagement]] (resulting in the use of some preconfigured pattern or maybe the creation of a new ProcPatt object if necessary)
+Pipe assets are created automatically by being used and referred. The [[Session]] holds a collection of global pipes ({{red{todo: implementation missing as of 5/08}}}), and further pipes can be created by using a new pipe reference in some placement. Moreover, every clip has an (implicit) [[source port|ClipSourcePort]], which will appear as pipe asset when first used (referred) while [[building|BuildProcess]]. Note that creating a new pipe implies using a [[processing pattern|ProcPatt]], which will be queried from the [[Defaults Manager|DefaultsManagement]] (resulting in the use of some preconfigured pattern or maybe the creation of a new ProcPatt object if necessary)
 
 !removal
 Deleting a Pipe is an advanced operation, because it includes finding and "detaching" all references, otherwise the pipe will leap back into existence immediately. Thus, global pipe entries in the Session and pipe references in [[locating pins|LocatingPin]] within any placement have to be removed, while clips using a given source port will be disabled. {{red{todo: implementation deferred}}}
@@ -2577,13 +2593,12 @@ Besides, they provide an important __inward interface__ for the [[ProcNode]]s, w
 
 
-
+
The Render Engine is the part of the application doing the actual video calculations. Its operations are guided by the Objects and Parameters edited by the user in [[the EDL|EDL]] and it retrieves the raw audio and video data from the [[Data backend|backend.html]]. Because the inner workings of the Render Engine are closely related to the structures used in the EDL, this design covers [[the aspect of objects placed into the EDL|MObjects]] as well.
 <<<
 ''Status'': started out as design draft in summer '07, Ichthyo is now in the middle of a implementing the foundations and main structures in C++
 * basic AssetManager working
 * currently impmenenting the Builder (&rarr;[[more|PlanningNodeCreatorTool]])
-* intermittently working out how to deal with &rarr; [[ConfigQueries / default objects|ConfigQueryIntegration]])
 <<<
 
 !Summary

From 2e58b02b8a1cc84a7f9769f46a6fab9ff9d79ecd Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Mon, 26 May 2008 07:28:10 +0200
Subject: [PATCH 120/245] write down implementation specs and further planned
 details

---
 src/proc/mobject/builder/assembler.cpp        |  6 +-
 src/proc/mobject/builder/assembler.hpp        |  6 +-
 src/proc/mobject/builder/conmanager.cpp       |  7 +-
 src/proc/mobject/builder/conmanager.hpp       |  6 +-
 src/proc/mobject/builder/mould.cpp            | 37 ++++++++
 src/proc/mobject/builder/mould.hpp            | 85 ++++++++++++++++++
 ...odecreatertool.cpp => nodecreatortool.cpp} |  4 +-
 ...odecreatertool.hpp => nodecreatortool.hpp} |  6 +-
 src/proc/mobject/builder/operationpoint.hpp   | 52 +++++++++++
 src/proc/mobject/builder/toolfactory.cpp      | 11 +--
 src/proc/mobject/builder/toolfactory.hpp      | 21 +++--
 src/proc/mobject/builder/wiringrequest.hpp    | 54 ++++++++++++
 wiki/renderengine.html                        | 87 +++++++++++++++----
 13 files changed, 327 insertions(+), 55 deletions(-)
 create mode 100644 src/proc/mobject/builder/mould.cpp
 create mode 100644 src/proc/mobject/builder/mould.hpp
 rename src/proc/mobject/builder/{nodecreatertool.cpp => nodecreatortool.cpp} (92%)
 rename src/proc/mobject/builder/{nodecreatertool.hpp => nodecreatortool.hpp} (92%)
 create mode 100644 src/proc/mobject/builder/operationpoint.hpp
 create mode 100644 src/proc/mobject/builder/wiringrequest.hpp

diff --git a/src/proc/mobject/builder/assembler.cpp b/src/proc/mobject/builder/assembler.cpp
index 8542860f3..7bad26aac 100644
--- a/src/proc/mobject/builder/assembler.cpp
+++ b/src/proc/mobject/builder/assembler.cpp
@@ -23,10 +23,8 @@
 
 #include "proc/mobject/builder/assembler.hpp"
 
-namespace mobject
-  {
-  namespace builder
-    {
+namespace mobject {
+  namespace builder {
 
 
 
diff --git a/src/proc/mobject/builder/assembler.hpp b/src/proc/mobject/builder/assembler.hpp
index f0274f171..c4900e2da 100644
--- a/src/proc/mobject/builder/assembler.hpp
+++ b/src/proc/mobject/builder/assembler.hpp
@@ -28,10 +28,8 @@
 
 
 
-namespace mobject
-  {
-  namespace builder
-    {
+namespace mobject {
+  namespace builder {
 
 
     /**
diff --git a/src/proc/mobject/builder/conmanager.cpp b/src/proc/mobject/builder/conmanager.cpp
index e32ecf92b..3ad9e4fce 100644
--- a/src/proc/mobject/builder/conmanager.cpp
+++ b/src/proc/mobject/builder/conmanager.cpp
@@ -23,11 +23,8 @@
 
 #include "proc/mobject/builder/conmanager.hpp"
 
-namespace mobject
-  {
-
-  namespace builder
-    {
+namespace mobject {
+  namespace builder {
 
 
 
diff --git a/src/proc/mobject/builder/conmanager.hpp b/src/proc/mobject/builder/conmanager.hpp
index 3cd75cc6d..2c234afdd 100644
--- a/src/proc/mobject/builder/conmanager.hpp
+++ b/src/proc/mobject/builder/conmanager.hpp
@@ -26,10 +26,8 @@
 
 
 
-namespace mobject
-  {
-  namespace builder
-    {
+namespace mobject {
+  namespace builder {
 
 
     /**
diff --git a/src/proc/mobject/builder/mould.cpp b/src/proc/mobject/builder/mould.cpp
new file mode 100644
index 000000000..1cc98441b
--- /dev/null
+++ b/src/proc/mobject/builder/mould.cpp
@@ -0,0 +1,37 @@
+/*
+  Mould  -  builder tool kit for the basic building situations
+ 
+  Copyright (C)         Lumiera.org
+    2008,               Hermann Vosseler 
+ 
+  This program 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 2 of the
+  License, or (at your option) any later version.
+ 
+  This program 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 this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+* *****************************************************/
+
+
+#include "proc/mobject/builder/mould.hpp"
+
+namespace mobject {
+  namespace builder {
+
+
+
+    /** */
+
+
+
+  } // namespace mobject::builder
+
+} // namespace mobject
diff --git a/src/proc/mobject/builder/mould.hpp b/src/proc/mobject/builder/mould.hpp
new file mode 100644
index 000000000..6c714157a
--- /dev/null
+++ b/src/proc/mobject/builder/mould.hpp
@@ -0,0 +1,85 @@
+/*
+  MOULD.hpp  -  builder tool kit for the basic building situations
+ 
+  Copyright (C)         Lumiera.org
+    2008,               Hermann Vosseler 
+ 
+  This program 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 2 of the
+  License, or (at your option) any later version.
+ 
+  This program 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 this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+*/
+
+
+#ifndef MOBJECT_BUILDER_MOULD_H
+#define MOBJECT_BUILDER_MOULD_H
+
+
+#include "proc/asset/procpatt.hpp"
+#include "proc/mobject/builder/operationpoint.hpp"
+
+#include 
+
+namespace mobject {
+  namespace builder {
+  
+    using std::vector;
+    using asset::PProcPatt;
+    using lumiera::Symbol;
+
+
+    /**
+     * Interface: a holder tool used by the builder to
+     * wire up a specific building situation and then to
+     * apply/execute a single building step. Mould is the 
+     * passive part, while usually the ProcPatt is the active
+     * counterpart. By means of the Mould interface, the specifics
+     * of a build situation are abstracted away, thus allowing the
+     * processing pattern to be defined as working on symbolic
+     * locations. The most common location is "current", denoting
+     * the render node just being built.
+     * 
  • PipeMould supports attaching an effect to a pipe
  • + *
  • combining pipes via a transition is done by a CombiningMould
  • + *
  • a SourceChainMould allows to start out from a source reader and build a clip
  • + *
  • wiring general connections is supported by the WiringMould
  • + */ + class Mould + { + public: + vector operate (); + + OperationPoint& getLocation (Symbol locationID); + }; + + + class PipeMould : public Mould + { + }; + + class CombiningMould : public Mould + { + }; + + class SourceChainMould : public Mould + { + }; + + class WiringMould : public Mould + { + }; + + + } // namespace mobject::builder + +} // namespace mobject +#endif diff --git a/src/proc/mobject/builder/nodecreatertool.cpp b/src/proc/mobject/builder/nodecreatortool.cpp similarity index 92% rename from src/proc/mobject/builder/nodecreatertool.cpp rename to src/proc/mobject/builder/nodecreatortool.cpp index 93362ef25..1d0acec05 100644 --- a/src/proc/mobject/builder/nodecreatertool.cpp +++ b/src/proc/mobject/builder/nodecreatortool.cpp @@ -1,5 +1,5 @@ /* - NodeCreaterTool - central Tool implementing the Renderengine building + NodeCreatorTool - central Tool implementing the Renderengine building Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,7 +21,7 @@ * *****************************************************/ -#include "proc/mobject/builder/nodecreatertool.hpp" +#include "proc/mobject/builder/nodecreatortool.hpp" #include "proc/mobject/session/clip.hpp" #include "proc/mobject/session/effect.hpp" #include "proc/mobject/session/auto.hpp" diff --git a/src/proc/mobject/builder/nodecreatertool.hpp b/src/proc/mobject/builder/nodecreatortool.hpp similarity index 92% rename from src/proc/mobject/builder/nodecreatertool.hpp rename to src/proc/mobject/builder/nodecreatortool.hpp index e37d0d14f..616700a87 100644 --- a/src/proc/mobject/builder/nodecreatertool.hpp +++ b/src/proc/mobject/builder/nodecreatortool.hpp @@ -1,5 +1,5 @@ /* - NODECREATERTOOL.hpp - central Tool implementing the Renderengine building + NODECREATORTOOL.hpp - central Tool implementing the Renderengine building Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,8 +21,8 @@ */ -#ifndef MOBJECT_BUILDER_NODECREATERTOOL_H -#define MOBJECT_BUILDER_NODECREATERTOOL_H +#ifndef MOBJECT_BUILDER_NODECREATORTOOL_H +#define MOBJECT_BUILDER_NODECREATORTOOL_H #include "proc/mobject/builder/applicablebuildertargettypes.hpp" diff --git a/src/proc/mobject/builder/operationpoint.hpp b/src/proc/mobject/builder/operationpoint.hpp new file mode 100644 index 000000000..d48e9ecf6 --- /dev/null +++ b/src/proc/mobject/builder/operationpoint.hpp @@ -0,0 +1,52 @@ +/* + OPERATIONPOINT.hpp - abstraction representing the point where to apply a build instruction + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#ifndef MOBJECT_BUILDER_OPERATIONPOINT_H +#define MOBJECT_BUILDER_OPERATIONPOINT_H + + + + +namespace mobject { + namespace builder { + + + /** + * A point in the render node network under construction. + * By means of this unspecific reference, a ProcPatt is able + * to deal with this location and to execute a single elementary + * building operation denoted by a BuildInstruct at this point. + * Usually, the actual point is retrieved from a Mould + */ + class OperationPoint + { + public: + + }; + + + + } // namespace mobject::builder + +} // namespace mobject +#endif diff --git a/src/proc/mobject/builder/toolfactory.cpp b/src/proc/mobject/builder/toolfactory.cpp index 8e1b14631..06cbd114c 100644 --- a/src/proc/mobject/builder/toolfactory.cpp +++ b/src/proc/mobject/builder/toolfactory.cpp @@ -23,17 +23,12 @@ #include "proc/mobject/builder/toolfactory.hpp" -namespace mobject - { - namespace builder - { +namespace mobject { + namespace builder { - BuilderTool & - ToolFactory::configure () - { - } + /** */ diff --git a/src/proc/mobject/builder/toolfactory.hpp b/src/proc/mobject/builder/toolfactory.hpp index 2061b4fd2..5d30c9eea 100644 --- a/src/proc/mobject/builder/toolfactory.hpp +++ b/src/proc/mobject/builder/toolfactory.hpp @@ -25,19 +25,28 @@ #define MOBJECT_BUILDER_TOOLFACTORY_H #include "proc/mobject/builder/buildertool.hpp" +#include "proc/asset/pipe.hpp" +#include "proc/mobject/session/clip.hpp" +#include "proc/mobject/builder/wiringrequest.hpp" + +#include +namespace mobject { + namespace builder { -namespace mobject - { - namespace builder - { - + using std::vector; + using asset::PPipe; + using session::PClipMO; class ToolFactory { public: - BuilderTool & configure () ; + PipeMould& provideMould(PPipe const&); + CombiningMould& provideMould(vector&); + SourceChainMould& provideMould(PClipMO const&); + WiringMould& provideMould(WiringRequest const&); + }; diff --git a/src/proc/mobject/builder/wiringrequest.hpp b/src/proc/mobject/builder/wiringrequest.hpp new file mode 100644 index 000000000..ae1992832 --- /dev/null +++ b/src/proc/mobject/builder/wiringrequest.hpp @@ -0,0 +1,54 @@ +/* + WIRINGREQUEST.hpp - intention to send the output of a pipe to another pipe's port + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#ifndef MOBJECT_BUILDER_WIRINGREQUEST_H +#define MOBJECT_BUILDER_WIRINGREQUEST_H + + + + +namespace mobject { + namespace builder { + + + /** + * Request to make a connection. + * This connection may imply some data conversions, + * thus it has to be \link #isInvestigated chcked \endlink + * and may be deemed impossible. Otherwise, it can actually + * be carried out by the help of the WiringMould. + * @see ToolFactory#provideMould(WiringRequest const&); + */ + class WiringRequest + { + public: + bool isInvestigated(); + bool isPossible(); + }; + + + + } // namespace mobject::builder + +} // namespace mobject +#endif diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 94a0886b7..c55d698a2 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -773,10 +773,18 @@ As the builder has to create a render node network implementing most of the feat !!pattern of operation The working pattern of this builder mechanics can be described as triggering, enqueuing, priorizing, recursing and exhausting. Without the priorizing part, it would be a depth-first call graph without any context state, forcing us to have all cross reference information available at every node or element to be treated. We prefer to avoid this overhead by ordering the operations into several phases and within these phases into correlated entities with the help of a ''weighting function'' and scheduling with a ''priority queue''
-
+
+
The [[Builder]] uses different kinds of tools for creating a network of render nodes from a given high-level model. When breaking down this (necessarily complex) process into small manageable chunks, we arrive at [[elementary building situations|BuilderPrimitives]]. For each of these there is a specialized tool. We denote these tools as "moulds" because they are a rather passive holder for the objects to be attached and wired up. They are shaped according to the basic form the connections have to follow for each of these basic situations:
+* attaching an effect to a pipe
+* combining pipes via a transition
+* starting out a pipe from a source reader
+* general connections from the exit node of a pipe to the port of another pipe
+In all those cases, the active part is provided by [[processing patterns|ProcPatt]] &mdash; sort of micro programs executed within the context of a given mould: the processing pattern defines the steps to take (in the standard/basic case this is just "attach"), while the mould holds and provides the location where these steps will operate.
+
+
While assembling and building up the render engines node network, a small number of primitive building situations is encountered repeatedly. The BuilderToolKit provides a "[[mould|BuilderMould]]" for each of these situations, typically involving parametrisation and the application of a [[processing pattern|ProcPatt]].
 
-The ''Lifecycle'' of such a mould starts out by arming it with the object references involved into the next building step. After conducting this building step, the resulting render nodes can be found &mdash; depending on the situation &mdash; attached either to the same mould, or to another kind of mould, but in any case ready to included in the next building step. Thus, //effectively//&nbsp; the moulds are //used to handle the nodes being built,// due to the fact that the low-level model (nodes to be built) and the high-level model (objects directing what is to be built) are //never connected directly.//
+The ''Lifecycle'' of such a mould starts out by arming it with the object references involved into the next building step. After conducting this building step, the resulting render nodes can be found &mdash; depending on the situation &mdash; attached either to the same mould, or to another kind of mould, but in any case ready to be included in the next building step. Thus, //effectively//&nbsp; the moulds are //used to handle the nodes being built,// due to the fact that the low-level model (nodes to be built) and the high-level model (objects directing what is to be built) are //never connected directly.//
 
 !List of elementary building situations
 !!!inserting an Effect or Plugin
@@ -792,20 +800,20 @@ The __~PipeMould__ is used to chain up the effects attached to a clip (=local pi
 
 !!!attaching a transition 
 [>img[draw/builder-primitives2.png]]
-After having completed N pipe's node chains, a __~CombiningMould__ can be used to join them into a [transition|TransitionsHandling]
+After having completed N pipe's node chains, a __~CombiningMould__ can be used to join them into a [[transition|TransitionsHandling]]
 * participating: N pipe's exit nodes, transition
 * point of reference: N exit nodes corresponding to (completed) pipes
 * result: transition has been attached with the pipe's exit nodes, new wiring requests created attached to the transition's exit node(s)
 * returns: ~WiringMould, connected with the created wiring request
-Using this mould implicitly "closes" the involved pipes, which means that we give up any reference to the exit node and can't build any further effect attached to this pipes. Generally speaking, "exit node" isn't a special kind of node, rather it's a node we are currently holding on. Similarly, there is nothing directly correlated to a pipe within the render nodes network after we are done with building the part of the network corresponding to the pipe, which is used as a blueprint for building, but isn't an entity in the resulting low-level model.
+Using this mould implicitly "closes" the involved pipes, which means that we give up any reference to the exit node and can't build any further effect attached to this pipes. Generally speaking, "exit node" isn't a special kind of node, rather it's a node we are currently holding on. Similarly, there is nothing directly correlated to a pipe within the render nodes network after we are done with building the part of the network corresponding to the pipe; the latter serves rather as a blueprint for building, but isn't an entity in the resulting low-level model.
 Actually, there is {{red{planned}}} a more general (and complicated) kind of transition, which can be inserted into N data connections without joining them together into one single output, as the standard transitions do. The ~CombiningMould can handle this case too by just returning N wiring moulds as a result.
 
 @@clear(right):display(block):@@
 
 !!!building a source connection
 [>img[draw/builder-primitives3.png]]
-The __~SourceChainMould__ is used as a starting point for any further building, as it results in a local pipe (=clip) rooted at the clip source port. This reflects the fact that the source readers (media access points) are the leaf nodes in the graph
-* participating: source port of a clip, media access point, processing pattern
+The __~SourceChainMould__ is used as a starting point for any further building, as it results in a local pipe (=clip) rooted at the clip source port. This reflects the fact that the source readers (=media access points) are the //leaf nodes// in the node graph we are about to build.
+* participating: source port of a clip, media access point, [[processing pattern|ProcPatt]]
 * point of reference: //none//
 * result: processing pattern has been //executed//, resulting in a chain of nodes from the source reader to the clip source port
 * returns: ~PipeMould holding onto the new exit node (of a yet-empty pipe)
@@ -816,7 +824,7 @@ The __~SourceChainMould__ is used as a starting point for any further building,
 Any wiring (outside the chain of effects within a pipe) is always done from exit nodes to the port of another pipe, requiring an [[wiring request|WiringRequest]] already checked and deemed resolvable. Within the __~WiringMould__ the actual wiring is conducted, possibly adding a summation node (called "overlayer" in case of video) and typically a fader element (the specific setup to be used is subject to configuration by processing patterns)
 * participating: already verified connection request, providing a Pipe and an exit node; a processing pattern and a Placement
 * points of reference: exit node and (optionally) starting point of a pipe's chain (in case there are already other connections)
-* result: summation node prepended to the port of the pipe, processing pattern has been //executed// for building the connection from the exit node to the pipe's port, ParamProvider has been setup in accordance to the Placement.
+* result: summation node prepended to the port of the pipe, processing pattern has been //executed// for building the connection from the exit node to the pipe's port, ParamProvider has been setup in [[accordance|PlacementDerivedDimension]] to the Placement.
 * returns: ~PipeMould holding onto the destination pipe's exit node, ~WiringMould holding onto the port side of the same pipe, i.e. the destination where further connections will insert summation nodes. {{red{TODO how to handle the //empty//-case?}}}
 [>img[draw/builder-primitives4.png]]
 
@@ -844,14 +852,23 @@ While building, the application of such a visiting tool (especially the [[NodeCr
 
 
-
-
Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounder several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool" or [[mould|BuilderMould]]. The palette of these moulds is called the ''tool kit'' of the builder. It is subject to configuration by rules.
+
+
Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounter several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool" or [[mould|BuilderMould]]. The palette of these moulds is called the ''tool kit'' of the builder. It is subject to configuration by rules.
 
 !! {{red{open questions}}}
 * how to address these moulds
 * how to type them
 * how to parametrize them
 
+!!addressing a mould
+All mould instances are owned and managed by the [[tool factory|BuilderToolFactory]], and can be referred to by their type ({{{PipeMould}}}, {{{CombiningMould}}}, {{{SourceChainMould}}}, {{{WiringMould}}}) and a concrete object instance (of suitable type). The returned mould (instance) acts as a handle to stick together the given object instance (from the high-level model) with the corresponding point in the low-level node network under construction. As consequence of this approach, the tool factory instance holds a snapshot of the current building state, including all the active spots in the build process. As the latter is driven by objects from the high-level model appearing (in a sensible order &rarr; see BuilderMechanics) within the NodeCreatorTool, new moulds will be created and fitted as necessary, and existing moulds will be exhausted when finished, until the render node network is complete.
+
+!!configuring a mould
+As each mould kind is different, it has a {{{prepare(...)}}} function with suitably typed parameters. The rest is intended to be  self-configuring (for example, a ~CombiningMould will detect the actual kind of Transition and select the internal mode of operation), so that it's sufficient to just call {{{operate()}}}
+
+!!sequence of operations
+When {{{operate()}}} doesn't throw, the result is a list of //successor moulds// &mdash; you shouldn't use the original mould after triggering its operation, because it may have been retracted as a result and reused for another purpose by the tool factory. It is not necessary to store these resulting moulds either (as they can be retrieved as described above), but they can be used right away for the next building step if applicable. In the state they are returned from a successful building step (mould operation = execution of a contained [[processing pattern|ProcPatt]]), they are usually already holding a reference to the part of the network just created and need to be configured only with the next high-level object (effect, placement, pipe, processing pattern or similar, depending on the concrete situation) in order to carry out the next step.
+
 &rarr;see also: BuilderPrimitives for the elementary working situations corresponding to these fitting tools
 
@@ -2410,17 +2427,37 @@ there is not much you can do directly with a pipe asset. It is an point of refer Pipes are integrated with the [[management of defaults|DefaultsManagement]]. For example, any pipe uses implicitly some [[processing pattern|ProcPatt]] &mdash; it may default to the empty pattern. This feature enables to apply some standard wiring to the pipes (e.g a fader for audio, similar to the classic mixing consoles). This //is // a global property of the pipe, but &mdash; contrary to the stream type &mdash; this pattern may be switched
-
-
A Placement represents a //relation:// it is always linked to a //Subject// (this being a [[Media Object|MObject]]) and has the meaning to //place// this Subject in some manner, either relatively to other Media Objects, or by some Constraint or simply absolute at (time,track). The latter case is especially important and represented by a special [[Sub-Interface|ExplicitPlacement]]
+
+
A Placement represents a //relation:// it is always linked to a //Subject// (this being a [[Media Object|MObject]]) and has the meaning to //place// this Subject in some manner, either relatively to other Media Objects, or by some Constraint or simply absolute at (time, output). The latter case is especially important for the build process and thus represented by a special [[Sub-Interface ExplicitPlacement|ExplicitPlacement]]. Besides this simple cases, Placements can also express more specific kinds of "locating" an object, like placing a sound source at a pan position or placing a video clip at a given layer (above or below another video clip)
+
+So basically placements represent a query interface: you can allways ask the placement to find out about the position of the related object in terms of (time, output), and &mdash; depending on the specific object and situation &mdash; also about these additional [[placement derived dimensions|PlacementDerivedDimension]] like sound pan or layer order or similar things which also fit into the general concept of "placing" an object.
 
 The fact of being placed in the [[Session|SessionOverview]]/[[EDL]]is constitutive for all sorts of [[MObject]]s, without Placement they make no sense. Thus &mdash; technically &mdash; Placements act as ''smart pointers''. Of course, there are several kinds of Placements and they are templated on the type of MObject they are refering to. Placements can be //aggregated// to increasingly constrain the resulting "location" of the refered ~MObject. See &rarr; [[handling of Placements|PlacementHandling]] for more details
-
+
+
For any [[media object|MObject]] within the session, we can allways at least query the time (reference/start) point and the output destination from the [[Placement]], by which the object is being handled. But the simple act of placing an object in some way, can &mdash; depending on the context &mdash; create additional degrees of freedom. To list some important examples:
+* placing a video clip overlapping with other clips on other tracks creates the possibility for the clip to be above another clip or to be combined in various other ways with the other clips at the same time position
+* placing a mono sound object plugged to a stereophoic output destination creates the freedom to define the pan position
+The Placement interface allows to query for these additional //parameter values derived from the fact of being placed.//
+
+!defining additional dimensions
+probably a LocatingPin but... {{red{TODO any details are yet unknown as of 5/08}}}
+!querying additional dimensions
+basically you resolve the Placement, yielding an ExplicitPlacement... {{red{TODO but any details of how additional dimensions are resolved is still undefined as of 5/08}}}
+
+
[[Placement]]s are at the very core of all [[editing operations|EditingOperations]], because they act as handles (smart pointers) to access the [[media objects|MObject]] to be manipulated. Moreover, Placements are the actual content of the EDL(s) and Fixture and thus are small objects with //value semantics//. Many editing tasks include finding some Placement in the EDL or directly take a ref to some Placement. By acting on the Placement object, we can in some cases change parameters of the way the media object is placed (e.g. adjust an offset), while by dereferencing the Placement object, we access the "real" media object (e.g. for trimming its length). Placements are ''templated'' on the type of the actual ~MObject they refer to, thus defining the interface/methods usable on this object.
 
-Actually, the way each Placement locates its subject is implemented by one or several small LocatingPin objects, where subclasses of LocatingPin implement the various differend methods of placing and resolving the final location. Notably, we can give a ~FixedLocation or we can atach to another ~MObject to get a ~RelativeLocation, etc.
+Actually, the way each Placement locates its subject is implemented by one or several small LocatingPin objects, where subclasses of LocatingPin implement the various different methods of placing and resolving the final location. Notably, we can give a ~FixedLocation or we can atach to another ~MObject to get a ~RelativeLocation, etc. In the typical use case, these ~LocatingPins are added to the Placement, but never retrieved directly. Rather the Placement acts as a ''query interface'' for determining the location of the related object. Here, "location" can be thought of as encompassing multiple dimenstions at the same time. An object can be
+* located at a specific point in time
+* related to and plugged into a specific output or global bus
+* defined to have a position within some [[context-dependant additional dimensions|PlacementDerivedDimension]] like
+** the pan position, either on the stereophoic base, or within a fully periphoic (spatial) sound system
+** the layer order and overlay mode for video (normal, additive, subtractive, masking)
+** the stereoscopic window position (depth parameter) for 3D video
+** channel and parameter selection for MIDI data
 
-Placements have //value semantics,// i.e. we don't stress the identity of a placement object (~MObjects on the other hand //do have// a distinguishable identity): initially, you create a Placement parametrized to some specific kind (fixed, relative,...), but later on, you treat the placement polymorphically and don't care about its kind. The sole purpose of the placement's kind is to select some virtual function implementing the desired behaviour. There is no limitation to one single Placement per ~MObject, indeed we have several different Placements of the same MObject (from a users point of view, this behaves like having clones). Besides, we can ''aggregate'' additional [[LocatingPin]]a to one Placements, resulting in their properties and constraints being combined to yield the actual position of the referred ~MObject.
+Placements have //value semantics,// i.e. we don't stress the identity of a placement object (~MObjects on the other hand //do have// a distinguishable identity): initially, you create a Placement parametrized to some specific kind by adding [[LocatingPin]]s (fixed, relative,...) and possibliy you use a subclass of {{{Placement<MObject>}}} to encode additional type information, say {{{Placement<Clip>}}}, but later on, you treat the placement polymorphically and don't care about its kind. The sole purpose of the placement's kind is to select some virtual function implementing the desired behaviour. There is no limitation to one single Placement per ~MObject, indeed we can have several different Placements of the same MObject (from a users point of view, these behave like being clones). Besides, we can ''aggregate'' additional [[LocatingPin]]s to one Placements, resulting in their properties and constraints being combined to yield the actual position of the referred ~MObject.
 
 !design decisions
 * the actual way of placing is implemented similar to the ''State Pattern'' by small embedded LocatingPin objects.
@@ -2624,17 +2661,29 @@ The system is ''open'' inasmuch every part mirrors the structure of correspondin
 
A data processing node within the Render Engine. Its key feature is the possibility to pull from it one (freely addressable) [[Frame]] of calculated data. Further, each ~ProcNode has the ability to be wired with other nodes and [[Parameter Providers|ParamProvider]]
 
-
-
This special type of [[structural Asset|StructAsset]] represents information how to build some part of the render engine's processing nodes network. It can be thought of as a template or blueprint for construction. Most notably, it is used for creating nodes reading, decoding and delivering source media material to the render network. Each [[media Asset|MediaAsset]] has associated processing patterns describing the codecs and other transformations needed to get at the media data of this asset. (and because media assets are typically compound objects, the referred ~ProcPatt will be compound too). Obviously, the possibilities opened by using processing patterns go far beyond.
+
+
This special type of [[structural Asset|StructAsset]] represents information how to build some part of the render engine's processing nodes network. Processing patterns can be thought of as a blueprint or micro program for construction. Most notably, they are used for creating nodes reading, decoding and delivering source media material to the render network, and they are used for building the output connection via faders, summation or overlay nodes to the global pipes (busses). Each [[media Asset|MediaAsset]] has associated processing patterns describing the codecs and other transformations needed to get at the media data of this asset. (and because media assets are typically compound objects, the referred ~ProcPatt will be compound too). Similarily, for each stream kind, we can retrieve a processing pattern for making output connections. Obviously, the possibilities opened by using processing patterns go far beyond.
 
 Technically, a processing pattern is a list of building instructions, which will be //executed// by the [[Builder]] on the render node network under construction. This implies the possibility to define further instruction kinds when needed in future; at the moment the relevant sorts of instructions are
 * attach the given sequence of nodes to the specified point
 * recursively execute a nested ~ProcPatt
-More specifically, a sequence of nodes is given by a sequence of prototypical effect and codec assets (and from each of them we can create the corresponding render node). And the point to attach these nodes is given by an identifier &mdash; in most cases just "{{{current}}}", denoting the point the builder was just working at, when he treated some MObject which in turn yielded this processing pattern in question.
+More specifically, a sequence of nodes is given by a sequence of prototypical effect and codec assets (and from each of them we can create the corresponding render node). And the point to attach these nodes is given by an identifier &mdash; in most cases just "{{{current}}}", denoting the point the builder is currently working at, when treating some placed ~MObject which in turn yielded this processing pattern in question.
 
-Like all [[structural assets|StructAsset]], ~ProcPatt employs a special naming scheme within the asset name field, which directly mirrors its purpose and allows to bind to existing processing pattern instances when needed. The idea is letting all assets in need of a similar processing pattern refer to one shared ~ProcPatt instance. For example, within a MPEG video media asset, at some point there will be a ~ProcPatt labeled "{{{stream(mpeg)}}}". In consequence, all MPEG video will use the same pattern of node wiring. And, of course, this pattern could be changed, either globally, or by binding a single clip to some other processing pattern (for making a punctual exception from the general rule)
+Like all [[structural assets|StructAsset]], ~ProcPatt employs a special naming scheme within the asset name field, which directly mirrors its purpose and allows to bind to existing processing pattern instances when needed. {{red{TODO: that's just the general idea, but really it will rather use some sort of tags. Yet undefined as of 5/08}}} The idea is letting all assets in need of a similar processing pattern refer to one shared ~ProcPatt instance. For example, within a MPEG video media asset, at some point there will be a ~ProcPatt labeled "{{{stream(mpeg)}}}". In consequence, all MPEG video will use the same pattern of node wiring. And, of course, this pattern could be changed, either globally, or by binding a single clip to some other processing pattern (for making a punctual exception from the general rule) 
+
+!!defining Processing Patterns
+The basic working set of processing patterns can be expected to be just there (hard wired or default configuration, mechanism for creating an sensible fallback). Besides, the idea is that new processing patterns can be added via rules in the session and then referred to by other rules controlling the build process. Any processing pattern is assembled by adding individual build instructions, or by including another (nested) processing pattern.
+
+!!retrieving a suitable Processing Pattern
+For a given situation, the necessary ProcPatt can be retrieved by issuing a [[configuration query|ConfigQuery]]. This query should include the needed capabilities in predicate form (technically this query is a Prolog goal), but it can leave out informations by just requesting "the default" &rarr; see DefaultsManagement
+
+!!how does this actually work?
+Any processing pattern needs the help of a passive holder tool suited for a specific [[building situation|BuilderPrimitives]]; we call these holder tools [[building moulds|BuilderMould]]. Depending on the situation, the mould has been armed up by the builder with the involved objects to be connected and extended. So, just by issuing the //location ID// defined within the individual build instruction (in most cases simply {{{"current"}}}), the processing pattern can retrieve the actual render object to use for building from the mould it is executed in.
+
+!!errors and misconfiguration
+Viewed as a micro program, the processing patterns are ''weak typed'' &mdash; thus providing the necessary flexibility within an otherwise strong typed system. Consequently, the builder assumes they are configured //the right way// &mdash; and will just bail out when this isn't the case, marking the related part of the high-level model as erroneous.
+&rarr; see BuilderErrorHandling for details
 
-//Note,// nothing has been said about how processing patterns are defined. One can expect for some //default patterns// beeing defined somewhere in the application, any session could overrule these defaults, and when there is no default, we can expect some mechanism deriving sensible fallback patterns //for every specific use case// of processing patterns. See the problem of [[Loading Media]] as an example.
 
From 5d5119631bbc5997ef828a7908af9f1b7c603d43 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 27 May 2008 07:22:27 +0200 Subject: [PATCH 121/245] first outline regarding the wiring of nodes within the builder --- src/proc/engine/nodefactory.cpp | 41 ++++++++++++ src/proc/engine/nodefactory.hpp | 70 +++++++++++++++++++++ src/proc/engine/procnode.cpp | 8 ++- src/proc/engine/procnode.hpp | 35 +++++++++-- src/proc/engine/trafo.hpp | 16 ++++- src/proc/mobject/builder/mould.hpp | 22 ++++--- src/proc/mobject/builder/operationpoint.hpp | 23 ++++++- src/proc/mobject/builder/toolfactory.hpp | 1 + src/proc/mobject/session/mobjectfactory.hpp | 17 +++-- wiki/renderengine.html | 35 ++++++++--- 10 files changed, 230 insertions(+), 38 deletions(-) create mode 100644 src/proc/engine/nodefactory.cpp create mode 100644 src/proc/engine/nodefactory.hpp diff --git a/src/proc/engine/nodefactory.cpp b/src/proc/engine/nodefactory.cpp new file mode 100644 index 000000000..d439232f3 --- /dev/null +++ b/src/proc/engine/nodefactory.cpp @@ -0,0 +1,41 @@ +/* + NodeFactory - Interface for creating processing nodes of variouos kinds + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include "proc/engine/nodefactory.hpp" +#include "proc/mobject/session/effect.hpp" + +namespace engine { + + using mobject::Placement; + using mobject::session::Effect; + + + /** create a processing node able to render an effect */ + PTrafo + NodeFactory::operator() (Placement const&) + { + UNIMPLEMENTED ("create proc node for Effect/Plugin"); + } + + +} // namespace engine diff --git a/src/proc/engine/nodefactory.hpp b/src/proc/engine/nodefactory.hpp new file mode 100644 index 000000000..8dbcc5f0c --- /dev/null +++ b/src/proc/engine/nodefactory.hpp @@ -0,0 +1,70 @@ +/* + NODEFACTORY.hpp - Interface for creating processing nodes of variouos kinds + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#ifndef ENGINE_NODEFACTORY_H +#define ENGINE_NODEFACTORY_H + +#include "proc/engine/procnode.hpp" +#include "proc/mobject/placement.hpp" + + + +namespace mobject { + namespace session { + + class Clip; + class Effect; + typedef Placement PEffect; + // TODO: class Transition; + + } // namespace mobject::session + +} // namespace mobject + + +namespace engine { + + using std::vector; + + class Trafo; + typedef Trafo* PTrafo; ///< @todo handle ProcNode by pointer or by shared-ptr?? + + + /** + * Create processing nodes based on given objects of the high-level model. + */ + class NodeFactory + { + /** custom deleter func allowing a smart-ptr + * to take ownership of processing nodes + */ + static void deleterFunc (ProcNode* pno) { delete pno; } + + public: + + PTrafo operator() (mobject::session::PEffect const&); + + }; + +} // namespace engine +#endif diff --git a/src/proc/engine/procnode.cpp b/src/proc/engine/procnode.cpp index 48e33c498..984c4dece 100644 --- a/src/proc/engine/procnode.cpp +++ b/src/proc/engine/procnode.cpp @@ -22,12 +22,14 @@ #include "proc/engine/procnode.hpp" +#include "proc/engine/nodefactory.hpp" -namespace engine - { +namespace engine { - /** */ + /** Storage for the (single, static) ProcNode factory object. + */ + NodeFactory ProcNode::create; } // namespace engine diff --git a/src/proc/engine/procnode.hpp b/src/proc/engine/procnode.hpp index ae210f96b..e2a4c89b9 100644 --- a/src/proc/engine/procnode.hpp +++ b/src/proc/engine/procnode.hpp @@ -29,12 +29,16 @@ #include "proc/mobject/parameter.hpp" -using std::vector; +namespace engine { -namespace engine - { + using std::vector; + + class ProcNode; + class NodeFactory; + + typedef ProcNode* PNode; ///< @todo handle ProcNode by pointer or by shared-ptr?? /** @@ -42,16 +46,37 @@ namespace engine */ class ProcNode { - protected: typedef mobject::Parameter Param; /** The predecessor in a processing pipeline. * I.e. a source to get data to be processed */ - ProcNode * datasrc; + PNode datasrc; vector params; + protected: + ProcNode(); + virtual ~ProcNode() {}; + + friend class NodeFactory; + + + /** do the actual calculations. + * @internal dispatch to implementation. + * Client code should use #render() + * @todo obviously we need a parameter!!! + */ + virtual void process() = 0; + + public: + static NodeFactory create; + + /** render and pull output from this node. + * @todo define the parameter!!! + */ + void render() { this->process(); } + }; } // namespace engine diff --git a/src/proc/engine/trafo.hpp b/src/proc/engine/trafo.hpp index 8d2155661..d1b6ba3cb 100644 --- a/src/proc/engine/trafo.hpp +++ b/src/proc/engine/trafo.hpp @@ -42,9 +42,23 @@ namespace engine */ class Trafo : public ProcNode { - /////////// + protected: + Trafo() : ProcNode() { }; + + friend class NodeFactory; + + + + /** do the actual calculations. + * @internal dispatch to implementation. + * Client code should use #render() + * @todo obviously we need a parameter!!! + */ + virtual void process() = 0; }; + typedef Trafo* PTrafo; ///< @todo handle ProcNode by pointer or by shared-ptr?? + } // namespace engine diff --git a/src/proc/mobject/builder/mould.hpp b/src/proc/mobject/builder/mould.hpp index 6c714157a..be29f2b21 100644 --- a/src/proc/mobject/builder/mould.hpp +++ b/src/proc/mobject/builder/mould.hpp @@ -39,19 +39,21 @@ namespace mobject { /** - * Interface: a holder tool used by the builder to - * wire up a specific building situation and then to - * apply/execute a single building step. Mould is the - * passive part, while usually the ProcPatt is the active - * counterpart. By means of the Mould interface, the specifics - * of a build situation are abstracted away, thus allowing the - * processing pattern to be defined as working on symbolic - * locations. The most common location is "current", denoting - * the render node just being built. + * Interface: a workbench-like tool used by the builder + * for wiring up a specific building situation, followed by + * the application/execution of a single building step. Mould is + * conceived as the passive part, while usually the ProcPatt plays + * the role of the active counterpart. By means of the Mould interface, + * the specifics of a build situation are abstracted away, thus allowing + * the processing pattern to be defined as working on symbolic locations. + * Most commonly this is "current", denoting the render node just being built. *
  • PipeMould supports attaching an effect to a pipe
  • *
  • combining pipes via a transition is done by a CombiningMould
  • *
  • a SourceChainMould allows to start out from a source reader and build a clip
  • - *
  • wiring general connections is supported by the WiringMould
  • + *
  • wiring general connections is supported by the WiringMould
  • + *
+ * @see ToolFactory + * @see NodeCreatorTool */ class Mould { diff --git a/src/proc/mobject/builder/operationpoint.hpp b/src/proc/mobject/builder/operationpoint.hpp index d48e9ecf6..daa0f18d6 100644 --- a/src/proc/mobject/builder/operationpoint.hpp +++ b/src/proc/mobject/builder/operationpoint.hpp @@ -24,12 +24,18 @@ #ifndef MOBJECT_BUILDER_OPERATIONPOINT_H #define MOBJECT_BUILDER_OPERATIONPOINT_H +#include "proc/engine/procnode.hpp" +#include "common/query.hpp" +#include +#include namespace mobject { namespace builder { + using std::vector; + using std::string; /** * A point in the render node network under construction. @@ -40,8 +46,23 @@ namespace mobject { */ class OperationPoint { - public: + typedef engine::PNode PNode; + vector refPoint_; + const string streamID_; + + public: + /** create node(s) corresponding to the given Processor-Asset + * and wire them as a successor to this OperationPoint; then + * move this point to point at the resulting new exit node(s) + */ + void attach (asset::PProc const&); + + /** connect the output this OperationPoint referes such as to + * connect or combine with the input of the already existing + * nodes accessible via the target OperationPoint. + */ + void join (OperationPoint& target); }; diff --git a/src/proc/mobject/builder/toolfactory.hpp b/src/proc/mobject/builder/toolfactory.hpp index 5d30c9eea..ecb9f7949 100644 --- a/src/proc/mobject/builder/toolfactory.hpp +++ b/src/proc/mobject/builder/toolfactory.hpp @@ -25,6 +25,7 @@ #define MOBJECT_BUILDER_TOOLFACTORY_H #include "proc/mobject/builder/buildertool.hpp" +#include "proc/mobject/builder/mould.hpp" #include "proc/asset/pipe.hpp" #include "proc/mobject/session/clip.hpp" #include "proc/mobject/builder/wiringrequest.hpp" diff --git a/src/proc/mobject/session/mobjectfactory.hpp b/src/proc/mobject/session/mobjectfactory.hpp index 427385194..e1a7a5695 100644 --- a/src/proc/mobject/session/mobjectfactory.hpp +++ b/src/proc/mobject/session/mobjectfactory.hpp @@ -28,8 +28,8 @@ -namespace asset - { +namespace asset { + class Clip; class Media; class Track; @@ -37,10 +37,9 @@ namespace asset } -namespace mobject - { - namespace session - { +namespace mobject { + namespace session { + class Clip; class Track; class Effect; @@ -57,10 +56,10 @@ namespace mobject public: - Placement operator() (const asset::Clip&, const asset::Media&); - Placement operator() (const asset::Clip&, vector); + Placement operator() (asset::Clip const&, asset::Media const&); + Placement operator() (asset::Clip const&, vector); Placement operator() (PTrackAsset&); - Placement operator() (const asset::Effect&); + Placement operator() (asset::Effect const&); }; diff --git a/wiki/renderengine.html b/wiki/renderengine.html index c55d698a2..44b635e79 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -773,13 +773,14 @@ As the builder has to create a render node network implementing most of the feat !!pattern of operation The working pattern of this builder mechanics can be described as triggering, enqueuing, priorizing, recursing and exhausting. Without the priorizing part, it would be a depth-first call graph without any context state, forcing us to have all cross reference information available at every node or element to be treated. We prefer to avoid this overhead by ordering the operations into several phases and within these phases into correlated entities with the help of a ''weighting function'' and scheduling with a ''priority queue''
-
+
The [[Builder]] uses different kinds of tools for creating a network of render nodes from a given high-level model. When breaking down this (necessarily complex) process into small manageable chunks, we arrive at [[elementary building situations|BuilderPrimitives]]. For each of these there is a specialized tool. We denote these tools as "moulds" because they are a rather passive holder for the objects to be attached and wired up. They are shaped according to the basic form the connections have to follow for each of these basic situations:
 * attaching an effect to a pipe
 * combining pipes via a transition
 * starting out a pipe from a source reader
 * general connections from the exit node of a pipe to the port of another pipe
-In all those cases, the active part is provided by [[processing patterns|ProcPatt]] &mdash; sort of micro programs executed within the context of a given mould: the processing pattern defines the steps to take (in the standard/basic case this is just "attach"), while the mould holds and provides the location where these steps will operate.
+In all those cases, the active part is provided by [[processing patterns|ProcPatt]] &mdash; sort of micro programs executed within the context of a given mould: the processing pattern defines the steps to take (in the standard/basic case this is just "attach"), while the mould holds and provides the location where these steps will operate. Actually, this location is represented as a OperationPoint, provided by the mould and abstracting the details of making multi-channel connections. +
While assembling and building up the render engines node network, a small number of primitive building situations is encountered repeatedly. The BuilderToolKit provides a "[[mould|BuilderMould]]" for each of these situations, typically involving parametrisation and the application of a [[processing pattern|ProcPatt]].
@@ -852,13 +853,9 @@ While building, the application of such a visiting tool (especially the [[NodeCr
 
 
-
+
Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounter several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool" or [[mould|BuilderMould]]. The palette of these moulds is called the ''tool kit'' of the builder. It is subject to configuration by rules.
 
-!! {{red{open questions}}}
-* how to address these moulds
-* how to type them
-* how to parametrize them
 
 !!addressing a mould
 All mould instances are owned and managed by the [[tool factory|BuilderToolFactory]], and can be referred to by their type ({{{PipeMould}}}, {{{CombiningMould}}}, {{{SourceChainMould}}}, {{{WiringMould}}}) and a concrete object instance (of suitable type). The returned mould (instance) acts as a handle to stick together the given object instance (from the high-level model) with the corresponding point in the low-level node network under construction. As consequence of this approach, the tool factory instance holds a snapshot of the current building state, including all the active spots in the build process. As the latter is driven by objects from the high-level model appearing (in a sensible order &rarr; see BuilderMechanics) within the NodeCreatorTool, new moulds will be created and fitted as necessary, and existing moulds will be exhausted when finished, until the render node network is complete.
@@ -869,7 +866,10 @@ As each mould kind is different, it has a {{{prepare(...)}}} function with suita
 !!sequence of operations
 When {{{operate()}}} doesn't throw, the result is a list of //successor moulds// &mdash; you shouldn't use the original mould after triggering its operation, because it may have been retracted as a result and reused for another purpose by the tool factory. It is not necessary to store these resulting moulds either (as they can be retrieved as described above), but they can be used right away for the next building step if applicable. In the state they are returned from a successful building step (mould operation = execution of a contained [[processing pattern|ProcPatt]]), they are usually already holding a reference to the part of the network just created and need to be configured only with the next high-level object (effect, placement, pipe, processing pattern or similar, depending on the concrete situation) in order to carry out the next step.
 
-&rarr;see also: BuilderPrimitives for the elementary working situations corresponding to these fitting tools
+!!single connection step
+at the lowest level within the builder there is the step of building a //connection.// This step is executed by the processing pattern with the help of the mould. Actually, making such a connection is more complicated, because in the standard case it will connect N media streams simultaneously (N=2 for stereo sound or 3D video, N=6 for 5.1 Surround, N=9 for 2nd order Ambisonics). These details are encapsulated within the OperationPoint, which is provides by the mould and exhibits a common interface for the processing pattern to express the connecting operation.
+
+&rarr;see also: BuilderPrimitives for the elementary working situations corresponding to each of these [[builder moulds|BuilderMould]]
 
@@ -1831,6 +1831,14 @@ But because I know the opinions on this topc are varying (users tend to be delig My proposed aproach is to treat OpenGL as a separate video raw data type, requiring separete and specialized [[Processing Nodes|ProcNode]] for all calculations. Thus the Builder could connect OpenGL nodes if it is possible to cover the whole render path for preview and fall back to the normal ~ProcNodes for all relevant renders
+
+
A low-level abstraction within the [[Builder]] &mdash; it serves to encapsulate the details of making multi-channel connections between the render nodes: In some cases, a node can handle N channels internally, while in other cases we need to replicate the node N times and wire each channel individually.
+
+The operation point is provided by the current BuilderMould and used by the [[processing pattern|ProcPatt]] executing within this mould and conducting the current build step. The operation point's interface allows //to abstract//&nbsp; these details, as well as to //gain additional control//&nbsp; if necessary (e.g. addressing only one of the channels). The most prominent build instruction used within the processing patterns (which is the instruction {{{"attach"}}}) relies on the aforementioned //approach of abstracted handling,// letting the operation point determine automatically how to make the connection.
+
+This is possible because the operation point has been provided (by the mould) with informations about the media stream type to be wired, while at the same time relying on the [[render node interface|ProcNode]] for finding out whats possible and making the desired connections.
+
+
The Lumiera Processing Layer is comprised of various subsystems and can be separated into a low-level and a high-level part. At the low-level end is the [[Render Engine|OverviewRenderEngine]] which basically is a network of render nodes cooperating closely with the Backend Layer in order to carry out the actual playback and media transforming calculations. Whereas on the high-level side we find several different [[Media Objects|MObjects]] that can be placed into the [[EDL]], edited and manipulated. This is complemented by the [[Asset Management|Asset]], which is the "bookkeeping view" of all the different "things" within each [[Session|SessionOverview]].
 
@@ -2657,8 +2665,17 @@ The system is ''open'' inasmuch every part mirrors the structure of correspondin
 &rarr; [[Implementation Details|ImplementationDetails]] {{red{WIP}}}
 
-
+
A data processing node within the Render Engine. Its key feature is the possibility to pull from it one (freely addressable) [[Frame]] of calculated data. Further, each ~ProcNode has the ability to be wired with other nodes and [[Parameter Providers|ParamProvider]]
+
+!! {{red{open questions}}}
+* how to address a node
+* how to type them
+* how to discover the number and type of the ports
+* how to discover the possible parameter ports
+* how to define and query for additional capabilities
+
+&rarr; see also the [[open design process draft|http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/DesignRenderNodesInterface]]
 
From 8daec32733cdb4bd25e99f982354268c09c5a2ce Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 30 May 2008 06:23:13 +0200 Subject: [PATCH 122/245] first draft plans for the render process, as far as needed for defining the builder --- src/proc/mobject/builder/toolfactory.hpp | 6 ++ wiki/renderengine.html | 75 ++++++++++++++++++------ 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/proc/mobject/builder/toolfactory.hpp b/src/proc/mobject/builder/toolfactory.hpp index ecb9f7949..1f6cbd7aa 100644 --- a/src/proc/mobject/builder/toolfactory.hpp +++ b/src/proc/mobject/builder/toolfactory.hpp @@ -40,6 +40,12 @@ namespace mobject { using asset::PPipe; using session::PClipMO; + /** + * provides the builder with the necessary, preconfigured tools. + * Dedicated to a single build process, it holds the internal state + * of this process and thus serves to coordinate and link together all + * the individual parts fabricated by using the various tools. + */ class ToolFactory { public: diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 44b635e79..8b1883bbe 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -578,6 +578,9 @@ The first step towards an solution is to isolate the problem; obviously we //nee [img[how to implement Automation|uml/fig129669.png]]
+
+
While generally automation is treated as a function over time, defining and providing such a function requires some //Automation Data.// The actual layout and meaning of this data is deemed an implementation detail of the [[parameter provider|ParamProvider]] used, but nevertheless an automation data set has object characteristics within the [[EDL (high-level-model)|EDL]], allowing it to be attached, moved and [[placed|Placement]] by the user.
+
Starting out from the concepts of Objects, Placement to Tracks, render Pipes and connection properties (&rarr; see [[here|TrackPipeEDL]]) within the EDL, we can identify the elementary operations occuring within the Builder. Overall, the Builder is organized as application of //visiting tools// to a collection of objects, so finally we have to consider some object kind appearing in the working function of the given builder tool, which holds at this moment some //context//. The job now is to organize this context such as to create a predictable build process from this //event driven// approach.
 &rarr;see also: BuilderPrimitives for the elementary situations used to cary out the building operations
@@ -729,11 +732,11 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
 }
 //}}}
-
+
All decisions on //how // the RenderProcess has to be carried out are concentrated in this rather complicated Builder Subsystem. The benefit of this approach is, besides decoupling of subsystems, to keep the actual performance-intensive video processing code as simple and transparent as possible. The price, in terms of increased complexity &mdash; to pay in the Builder &mdash; can be handled by making the Build Process generic to a large degree. Using a Design By Contract approach we can decompose the various decisions into small decision modules without having to trace the actual workings of the Build Process as a whole.
 
 [>img[Outline of the Build Process|uml/fig129413.png]]
-The building itself will be broken down into several small tool application steps. Each of these steps has to be mapped to the MObjects found on the [[Timeline]]. Remember: the idea is that the so called "[[Fixture]]" contains only [[ExplicitPlacement]]s which in turn link to MObjects like Clips, Effects and Automation. So it is sufficient to traverse this list and map the build tools to the elements. Each of these build tools has its own state, which serves to build up the resulting Render Engine. So far I see two steps to be necessary:
+The building itself will be broken down into several small tool application steps. Each of these steps has to be mapped to the MObjects found on the [[Timeline]]. Remember: the idea is that the so called "[[Fixture]]" contains only [[ExplicitPlacement]]s which in turn link to MObjects like Clips, Effects and [[Automation]]. So it is sufficient to traverse this list and map the build tools to the elements. Each of these build tools has its own state, which serves to build up the resulting Render Engine. So far I see two steps to be necessary:
 * find the "Segments", i.e. the locations where the overall configuration changes
 * for each segment: generate a ProcNode for each found MObject and wire them accordingly
 Note, //we still have to work out how exactly building, rendering and playback work// together with the backend-design. The build process as such doesn't overly depend on these decisions. It is easy to reconfigure this process. For example, it would be possible as well to build for each frame separately (as Cinelerra2 does), or to build one segment covering the whole timeline (and handle everything via [[Automation]]
@@ -749,7 +752,30 @@ Note, //we still have to work out how exactly building, rendering and playback w
 [img[Colaborations in the Build Process|uml/fig128517.png]]
 
-
+
+
Actually setting up and wiring a [[processing node|ProcNode]] involves several issues and is carried out at the lowest level of the build process. 
+
+!!!object creation
+The Nodes are small polymorphic objects, carrying configuration data, but no state. They are [[specially allocated|ManagementRenderNodes]], and the object creation is accessible solely by the NodeFactory. They //must not be deallocated manually.// The decision of what concrete node type to create depends on the actual build situation and is worked out by the combination of [[mould|BuilderMould]] and [[processing pattern|ProcPatt]] at the current OperationPoint, issuing a call to one of NodeFactory's {{{operator()}}}
+
+!!!node, plugin and processing function
+Its a good idea to distinguish clearly between those concepts. A plugin is a piece of (possibly external) code we use to carry out operations. We have to //discover its properties and capabilities.// We don't have to discover anything regarding nodes, because we (Lumiera builder and renderengine) are creating, configuring and wiring them to fit the specific purpose. Both are to be distinguished from processing functions, which do the actual calculations on the media data. Every node typically encompasses at least one processing function, which may be an internal function in the node object, a library function from Lumiera or GAVL, or external code loaded from a plugin.
+
+!!!node interfaces
+As a consequence of this distinctions, in conjunction with a processing node, we have to deal with three different interfaces
+* the __build interface__ is used by the builder to set up and wire the nodes. It can be full blown C++ (including templates)
+* the __operation interface__ is used to run the calculations, which happens in cooperation of Proc-Layer and Backend. So a function-style interface is preferable.
+* the __inward interface__ is accessed by the processing function in the course of the calculations to get at the necessary context, including in/out buffers and param values.
+
+!!!wiring data connections
+A node //knows its predecessors, but not its successors.// When being //pulled//&nbsp; in operation, it can expect to get a frame provider for accessing the in/out buffer locations (some processing functions may be "in-place capable", but that's only a special case of the former). At this point, the ''pull principle'' comes into play: the node may request input frames from the frame provider, passing its predecessors as a ''continuation''.
+With regard to the build process, the wiring of data connections translates into providing the node with its predecessors and preconfiguring the possible continuations. While in the common case, a node has just one input/output and pulls from its predecessor a frame for the same timeline position, the general case can be more contrived. A node may process N buffers in parallel and may require several different time positions for it's input, even at a differing framerate. So the actual source specification is (predNode,time,frameType). The objective of the wiring done in the build process is to factor out the parts known in advance, while in the render process only the variable part need to be filled in. Or to put it differently: wiring builds a higher order function (time)->(continuation), where continuation can be invoked to get the desired input frame.
+
+!!!wiring control conections
+In many cases, the parameter values provided by these connections aren't frame based data, rather, the processing function needs a call interface to get the current value (value for a given time), which is provided by the parameter object. Here, the wiring needs to link to the suitable parameter instance, which is located within the high-level model (!). As an additional complication, calculating the actual parameter value may require a context data frame (typically for caching purposes to speed up the interpolation). While these parameter context data frames are completely opaque for the render node, they have to be passed in and out similar to the state needed by the node itself, and the wiring has to prepare for accessing these frames too.
+
+
+
The Builder takes some MObject/[[Placement]] information (called Timeline) and generates out of this a Render Engine configuration able to render this Objects. It does all decisions and retrieves the current configuration of all objects and plugins, so the Render Engine can just process them stright forward.
 
 The Builder is the central part of the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]]
@@ -761,7 +787,7 @@ As the builder has to create a render node network implementing most of the feat
 * //operating the Builder// can be viewed at from two different angles, either emphasizing the [[basic building operations|BasicBuildingOperations]] employed to assemble the render node network, or focussing rather at the [[mechanics|BuilderMechanics]] of cooperating parts while processing.
 * besides, we can identify a small set of elementary situations we call [[builder primitives|BuilderPrimitives]], to be covered by the mentioned BuilderToolKit; by virtue of [[processing patterns|ProcPatt]] they form an [[interface to the rule based configuration|BuilderRulesInterface]].
 * the actual building (i.e. the application of tools to the timeline) is done by the [[Assembler|BuilderAssembler]], which is basically a collection of functions (but has a small amount of global configuration state)
-* any non-trivial wiring of render nodes, tracks, pipes and automation is done by the services of the [[connection manager|ConManager]]
+* any non-trivial wiring of render nodes, tracks, pipes and [[automation|Automation]] is done by the services of the [[connection manager|ConManager]]
 
@@ -1010,7 +1036,7 @@ As we don't have a Prolog interpreter on board yet, we utilize a mock store with {{{default(Obj)}}} is a predicate expressing that the object {{{Obj}}} can be considered the default setup under the given conditions. Using the //default// can be considered as a shortcut for actually finding a exact and unique solution. The latter would require to specify all sorts of detailed properties up to the point where only one single object can satisfy all conditions. On the other hand, leaving some properties unspecified would yield a set of solutions (and the user code issuing the query had to provide means for selecting one soltution from this set). Just falling back on the //default// means that the user code actually doesn't care for any additional properties (as long as the properties he //does// care for are satisfied). Nothing is said specifically on //how//&nbsp; this default gets configured; actually there can be rules //somewhere,// and, additionally, anything encountered once while asking for a default can be re-used as default under similar circumstances. &rarr; [[implementing defaults|DefaultsImplementation]]
-
+
Along the way of working out various [[implementation details|ImplementationDetails]], decisions need to be made on how to understand the different facilities and entities and how to tackle some of the problems. This page is mainly a collection of keywords, summaries and links to further the discussion. And the various decisions should allways be read as proposals to solve some problem at hand...
 
 ''Everything is an object'' &mdash; of course, that's a //no-brainer // todays. Rather, important is what is not "an object", meaning it can't be arranged arbitrarily
@@ -1023,10 +1049,10 @@ We ''separate'' processing (rendering) and configuration (building). We have a [
 ''Objects are [[placed|Placement]] rather'' than assembled, connected, wired, attached. This is more of a rule-based approach and gives us one central metaphor and abstraction, allowing us to treat everything in an uniform manner. You can place it as you like, and the builder tries to make sense out of it, silently disabling what doesn't make sense.
 An [[EDL]] is just a collection of configured and placed objects (and has no additional, fixed structure). [[Tracks|Track]] form a mere organisational grid, they are grouping devices not first-class entities (a track doesn't "have" a pipe or "is" a video track and the like; it can be configured to behave in such manner by using placements though). [[Pipes|Pipe]] are hooks for making connections and are the only facility to build processing chains. We have global pipes, and each clip is built around a lokal [[source port|ClipSourcePort]] &mdash; and that's all. No special "media viewer" and "arranger", no special role for media sources, no commitment to some fixed media stream types (video and audio). All of this is sort of pushed down to be configuration, represented as asset of some kind. For example, we have [[processing pattern|ProcPatt]] assets to represent the way of building the source network for reading from some media file (including codecs treated like effect plugin nodes)
 
-''State'' is rigorously ''externalized'' and operations are to be ''scheduled'', to simplify locking and error handling. State is either treated similar to media stream data (as addressable and cacheable data frame), or is represented as "parameter" to be served by some [[parameter provider|ParamProvider]]. Automation is just another kind of parameter, i.e. a function, and how this function is calculated is an encapsulated implementation detail (we don't have "bezier automation", and then maybe a "linear automation", a "mask automation" and yet another way to handle transitions)
+''State'' is rigorously ''externalized'' and operations are to be ''scheduled'', to simplify locking and error handling. State is either treated similar to media stream data (as addressable and cacheable data frame), or is represented as "parameter" to be served by some [[parameter provider|ParamProvider]]. Consequently, [[Automation]] is just another kind of parameter, i.e. a function &mdash; how this function is calculated is an encapsulated implementation detail (we don't have "bezier automation", and then maybe a "linear automation", a "mask automation" and yet another way to handle transitions)
 
-
+
This __proc-Layer__ and ~Render-Engine implementation started out as a design-draft by [[Ichthyo|mailto:Ichthyostega@web.de]] in summer 2007. The key idea of this design-draft is to use the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]] for the Render Engine, thus separating completely the //building// of the Render Pipeline from //running,// i.e. doing the actual Render. The Nodes in this Pipeline should process Video/Audio and do nothing else. No more decisions, tests and conditional operations when running the Pipeline. Move all of this out into the configuration of the pipeline, which is done by the Builder.
 
 !Why doesn't the current Cinelerra-2 Design succeed?
@@ -1045,7 +1071,7 @@ As always, the main goal is //to cut down complexity// by the usual approach to
 
 To achieve this, here we try to separate ''Configuration'' from ''Processing''. Further, in Configuration we try to separate the ''high level view'' (users view when editing) from the ''low level view'' (the actual configuration effective for the calculations). Finally, we try to factor out and encapsulate ''State'' in order to make State explicit.
 
-The main tool used to implement this separation is the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]]. Here especially we move all decisions and parametrization into the BuildProcess. The Nodes in the render pipeline should process Video/Audio and do nothing else. No more decisions, tests and conditional operations when running the Pipeline. Move all of this out into the configuration of the pipeline, which is done by the Builder. Make the actual processing nodes Template classes, parametrized by the color model and number of components. Make all Nodes of equal footing with each other, able to be connected freely within the limitations of the necessary input and output. Make the OpenGL rendering into alternate implementation of some operations together with an alternate signal flow (usable only if the whole Pipeline can be built up to support this changed signal flow), thus factoring out all the complexities of managing the data flow between core and hardware accelerated rendering out of the implementation of the actual processing. Introduce separate control data connections for the automation data, separating the case of true multi-channel-effects from the case where one node just gets remote controlled by another node (or two nodes using the same automation data).
+The main tool used to implement this separation is the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]]. Here especially we move all decisions and parametrization into the BuildProcess. The Nodes in the render pipeline should process Video/Audio and do nothing else. No more decisions, tests and conditional operations when running the Pipeline. Move all of this out into the configuration of the pipeline, which is done by the Builder. Make the actual processing nodes Template classes, parametrized by the color model and number of components. Make all Nodes of equal footing with each other, able to be connected freely within the limitations of the necessary input and output. Make the OpenGL rendering into alternate implementation of some operations together with an alternate signal flow (usable only if the whole Pipeline can be built up to support this changed signal flow), thus factoring out all the complexities of managing the data flow between core and hardware accelerated rendering out of the implementation of the actual processing. Introduce separate control data connections for the [[automation data|Automation]], separating the case of true multi-channel-effects from the case where one node just gets remote controlled by another node (or two nodes are utilizing the same automation data).
 
 Another pertinent theme is to make the basic building blocks simpler, while on the other hand gaining much more flexibility for combining these building blocks. For example we try to unfold any "internal-multi" effects into separate instances (e.g. the possibility of having an arbitrary number of single masks at any point of the pipeline instead of having one special masking facility encompassing multiple sub-masks. Similarly, we treat the Objects in the EDL in a more uniform manner and gain the possibility to [[place|Placement]] them in various ways.
 
@@ -1722,6 +1748,12 @@ This Design strives to achieve a StrongSeparation between the low-level Structur {{red{let's see if this approach works...}}}
+
+
Contrary to the &rarr;[[Assets and MObjects|ManagementAssetRelation]], the usage pattern for [[render nodes|ProcNode]] is quite simple: All nodes are created together every time a new segment of the network is being build and are all needed together until this segment is re-built, at which point they can be thrown away altogether. While it would be easy to handle the nodes automatically by smart-ptr (the creation is accessible only by use of the {{{NodeFactory}}} anyways), it //seems advisable to care for a bulk allocation/deallocation here.// The reason being not so much the amount of memory (which is expected to be moderate), but the fact, that the build process can be triggered repeatedly several times a second when tweaking the EDL, which could lead to fragmentation and memory pressure.
+
+__5/2008__: the allocation mechanism can surely be improved later, but for now I am going for a simple implementation based on keeping all nodes of one kind together in a vector. The list of possible node kinds is hard wired, allowing to generate the object holding a chunk of nodes for one segment, mostly relying on the runtime system for the management.
+
+
<!--{{{-->
 <link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
@@ -1887,8 +1919,8 @@ see also: RenderEntities, [[two Examples (Object diagrams)|Examples]]
 <!--}}}-->
 
-
-
A ParamProvider is the counterpart for (one or many) Parameter instances. It implements the value access function made available by the Parameter object to its clients.
+
+
A ParamProvider is the counterpart for (one or many) [[Parameter]] instances. It implements the value access function made available by the Parameter object to its clients.
 
 To give a concrete example: 
 * a Fade Plugin needs the actual fade value for Frame t=xxx
@@ -1900,8 +1932,8 @@ To give a concrete example:
 &rarr; see the class diagram for [[Automation]]
 
-
-
Parameters are all probably variable control values used within the Render Engine. Contrast this with configuration values, which are considered to be fixed and need an internal reset of the application state to take effect.
+
+
Parameters are all possibly variable control values used within the Render Engine. Contrast this with configuration values, which are considered to be fixed and need an internal reset of the application (or session) state to take effect.
 
 A ''Parameter Object'' provides a descriptor of the kind of parameter, together with a function used to pull the //actual value// of this parameter. Here, //actual// has a two-fold meaning:
 * if called without a time specification, it is either a global (but variable) system or session parameter or a default value for automated Parameters. (the intention is to treat this cases uniformly)
@@ -2665,7 +2697,7 @@ The system is ''open'' inasmuch every part mirrors the structure of correspondin
 &rarr; [[Implementation Details|ImplementationDetails]] {{red{WIP}}}
 
-
+
A data processing node within the Render Engine. Its key feature is the possibility to pull from it one (freely addressable) [[Frame]] of calculated data. Further, each ~ProcNode has the ability to be wired with other nodes and [[Parameter Providers|ParamProvider]]
 
 !! {{red{open questions}}}
@@ -2676,6 +2708,7 @@ The system is ''open'' inasmuch every part mirrors the structure of correspondin
 * how to define and query for additional capabilities
 
 &rarr; see also the [[open design process draft|http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/DesignRenderNodesInterface]]
+&rarr; see RenderProcess
 
@@ -4347,12 +4380,12 @@ Placements are __resolved__ resulting in an ExplicitPlacement. In most cases thi &rarr; [[Definition|Pipe]] and [[handling of Pipes|PipeHandling]]
-
+
Transitions combine the data from at least two processing chains and do this combining in a time varying fashion. So, any transition has
 * N input connections
 * either one or N output connections
 * temporal coordinates (time, length)
-* some control data connection to a ParamProvider, because in the most general case the controling curves are treated like automation
+* some control data connection to a ParamProvider, because in the most general case the controling curves are treated similar to  [[automation data|AutomationData]]
 
 !!!how much output ports?
 The standard case of a transition is sort of mixing together two input streams, like e.g. a simple dissolve. For this to be of any use, this input streams need to be connected to the same ouput destination before and after the transition (with regards to the timeline), i.e. the inputs and the transition share placement to the same output pipe. In this case, when the transition starts, the direct connections can be suspended and the transition will switch in seamlessly.
@@ -4416,7 +4449,7 @@ generally speaking, visitors are preferable when the underlying element type hie
 To see an simple example of our "visiting tool", have a look at {{{tests/components/common/visitingtooltest.cpp}}}
 
-
+
The Intention of this text is to help you understanding the design and to show some notable details.
 
 !!!!Starting Point
@@ -4437,7 +4470,7 @@ This design strives to build each level and subsystem around some central concep
 * albeit being a special form of a Placement, the ExplicitPlacement is treated as a separate concept. With respect to edit operations within the EDL, it can stand for any sort of Placement. On the other hand the Builder takes a list of ~ExplicitPlacements as input for building up the Render Engine(s). This corresponds to the fact that the render process needs to organize the things to be done on a simple two dimensional grid of (output channel / time). The (extended) contract of an ~ExplicitPlacement provides us with this (output,time).
 * on the lower end of the builder, everything is organized around the Concept of a ProcNode, which enables us to //pull// one (freely addressable) Frame of calculated data. Further, the ProcNode has the ability to be wired with other nodes and [[Parameter Providers|ParamProvider]]
 * the various types of data to be processed are abstracted away under the notion of a [[Frame]]. Basically, a Frame is an Buffer containing an Array of raw data and it can be located by some generic scheme, including (at least) the absolute starting time (and probably some type or channel id).
-* All sorts of (target domain) [[Parameters]] are treated uniformly. There is a distinction between Parameters (which //could// be variable) and Configuration (which is considered to be fixed). In this context, Automation just appears as a special kind of ParamProvider.
+* All sorts of (target domain) [[parameters|Parameter]] are treated uniformly. There is a distinction between Parameters (which //could// be variable) and Configuration (which is considered to be fixed). In this context, [[Automation]] just appears as a special kind of ParamProvider.
 * and finally, the calculation //process// together with its current state is represented by a StateProxy. I call this a "proxy", because it should encapsulate and hide all tedious details of communication, be it even asynchronous communication with some Controller or Dispatcher running in another Thread. In order to maintain a view on the current state of the render process, it could eventually be necessary to register as an observer somewhere or to send notifications to other parts of the system.
 
 !!!!Handling Diversity
@@ -4450,6 +4483,14 @@ In case it's not already clear: we don't have "the" Render Engine, rat
 The &raquo;current setup&laquo; of the objects in the EDL is sort of a global state. Same holds true for the Controller, as the Engine can be at playback, it can run a background render or scrub single frames. But the whole complicated subsystem of the Builder and one given Render Engine configuration can be made ''stateless''. As a benefit of this we can run this subsystems multi-threaded without the need of any precautions (locking, synchronizing). Because all state information is just passed in as function parameters and lives in local variables on the stack, or is contained in the StateProxy which represents the given render //process// and is passed down as function parameter as well. (note: I use the term "stateless" in the usual, slightly relaxed manner; of course there are some configuration values contained in instance variables of the objects carrying out the calculations, but this values are considered to be constant over the course of the object usage).
 
+
+
The purpose of automation is to vary a parameter of some data processing instance in the course of time while rendering. Thus, automation encompasses all the variability within the render network //which is not a structural change.//
+
+
+!Parameters and Automation
+
+[[Automation]] is treated as a function over time. Everything beyond this definition is considered an implementation detail of the [[parameter provider|ParamProvider]] used to yield the value. Thus automation is closely tied to the concept of a [[Parameter]], which also plays an important role in the communication with the GUI and while [[setting up and wiring the render nodes|BuildRenderNode]] in the course of the build process (&rarr; see [[tag:Builder|Builder]])
+
From 7e2092825e25a3523ec229ac7edae6934f9be497 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 31 May 2008 13:22:15 +0100 Subject: [PATCH 123/245] Simple scrolling and drawing added --- src/gui/Makefile.am | 78 ++++++++++--------- src/gui/widgets/timeline-widget.cpp | 88 +++++++++++++++------- src/gui/widgets/timeline-widget.hpp | 59 ++++++++++----- src/gui/widgets/timeline/timeline-body.cpp | 87 +++++++++++++++++++++ src/gui/widgets/timeline/timeline-body.hpp | 56 ++++++++++++++ src/gui/widgets/timeline/track.cpp | 51 +++++++++++++ src/gui/widgets/timeline/track.hpp | 59 +++++++++++++++ src/gui/widgets/timeline/video-track.cpp | 56 ++++++++++++++ src/gui/widgets/timeline/video-track.hpp | 57 ++++++++++++++ src/gui/widgets/video-display-widget.hpp | 1 + 10 files changed, 512 insertions(+), 80 deletions(-) create mode 100644 src/gui/widgets/timeline/timeline-body.cpp create mode 100644 src/gui/widgets/timeline/timeline-body.hpp create mode 100644 src/gui/widgets/timeline/track.cpp create mode 100644 src/gui/widgets/timeline/track.hpp create mode 100644 src/gui/widgets/timeline/video-track.cpp create mode 100644 src/gui/widgets/timeline/video-track.hpp diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index e056225fa..b498fa3e8 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -33,47 +33,53 @@ AM_CFLAGS =\ bin_PROGRAMS += lumigui -lumigui_SOURCES = \ - $(lumigui_srcdir)/gtk-lumiera.cpp \ - $(lumigui_srcdir)/gtk-lumiera.hpp \ - $(lumigui_srcdir)/window-manager.cpp \ - $(lumigui_srcdir)/window-manager.hpp \ - $(lumigui_srcdir)/workspace/actions.cpp \ - $(lumigui_srcdir)/workspace/actions.hpp \ - $(lumigui_srcdir)/workspace/workspace-window.cpp \ - $(lumigui_srcdir)/workspace/workspace-window.hpp \ - $(lumigui_srcdir)/dialogs/render.cpp \ - $(lumigui_srcdir)/dialogs/render.hpp \ - $(lumigui_srcdir)/dialogs/preferences-dialog.cpp \ - $(lumigui_srcdir)/dialogs/preferences-dialog.hpp \ - $(lumigui_srcdir)/panels/panel.cpp \ - $(lumigui_srcdir)/panels/panel.hpp \ - $(lumigui_srcdir)/panels/timeline-panel.cpp \ - $(lumigui_srcdir)/panels/timeline-panel.hpp \ - $(lumigui_srcdir)/panels/viewer-panel.cpp \ - $(lumigui_srcdir)/panels/viewer-panel.hpp \ - $(lumigui_srcdir)/panels/assets-panel.cpp \ - $(lumigui_srcdir)/panels/asset-panels.hpp \ - $(lumigui_srcdir)/widgets/video-display-widget.cpp \ - $(lumigui_srcdir)/widgets/video-display-widget.hpp \ - $(lumigui_srcdir)/widgets/timeline-widget.cpp \ - $(lumigui_srcdir)/widgets/timeline-widget.hpp \ - $(lumigui_srcdir)/model/project.cpp \ - $(lumigui_srcdir)/model/project.hpp \ - $(lumigui_srcdir)/output/displayer.cpp \ - $(lumigui_srcdir)/output/displayer.hpp \ - $(lumigui_srcdir)/output/gdkdisplayer.cpp \ - $(lumigui_srcdir)/output/gdkdisplayer.hpp \ - $(lumigui_srcdir)/output/xvdisplayer.cpp \ +lumigui_SOURCES = \ + $(lumigui_srcdir)/gtk-lumiera.cpp \ + $(lumigui_srcdir)/gtk-lumiera.hpp \ + $(lumigui_srcdir)/window-manager.cpp \ + $(lumigui_srcdir)/window-manager.hpp \ + $(lumigui_srcdir)/workspace/actions.cpp \ + $(lumigui_srcdir)/workspace/actions.hpp \ + $(lumigui_srcdir)/workspace/workspace-window.cpp \ + $(lumigui_srcdir)/workspace/workspace-window.hpp \ + $(lumigui_srcdir)/dialogs/render.cpp \ + $(lumigui_srcdir)/dialogs/render.hpp \ + $(lumigui_srcdir)/dialogs/preferences-dialog.cpp \ + $(lumigui_srcdir)/dialogs/preferences-dialog.hpp \ + $(lumigui_srcdir)/panels/panel.cpp \ + $(lumigui_srcdir)/panels/panel.hpp \ + $(lumigui_srcdir)/panels/timeline-panel.cpp \ + $(lumigui_srcdir)/panels/timeline-panel.hpp \ + $(lumigui_srcdir)/panels/viewer-panel.cpp \ + $(lumigui_srcdir)/panels/viewer-panel.hpp \ + $(lumigui_srcdir)/panels/assets-panel.cpp \ + $(lumigui_srcdir)/panels/asset-panels.hpp \ + $(lumigui_srcdir)/widgets/video-display-widget.cpp \ + $(lumigui_srcdir)/widgets/video-display-widget.hpp \ + $(lumigui_srcdir)/widgets/timeline-widget.cpp \ + $(lumigui_srcdir)/widgets/timeline-widget.hpp \ + $(lumigui_srcdir)/widgets/timeline/track.cpp \ + $(lumigui_srcdir)/widgets/timeline/track.hpp \ + $(lumigui_srcdir)/widgets/timeline/video-track.cpp \ + $(lumigui_srcdir)/widgets/timeline/video-track.hpp \ + $(lumigui_srcdir)/widgets/timeline/timeline-body.cpp \ + $(lumigui_srcdir)/widgets/timeline/timeline-body.hpp \ + $(lumigui_srcdir)/model/project.cpp \ + $(lumigui_srcdir)/model/project.hpp \ + $(lumigui_srcdir)/output/displayer.cpp \ + $(lumigui_srcdir)/output/displayer.hpp \ + $(lumigui_srcdir)/output/gdkdisplayer.cpp \ + $(lumigui_srcdir)/output/gdkdisplayer.hpp \ + $(lumigui_srcdir)/output/xvdisplayer.cpp \ $(lumigui_srcdir)/output/xvdisplayer.hpp lumigui_LDFLAGS = lumigui_LDADD = $(GTK_LUMIERA_LIBS) -lumigui_DEPENDENCIES = \ - $(top_builddir)/lumiera_ui.rc \ - $(top_builddir)/assets-panel.png \ - $(top_builddir)/timeline-panel.png \ +lumigui_DEPENDENCIES = \ + $(top_builddir)/lumiera_ui.rc \ + $(top_builddir)/assets-panel.png \ + $(top_builddir)/timeline-panel.png \ $(top_builddir)/viewer-panel.png $(top_builddir)/lumiera_ui.rc: diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index 4e60ba7b8..3665ec98b 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -1,5 +1,5 @@ /* - timeline.cpp - Implementation of the timeline widget + timeline-widget.cpp - Implementation of the timeline widget Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -20,13 +20,11 @@ * *****************************************************/ -#include -#include -#include - #include "timeline-widget.hpp" using namespace Gtk; +using namespace std; +using namespace lumiera::gui::widgets::timeline; namespace lumiera { namespace gui { @@ -34,38 +32,76 @@ namespace widgets { TimelineWidget::TimelineWidget() : Table(2, 2), - horizontalAdjustment(0, 200, 400), - verticalAdjustment(0, 200, 400), + totalHeight(0), + horizontalAdjustment(0, 0, 0), + verticalAdjustment(0, 0, 0), horizontalScroll(horizontalAdjustment), verticalScroll(verticalAdjustment), - rowHeaderViewport(), - label1("label1"), label2("label2"), label3("label3"), label4("label4"), - label5("label5"), label6("label6"), label7("label7"), label8("label8"), - label9("label1"), label10("label10"), label11("label11"), ruler("ruler") + ruler("ruler") { - rowHeaderBox.pack_start(label1); - rowHeaderBox.pack_start(label2); - rowHeaderBox.pack_start(label3); - rowHeaderBox.pack_start(label4); - rowHeaderBox.pack_start(label5); - rowHeaderBox.pack_start(label6); - rowHeaderBox.pack_start(label7); - rowHeaderBox.pack_start(label8); - rowHeaderBox.pack_start(label9); - rowHeaderBox.pack_start(label10); - rowHeaderBox.pack_start(label11); - rowHeaderViewport.add(rowHeaderBox); + rowHeaderLayout.set_size_request(100, 100); - rowHeaderViewport.set_hadjustment(horizontalAdjustment); - rowHeaderViewport.set_vadjustment(verticalAdjustment); + body = new TimelineBody(horizontalAdjustment, verticalAdjustment); + + verticalAdjustment.signal_value_changed().connect( + sigc::mem_fun(this, &TimelineWidget::on_scroll) ); + attach(*body, 1, 2, 1, 2, FILL|EXPAND, FILL|EXPAND); attach(ruler, 1, 2, 0, 1, FILL|EXPAND, SHRINK); - attach(rowHeaderViewport, 0, 1, 1, 2, SHRINK, FILL|EXPAND); + attach(rowHeaderLayout, 0, 1, 1, 2, SHRINK, FILL|EXPAND); attach(horizontalScroll, 1, 2, 2, 3, FILL|EXPAND, SHRINK); attach(verticalScroll, 2, 3, 1, 2, SHRINK, FILL|EXPAND); + + tracks.push_back(&video1); + tracks.push_back(&video2); + + layout_tracks(); } +TimelineWidget::~TimelineWidget() + { + delete body; + } +void +TimelineWidget::on_scroll() + { + move_headers(); + } + +void +TimelineWidget::layout_tracks() + { + vector::iterator i; + for(i = tracks.begin(); i != tracks.end(); i++) + { + timeline::Track *track = *i; + g_assert(track != NULL); + rowHeaderLayout.put(track->get_header_widget(), 0, 0); + } + + move_headers(); + } + +void +TimelineWidget::move_headers() + { + int offset = 0; + const int y_scroll_offset = (int)verticalAdjustment.get_value(); + + vector::iterator i; + for(i = tracks.begin(); i != tracks.end(); i++) + { + timeline::Track *track = *i; + g_assert(track != NULL); + + const int height = track->get_track_height(); + rowHeaderLayout.move(track->get_header_widget(), 0, offset - y_scroll_offset); + offset += height; + } + totalHeight = offset; + verticalAdjustment.set_upper(totalHeight); + } } // namespace widgets } // namespace gui diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp index e89e684e0..7ceb3f125 100644 --- a/src/gui/widgets/timeline-widget.hpp +++ b/src/gui/widgets/timeline-widget.hpp @@ -1,5 +1,5 @@ /* - timeline.hpp - Declaration of the timeline widget + timeline-widget.hpp - Declaration of the timeline widget Copyright (C) Lumiera.org 2008, Joel Holdsworth @@ -19,40 +19,63 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/** @file timeline.hpp +/** @file timeline-widget.hpp ** This file contains the definition of timeline widget */ #ifndef TIMELINE_WIDGET_HPP #define TIMELINE_WIDGET_HPP +#include "timeline/timeline-body.hpp" +#include "timeline/track.hpp" +#include "timeline/video-track.hpp" + #include +#include namespace lumiera { namespace gui { namespace widgets { - class TimelineWidget : public Gtk::Table - { - public: - TimelineWidget(); +class TimelineWidget : public Gtk::Table + { + public: + TimelineWidget(); - /* ===== Overrides ===== */ - protected: - Gtk::Adjustment horizontalAdjustment, verticalAdjustment; - Gtk::HScrollbar horizontalScroll; - Gtk::VScrollbar verticalScroll; + ~TimelineWidget(); - Gtk::Viewport rowHeaderViewport; - Gtk::VBox rowHeaderBox; - Gtk::Label label1, label2, label3, label4; - Gtk::Label label5, label6, label7, label8; - Gtk::Label label9, label10, label11, label12; - Gtk::Label ruler; - }; + /* ===== Events ===== */ + protected: + void on_scroll(); + + /* ===== Internals ===== */ + protected: + void layout_tracks(); + + void move_headers(); + + protected: + int totalHeight; + + timeline::VideoTrack video1; + timeline::VideoTrack video2; + std::vector tracks; + + Gtk::Layout rowHeaderLayout; + Gtk::Label ruler; + + timeline::TimelineBody *body; + + Gtk::Adjustment horizontalAdjustment, verticalAdjustment; + Gtk::HScrollbar horizontalScroll; + Gtk::VScrollbar verticalScroll; + + friend class timeline::TimelineBody; + }; } // namespace widgets } // namespace gui } // namespace lumiera #endif // TIMELINE_WIDGET_HPP + diff --git a/src/gui/widgets/timeline/timeline-body.cpp b/src/gui/widgets/timeline/timeline-body.cpp new file mode 100644 index 000000000..f3e204cf9 --- /dev/null +++ b/src/gui/widgets/timeline/timeline-body.cpp @@ -0,0 +1,87 @@ +/* + timeline.cpp - Implementation of the timeline widget + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include + +#include "timeline-body.hpp" + +using namespace Gtk; +using namespace std; +using namespace lumiera::gui::widgets::timeline; + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget &timeline_widget) : + timelineWidget(timeline_widget) + { + timelineWidget.horizontalAdjustment.signal_value_changed().connect( + sigc::mem_fun(this, &TimelineBody::on_scroll) ); + timelineWidget.verticalAdjustment.signal_value_changed().connect( + sigc::mem_fun(this, &TimelineBody::on_scroll) ); + } + +void +TimelineBody::on_scroll() + { + queue_draw(); + } + +bool +TimelineBody::on_expose_event(GdkEventExpose* event) + { + // This is where we draw on the window + Glib::RefPtr window = get_window(); + if(window) + { + Gtk::Allocation allocation = get_allocation(); + const int width = allocation.get_width(); + const int height = allocation.get_height(); + + Cairo::RefPtr cr = window->create_cairo_context(); + cr->set_line_width(10.0); + + cr->translate(-horizontalAdjustment.get_value(), -verticalAdjustment.get_value()); + cr->save(); + + vector::iterator i; + for(i = tracks.begin(); i != tracks.end(); i++) + { + timeline::Track *track = *i; + g_assert(track != NULL); + track->draw_track(); + } + + cr->restore(); + } + + return true; + + } + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + diff --git a/src/gui/widgets/timeline/timeline-body.hpp b/src/gui/widgets/timeline/timeline-body.hpp new file mode 100644 index 000000000..39fd8773a --- /dev/null +++ b/src/gui/widgets/timeline/timeline-body.hpp @@ -0,0 +1,56 @@ +/* + timeline-body.hpp - Declaration of the timeline body widget + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file timeline-body.hpp + ** This file contains the definition of timeline body widget + */ + +#ifndef TIMELINE_BODY_HPP +#define TIMELINE_BODY_HPP + +#include + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +class TimelineBody : public Gtk::DrawingArea + { + public: + TimelineBody(lumiera::gui::widgets::TimelineWidget &timeline_widget); + + protected: + lumiera::gui::widgets::TimelineWidget &timelineWidget; + + /* ===== Events ===== */ + protected: + void on_scroll(); + + virtual bool on_expose_event(GdkEventExpose* event); + }; + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + +#endif // TIMELINE_BODY_HPP diff --git a/src/gui/widgets/timeline/track.cpp b/src/gui/widgets/timeline/track.cpp new file mode 100644 index 000000000..c0564e37f --- /dev/null +++ b/src/gui/widgets/timeline/track.cpp @@ -0,0 +1,51 @@ +/* + track.cpp - Implementation of the timeline track object + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "track.hpp" + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +Track::Track() + { + + } + +Glib::ustring +Track::get_title() + { + return "Hello"; + } + +void +Track::draw_track() + { + + } + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + diff --git a/src/gui/widgets/timeline/track.hpp b/src/gui/widgets/timeline/track.hpp new file mode 100644 index 000000000..204b650a0 --- /dev/null +++ b/src/gui/widgets/timeline/track.hpp @@ -0,0 +1,59 @@ +/* + track.hpp - Declaration of the timeline track object + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file track.hpp + ** This file contains the definition of timeline track object + */ + +#ifndef TRACK_HPP +#define TRACK_HPP + +#include + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +class Track + { + public: + Track(); + + Glib::ustring get_title(); + + virtual Gtk::Widget& get_header_widget() = 0; + + virtual int get_track_height() = 0; + + virtual void draw_track(); + + protected: + + }; + + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + +#endif // TRACK_HPP diff --git a/src/gui/widgets/timeline/video-track.cpp b/src/gui/widgets/timeline/video-track.cpp new file mode 100644 index 000000000..b3b45c543 --- /dev/null +++ b/src/gui/widgets/timeline/video-track.cpp @@ -0,0 +1,56 @@ +/* + video-track.cpp - Implementation of the timeline video track object + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "video-track.hpp" + +using namespace Gtk; + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +VideoTrack::VideoTrack() : + headerWidget("HeaderTest") + { + + } + +Gtk::Widget& VideoTrack::get_header_widget() + { + return headerWidget; + } + +int VideoTrack::get_track_height() + { + return 100; + } + +void VideoTrack::draw_track() + { + + } + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera diff --git a/src/gui/widgets/timeline/video-track.hpp b/src/gui/widgets/timeline/video-track.hpp new file mode 100644 index 000000000..e82a178bd --- /dev/null +++ b/src/gui/widgets/timeline/video-track.hpp @@ -0,0 +1,57 @@ +/* + video-track.hpp - Declaration of the timeline video track object + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file video-track.hpp + ** This file contains the definition of video track object + */ + +#ifndef VIDEO_TRACK_HPP +#define VIDEO_TRACK_HPP + +#include "track.hpp" + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +class VideoTrack : public Track + { + public: + VideoTrack(); + + virtual Gtk::Widget& get_header_widget(); + + virtual int get_track_height(); + + virtual void draw_track(); + + protected: + Gtk::Label headerWidget; + }; + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + +#endif // VIDEO_TRACK_HPP + diff --git a/src/gui/widgets/video-display-widget.hpp b/src/gui/widgets/video-display-widget.hpp index 7a80a4b04..66e224c18 100644 --- a/src/gui/widgets/video-display-widget.hpp +++ b/src/gui/widgets/video-display-widget.hpp @@ -51,6 +51,7 @@ namespace widgets { virtual bool on_expose_event(GdkEventExpose* event); + // TEST CODE!!!! virtual bool on_button_press_event (GdkEventButton* event); /* ===== Internals ===== */ From 71b45acf54b7e970957ef2089e1284fa5ff3e12b Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 31 May 2008 17:44:44 +0100 Subject: [PATCH 124/245] Styles for custom widgets now load --- src/gui/lumiera_ui.rc | 1443 +------------------- src/gui/widgets/timeline-widget.cpp | 2 +- src/gui/widgets/timeline/timeline-body.cpp | 92 +- src/gui/widgets/timeline/timeline-body.hpp | 14 +- src/gui/widgets/timeline/track.cpp | 2 +- src/gui/widgets/timeline/track.hpp | 2 +- src/gui/widgets/timeline/video-track.cpp | 2 +- src/gui/widgets/timeline/video-track.hpp | 2 +- 8 files changed, 119 insertions(+), 1440 deletions(-) diff --git a/src/gui/lumiera_ui.rc b/src/gui/lumiera_ui.rc index d87322014..f0c1163e5 100644 --- a/src/gui/lumiera_ui.rc +++ b/src/gui/lumiera_ui.rc @@ -1,86 +1,22 @@ # -# This is the GTK style file for Ardour +# This is the GTK style file for Lumiera # # -style "very_small_text" +#---------- Styles for Standard Widgets ----------# + +style "medium_bold_entry" { - font_name = "sans 7" -} + font_name = "sans bold 10" -style "small_text" -{ - font_name = "sans 8" -} - -style "small_bold_text" -{ - font_name = "sans bold 8" -} - -style "medium_bold_text" -{ - font_name = "sans bold 8" -} - -style "medium_text" -{ - font_name = "sans 8" -} - -style "red_medium_text" = "medium_text" -{ - fg[NORMAL] = { 1.0, 0, 0 } - fg[ACTIVE] = { 1.0, 0, 0 } - fg[SELECTED] = { 1.0, 0, 0 } -} - - -style "large_text" -{ - font_name = "sans 18" -} - -style "larger_bold_text" -{ - font_name = "sans bold 14" -} - -style "plugin_name_text" -{ - font_name = "sans bold 25" - fg[NORMAL] = { 0.80, 0.80, 0.80 } -} - -style "plugin_maker_text" -{ - font_name = "sans bold 14" - fg[NORMAL] = { 0.80, 0.80, 0.80 } -} - -style "automation_track_name" -{ - font_name = "sans italic 8" -} - -style "first_action_message" -{ - font_name = "sans medium 34" -} - -style "verbose_canvas_cursor" -{ - font_name = "sans bold 24" -} - -style "marker_text" -{ - font_name = "sans 8" -} - -style "time_axis_view_item_name" -{ - font_name = "sans 9" + fg[NORMAL] = { 0.70, 0.70, 0.70 } + fg[ACTIVE] = { 0.70, 0.70, 0.70 } + + bg[NORMAL] = { 0.35, 0.35, 0.40 } + + base[NORMAL] = { 0, 0, 0 } + base[ACTIVE] = { 0, 0, 0 } + base[SELECTED] = { 0, 0, 0 } } style "default_base" = "medium_text" @@ -120,37 +56,15 @@ style "default_base" = "medium_text" engine "clearlooks" { menubarstyle = 2 # 0 = flat, 1 = sunken, 2 = flat gradient - menuitemstyle = 1 # 0 = flat, 1 = 3d-ish (gradient), 2 = 3d-ish (button) - listviewitemstyle = 1 # 0 = flat, 1 = 3d-ish (gradient) - progressbarstyle = 1 # 0 = candy bar, 1 = fancy candy bar, 2 = flat +# menuitemstyle = 1 # 0 = flat, 1 = 3d-ish (gradient), 2 = 3d-ish (button) +# listviewitemstyle = 1 # 0 = flat, 1 = 3d-ish (gradient) +# progressbarstyle = 1 # 0 = candy bar, 1 = fancy candy bar, 2 = flat } } -style "base_frame" -{ - fg[NORMAL] = { 0.80, 0.80, 0.80 } - bg[NORMAL] = { 0.35, 0.35, 0.40 } -} - -style "transport_base" = "medium_bold_text" -{ - bg[NORMAL] = { 0.10, 0.10, 0.10 } - bg[ACTIVE] = { 0, 0, 0 } - bg[PRELIGHT] = { 0, 0, 0 } - bg[INSENSITIVE] = { 0, 0, 0 } - bg[SELECTED] = { 0, 0, 0 } -} - -style "black_mackie_menu_bar" -{ - font_name = "sans bold 9" - fg[NORMAL] = { 1.0, 1.0, 1.0 } - bg[NORMAL] = { 0, 0, 0 } -} - style "default_buttons_menus" { - font_name = "sans 8" + font_name = "sans 10" fg[ACTIVE] = { 1.0, 1.0, 1.0 } bg[NORMAL] = { 0.30, 0.30, 0.35 } @@ -160,913 +74,23 @@ style "default_buttons_menus" bg[SELECTED] = { 0.15, 0.15, 0.20 } } -style "very_small_button" = "default_buttons_menus" -{ - font_name = "sans 7" - ythickness = 0 - xthickness = 0 -} - -style "small_button" = "default_buttons_menus" -{ -} - -style "very_small_red_active_and_selected_button" = "very_small_button" -{ - bg[ACTIVE] = { 1.0, 0, 0} - bg[SELECTED] = { 1.0, 0, 0} -} - -style "small_red_active_and_selected_button" = "small_button" -{ - fg[ACTIVE] = { 0, 0, 0 } - bg[ACTIVE] = { 1.0, 0, 0} - bg[SELECTED] = { 1.0, 0, 0} -} - -style "gain_fader" -{ - bg[NORMAL] = { 0.269, 0.269, 0.300} - bg[ACTIVE] = { 0.152, 0.152, 0.168 } -} - - -style "track_rec_enable_button" = "small_button" -{ -} - -style "track_rec_enable_button_active" = "small_button" -{ - fg[SELECTED] = { 0.0, 0.0, 0.0 } - fg[ACTIVE] = { 0.0, 0.0, 0.0 } - fg[PRELIGHT] = { 0.0, 0.0, 0.0 } - fg[NORMAL] = { 0.0, 0.0, 0.0 } - - bg[NORMAL] = { 1.0, 0.0, 0.0 } - bg[ACTIVE] = { 1.0, 0.0, 0.0 } - bg[SELECTED] = { 1.0, 0.0, 0.0 } - bg[PRELIGHT] = { 1.0, 0.0, 0.0 } -} - -style "track_rec_enable_button_alternate" = "small_button" -{ - fg[SELECTED] = { 0.0, 0.0, 0.0 } - fg[ACTIVE] = { 0.0, 0.0, 0.0 } - fg[PRELIGHT] = { 0.0, 0.0, 0.0 } - fg[NORMAL] = { 0.0, 0.0, 0.0 } - - bg[NORMAL] = { 0.91, 0.68, 0.68} - bg[ACTIVE] = { 0.91, 0.68, 0.68} - bg[SELECTED] = { 0.91, 0.68, 0.68} - bg[PRELIGHT] = { 0.91, 0.68, 0.68} -} - -style "mixer_track_rec_enable_button" = "track_rec_enable_button" -{ - font_name = "sans 7" - xthickness = 0 - ythickness = 0 -} - -style "mixer_track_rec_enable_button_alternate" = "track_rec_enable_button_alternate" -{ - font_name = "sans 7" - xthickness = 0 - ythickness = 0 -} - -style "mixer_track_rec_enable_button_active" = "track_rec_enable_button_active" -{ - font_name = "sans 7" - xthickness = 0 - ythickness = 0 -} - -style "solo_button" = "small_button" -{ -} - -style "solo_button_alternate" = "small_button" -{ - bg[NORMAL] = { 0.19, 0.97, 0.69 } # solo-safe - bg[ACTIVE] = { 0.19, 0.97, 0.69 } # solo-safe - bg[SELECTED] = { 0.19, 0.97, 0.69 } # solo-safe - bg[PRELIGHT] = { 0.19, 0.97, 0.69 } # solo-safe - - fg[ACTIVE] = { 0, 0, 0 } - fg[SELECTED] = { 0, 0, 0 } - fg[NORMAL] = { 0, 0, 0 } - fg[PRELIGHT] = { 0, 0, 0 } -} - - -style "solo_button_active" = "small_button" -{ - bg[NORMAL] = { 0.66, 0.97, 0.19 } # solo - bg[ACTIVE] = { 0.66, 0.97, 0.19 } # solo - bg[SELECTED] = { 0.66, 0.97, 0.19 } # solo - bg[PRELIGHT] = { 0.66, 0.97, 0.19 } # solo - - fg[ACTIVE] = { 0, 0, 0 } - fg[SELECTED] = { 0, 0, 0 } - fg[NORMAL] = { 0, 0, 0 } - fg[PRELIGHT] = { 0, 0, 0 } -} - -style "mixer_solo_button" = "solo_button" -{ - font_name = "sans 7" - xthickness = 0 - ythickness = 0 -} - -style "mixer_solo_button_alternate" = "solo_button_alternate" -{ - font_name = "sans 7" - xthickness = 0 - ythickness = 0 -} -style "mixer_solo_button_active" = "solo_button_active" -{ - font_name = "sans 7" - xthickness = 0 - ythickness = 0 -} - - -style "mute_button" = "small_button" -{ -} - -style "mute_button_alternate" = "small_button" -{ - bg[ACTIVE] = { 1.0, 0.98, 0.53 } - bg[NORMAL] = { 1.0, 0.98, 0.53 } - bg[SELECTED] = { 1.0, 0.98, 0.53 } - bg[PRELIGHT] = { 1.0, 0.98, 0.53 } - - fg[SELECTED] = { 0, 0, 0 } - fg[ACTIVE] = { 0, 0, 0 } - fg[NORMAL] = { 0, 0, 0 } - fg[PRELIGHT] = { 0, 0, 0 } -} - -style "mute_button_active" = "small_button" -{ - bg[NORMAL] = { 0.90, 0.89, 0.73 } - bg[ACTIVE] = { 0.90, 0.89, 0.73 } - bg[PRELIGHT] = { 0.90, 0.89, 0.73 } - bg[SELECTED] = { 0.90, 0.89, 0.73 } - - fg[SELECTED] = { 0, 0, 0 } - fg[ACTIVE] = { 0, 0, 0 } - fg[NORMAL] = { 0, 0, 0 } - fg[PRELIGHT] = { 0, 0, 0 } -} - -style "mixer_mute_button" = "mute_button" -{ - font_name = "sans 7" - xthickness = 0 - ythickness = 0 -} - -style "mixer_mute_button_alternate" = "mute_button_alternate" -{ - font_name = "sans 7" - xthickness = 0 - ythickness = 0 -} - -style "mixer_mute_button_active" = "mute_button_active" -{ - font_name = "sans 7" - xthickness = 0 - ythickness = 0 -} - -style "multiline_combo" = "small_button" -{ - font_name = "sans 8" - xthickness = 0 - ythickness = 0 -} - -style "mixer_mute_button" = "mute_button" -{ - font_name = "sans 7" - xthickness = 0 - ythickness = 0 -} - -style "track_loop_button" = "small_button" -{ - bg[ACTIVE] = { 1.0, 0.98, 0.53 } - bg[PRELIGHT] = { 1.0, 0.98, 0.53 } - -} - -style "mixer_red_active_button" = "very_small_button" -{ - fg[ACTIVE] = { 0, 1.0, 1.0 } - bg[ACTIVE] = { 0.7, 0, 0 } - - base[INSENSITIVE] = { 0.16, 0.16, 0.21 } - bg[INSENSITIVE] = { 0.16, 0.16, 0.21 } -} - -style "time_button" = "default_buttons_menus" -{ - font_name = "sans 8" -} - -style "transport_button" -{ -} - -style "transport_button_active" -{ - bg[NORMAL] = { 0.50, 1.0, 0.50 } - bg[ACTIVE] = { 0.50, 1.0, 0.50 } - bg[SELECTED] = { 0.50, 1.0, 0.50 } - bg[PRELIGHT] = { 0.50, 1.0, 0.50 } - - fg[NORMAL] = { 0, 0, 0 } - fg[PRELIGHT] = { 0, 0, 0 } - fg[SELECTED] = { 0, 0, 0 } - fg[ACTIVE] = { 0, 0, 0 } -} - -style "transport_rec_button" -{ -} - -style "transport_rec_button_active" -{ - bg[ACTIVE] = { 1.0, 0, 0 } - bg[NORMAL] = { 1.0, 0, 0 } - bg[SELECTED] = { 1.0, 0, 0 } - bg[PRELIGHT] = { 1.0, 0, 0 } -} - -style "transport_rec_button_alternate" -{ - bg[PRELIGHT] = { 0.91, 0.68, 0.68 } - bg[NORMAL] = { 0.91, 0.68, 0.68 } - bg[SELECTED] = { 0.91, 0.68, 0.68 } - bg[ACTIVE] = { 0.91, 0.68, 0.68 } -} - -style "shuttle_control" = "very_small_text" -{ - fg[NORMAL] = { 0.85, 0.92, 0.98 } - fg[ACTIVE] = { 0.85, 0.92, 0.98 } - fg[PRELIGHT] = { 0.85, 0.92, 0.98 } - fg[SELECTED] = { 0.85, 0.92, 0.98 } - fg[INSENSITIVE] = { 0.85, 0.92, 0.98 } - - bg[NORMAL] = { 0.26, 0.26, 0.31 } - bg[PRELIGHT] = { 0.26, 0.26, 0.31 } - bg[INSENSITIVE] = { 0.26, 0.26, 0.31 } - bg[ACTIVE] = { 0.70, 0.70, 0.70 } - bg[SELECTED] = { 1.0, 0.04, 0.04 } -} - -style "ardour_adjusters" = "default_buttons_menus" +style "lumiera_adjusters" = "default_buttons_menus" { bg[NORMAL] = { 0.60, 0.60, 0.60 } bg[PRELIGHT] = { 0.80, 0.80, 0.80 } bg[ACTIVE] = { 0.06, 0.06, 0.06 } } -style "editor_hscrollbar" = "ardour_adjusters" -{ - # - # special case: we want this scrollbar to be as tall as the - # zoom focus selector combobox. scrollbars don't expand to - # fill the space available to them, so we have to explicitly - # make it bigger. - # - GtkRange::slider_width = 27 - GtkScrollbar::slider_width = 27 -} - -style "ardour_progressbars" = "default_buttons_menus" +style "lumiera_progressbars" = "default_buttons_menus" { bg[NORMAL] = { 0, 0, 0 } bg[PRELIGHT] = { 0.00, 0.36, 0.40 } } -style "options_window" = "default_base" +style "lumiera_button" = "default_buttons_menus" { - font_name = "sans 8" - fg[PRELIGHT] = { 0.80, 0.80, 0.80 } -} - -style "option_entry" = "default_base" -{ - fg[NORMAL] = { 1.0, 1.0, 1.0 } - fg[ACTIVE] = { 1.0, 1.0, 1.0 } - fg[INSENSITIVE] = { 0.80, 0.80, 0.80 } - - base[INSENSITIVE] = { 0.07, 0.07, 0.12 } - - bg[NORMAL] = { 0.35, 0.35, 0.40 } - bg[ACTIVE] = { 0.35, 0.35, 0.40 } -} - -style "red_when_active" = "medium_text" -{ - fg[NORMAL] = { 0.80, 0.80, 0.80 } - bg[NORMAL] = { 0.26, 0.26, 0.31 } - - fg[ACTIVE] = { 0.80, 0.80, 0.80 } - bg[ACTIVE] = { 1.0, 0, 0} -} - -style "xrun_warn" -{ - font_name = "sans bold 18" - - fg[NORMAL] = { 1.0, 1.0, 1.0 } - fg[ACTIVE] = { 1.0, 1.0, 1.0 } - text[NORMAL] = { 1.0, 1.0, 1.0 } - text[ACTIVE] = { 1.0, 1.0, 1.0 } - base[NORMAL] = { 0.09, 0.48, 0.46 } - base[ACTIVE] = { 0.09, 0.48, 0.46 } - bg[NORMAL] = { 1.0, 0.48, 0.46 } - bg[ACTIVE] = { 0.09, 1.0, 0.46 } -} - -style "menu_bar_base" = "default_base" -{ - bg[NORMAL] = { 0.2, 0.2, 0.3 } - bg[ACTIVE] = { 0, 0, 0 } - bg[PRELIGHT] = { 0, 0, 0 } - bg[INSENSITIVE] = { 0, 0, 0 } - bg[SELECTED] = { 0, 0, 0 } -} - -style "fatal_message" = "medium_text" -{ - fg[ACTIVE] = { 1.0, 0, 1.0 } - fg[NORMAL] = { 0.80, 0.80, 0.80 } - bg[ACTIVE] = { 0,0,0 } - bg[NORMAL] = { 0,0,0 } - base[ACTIVE] = { 0,0,0 } - base[NORMAL] = { 0,0,0 } -} - -style "error_message" = "medium_text" -{ - fg[ACTIVE] = { 1.0, 0, 0 } - fg[NORMAL] = { 0.80, 0.80, 0.80 } - bg[ACTIVE] = { 0,0,0 } - bg[NORMAL] = { 0,0,0 } - base[ACTIVE] = { 0,0,0 } - base[NORMAL] = { 0,0,0 } -} - -style "info_message" = "medium_text" -{ - fg[ACTIVE] = { 1.0, 0, 0 } - fg[NORMAL] = { 0.80, 0.80, 0.80 } - bg[ACTIVE] = { 0,0,0 } - bg[NORMAL] = { 0,0,0 } - base[ACTIVE] = { 0,0,0 } - base[NORMAL] = { 0,0,0 } -} - -style "warning_message" = "medium_text" -{ - fg[ACTIVE] = { 0.30,0.30, 1.0 } - fg[NORMAL] = { 0.80, 0.80, 0.80 } - bg[ACTIVE] = { 0, 0, 0 } - bg[NORMAL] = { 0, 0, 0 } - base[ACTIVE] = { 0, 0, 0 } - base[NORMAL] = { 0, 0, 0 } -} - -style "medium_entry" = "medium_text" -{ - fg[NORMAL] = { 0.70, 0.70, 0.70 } - fg[ACTIVE] = { 0.70, 0.70, 0.70 } - fg[SELECTED] = { 1.0, 1.0, 1.0 } - - bg[NORMAL] = { 0.35, 0.35, 0.40 } - - base[NORMAL] = { 0, 0, 0 } - base[ACTIVE] = { 0, 0, 0 } - base[SELECTED] = { 0.70, 0.70, 0.70 } -} - -style "medium_entry_noselection_fg" = "medium_entry" -{ - fg[SELECTED] = { 0.50, 1.0, 0.50 } -} - -style "medium_entry_noselection_bg" = "medium_entry" -{ - bg[SELECTED] = { 1.0, 1.0, 1.0 } -} - -style "medium_bold_entry" = "medium_bold_text" -{ - fg[NORMAL] = { 0.70, 0.70, 0.70 } - fg[ACTIVE] = { 0.70, 0.70, 0.70 } - - bg[NORMAL] = { 0.35, 0.35, 0.40 } - - base[NORMAL] = { 0, 0, 0 } - base[ACTIVE] = { 0, 0, 0 } - base[SELECTED] = { 0, 0, 0 } -} - -style "small_entry" = "small_text" -{ - fg[NORMAL] = { 0.70, 0.70, 0.70 } - fg[ACTIVE] = { 0, 1.0, 0 } - fg[SELECTED] = { 0, 1.0, 0 } - text[NORMAL] = { 0.70, 0.70, 0.70 } - text[ACTIVE] = { 0, 1.0, 0 } - text[SELECTED] = { 0, 1.0, 0 } - bg[NORMAL] = { 0.0, 0.0, 0.0 } - bg[SELECTED] = { 0.0, 0.0, 0.0 } - bg[SELECTED] = { 0.0, 0.0, 0.0 } - base[NORMAL] = { 0, 0, 0 } - base[ACTIVE] = { 0, 0, 0 } - base[SELECTED] = { 0, 0, 0 } -} - -style "red_active_small_entry" = "small_entry" -{ - fg[ACTIVE] = { 1.0, 0.0, 0.0 } - fg[SELECTED] = { 1.0, 0, 0 } -} - -style "small_bold_entry" = "small_bold_text" -{ - fg[NORMAL] = { 0.70, 0.70, 0.70 } - fg[ACTIVE] = { 0.70, 0.70, 0.70 } - - bg[NORMAL] = { 0.35, 0.35, 0.40 } - - base[NORMAL] = { 0, 0, 0 } - base[ACTIVE] = { 0, 0, 0 } - base[SELECTED] = { 0, 0, 0 } -} - -style "small_red_on_black_entry" = "small_bold_text" -{ - fg[NORMAL] = { 1.0, 0, 0 } - fg[ACTIVE] = { 1.0, 0, 0 } - base[NORMAL] = { 0.0, 0.0, 0.0 } - base[ACTIVE] = { 0.0, 0.0, 0.0 } - bg[NORMAL] = { 0.0, 0.0, 0.0 } - bg[ACTIVE] = { 0.0, 0.0, 0.0 } -} - -style "non_recording_big_clock_display" = "medium_entry" -{ - font_name = "sans 60" - - fg[NORMAL] = { 0.50, 1.0, 0.50 } - fg[ACTIVE] = { 1.0, 0, 0.0 } - fg[SELECTED] = { 1.0, 0, 0 } - fg[PRELIGHT] = { 1.0, 0, 0.0 } - fg[INSENSITIVE] = { 1.0, 0, 0.0 } - - base[NORMAL] = { 0.0, 0.0, 0.0 } - base[ACTIVE] = { 0.0, 0.0, 0.0 } - bg[NORMAL] = { 0.0, 0.0, 0.0 } - bg[ACTIVE] = { 0.7, 0.0, 0.0 } -} - -style "recording_big_clock_display" = "non_recording_big_clock_display" -{ - fg[NORMAL] = { 1.0, 0, 0 } -} - -style "transport_clock_display" -{ - font_name = "sans bold 14" - - fg[NORMAL] = { 0.50, 1.0, 0.50 } - fg[ACTIVE] = { 1.0, 0, 0.0 } - fg[SELECTED] = { 1.0, 0, 0 } - fg[PRELIGHT] = { 1.0, 0, 0.0 } - fg[INSENSITIVE] = { 1.0, 0, 0.0 } - - base[NORMAL] = { 0.0, 0.0, 0.0 } - base[ACTIVE] = { 0.0, 0.0, 0.0 } - bg[NORMAL] = { 0.0, 0.0, 0.0 } - bg[ACTIVE] = { 0.0, 0.0, 0.0 } -} - -style "tempo_meter_clock_display" -{ - font_name = "sans 7" - fg[NORMAL] = { 1.0, 1.0, 1.0 } - fg[ACTIVE] = { 1.0, 1.0, 0.0 } - fg[SELECTED] = { 1.0, 0, 0 } - base[NORMAL] = { 0.0, 0.48, 1.0 } - base[ACTIVE] = { 0.09, 0.98, 0.46 } - bg[NORMAL] = { 0.0, 0.48, 1.0 } - bg[ACTIVE] = { 0.09, 0.98, 0.46 } -} - -style "default_clock_display" = "medium text" -{ - fg[NORMAL] = { 0.50, 1.0, 0.50 } - fg[ACTIVE] = { 1.0, 0.0, 0.0 } - fg[SELECTED] = { 1.0, 0, 0 } - base[NORMAL] = { 0, 0, 0 } - base[ACTIVE] = { 0, 0, 0 } - bg[NORMAL] = { 0, 0, 0 } - bg[ACTIVE] = { 0, 0, 0 } -} - -style "editor_time_ruler" = "small_text" -{ - fg[NORMAL] = { 0.80, 0.80, 0.80 } - bg[NORMAL] = { 0.09, 0.09, 0.09 } -} - -style "audio_track_base" = "default_base" -{ - font_name = "sans 6" - fg[NORMAL] = { 0.77, 0.77, 0.72 } - bg[NORMAL] = { 0.18, 0.19, 0.22 } - bg[ACTIVE] = { 0.20, 0.20, 0.20 } - bg[PRELIGHT] = { 0.20, 0.20, 0.20 } - bg[INSENSITIVE] = { 0.20, 0.20, 0.20 } - bg[SELECTED] = { 0.20, 0.20, 0.20 } -} - -style "audio_bus_base" -{ - font_name = "sans 6" - fg[NORMAL] = { 0.77, 0.77, 0.72 } - fg[NORMAL] = { 0.7, 0.8, 0.2 } - #bg[NORMAL] = {0, 0.36, 0.40 } - bg[NORMAL] = "#444466" -} - -style "track_name_display" -{ - font_name = "sans medium 8" - fg[NORMAL] = { 0.80, 0.80, 0.80 } - fg[ACTIVE] = { 0.80, 0.80, 0.80 } - - base[NORMAL] = { 0.06, 0.06, 0.06 } - base[ACTIVE] = { 0.26, 0.26, 0.26 } - bg[NORMAL] = { 0.26, 0.26, 0.26 } - bg[ACTIVE] = { 0.26, 0.26, 0.26 } -} - -style "active_track_name_display" -{ - font_name = "sans medium 8" - text[NORMAL] = { 0.26, 0.26, 0.26 } - base[NORMAL] = { 0.89, 0.89, 0.89 } -} - -style "track_separator" -{ - bg[NORMAL] = { 0.35, 0.35, 0.40 } -} - -# -# Track edit groups. These styles define -# the colors that the "edit" button will -# use as a track is moved from -# track edit group to track edit group. -# There are 8 edit groups. Edit group 0 -# is used for tracks that are not editable, -# so we leave its style to the default. -# - -style "edit_group_0" - -{ - bg[ACTIVE] = { 1.0, 0.65, 0.13 } - bg[NORMAL] = { 0.31, 0.31, 0.31 } - fg[NORMAL] = { 0.82, 0.91, 0.99 } - fg[ACTIVE] = { 0, 0, 0 } -} - -style "edit_group_1" -{ - fg[NORMAL] = { 0, 0, 0 } - fg[PRELIGHT] = { 0, 0, 0 } - fg[SELECTED] = { 0, 0, 0 } - bg[NORMAL] = { 0.93, 0.34, 0.08 } - bg[PRELIGHT] = { 0.93, 0.34, 0.08 } - bg[SELECTED] = { 0.93, 0.34, 0.08 } -} - -style "edit_group_2" -{ - fg[NORMAL] = { 0, 0, 0 } - fg[PRELIGHT] = { 0, 0, 0 } - fg[SELECTED] = { 0, 0, 0 } - bg[NORMAL] = { 0.93, 0.34, 0.08 } - bg[PRELIGHT] = { 0.93, 0.34, 0.08 } - bg[SELECTED] = { 0.93, 0.34, 0.08 } -} - -style "edit_group_3" -{ - fg[NORMAL] = { 0, 0, 0 } - fg[PRELIGHT] = { 0, 0, 0 } - fg[SELECTED] = { 0, 0, 0 } - bg[NORMAL] = { 0.93, 0.34, 0.08 } - bg[PRELIGHT] = { 0.93, 0.34, 0.08 } - bg[SELECTED] = { 0.93, 0.34, 0.08 } -} - -style "treeview_parent_node" -{ - # specifies *just* the color used for whole file rows when not selected - fg[NORMAL] = { 0.0, 0.6, 0.85 } -} - -style "treeview_display" = "small_bold_text" -{ - # expander arrow border and DnD "icon" text - fg[NORMAL] = { 0.8, 0.8, 0.8 } - - # background with no rows or no selection, plus - # expander arrow core and DnD "icon" background - base[NORMAL] = { 0.20, 0.20, 0.25 } - - # selected row bg when window does not have focus (including during DnD) - base[ACTIVE] = { 0.0, 0.60, 0.60 } - - # selected row bg when window has focus - base[SELECTED] = { 0, 0.75, 0.75 } - - # row text when in normal state and not a parent - text[NORMAL] = { 0.80, 0.80, 0.80 } - - # selected row text with window focus - text[SELECTED] = { 0, 1.0, 1.0 } - - # selected row text without window focus (including during DnD) - text[ACTIVE] = { 0, 1.0, 1.0 } -} - -style "main_canvas_area" -{ - bg[NORMAL] = { 0.30, 0.30, 0.34 } - bg[ACTIVE] = { 0.30, 0.30, 0.34 } - bg[INSENSITIVE] = { 0.30, 0.30, 0.34 } - bg[SELECTED] = { 0.30, 0.30, 0.34 } - bg[PRELIGHT] = { 0.30, 0.30, 0.34 } -} - -style "track_controls_inactive" -{ - bg[NORMAL] = { 0.60, 0.60, 0.66 } - bg[ACTIVE] = { 0.60, 0.60, 0.66 } - bg[INSENSITIVE] = { 0.60, 0.60, 0.66 } - bg[SELECTED] = { 0.60, 0.60, 0.66 } - bg[PRELIGHT] = { 0.60, 0.60, 0.66 } - - font_name = "sans medium 10" - fg[NORMAL] = { 0.7, 0.8, 0.2 } -} - -style "edit_controls_base_selected" -{ - bg[NORMAL] = { 0.60, 0.54, 0.60 } - bg[ACTIVE] = { 0.60, 0.54, 0.60 } - bg[INSENSITIVE] = { 0.60, 0.54, 0.60 } - bg[SELECTED] = { 0.60, 0.54, 0.60 } - bg[PRELIGHT] = { 0.60, 0.54, 0.60 } -} - -style "automation_track_controls_base" -{ - bg[NORMAL] = { 0.22, 0.22, 0.29 } - bg[ACTIVE] = { 0.22, 0.22, 0.29 } - bg[INSENSITIVE] = { 0.22, 0.22, 0.29 } - bg[SELECTED] = { 0.22, 0.22, 0.29 } - bg[PRELIGHT] = { 0.22, 0.22, 0.29 } -} - -# Plugin Editors -style "plugin_slider" -{ - font_name ="sans bold 10" - - # the slider itself. the inactive part is INSENSITIVE, - # the active part is something else. - - fg[NORMAL] = { 0.37, 0.43, 0.52 } - fg[ACTIVE] = { 0.37, 0.43, 0.52 } - fg[INSENSITIVE] = {0.35, 0.35, 0.40 } # matches default_base - fg[SELECTED] = { 0.37, 0.43, 0.52 } - fg[PRELIGHT] = { 0.37, 0.43, 0.52 } - - # draws the outer rectangle around the slider - - bg[NORMAL] = { 0.80, 0.80, 0.80 } - bg[ACTIVE] = { 0.80, 0.80, 0.80 } - bg[INSENSITIVE] = {0.80, 0.80, 0.80 } - bg[SELECTED] = { 0.80, 0.80, 0.80 } - bg[PRELIGHT] = { 0.80, 0.80, 0.80 } - - # the numeric display - - text[NORMAL] = { 0.80, 0.80, 0.80 } - text[ACTIVE] = { 0.80, 0.80, 0.80 } - text[INSENSITIVE] = { 0.80, 0.80, 0.80 } - text[SELECTED] = { 0.80, 0.80, 0.80 } - text[PRELIGHT] = { 0.80, 0.80, 0.80 } -} - -style "track_list_display" = "small_bold_text" -{ - text[NORMAL] = { 0.80, 0.80, 0.80 } - text[ACTIVE] = { 0.3, 0.3, 0.3 } - text[INSENSITIVE] = { 0, 0, 0 } - text[SELECTED] = { 0.8, 0.8, 0.8 } - - base[NORMAL] = { 0, 0, 0 } - base[ACTIVE] = { 0, 0, 0 } - base[INSENSITIVE] = { 0, 0, 0 } - base[SELECTED] = { 0, 0, 0 } -} - -style "inspector_track_list_display" = "track_list_display" -{ - text[ACTIVE] = { 0.8, 0.8, 0.8 } - - base[NORMAL] = { 0, 0, 0 } - base[ACTIVE] = { 0.2, 0.2, 0.2 } - base[INSENSITIVE] = { 0, 0, 0 } - base[SELECTED] = { 0.3, 0.3, 0.4 } -} - -style "redirect_list_display" -{ - GtkTreeView::horizontal-separator = 0 - GtkTreeView::vertical-separator = 0 - - font_name = "sans 7" - text[NORMAL] = { 0.80, 0.80, 0.80 } - text[ACTIVE] = { 0.70, 0.70, 0.70 } - text[INSENSITIVE] = { 0, 0, 0 } - text[SELECTED] = { 0.9, 0.3, 0.3 } - - base[NORMAL] = { 0, 0, 0 } - base[ACTIVE] = { 0, 0, 0 } - base[INSENSITIVE] = { 0, 0, 0 } - base[SELECTED] = { 0, 0, 0 } - - # these two are explicitly used by the cell renderer for the - # text - - fg[NORMAL] = { 0.5, 0.5, 0.5 } # used for inactive - fg[ACTIVE] = { 1.0, 1.0, 1.0 } # used for active -} - -style "inspector_redirect_list_display" = "redirect_list_display" -{ - base[SELECTED] = { 0.3, 0.3, 0.3 } -} - -# MixerPanZone: -# -# the NORMAL fg color is used for the pan puck -# the ACTIVE fg color is used for the speaker boxes - -style "pan_zone" = "default_base" -{ - fg[NORMAL] = { 0.34, 0.95, 0.92 } - fg[ACTIVE] = { 0.95, 0.48, 0.11 } -} - -style "paler_red_when_active" = "medium_text" -{ - fg[NORMAL] = { 0.80, 0.80, 0.80 } - fg[PRELIGHT] = { 0.80, 0.80, 0.80 } - bg[NORMAL] = { 0.31, 0.31, 0.31 } - bg[PRELIGHT] = { 0.31, 0.31, 0.31 } - - fg[ACTIVE] = { 0.36, 0.46, 0.28 } - bg[ACTIVE] = { 1.00, 0.59, 0.59} -} - -style "peak_display_peaked_entry" = "small_text" -{ - fg[NORMAL] = { 1.0, 1.0, 1.0 } - fg[ACTIVE] = { 1.0, 1.0, 1.0 } - fg[SELECTED] = { 1.0, 1.0, 1.0 } - - bg[NORMAL] = {0.9, 0.0, 0.0 } - bg[ACTIVE] = { 0.9, 0.0, 0.0 } - bg[PRELIGHT] = { 0.9, 0.0, 0.0 } - bg[INSENSITIVE] = { 0.9, 0.0, 0.0 } - bg[SELECTED] = { 0.9, 0.0, 0.0 } - base[NORMAL] = { 0.9, 0.0, 0.0 } - base[ACTIVE] = { 0.9, 0.0, 0.0 } - base[PRELIGHT] = { 0.9, 0.0, 0.0 } - base[INSENSITIVE] = { 0.9, 0.0, 0.0 } - base[SELECTED] = { 0.9, 0.0, 0.0 } -} - -style "selected_strip_frame" -{ - fg[NORMAL] = { 0.74, 0.42, 0.47 } - bg[NORMAL] = { 0.79, 0.28, 0.18 } -} - -style "flashing_alert" = "very_small_text" -{ - fg[NORMAL] = { 0.80, 0.80, 0.80 } - bg[NORMAL] = { 0.26, 0.26, 0.31 } - - fg[ACTIVE] = { 0.80, 0.80, 0.80 } - bg[ACTIVE] = { 1.0, 0, 0} -} - -style "selected_io_selector_port_list" = "medium_bold_text" -{ - - GtkTreeView::even-row-color = { 0, 0, 0 } - GtkTreeView::odd-row-color = { 0, 0, 0 } - -# fg is used to color the fg (text) of the column header button - - fg[NORMAL] = { 0.85, 0.85, 0.85 } - fg[SELECTED] = { 0.85, 0.85, 0.85 } - fg[ACTIVE] = { 0.85, 0.85, 0.85 } - fg[PRELIGHT] = { 0.85, 0.85, 0.85 } - fg[INSENSITIVE] = { 0.85, 0.85, 0.85 } - -# bg is used used to color the background of the column header button - - bg[NORMAL] = { 0.30, 0.30, 0.35 } - bg[ACTIVE] = { 0.30, 0.30, 0.35 } - bg[PRELIGHT] = { 0.30, 0.30, 0.35 } - bg[INSENSITIVE] = { 0.30, 0.30, 0.35 } - bg[SELECTED] = { 0.30, 0.30, 0.35 } - -# text is used to color the treeview row text - - text[NORMAL] = { 0.85, 0.85, 0.85 } - text[SELECTED] = { 0.85, 0.85, 0.85 } - -# base is used to color a treeview with no rows - - base[NORMAL] = { 0.20, 0.20, 0.25 } - base[ACTIVE] = { 0.20, 0.20, 0.25 } - base[PRELIGHT] = { 0.20, 0.20, 0.25 } - base[INSENSITIVE] = { 0.20, 0.20, 0.25 } - base[SELECTED] = { 0.20, 0.20, 0.25 } - -} - -style "io_selector_port_list" = "medium_text" -{ - GtkTreeView::even-row-color = { 0.20, 0.20, 0.25 } - GtkTreeView::odd-row-color = { 0.20, 0.20, 0.25 } -# fg is used to color the fg (text) of the column header button - - fg[NORMAL] = { 0.70, 0.70, 0.70 } - fg[SELECTED] = { 0.70, 0.70, 0.70 } - fg[ACTIVE] = { 0.70, 0.70, 0.70 } - fg[PRELIGHT] = { 0.70, 0.70, 0.70 } - fg[INSENSITIVE] = { 0.70, 0.70, 0.70 } - -# bg is used used to color the background of the column header button - - bg[NORMAL] = { 0.30, 0.30, 0.35 } - bg[ACTIVE] = { 0.30, 0.30, 0.35 } - bg[PRELIGHT] = { 0.30, 0.30, 0.35 } - bg[INSENSITIVE] = { 0.30, 0.30, 0.35 } - bg[SELECTED] = { 0.30, 0.30, 0.35 } - -# text is used to color the treeview row text - - text[NORMAL] = { 0.80, 0.80, 0.80 } - text[SELECTED] = { 0.80, 0.80, 0.80 } - -# base is used to color a treeview with no rows - - base[NORMAL] = { 0.20, 0.20, 0.25 } - base[ACTIVE] = { 0.20, 0.20, 0.25 } - base[PRELIGHT] = { 0.20, 0.20, 0.25 } - base[INSENSITIVE] = { 0.20, 0.20, 0.25 } - base[SELECTED] = { 0.20, 0.20, 0.25 } -} - -style "io_selector_notebook" = "default_base" -{ - fg[NORMAL] = { 1.0, 1.0, 1.0 } - font_name ="sans bold 8" + xthickness = 1 + ythickness = 1 } style "tearoff_arrow" = "medium_bold_entry" @@ -1077,420 +101,19 @@ style "tearoff_arrow" = "medium_bold_entry" bg[PRELIGHT] = { 0.80, 0.80, 0.80 } } -style "meter_metrics_strip" = "default_base" -{ - font_name = "sans 4" - fg[NORMAL] = { 1.0, 0.8, 0.2 } -} - -style "location_row_button" = "default_buttons_menus" -{ - font_name = "sans 10" -} - -style "location_rows_clock" = "default_clock_display" -{ - font_name = "sans 12" -} - -style "pan_slider" -{ - font_name = "sans 8" - - fg[NORMAL] = { 0.22, 0.73, 0.22 } - fg[ACTIVE] = { 0.22, 0.73, 0.22 } - fg[INSENSITIVE] = {0.22, 0.53, 0.22 } - fg[SELECTED] = { 0.67, 0.23, 0.22 } - fg[PRELIGHT] = { 0.67, 0.23, 0.22 } - - bg[NORMAL] = { 0.05, 0.05, 0.05 } - bg[ACTIVE] = { 0, 0, 0 } - bg[INSENSITIVE] = {0.12, 0.19, 0.25 } - bg[SELECTED] = { 0, 0, 0 } - bg[PRELIGHT] = { 0, 0, 0 } - - text[NORMAL] = { 0.70, 0.70, 0.70 } - text[ACTIVE] = { 0.70, 0.70, 0.70 } - text[INSENSITIVE] = { 0.70, 0.70, 0.70 } - text[SELECTED] = { 0.70, 0.70, 0.70 } - text[PRELIGHT] = { 0.70, 0.70, 0.70 } - - # used to draw the triangular indicators - - base[NORMAL] = { 0.80, 0.80, 0.80 } - base[ACTIVE] = { 0.80, 0.80, 0.80 } - base[INSENSITIVE] = {0.6, 0.6, 0.6 } - base[SELECTED] = { 0.80, 0.80, 0.80 } - base[PRELIGHT] = { 0.80, 0.80, 0.80 } - -} - -style "ardour_button" ="default_buttons_menus" -{ - xthickness = 1 - ythickness = 1 -} - -#--------------------------------------------------------------- - class "GtkWidget" style:highest "default_base" -class "GtkScrollbar" style:highest "ardour_adjusters" +class "GtkScrollbar" style:highest "lumiera_adjusters" class "GtkLabel" style:highest "default_buttons_menus" -class "GtkButton" style:highest "ardour_button" +class "GtkButton" style:highest "lumiera_button" class "GtkArrow" style:highest "tearoff_arrow" -class "GtkProgressBar" style:highest "ardour_progressbars" +class "GtkProgressBar" style:highest "lumiera_progressbars" -widget "*FirstActionMessage" style:highest "first_action_message" -widget "*VerboseCanvasCursor" style:highest "verbose_canvas_cursor" -widget "*MarkerText" style:highest "marker_text" -widget "*TimeAxisViewItemName*" style:highest "time_axis_view_item_name" -#widget "*ExportProgress" style:highest "default_buttons_menus" -widget "*ExportFileLabel" style:highest "small_bold_text" -widget "*ExportFormatLabel" style:highest "medium_bold_text" -widget "*ExportHeader" style:highest "small_bold_text" -widget "*ExportFileDisplay" style:highest "medium_entry" -widget "*ExportFormatDisplay" style:highest "medium_entry" -widget "*ExportCheckbox" style:highest "small_entry" -widget "*ExportTrackSelector*" style:highest "medium_entry_noselection_bg" -widget "*EditModeSelector" style:highest "medium_bold_entry" -widget "*SnapTypeSelector" style:highest "medium_bold_entry" -widget "*SnapModeSelector" style:highest "medium_bold_entry" -widget "*ZoomFocusSelector" style:highest "medium_bold_entry" -widget "*ArdourContextMenu*" style:highest "default_buttons_menus" -widget "*EditGroupTitleButton*" style:highest "default_buttons_menus" -widget "*MixerGroupTitleButton*" style:highest "default_buttons_menus" -widget "*ErrorLogCloseButton" style:highest "default_buttons_menus" -widget "*EditorGTKButton*" style:highest "default_buttons_menus" -widget "*ToolbarButton" style:highest "default_buttons_menus" -widget "*ToolbarButton*" style:highest "default_buttons_menus" -widget "*CrossfadeEditButton" style:highest "default_buttons_menus" -widget "*CrossfadeEditButton*" style:highest "default_buttons_menus" -widget "*TrackHistoryButton*" style:highest "default_buttons_menus" -widget "*TrackSizeButton*" style:highest "default_buttons_menus" -widget "*TrackPlaylistButton*" style:highest "default_buttons_menus" -widget "*TrackAutomationButton*" style:highest "default_buttons_menus" -widget "*TrackGroupButton*" style:highest "default_buttons_menus" -widget "*TrackMixButton*" style:highest "default_buttons_menus" -widget "*TrackVisualButton*" style:highest "default_buttons_menus" -widget "*TrackRemoveButton*" style:highest "default_buttons_menus" -widget "*BaseButton" style:highest "default_buttons_menus" -widget "*TakeButtonLabel" style:highest "default_buttons_menus" -widget "*MixerWidthButton" style:highest "default_buttons_menus" -widget "*MixerHideButton" style:highest "default_buttons_menus" -widget "*MixerSendButton" style:highest "default_buttons_menus" -widget "*MixerSendButtonLabel" style:highest "default_buttons_menus" -widget "*MixerSendSwitch" style:highest "default_buttons_menus" -widget "*MixerInsertButton" style:highest "default_buttons_menus" -widget "*MixerInsertButtonLabel" style:highest "default_buttons_menus" -widget "*MixerInsertSwitch" style:highest "default_buttons_menus" -widget "*MixerMonitorInputButton*" style:highest "very_small_button" -widget "*MixerMonitorInputButton.*" style:highest "very_small_button" -widget "*MixerIOButton" style:highest "very_small_button" -widget "*MixerIOButtonLabel" style:highest "very_small_button" -widget "*AddRouteDialogSpinner" style:highest "ardour_adjusters" -widget "*AddRouteDialogRadioButton*" style:highest "options_window" -widget "*OptionsNotebook" style:highest "options_window" -widget "*OptionEditorToggleButton*" style:highest "options_window" -widget "*OptionsLabel" style:highest "options_window" -widget "*OptionEditorAuditionerLabel" style:highest "options_window" -widget "*OptionsEntry" style:highest "option_entry" -widget "*InspectorNotebook" style:highest "options_window" -widget "*NewSessionDialog" style:highest "options_window" -widget "*NewSessionDialogButton*" style:highest "options_window" -widget "*MixerSendSwitch*" style:highest "very_small_red_active_and_selected_button" -widget "*OptionEditorToggleButton" style:highest "small_red_active_and_selected_button" -widget "*NewSessionDialogButton" style:highest "small_red_active_and_selected_button" -widget "*RecordEnableButton" style:highest "track_rec_enable_button" -widget "*RecordEnableButton-active" style:highest "track_rec_enable_button_active" -widget "*RecordEnableButton-alternate" style:highest "track_rec_enable_button_alternate" -widget "*MixerRecordEnableButton" style:highest "mixer_track_rec_enable_button" -widget "*MixerRecordEnableButton-active" style:highest "mixer_track_rec_enable_button_active" -widget "*MixerRecordEnableButton-alternate" style:highest "mixer_track_rec_enable_button_alternate" -widget "*MuteButton" style:highest "mute_button" -widget "*MuteButton-alternate" style:highest "mute_button_alternate" -widget "*MuteButton-active" style:highest "mute_button_active" -widget "*MixerMuteButton" style:highest "mixer_mute_button" -widget "*MixerMuteButton-alternate" style:highest "mixer_mute_button_alternate" -widget "*MixerMuteButton-active" style:highest "mixer_mute_button_active" -widget "*SoloButton" style:highest "solo_button" -widget "*SoloButton-alternate" style:highest "solo_button_alternate" -widget "*SoloButton-active" style:highest "solo_button_active" -widget "*MixerSoloButton" style:highest "mixer_solo_button" -widget "*MixerSoloButton-alternate" style:highest "mixer_solo_button_alternate" -widget "*MixerSoloButton-active" style:highest "mixer_solo_button_active" -widget "*TrackLoopButton*" style:highest "track_loop_button" -widget "*PanAutomationLineSelector*" style:highest "multiline_combo" -widget "*EditorTimeButton*" style:highest "time_button" -widget "*MixerPhaseInvertButton*" style:highest "very_small_button" -widget "*MixerPhaseInvertButton.*" style:highest "very_small_button" -widget "*MixerAutomationRecordingButton*" style:highest "very_small_button" -widget "*MixerAutomationRecordingButton.*" style:highest "very_small_button" -widget "*MixerAutomationModeButton*" style:highest "very_small_button" -widget "*MixerAutomationModeButton.*" style:highest "very_small_button" -widget "*MixerAutomationPlaybackButton*" style:highest "very_small_button" -widget "*MixerAutomationPlaybackButton.*" style:highest "very_small_button" -widget "*MixerNameButton" style:highest "very_small_button" -widget "*MixerNameButtonLabel" style:highest "very_small_button" -widget "*MixerGroupButton" style:highest "very_small_button" -widget "*MixerGroupButtonLabel" style:highest "very_small_button" -widget "*MixerCommentButton" style:highest "very_small_button" -widget "*MixerCommentButton*" style:highest "very_small_button" -widget "*EditGroupButton" style:highest "very_small_button" -widget "*EditGroupButtonLabel" style:highest "very_small_button" -widget "*TransportButton" style:highest "transport_rec_button" -widget "*TransportButton-active" style:highest "transport_button_active" -widget "*ShuttleButton" style:highest "transport_button" -widget "*ShuttleButton*" style:highest "transport_button" -widget "*ShuttleDisplay" style:highest "transport_button" -widget "*ShuttleDisplay*" style:highest "transport_button" -widget "*ShuttleControl" style:highest "shuttle_control" -widget "*TransportRecButton" style:highest "transport_rec_button" -widget "*TransportRecButton*" style:highest "transport_rec_button" -widget "*TransportRecButton-active" style:highest "transport_rec_button_active" -widget "*TransportRecButton-active*" style:highest "transport_rec_button_active" -widget "*TransportRecButton-alternate" style:highest "transport_rec_button_alternate" -widget "*TransportRecButton-alternate*" style:highest "transport_rec_button_alternate" -widget "*TransportRecButton*" style:highest "transport_rec_button" -widget "*RecordingXrunWarningWindow" style:highest "xrun_warn" -widget "*RecordingXrunWarningWindow*" style:highest "xrun_warn" -widget "*MainMenuBar" style:highest "menu_bar_base" -widget "*ErrorMessage" style:highest "error_message" -widget "*FatalMessage" style:highest "fatal_message" -widget "*InfoMessage" style:highest "info_message" -widget "*WarningMessage" style:highest "warning_message" -widget "*BigClockNonRecording" style:highest "non_recording_big_clock_display" -widget "*BigClockRecording" style:highest "recording_big_clock_display" -widget "*TransportClockDisplay" style:highest "transport_clock_display" -widget "*SecondaryClockDisplay" style:highest "transport_clock_display" -widget "*AudioClockFramesUpperInfo" style:highest "tempo_meter_clock_display" -widget "*AudioClockFramesLowerInfo" style:highest "tempo_meter_clock_display" -widget "*AudioClockSMPTEUpperInfo" style:highest "tempo_meter_clock_display" -widget "*AudioClockSMPTELowerInfo" style:highest "tempo_meter_clock_display" -widget "*AudioClockBBTUpperInfo" style:highest "tempo_meter_clock_display" -widget "*AudioClockBBTLowerInfo" style:highest "tempo_meter_clock_display" -widget "*SelectionStartClock" style:highest "default_clock_display" -widget "*SelectionEndClock" style:highest "default_clock_display" -widget "*EditCursorClock" style:highest "default_clock_display" -widget "*PreRollClock" style:highest "default_clock_display" -widget "*PostRollClock" style:highest "default_clock_display" -widget "*NudgeClock" style:highest "default_clock_display" -widget "*ZoomRangeClock" style:highest "default_clock_display" -widget "*SMPTEOffsetClock" style:highest "default_clock_display" -widget "*TransportLabel" style:highest "small_bold_text" -widget "*TakeLabel" style:highest "small_bold_text" -widget "*LocationLabel" style:highest "small_bold_text" -widget "*WipeLabel" style:highest "small_bold_text" -widget "*TakeTagLabel" style:highest "small_bold_text" -widget "*ToolBarLabel" style:highest "small_bold_text" -widget "*EditorDisplayLabel" style:highest "small_bold_text" -widget "*NewSessionLabel" style:highest "large_text" -widget "*GlobalButtonLabel" style:highest "default_buttons_menus" -widget "*ClickButton" style:highest "medium_entry" -widget "*RegionNameDisplay" style:highest "medium_entry" -widget "*PluginDisplay" style:highest "medium_entry" -widget "*SelectionDisplay" style:highest "medium_entry" -widget "*HistorySelector" style:highest "medium_entry" -widget "*LocationSelector" style:highest "medium_entry" -widget "*TakeSelector" style:highest "medium_entry" -widget "*RegionSelector" style:highest "medium_entry" -widget "*SMPTERuler" style:highest "editor_time_ruler" -widget "*BBTRuler" style:highest "editor_time_ruler" -widget "*FramesRuler" style:highest "editor_time_ruler" -widget "*MinSecRuler" style:highest "editor_time_ruler" -widget "*BaseFrame" style:highest "base_frame" -widget "*AudioTrackStripBase" style:highest "audio_track_base" -widget "*TimeAxisViewControlsBaseUnselected" style:highest "audio_track_base" -widget "*AudioTrackControlsBaseUnselected" style:highest "audio_track_base" -widget "*AudioTrackFader" style:highest "gain_fader" -widget "*AudioBusStripBase" style:highest "audio_bus_base" -widget "*BusControlsBaseUnselected" style:highest "audio_bus_base" -widget "*AudioBusFader" style:highest "gain_fader" -widget "*TrackSeparator" style:highest "track_separator" -widget "*TrackEditIndicator0*" style:highest "edit_group_0" -widget "*TrackEditIndicator1*" style:highest "edit_group_1" -widget "*TrackEditIndicator2*" style:highest "edit_group_2" -widget "*TrackEditIndicator3*" style:highest "edit_group_3" -widget "*TrackEditIndicator4*" style:highest "edit_group_3" -widget "*TrackEditIndicator5*" style:highest "edit_group_3" -widget "*TrackEditIndicator6*" style:highest "edit_group_3" -widget "*TrackEditIndicator7*" style:highest "edit_group_3" -widget "*EditorTrackNameDisplay" style:highest "track_name_display" -widget "*EditorTrackNameDisplay*" style:highest "track_name_display" -widget "*EditorActiveTrackNameDisplay" style:highest "active_track_name_display" -widget "*EditorActiveTrackNameDisplay*" style:highest "active_track_name_display" -widget "*CrossfadeEditAuditionButton" style:highest "red_when_active" -widget "*CrossfadeEditAuditionButton*" style:highest "red_when_active" -widget "*CrossfadeEditCurveButton" style:highest "red_when_active" -widget "*CrossfadeEditCurveButton*" style:highest "red_when_active" -widget "*CrossfadeEditLabel" style:highest "medium_text" -widget "*CrossfadeEditFrame" style:highest "base_frame" -widget "*MouseModeButton" style:highest "default_buttons_menus" -widget "*MouseModeButton*" style:highest "default_buttons_menus" -widget "*EditorMainCanvas" style:highest "main_canvas_area" -widget "*AudioTrackControlsBaseInactiveUnselected" style:highest "track_controls_inactive" -widget "*BusControlsBaseInactiveUnselected" style:highest "track_controls_inactive" -widget "*AutomationTrackControlsBaseInactiveUnselected" style:highest "track_controls_inactive" -widget "*AutomationTrackName" style:highest "automation_track_name" -widget "*AudioTrackControlsBaseInactiveSelected" style:highest "track_controls_inactive" -widget "*BusControlsBaseInactiveSelected" style:highest "track_controls_inactive" -widget "*AutomationTrackControlsBaseInactiveSelected" style:highest "track_controls_inactive" -widget "*AudioTrackStripBaseInactive" style:highest "track_controls_inactive" -widget "*AudioBusStripBaseInactive" style:highest "track_controls_inactive" -widget "*AudioTrackControlsBaseSelected" style:highest "edit_controls_base_selected" -widget "*BusControlsBaseSelected" style:highest "edit_controls_base_selected" -widget "*AutomationTrackControlsBase" style:highest "automation_track_controls_base" -widget "*AutomationTrackControlsBaseSelected" style:highest "edit_controls_base_selected" -widget "*EditorMenuBar*" style:highest "black_mackie_menu_bar" -widget "*MainMenuBar*" style:highest "black_mackie_menu_bar" -widget "*ZoomClickBox" style:highest "medium_bold_entry" -widget "*PluginParameterLabel" style:highest "medium_text" -widget "*PluginNameInfo" style:highest "plugin_name_text" -widget "*PluginMakerInfo" style:highest "plugin_maker_text" -widget "*PluginParameterInfo" style:highest "medium_text" -widget "*MotionControllerValue" style:highest "medium_entry" -widget "*ParameterValueDisplay" style:highest "medium_bold_entry" -widget "*PluginUIClickBox" style:highest "medium_bold_entry" -widget "*PluginUIClickBox*" style:highest "medium_bold_entry" -widget "*PluginSlider" style:highest "plugin_slider" -widget "*RedirectSelector" style:highest "redirect_list_display" -widget "*RedirectSelector.*" style:highest "redirect_list_display" -widget "*EditGroupDisplay" style:highest "treeview_display" -widget "*TrackListDisplay" style:highest "treeview_display" -widget "*RegionListDisplay" style:highest "treeview_display" -widget "*NamedSelectionDisplay" style:highest "treeview_display" -widget "*SnapshotDisplay" style:highest "treeview_display" -widget "*MixerTrackCommentArea" style:highest "option_entry" -widget "*MixerPanZone" style:highest "pan_zone" -widget "*MixerTrackDisplayList" style:highest "treeview_display" -widget "*MixerSnapshotDisplayList" style:highest "treeview_display" -widget "*MixerAuxDisplayList" style:highest "treeview_display" -widget "*MixerGroupList" style:highest "treeview_display" -widget "*RegionEditorLabel" style:highest "medium_text" -widget "*RegionEditorSmallLabel" style:highest "small_text" -widget "*RegionEditorEntry" style:highest "medium_entry" -widget "*RegionEditorClock" style:highest "default_clock_display" -widget "*RegionEditorToggleButton" style:highest "paler_red_when_active" -widget "*RegionEditorToggleButton*" style:highest "paler_red_when_active" -widget "*MixerStripSpeedBase" style:highest "small_entry" -widget "*MixerStripSpeedBase*" style:highest "small_entry" -widget "*MixerStripSpeedBaseNotOne" style:highest "small_red_on_black_entry" -widget "*MixerStripSpeedBaseNotOne*" style:highest "small_red_on_black_entry" -widget "*MixerStripGainDisplay" style:highest "small_entry" -widget "*MixerStripGainDisplay*" style:highest "small_entry" -widget "*MixerStripGainUnitButton" style:highest "very_small_button" -widget "*MixerStripGainUnitButton*" style:highest "very_small_button" -widget "*MixerStripMeterPreButton" style:highest "very_small_button" -widget "*MixerStripMeterPreButton*" style:highest "very_small_button" -widget "*MixerStripPeakDisplay*" style:highest "red_active_small_entry" -widget "*MixerStripPeakDisplayPeak*" style:highest "peak_display_peaked_entry" -widget "*MixerStripSelectedFrame" style:highest "selected_strip_frame" -widget "*MixerStripFrame" style:highest "base_frame" -widget "*HWMonitorButton" style:highest "red_when_active" -widget "*HWMonitorButton*" style:highest "red_when_active" -widget "*BypassButton" style:highest "red_when_active" -widget "*BypassButton*" style:highest "red_when_active" -widget "*TransportSoloAlert" style:highest "flashing_alert" -widget "*TransportSoloAlert.*" style:highest "flashing_alert" -widget "*TransportAuditioningAlert" style:highest "flashing_alert" -widget "*TransportAuditioningAlert.*" style:highest "flashing_alert" -widget "*FadeCurve" style:highest "medium_bold_entry" -widget "*FadeCurve*" style:highest "medium_bold_entry" -widget "*IOSelectorButton" style:highest "default_buttons_menus" -widget "*IOSelectorButton*" style:highest "default_buttons_menus" -widget "*IOSelectorList" style:highest "medium_entry_noselection_fg" -widget "*IOSelectorPortList" style:highest "io_selector_port_list" -widget "*IOSelectorPortList.*" style:highest "io_selector_port_list" -widget "*IOSelectorPortListSelected" style:highest "selected_io_selector_port_list" -widget "*IOSelectorPortListSelected.*" style:highest "selected_io_selector_port_list" -widget "*IOSelectorNotebook" style:highest "io_selector_notebook" -widget "*IOSelectorNotebookTab" style:highest "io_selector_notebook" -widget "*IOSelectorFrame" style:highest "base_frame" -widget "*ConnectionEditorButton" style:highest "default_buttons_menus" -widget "*ConnectionEditorButton*" style:highest "default_buttons_menus" -widget "*ConnectionEditorList" style:highest "medium_entry_noselection_fg" -widget "*ConnectionEditorConnectionList" style:highest "medium_entry" -widget "*ConnectionEditorPortList" style:highest "io_selector_port_list" -widget "*ConnectionEditorPortListSelected" style:highest "selected_io_selector_port_list" -widget "*ConnectionEditorNotebook" style:highest "io_selector_notebook" -widget "*ConnectionEditorNotebookTab" style:highest "io_selector_notebook" -widget "*ConnectionEditorFrame" style:highest "base_frame" -widget "*RouteParamsListDisplay" style:highest "inspector_track_list_display" -widget "*RouteParamsPreListDisplay" style:highest "inspector_redirect_list_display" -widget "*RouteParamsPostListDisplay" style:highest "inspector_redirect_list_display" -widget "*TearOffArrow" style:highest "tearoff_arrow" -widget "*RouteParamsTitleButton" style:highest "medium_text" -widget "*RouteParamsTitleLabel" style:highest "medium_text" -widget "*PluginAutomateRecordButton" style:highest "small_red_active_and_selected_button" -widget "*PluginAutomateRecordButton*" style:highest "small_red_active_and_selected_button" -widget "*PluginAutomatePlayButton" style:highest "small_red_active_and_selected_button" -widget "*PluginAutomatePlayButton*" style:highest "small_red_active_and_selected_button" -widget "*PluginAutomateButton" style:highest "small_button" -widget "*PluginAutomateButton*" style:highest "small_button" -widget "*PluginSaveButton" style:highest "small_button" -widget "*PluginSaveButton*" style:highest "small_button" -widget "*PluginLoadButton" style:highest "small_button" -widget "*PluginLoadButton*" style:highest "small_button" -widget "*FaderMetricsStrip" style:highest "meter_metrics_strip" -widget "*MeterMetricsStrip" style:highest "meter_metrics_strip" -widget "*MetricDialogFrame" style:highest "base_frame" -widget "*MetricEntry" style:highest "medium_bold_entry" -widget "*MetricButton" style:highest "default_buttons_menus" -widget "*MetricButton.*" style:highest "default_buttons_menus" -widget "*MetricLabel" style:highest "medium_text" -widget "*TimeStretchButton" style:highest "default_buttons_menus" -widget "*TimeStretchButton.*" style:highest "default_buttons_menus" -widget "*TimeStretchProgress" style:highest "default_buttons_menus" -widget "*ChoiceWindow" style:highest "default_buttons_menus" -widget "*ChoicePrompt" style:highest "default_buttons_menus" -widget "*ChoiceButton" style:highest "default_buttons_menus" -widget "*ChoiceButton*" style:highest "default_buttons_menus" -widget "*SelectionModeButton" style:highest "default_buttons_menus" -widget "*SelectionModeButton*" style:highest "default_buttons_menus" -widget "*TrackLabel" style:highest "medium_text" -widget "*TrackPlugName" style:highest "medium_text" -widget "*TrackParameterName" style:highest "small_text" -widget "*AddRouteDialog*" style:highest "medium_text" -widget "*AddRouteDialog.GtkLabel" style:highest "medium_text" -widget "*AddRouteDialogChannelChoice" style:highest "medium_bold_entry" -widget "*AddRouteDialogSpinner" style:highest "medium_bold_entry" -widget "*AddRouteDialogSpinner*" style:highest "medium_bold_entry" -widget "*AddRouteDialogRadioButton" style:highest "red_when_active" -widget "*AddRouteDialogButton" style:highest "default_buttons_menus" -widget "*AddRouteDialogNameTemplateEntry" style:highest "medium_bold_entry" -widget "*NewSessionIOLabel" style:highest "larger_bold_text" -widget "*NewSessionSR1Label" style:highest "red_medium_text" -widget "*NewSessionSR2Label" style:highest "medium_text" -widget "*NewSessionChannelChoice" style:highest "medium_bold_entry" -widget "*NewSessionMainButton" style:highest "larger_bold_text" -widget "*NewSessionMainButton*" style:highest "larger_bold_text" -widget "*NewSessionMainLabel" style:highest "larger_bold_text" -widget "*LocationEditRowClock" style:highest "location_rows_clock" -widget "*LocationEditNameLabel" style:highest "medium_text" -widget "*LocationEditSetButton" style:highest "location_row_button" -widget "*LocationEditSetButton*" style:highest "location_row_button" -widget "*LocationEditGoButton" style:highest "location_row_button" -widget "*LocationEditGoButton*" style:highest "location_row_button" -widget "*LocationEditCdButton" style:highest "small_red_active_and_selected_button" -widget "*LocationEditCdButton*" style:highest "small_red_active_and_selected_button" -widget "*LocationEditHideButton" style:highest "small_red_active_and_selected_button" -widget "*LocationEditHideButton*" style:highest "small_red_active_and_selected_button" -widget "*LocationEditNumberLabel" style:highest "small_text" -widget "*LocationLocEditorFrame" style:highest "base_frame" -widget "*LocationRangeEditorFrame" style:highest "base_frame" -widget "*LocationEditNameEntry" style:highest "option_entry" -widget "*LocationAddLocationButton" style:highest "default_buttons_menus" -widget "*LocationAddLocationButton*" style:highest "default_buttons_menus" -widget "*LocationAddRangeButton" style:highest "default_buttons_menus" -widget "*LocationAddRangeButton*" style:highest "default_buttons_menus" -widget "*LocationEditRemoveButton" style:highest "location_row_button" -widget "*LocationEditRemoveButton*" style:highest "location_row_button" -widget "*PanSlider" style:highest "pan_slider" -widget "*PanningLinkButton" style:highest "mixer_red_active_button" -widget "*PanningLinkButton.*" style:highest "mixer_red_active_button" -widget "*PanningLinkDirectionButton" style:highest "very_small_button" -widget "*PanningLinkDirectionButton.*" style:highest "very_small_button" -widget "*ChannelCountSelector" style:highest "medium_bold_entry" -widget "*ChannelCountSelector.GtkArrow" style:highest "default_buttons_menus" -widget "*RegionListWholeFile" style:highest "treeview_parent_node" -widget "*EditorHScrollbar" style:highest "editor_hscrollbar" +#---------- Styles for Lumiera Widgets ----------# + +style "timeline_body" +{ + gtkmm__CustomObject_TimelineBody::track_background = "#FF7F00" +} + +class "gtkmm__CustomObject_TimelineBody" style:highest "timeline_body" diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index 3665ec98b..163ea60c1 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -41,7 +41,7 @@ TimelineWidget::TimelineWidget() : { rowHeaderLayout.set_size_request(100, 100); - body = new TimelineBody(horizontalAdjustment, verticalAdjustment); + body = new TimelineBody(this); verticalAdjustment.signal_value_changed().connect( sigc::mem_fun(this, &TimelineWidget::on_scroll) ); diff --git a/src/gui/widgets/timeline/timeline-body.cpp b/src/gui/widgets/timeline/timeline-body.cpp index f3e204cf9..f7e747f55 100644 --- a/src/gui/widgets/timeline/timeline-body.cpp +++ b/src/gui/widgets/timeline/timeline-body.cpp @@ -23,6 +23,7 @@ #include #include "timeline-body.hpp" +#include "../timeline-widget.hpp" using namespace Gtk; using namespace std; @@ -33,13 +34,26 @@ namespace gui { namespace widgets { namespace timeline { -TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget &timeline_widget) : +TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widget) : + Glib::ObjectBase("TimelineBody"), timelineWidget(timeline_widget) { - timelineWidget.horizontalAdjustment.signal_value_changed().connect( + g_assert(timelineWidget != NULL); + + // Connect up some events + timelineWidget->horizontalAdjustment.signal_value_changed().connect( sigc::mem_fun(this, &TimelineBody::on_scroll) ); - timelineWidget.verticalAdjustment.signal_value_changed().connect( + timelineWidget->verticalAdjustment.signal_value_changed().connect( sigc::mem_fun(this, &TimelineBody::on_scroll) ); + + // Install style properties + gtk_widget_class_install_style_property( + GTK_WIDGET_CLASS(G_OBJECT_GET_CLASS(gobj())), + g_param_spec_boxed("track_background", + "Track Background", + "The background colour of timeline tracks", + GDK_TYPE_COLOR, G_PARAM_READABLE)); + } void @@ -53,32 +67,64 @@ TimelineBody::on_expose_event(GdkEventExpose* event) { // This is where we draw on the window Glib::RefPtr window = get_window(); - if(window) + if(!window) + return false; + + read_styles(); + + + Gtk::Allocation allocation = get_allocation(); + const int width = allocation.get_width(); + const int height = allocation.get_height(); + + Cairo::RefPtr cairo = window->create_cairo_context(); + cairo->set_line_width(10.0); + + cairo->rectangle(50, 50, 100, 100); + gdk_cairo_set_source_color(cairo->cobj(), &track_background); + + cairo->fill_preserve(); + + + cairo->translate( + -timelineWidget->horizontalAdjustment.get_value(), + -timelineWidget->verticalAdjustment.get_value()); + cairo->save(); + + vector::iterator i; + for(i = timelineWidget->tracks.begin(); + i != timelineWidget->tracks.end(); i++) { - Gtk::Allocation allocation = get_allocation(); - const int width = allocation.get_width(); - const int height = allocation.get_height(); - - Cairo::RefPtr cr = window->create_cairo_context(); - cr->set_line_width(10.0); - - cr->translate(-horizontalAdjustment.get_value(), -verticalAdjustment.get_value()); - cr->save(); - - vector::iterator i; - for(i = tracks.begin(); i != tracks.end(); i++) - { - timeline::Track *track = *i; - g_assert(track != NULL); - track->draw_track(); - } - - cr->restore(); + timeline::Track *track = *i; + g_assert(track != NULL); + track->draw_track(cairo); } + cairo->restore(); + return true; } + +void +TimelineBody::read_styles() +{ + GdkColor *colour; + + gtk_widget_style_get(Widget::gobj(), "track_background", &colour, NULL); + + // Did the color load successfully? + if(colour != NULL) + track_background = *colour; + else + { + g_warning("track_background style value failed to load"); + track_background.red = 0x0000; + track_background.green = 0x0000; + track_background.blue = 0x0000; + track_background.pixel = 0x00000000; + } +} } // namespace timeline } // namespace widgets diff --git a/src/gui/widgets/timeline/timeline-body.hpp b/src/gui/widgets/timeline/timeline-body.hpp index 39fd8773a..c58323b1b 100644 --- a/src/gui/widgets/timeline/timeline-body.hpp +++ b/src/gui/widgets/timeline/timeline-body.hpp @@ -31,21 +31,31 @@ namespace lumiera { namespace gui { namespace widgets { + +class TimelineWidget; + namespace timeline { class TimelineBody : public Gtk::DrawingArea { public: - TimelineBody(lumiera::gui::widgets::TimelineWidget &timeline_widget); + TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widget); protected: - lumiera::gui::widgets::TimelineWidget &timelineWidget; + lumiera::gui::widgets::TimelineWidget *timelineWidget; /* ===== Events ===== */ protected: void on_scroll(); virtual bool on_expose_event(GdkEventExpose* event); + + /* ===== Internals ===== */ + private: + void read_styles(); + + private: + GdkColor track_background; }; } // namespace timeline diff --git a/src/gui/widgets/timeline/track.cpp b/src/gui/widgets/timeline/track.cpp index c0564e37f..510dfc798 100644 --- a/src/gui/widgets/timeline/track.cpp +++ b/src/gui/widgets/timeline/track.cpp @@ -39,7 +39,7 @@ Track::get_title() } void -Track::draw_track() +Track::draw_track(Cairo::RefPtr cairo) { } diff --git a/src/gui/widgets/timeline/track.hpp b/src/gui/widgets/timeline/track.hpp index 204b650a0..15254ea00 100644 --- a/src/gui/widgets/timeline/track.hpp +++ b/src/gui/widgets/timeline/track.hpp @@ -44,7 +44,7 @@ class Track virtual int get_track_height() = 0; - virtual void draw_track(); + virtual void draw_track(Cairo::RefPtr cairo); protected: diff --git a/src/gui/widgets/timeline/video-track.cpp b/src/gui/widgets/timeline/video-track.cpp index b3b45c543..6fd55fea5 100644 --- a/src/gui/widgets/timeline/video-track.cpp +++ b/src/gui/widgets/timeline/video-track.cpp @@ -45,7 +45,7 @@ int VideoTrack::get_track_height() return 100; } -void VideoTrack::draw_track() +void VideoTrack::draw_track(Cairo::RefPtr cairo) { } diff --git a/src/gui/widgets/timeline/video-track.hpp b/src/gui/widgets/timeline/video-track.hpp index e82a178bd..d73a03b6e 100644 --- a/src/gui/widgets/timeline/video-track.hpp +++ b/src/gui/widgets/timeline/video-track.hpp @@ -42,7 +42,7 @@ class VideoTrack : public Track virtual int get_track_height(); - virtual void draw_track(); + virtual void draw_track(Cairo::RefPtr cairo); protected: Gtk::Label headerWidget; From e9747b360cd626ace1f04f357215411a90fdec14 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 31 May 2008 18:21:05 +0100 Subject: [PATCH 125/245] Track backgrounds are now painted from the style --- src/gui/lumiera_ui.rc | 2 +- src/gui/widgets/timeline-widget.cpp | 6 ++- src/gui/widgets/timeline-widget.hpp | 4 ++ src/gui/widgets/timeline/timeline-body.cpp | 52 ++++++++++++---------- 4 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/gui/lumiera_ui.rc b/src/gui/lumiera_ui.rc index f0c1163e5..f37b4c12b 100644 --- a/src/gui/lumiera_ui.rc +++ b/src/gui/lumiera_ui.rc @@ -112,7 +112,7 @@ class "GtkProgressBar" style:highest "lumiera_progressbars" style "timeline_body" { - gtkmm__CustomObject_TimelineBody::track_background = "#FF7F00" + gtkmm__CustomObject_TimelineBody::track_background = "#7E838B" } class "gtkmm__CustomObject_TimelineBody" style:highest "timeline_body" diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index 163ea60c1..e448f62f2 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -30,6 +30,8 @@ namespace lumiera { namespace gui { namespace widgets { +const int TimelineWidget::TrackPadding = 1; + TimelineWidget::TimelineWidget() : Table(2, 2), totalHeight(0), @@ -39,7 +41,7 @@ TimelineWidget::TimelineWidget() : verticalScroll(verticalAdjustment), ruler("ruler") { - rowHeaderLayout.set_size_request(100, 100); + rowHeaderLayout.set_size_request(100, 0); body = new TimelineBody(this); @@ -97,7 +99,7 @@ TimelineWidget::move_headers() const int height = track->get_track_height(); rowHeaderLayout.move(track->get_header_widget(), 0, offset - y_scroll_offset); - offset += height; + offset += height + TrackPadding; } totalHeight = offset; verticalAdjustment.set_upper(totalHeight); diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp index 7ceb3f125..fb87f321b 100644 --- a/src/gui/widgets/timeline-widget.hpp +++ b/src/gui/widgets/timeline-widget.hpp @@ -69,6 +69,10 @@ class TimelineWidget : public Gtk::Table Gtk::Adjustment horizontalAdjustment, verticalAdjustment; Gtk::HScrollbar horizontalScroll; Gtk::VScrollbar verticalScroll; + + /* ===== Constants ===== */ + protected: + static const int TrackPadding; friend class timeline::TimelineBody; }; diff --git a/src/gui/widgets/timeline/timeline-body.cpp b/src/gui/widgets/timeline/timeline-body.cpp index f7e747f55..e7c9e0b78 100644 --- a/src/gui/widgets/timeline/timeline-body.cpp +++ b/src/gui/widgets/timeline/timeline-body.cpp @@ -27,6 +27,7 @@ using namespace Gtk; using namespace std; +using namespace lumiera::gui::widgets; using namespace lumiera::gui::widgets::timeline; namespace lumiera { @@ -69,41 +70,44 @@ TimelineBody::on_expose_event(GdkEventExpose* event) Glib::RefPtr window = get_window(); if(!window) return false; - - read_styles(); - - - Gtk::Allocation allocation = get_allocation(); - const int width = allocation.get_width(); - const int height = allocation.get_height(); - - Cairo::RefPtr cairo = window->create_cairo_context(); - cairo->set_line_width(10.0); - cairo->rectangle(50, 50, 100, 100); - gdk_cairo_set_source_color(cairo->cobj(), &track_background); - - cairo->fill_preserve(); - + // Makes sure the widget styles have been loaded + read_styles(); + + // Prepare to render via cairo + Gtk::Allocation allocation = get_allocation(); + Cairo::RefPtr cairo = window->create_cairo_context(); + // Translate the view by the scroll distance cairo->translate( - -timelineWidget->horizontalAdjustment.get_value(), - -timelineWidget->verticalAdjustment.get_value()); - cairo->save(); - + -(int)timelineWidget->horizontalAdjustment.get_value(), + -(int)timelineWidget->verticalAdjustment.get_value()); + + // Interate drawing each track vector::iterator i; for(i = timelineWidget->tracks.begin(); i != timelineWidget->tracks.end(); i++) { timeline::Track *track = *i; - g_assert(track != NULL); - track->draw_track(cairo); - } + g_assert(track != NULL); - cairo->restore(); + const int track_height = track->get_track_height(); + + // Draw the track background + cairo->rectangle(0, 0, allocation.get_width(), track_height); + gdk_cairo_set_source_color(cairo->cobj(), &track_background); + cairo->fill(); + + // Render the track + cairo->save(); + track->draw_track(cairo); + cairo->restore(); + + // Shift for the next track + cairo->translate(0, track_height + TimelineWidget::TrackPadding); + } return true; - } void From 6ad61b0108239805c891c7bbe6b74ca7e16d67ef Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 1 Jun 2008 06:05:39 +0200 Subject: [PATCH 126/245] further draftings, esp. how the render nodes are operated --- wiki/renderengine.html | 45 ++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 8b1883bbe..be449639b 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -752,8 +752,9 @@ Note, //we still have to work out how exactly building, rendering and playback w [img[Colaborations in the Build Process|uml/fig128517.png]]
-
-
Actually setting up and wiring a [[processing node|ProcNode]] involves several issues and is carried out at the lowest level of the build process. 
+
+
Actually setting up and wiring a [[processing node|ProcNode]] involves several issues and is carried out at the lowest level of the build process.
+It is closely related to &rarr; [[the way nodes are operated|NodeOperationProtocol]]
 
 !!!object creation
 The Nodes are small polymorphic objects, carrying configuration data, but no state. They are [[specially allocated|ManagementRenderNodes]], and the object creation is accessible solely by the NodeFactory. They //must not be deallocated manually.// The decision of what concrete node type to create depends on the actual build situation and is worked out by the combination of [[mould|BuilderMould]] and [[processing pattern|ProcPatt]] at the current OperationPoint, issuing a call to one of NodeFactory's {{{operator()}}}
@@ -1823,6 +1824,21 @@ So, when creating a clip out of such a compound media asset, the clip has to be
 
NodeCreaterTool is a [[visiting tool|VisitorUse]] used as second step in the [[Builder]]. Starting out from a [[Fixture]], the builder first [[divides the Timeline into segments|SegmentationTool]] and then processes each segment with the NodeCreaterTool to build a render nodes network (Render Engine) for this part of the timeline. While visiting individual Objects and Placements, the NodeCreaterTool creates and wires the necessary [[nodes|ProcNode]]
+
+
The [[nodes|ProcNode]] are wired to form a "Directed Acyclic Graph"; each node knows its predecessor(s), but not its successor(s).  The RenderProcess is organized according to the ''pull principle'', thus we find an operation {{{pull()}}} at the core of this process. There is no such thing as an "engine object" calling nodes iteratively or table driven, rather, the nodes themselves issue recursive calls to their predecessor(s). For this to work, we need the nodes to adhere to a specific protocol:
+# Node is pulled, providing a StateProxy object (encapsulating the access to the frames or buffers)
+# Node may now access current parameter values, using the state accessible via the StateProxy
+# Node calles back into the StateProxy, providing the //input descriptor//
+# StateProxy tries to get the input frames from the Cache in the Backend. If this fails, it forwards the call using the information in the input descriptor
+# after this call returns, the Node is allowed to dereference the frame pointers and do its calculations
+# finally, when the {{{pull()}}} call returns, the StateProxy may push down the result frames to the cache
+some points to note:
+* the input descriptor is {{{const}}} and precalculated while building (remember another thread may call in parallel)
+* when a node is "inplace-capable", input and output buffer may actually point to the same location
+* but there is no guarantee for this to happen, because the cache may be involved (and we can't overwrite the contents of a cache frame)
+* generally, a node may have N inputs and M output frames, which are expected to be processed in a single call
+
+
We have to consider carefully how to handle the Creation of new class instances. Because, when done naively, it can defeat all efforts of separating subsystems, or &mdash; the other extreme &mdash; lead to a //switch-on-typeID//  programming style. We strive at a solution somewhere in the middle by utilizing __Abstract Factories__ on Interface or key abstraction classes, but providing specialized overloads for the different use cases. So in each use case we have to decide if we want to create a instance of some general concept (Interface), or if we have a direct collaboration and thus need the Factory to provide a more specific sub-Interface or even a concrete type.
 
@@ -1881,7 +1897,7 @@ There is rather strong separation between these two levels, and &mdash; <
 [img[Block Diagram|uml/fig128005.png]]
 
-
+
Render Engine, [[Builder]] and [[Controller]] are closely related Subsystems. Actually, the [[Builder]] //creates// a newly configured Render Engine //for every// RenderProcess. Before doing so, it queries from the Session (or, to be more precise, from the [[Fixture]] within the current Session) all necessary Media Object Placement information. The [[Builder]] then derives from this information the actual assembly of [[Processing Nodes|ProcNode]] comprising the Render Engine. Thus:
  * the source of the build process is a sequence of absolute (explicit) [[Placements|Placement]] called the [[Playlist]]
  * the [[build process|BuildProcess]] is driven, configured and controlled by the [[Controller]] subsystem component. It encompasses the actual playback configuration and State of the System.
@@ -2997,18 +3013,26 @@ At first sight the link between asset and clip-MO is a simple logical relation b
 &rarr; OverviewRenderEngine
 
-
-
The Render Engine only carries out the low-level and performance critical tasks. All configuration and decision concerns are to be handled by [[Builder]] and [[Controller]]. While the actual connection of the Render Nodes can be highly complex, basically each Segment of the Timeline with uniform characteristics is handled by one Processor, which is a graph of [[Processing Nodes|ProcNode]] discharging into a ExitNode. The Render Engine Components as such are //stateless// themselves; for the actual calculations they are combined with a StateProxy object generated by and connected internally to the [[Controller]], while at the same time holding the Data Buffers (Frames) for the actual calculations.
+
+
The [[Render Engine|Rendering]] only carries out the low-level and performance critical tasks. All configuration and decision concerns are to be handled by [[Builder]] and [[Controller]]. While the actual connection of the Render Nodes can be highly complex, basically each Segment of the Timeline with uniform characteristics is handled by one Processor, which is a graph of [[Processing Nodes|ProcNode]] discharging into a ExitNode. The Render Engine Components as such are //stateless// themselves; for the actual calculations they are combined with a StateProxy object generated by and connected internally to the [[Controller]], while at the same time holding the Data Buffers (Frames) for the actual calculations.
 
 [img[Entities comprising the Render Engine|uml/fig128389.png]]
 
-
-
{{red{TODO: describe the Render Process.}}}
-
- * see also the [[Entities involved in Rendering|RenderEntities]]
+
+
For each segment (of the effective timeline), there is a Processor holding the exit node(s) of a processing network, which is a "Directed Acyclic Graph" of small, preconfigured, stateless [[processing nodes|ProcNode]]. This network is operated according to the ''pull principle'', meaning that the rendering is just initiated by "pulling" output from the exit node, causing a cascade of recursive downcalls. Each node knows its predecessor(s) an can pull the necessary input from there. Consequently, there is no centralized "engine object" which may invoke nodes iteratively or table driven &mdash; rather, the rendering can be seen as a passive service provided for the backend, which may pull from the exit nodes at any time, in any order (?), and possibly multithreaded.
+All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy acts as a gateway to the backend to handle the communication with the Cache.
+{{red{TODO: fill in more details of the Render Process.}}}
+* see also
+&rarr; the [[Entities involved in Rendering|RenderEntities]]
+&rarr; the protocol [[how to operate the nodes|NodeOperationProtocol]]
 
+
+
The rendering of input sources to the desired output ports happens within the &raquo;''Render Engine''&laquo;, which can be seen as a collaboration of Proc-Layer, Backend together with external/library code for the actual data manipulation. In preparation of the RenderProcess, the [[Builder]] as wired up a network of [[processing nodes|ProcNode]] called the ''low-level model'' (in contrast to the high-level model of objects placed within the EDL/Session). Generally, this network is a "Directed Acyclic Graph" starting at the //exit nodes// (output ports) and pointing down to the //source readers.// In Lumiera, rendering is organized according to the ''pull principle'': when a specific frame of rendered data is requested from an exit node, a recursive calldown happens, as each node asks his predecessor(s) for the necessary input frame(s). This may include pulling frames from various input sources and for several time points, thus pull rendering is more powerful (but also more difficult to understand) than push rendering, where the process would start out with a given source frame.
+
+Rendering can be seen as a passive service available to the Backend, which remains in charge what to render and when. Render processes may be running in parallel without any limitations. All of the storage and data management falls into the realm of the Backend. The render nodes themselves are ''completely stateless'' &mdash; if some state is necessary for carrying out the calculations, the backend will provide a //state frame// in addition to the data frames.
+
The Session contains all informations, state and objects to be edited by the User. From a users view, the Session is synonymous to the //current Project//. It can be saved and loaded. The individual Objects within the Session, i.e. Clips, Media, Effects, are contained in one (or several) collections within the Session, which we call [[EDL (Edit Decision List)|EDL]]. &rarr; [[Session design overview|SessionOverview]]
 
@@ -3109,11 +3133,12 @@ if (oldText.indexOf("SplashScreen")==-1)
 }
 //}}}
-
+
An Object representing a //Render Process// and containing associated state information.
 * it is created in the Controller subsystem while initiating the BuildProcess
 * it is passed on to the generated Render Engine, which in turn passes it down to the individual Processors
 * moreover, it contains methods to communicate with other state relevant parts of the system, thereby shielding the rendering code from any complexities of Thread communication if necessary. (thus the name Proxy)
+* in a future version, it may also encapsulate the communication in a distributed render farm
 
From 3c2a6f0598225044c0eecd464b3746c8676c638b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 3 Jun 2008 06:22:41 +0200 Subject: [PATCH 127/245] planing more details of the render mechanics --- doc/devel/uml/class130949.html | 2 +- doc/devel/uml/class131589.html | 1 + doc/devel/uml/class131717.html | 5 +- doc/devel/uml/class131845.html | 1 + doc/devel/uml/class131973.html | 1 + doc/devel/uml/class132101.html | 1 + doc/devel/uml/class132229.html | 1 + doc/devel/uml/class132357.html | 1 + doc/devel/uml/class132485.html | 1 + doc/devel/uml/class132613.html | 1 + doc/devel/uml/class132741.html | 8 +- doc/devel/uml/class132869.html | 2 +- doc/devel/uml/class132997.html | 2 +- doc/devel/uml/class133125.html | 2 +- doc/devel/uml/class133765.html | 1 + doc/devel/uml/class135045.html | 1 + doc/devel/uml/class142085.html | 22 ++++++ doc/devel/uml/class142213.html | 27 +++++++ doc/devel/uml/class142341.html | 20 +++++ doc/devel/uml/class142469.html | 20 +++++ doc/devel/uml/class142597.html | 20 +++++ doc/devel/uml/classdiagrams.html | 1 + doc/devel/uml/classes.html | 8 +- doc/devel/uml/classes_list.html | 8 +- doc/devel/uml/collaborationdiagrams.html | 1 + doc/devel/uml/fig128389.png | Bin 30399 -> 31223 bytes doc/devel/uml/fig131973.png | Bin 0 -> 16309 bytes doc/devel/uml/fig132101.png | Bin 0 -> 18071 bytes doc/devel/uml/index.html | 37 +++++++-- doc/devel/uml/index_60.html | 4 +- doc/devel/uml/index_65.html | 4 +- doc/devel/uml/index_66.html | 3 +- doc/devel/uml/index_67.html | 44 ++++++----- doc/devel/uml/index_68.html | 2 +- doc/devel/uml/index_69.html | 5 +- doc/devel/uml/index_70.html | 2 +- doc/devel/uml/index_73.html | 3 +- doc/devel/uml/index_77.html | 2 +- doc/devel/uml/index_78.html | 3 + doc/devel/uml/index_79.html | 4 +- doc/devel/uml/index_80.html | 5 ++ doc/devel/uml/index_82.html | 4 +- doc/devel/uml/index_83.html | 7 +- doc/devel/uml/index_84.html | 6 +- doc/devel/uml/index_86.html | 20 ++--- doc/devel/uml/public_operations.html | 3 + uml/lumiera/128389.diagram | 28 +++---- uml/lumiera/129285 | 2 +- uml/lumiera/131973.diagram | 67 +++++++++++++++++ uml/lumiera/132101.diagram | 91 +++++++++++++++++++++++ uml/lumiera/5.session | 14 +++- uml/lumiera/lumiera.prj | 2 +- wiki/renderengine.html | 86 ++++++++++++++------- 53 files changed, 492 insertions(+), 114 deletions(-) create mode 100644 doc/devel/uml/class142085.html create mode 100644 doc/devel/uml/class142213.html create mode 100644 doc/devel/uml/class142341.html create mode 100644 doc/devel/uml/class142469.html create mode 100644 doc/devel/uml/class142597.html create mode 100644 doc/devel/uml/fig131973.png create mode 100644 doc/devel/uml/fig132101.png create mode 100644 uml/lumiera/131973.diagram create mode 100644 uml/lumiera/132101.diagram diff --git a/doc/devel/uml/class130949.html b/doc/devel/uml/class130949.html index 774585ac5..05f451c34 100644 --- a/doc/devel/uml/class130949.html +++ b/doc/devel/uml/class130949.html @@ -18,7 +18,7 @@

Declaration :

  • C++ : class RenderState

Encapsulates the logic used to get a "current render process" in accordance to the currentyl applicable controller settings. The provided StateProxy serves to hold any mutalbe state used in the render process, so the rest of the render engine can be stateless.

Artifact : renderstate

-
Operation getStateProxy

Declaration :

+
Operation getStateProxy

Declaration :

  • Uml : + getStateProxy() : State
  • C++ : public: State getStateProxy ()

All public operations : getStateProxy

diff --git a/doc/devel/uml/class131589.html b/doc/devel/uml/class131589.html index c65bef7fb..beefcf13d 100644 --- a/doc/devel/uml/class131589.html +++ b/doc/devel/uml/class131589.html @@ -18,5 +18,6 @@

Declaration :

The output of the render pipeline. Pulling from such exit nodes actually ivokes the render process

Artifact : exitnode

+

All public operations : pull

diff --git a/doc/devel/uml/class131717.html b/doc/devel/uml/class131717.html index d03898369..8952f6f05 100644 --- a/doc/devel/uml/class131717.html +++ b/doc/devel/uml/class131717.html @@ -20,6 +20,9 @@

Key abstraction of the Render Engine: A Data processing Node

Artifact : procnode

Relation datasrc (<unidirectional association>)

Declaration :

The predecessor in a processing pipeline, i.e. a source to get data to be processed

-
Relation params (<directional aggregation by value>)

Declaration :

+
Relation params (<directional aggregation by value>)

Declaration :

+
Operation pull

Declaration :

  • Uml : + pull(inout renderProcess : State) : void
  • C++ : public: void pull ()

trigger data processing by "pulling" results from the node's output

+
Relation predecessors (<directional aggregation by value>)

Declaration :

preconfigured table of all predecessor nodes, qualified
with the output port on these nodes and time offset of the data
we need for doing our calculations

+

All public operations : pull

diff --git a/doc/devel/uml/class131845.html b/doc/devel/uml/class131845.html index 278d1cdb1..c59787b25 100644 --- a/doc/devel/uml/class131845.html +++ b/doc/devel/uml/class131845.html @@ -19,5 +19,6 @@

Declaration :

Directly inherited by : CodecAdapter Mask PluginAdapter Projector

Artifact : trafo

+

All public operations : pull

diff --git a/doc/devel/uml/class131973.html b/doc/devel/uml/class131973.html index 68e7e24de..82d637b48 100644 --- a/doc/devel/uml/class131973.html +++ b/doc/devel/uml/class131973.html @@ -19,5 +19,6 @@

Declaration :

Directly inherited by : GLPipe

Artifact : link

+

All public operations : pull

diff --git a/doc/devel/uml/class132101.html b/doc/devel/uml/class132101.html index ca7d5ac7e..50eae3f1b 100644 --- a/doc/devel/uml/class132101.html +++ b/doc/devel/uml/class132101.html @@ -18,5 +18,6 @@

Declaration :

Artifact : hub

+

All public operations : pull

diff --git a/doc/devel/uml/class132229.html b/doc/devel/uml/class132229.html index f0ba8e9d7..28f198354 100644 --- a/doc/devel/uml/class132229.html +++ b/doc/devel/uml/class132229.html @@ -18,5 +18,6 @@

Declaration :

  • C++ : class Projector : public Trafo

Special video processing node used to scale and translate image data.

Artifact : projector

+

All public operations : pull

diff --git a/doc/devel/uml/class132357.html b/doc/devel/uml/class132357.html index 0d94f52bc..9dab6ff1f 100644 --- a/doc/devel/uml/class132357.html +++ b/doc/devel/uml/class132357.html @@ -18,5 +18,6 @@

Declaration :

  • C++ : class Mask : public Trafo

Artifact : mask

+

All public operations : pull

diff --git a/doc/devel/uml/class132485.html b/doc/devel/uml/class132485.html index b6389bd12..2ccb92506 100644 --- a/doc/devel/uml/class132485.html +++ b/doc/devel/uml/class132485.html @@ -18,5 +18,6 @@

Declaration :

  • C++ : class PluginAdapter : public Trafo

Adapter used to integrage an effects processor in the render pipeline

Artifact : pluginadapter

+

All public operations : pull

diff --git a/doc/devel/uml/class132613.html b/doc/devel/uml/class132613.html index 0134205d1..763de044c 100644 --- a/doc/devel/uml/class132613.html +++ b/doc/devel/uml/class132613.html @@ -18,5 +18,6 @@

Declaration :

  • C++ : class GLPipe : public Link

specialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form

Artifact : glpipe

+

All public operations : pull

diff --git a/doc/devel/uml/class132741.html b/doc/devel/uml/class132741.html index f0a749926..f543def13 100644 --- a/doc/devel/uml/class132741.html +++ b/doc/devel/uml/class132741.html @@ -4,21 +4,21 @@ -Class StateProxy +Class State -
Class StateProxy
+
Class State

-

Declaration :

  • C++ : class StateProxy
  • Java : public interface StateProxy

Directly inherited by : ARender GLRender VRender

+

Declaration :

  • C++ : class State
  • Java : public interface State

Directly inherited by : ARender GLRender StateAdapter StateProxy VRender

Artifact : stateproxy, Component(s) : Builder

-
Relation currFrame (<unidirectional association>)

Declaration :

  • Uml : # currFrame : Frame
  • C++ : protected: Frame * currFrame
+
Relation currFrame (<unidirectional association>)

Declaration :

  • Uml : # currFrame : Frame, multiplicity : 1..*
  • C++ : protected: vector<Frame *> currFrame
diff --git a/doc/devel/uml/class132869.html b/doc/devel/uml/class132869.html index 743378103..2d6833c2a 100644 --- a/doc/devel/uml/class132869.html +++ b/doc/devel/uml/class132869.html @@ -16,7 +16,7 @@ -

Declaration :

Representation of a Audio render process

Artifact : arender

+

Declaration :

  • C++ : class ARender : public State

Representation of a Audio render process

Artifact : arender

diff --git a/doc/devel/uml/class132997.html b/doc/devel/uml/class132997.html index 7680639be..a45d3c828 100644 --- a/doc/devel/uml/class132997.html +++ b/doc/devel/uml/class132997.html @@ -16,7 +16,7 @@ -

Declaration :

Representation of a Video render process. (Encapsulates the video buffers for the actual calculations)

Artifact : vrender

+

Declaration :

  • C++ : class VRender : public State

Representation of a Video render process. (Encapsulates the video buffers for the actual calculations)

Artifact : vrender

diff --git a/doc/devel/uml/class133125.html b/doc/devel/uml/class133125.html index 140cc4b67..d1cf4b2b6 100644 --- a/doc/devel/uml/class133125.html +++ b/doc/devel/uml/class133125.html @@ -16,7 +16,7 @@ -

Declaration :

Representation of a OpenGL accelerated Video render process

Artifact : glrender

+

Declaration :

  • C++ : class GLRender : public State

Representation of a OpenGL accelerated Video render process

Artifact : glrender

diff --git a/doc/devel/uml/class133765.html b/doc/devel/uml/class133765.html index af0e6bfb1..384101f0a 100644 --- a/doc/devel/uml/class133765.html +++ b/doc/devel/uml/class133765.html @@ -18,5 +18,6 @@

Declaration :

Source Node: represents a media source to pull data from.

Artifact : source

+

All public operations : pull

diff --git a/doc/devel/uml/class135045.html b/doc/devel/uml/class135045.html index 16259137b..a651d86b1 100644 --- a/doc/devel/uml/class135045.html +++ b/doc/devel/uml/class135045.html @@ -18,5 +18,6 @@

Declaration :

  • C++ : class CodecAdapter : public Trafo

Artifact : codecadapter

+

All public operations : pull

diff --git a/doc/devel/uml/class142085.html b/doc/devel/uml/class142085.html new file mode 100644 index 000000000..70fbc4c7b --- /dev/null +++ b/doc/devel/uml/class142085.html @@ -0,0 +1,22 @@ + + + + + + +Class StateProxy + + + + + +
Class StateProxy
+

+ + + + +

Declaration :

  • C++ : class StateProxy : public State
+
+ + diff --git a/doc/devel/uml/class142213.html b/doc/devel/uml/class142213.html new file mode 100644 index 000000000..a43acb9ac --- /dev/null +++ b/doc/devel/uml/class142213.html @@ -0,0 +1,27 @@ + + + + + + +Class StateAdapter + + + + + +
Class StateAdapter
+

+ + + + +

Declaration :

  • C++ : class StateAdapter : public State

lightweight value class used to manage the buffer associations for a single pull() call on a processing node

+ +
Operation pull

Declaration :

  • Uml : + pull(inout renderProcess : State) : void
  • C++ : public: void pull ()

trigger data processing by "pulling" results from the node's output

+
Operation retrieveBuffers

Declaration :

  • Uml : + retrieveBuffers(in requiredSource : vector<InputDescriptor> const) : void
  • C++ : public: void retrieveBuffers (const vector<InputDescriptor> const& requiredSource)

invoked from within the pull() - call of a node to set up the data buffers.
@param requiredSource descriptor denoting the predecessors and the frames required from them

+
Relation <unidirectional association>

Declaration :

+
Relation state (<unidirectional association>)

Declaration :

+

All public operations : pull , retrieveBuffers

+ + diff --git a/doc/devel/uml/class142341.html b/doc/devel/uml/class142341.html new file mode 100644 index 000000000..e9ac0ff67 --- /dev/null +++ b/doc/devel/uml/class142341.html @@ -0,0 +1,20 @@ + + + + + + +Class InputDescriptor + + + + + +
Class InputDescriptor
+

+ + + + +

Declaration :

  • C++ : class InputDescriptor

Artifact : procnode

+ diff --git a/doc/devel/uml/class142469.html b/doc/devel/uml/class142469.html new file mode 100644 index 000000000..9b6ed01a1 --- /dev/null +++ b/doc/devel/uml/class142469.html @@ -0,0 +1,20 @@ + + + + + + +Class caller + + + + + +
Class caller
+

+ + + + +

Declaration :

  • C++ : class caller
+ diff --git a/doc/devel/uml/class142597.html b/doc/devel/uml/class142597.html new file mode 100644 index 000000000..6465a8cd5 --- /dev/null +++ b/doc/devel/uml/class142597.html @@ -0,0 +1,20 @@ + + + + + + +Class Backend_Cache + + + + + +
Class Backend_Cache
+

+ + + + +

Declaration :

  • C++ : class Backend_Cache
+ diff --git a/doc/devel/uml/classdiagrams.html b/doc/devel/uml/classdiagrams.html index 4cf5416cc..c08c6d8a8 100644 --- a/doc/devel/uml/classdiagrams.html +++ b/doc/devel/uml/classdiagrams.html @@ -20,6 +20,7 @@ Automation Entities Builder Entities Controller Entities +Engine Details File MappingShows whats used to access Frames HierarchyLumiera Exception hierarchy In Memory Database diff --git a/doc/devel/uml/classes.html b/doc/devel/uml/classes.html index 23162b8f6..e1343f56e 100644 --- a/doc/devel/uml/classes.html +++ b/doc/devel/uml/classes.html @@ -26,10 +26,12 @@ AssetinterfaceSuperinterface describing especially the bookeeping properties of Assets AssetManagerboundaryFacade for the Asset subsystem AutoAutomation data for some parameter (i.e. a time varying function) +Backend_Cache Buildableinterface BuilderFacadeboundaryProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade BuilderToolinterfaceUsed according to the visitor pattern: each Tool contains the concrete implementation for one task to be done to the various MObject classes BuildInstruct(Interface) building instructions to be executed by the Builder on the render node network under construction. +caller Categorytree like classification of Assets Clipbookkeeping (asset) view of a media clip. Clip @@ -74,6 +76,7 @@ GLPipespecialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form GLRenderRepresentation of a OpenGL accelerated Video render process Hub +InputDescriptor InterpolatorProvides the implementation for getting the acutal value of a time varying or automated effect/plugin parameter Invalid Label @@ -101,6 +104,7 @@ Prefetch Previewalternative version of the media data, probably with lower resolution Prockey abstraction: data processing asset +ProcDispatcher Processor ProcNodeinterfaceKey abstraction of the Render Engine: A Data processing Node ProcPattspecial type of structural Asset representing information how to build some part of the render engine's processing nodes network. @@ -122,8 +126,10 @@ SimpleClipElementary clip consisting of only one media stream SmartPointerauxiliary SourceSource Node: represents a media source to pull data from. +Stateinterface State -StateProxyinterface +StateAdapterlightweight value class used to manage the buffer associations for a single pull() call on a processing node +StateProxyimplementation std::exceptionauxiliary Structkey abstraction: structural asset ThreadWe can basically reuse the Thread class design from Cinelerra2, Thread becomes a baseclass for all Threads diff --git a/doc/devel/uml/classes_list.html b/doc/devel/uml/classes_list.html index 6f3005da9..153e47670 100644 --- a/doc/devel/uml/classes_list.html +++ b/doc/devel/uml/classes_list.html @@ -27,10 +27,12 @@ Asset
AssetManager
Auto
+Backend_Cache
Buildable
BuilderFacade
BuilderTool
BuildInstruct
+caller
Category
Clip
Clip
@@ -75,6 +77,7 @@ GLPipe
GLRender
Hub
+InputDescriptor
Interpolator
Invalid
Label
@@ -102,6 +105,7 @@ Prefetch
Preview
Proc
+ProcDispatcher
Processor
ProcNode
ProcPatt
@@ -123,8 +127,10 @@ SimpleClip
SmartPointer
Source
+State
State
-StateProxy
+StateAdapter
+StateProxy
std::exception
Struct
Thread
diff --git a/doc/devel/uml/collaborationdiagrams.html b/doc/devel/uml/collaborationdiagrams.html index 2d8ab627d..9090762bc 100644 --- a/doc/devel/uml/collaborationdiagrams.html +++ b/doc/devel/uml/collaborationdiagrams.html @@ -18,6 +18,7 @@ +
"default" object
build processThis figure shows the process of building and starting a RenderEngine
pull call
diff --git a/doc/devel/uml/fig128389.png b/doc/devel/uml/fig128389.png index c6a57b8573f2a2faab08cafe49d0c14ed5d6d60b..adc3952e4ac393a8b720975eb6ea80813e91c328 100644 GIT binary patch literal 31223 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 literal 0 HcmV?d00001 diff --git a/doc/devel/uml/index.html b/doc/devel/uml/index.html index bbecbcbc0..a054cc161 100644 --- a/doc/devel/uml/index.html +++ b/doc/devel/uml/index.html @@ -32,7 +32,7 @@ Documentation

provided classes : Error, Time

Component Builder
-

provided classes : StateProxy

+

provided classes : State

required classes : Fixture, SessionImpl

Component Session
@@ -54,9 +54,10 @@ Documentation
Component AssetManagement
Component Dispatcher
+

provided classes : ProcDispatcher

Component Engine
-

Depends on Frame (Stream) Provider

required classes : StateProxy

+

Depends on Frame (Stream) Provider

required classes : State

Component ProcNode
@@ -78,6 +79,9 @@ Documentation

required classes : MediaAccessFacade

Component AssetDB
+ +
Component client code
+

required classes : ProcDispatcher

1.2 Component View interfaces

@@ -112,7 +116,7 @@ Documentation
Artifact Lumiera

Depends on common

Depends on gui

Depends on proc

Depends on backend

the main executable to be built

-

executable associated with : aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation, mobject, source, frame, placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter, effect, buildertool, segmentationtool

+

executable associated with : placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter, effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation, mobject, source, frame

Artifact main

Artifact source

@@ -192,7 +196,7 @@ Documentation
Artifact stateproxy

Key Interface representing a render process and encapsulating state

-

Artifact source associated with : StateProxy

+

Artifact source associated with : State

Artifact controllerfacade

Facade and service access point for the Proc Layer Controller

@@ -505,7 +509,7 @@ Documentation
Artifact procnode

Key abstraction of the Render Engine: a Processing Node

-

Artifact source associated with : ProcNode

+

Artifact source associated with : ProcNode, InputDescriptor

Artifact trafo

transforming processing Node

@@ -670,6 +674,7 @@ Documentation
+

2.2.2 Package Builder

@@ -759,7 +764,6 @@ Documentation
Class Assembler
-
Class Buildable
@@ -892,6 +896,27 @@ reuse exiting Engine

Selection :

    Transformation
    Class VFrame
    Class GLBuf
    Class Source
    + +

    +

    Engine Details



    +
    Class State
    +
    +
    +
    +
    + +

    2.3.3 Use Case View render process

    +
    + +

    +

    pull call



    + +
    Class instance

    type :StateAdapter

    +
    Class instance node1

    type :ProcNode

    +
    Class instance node2

    type :ProcNode

    +
    Class instance next_adapter

    type :StateAdapter

    +
    Class instance current_state

    type :StateProxy

    Class caller
    +
    diff --git a/doc/devel/uml/index_60.html b/doc/devel/uml/index_60.html index 4909e634c..8712d7074 100644 --- a/doc/devel/uml/index_60.html +++ b/doc/devel/uml/index_60.html @@ -17,8 +17,8 @@ - + @@ -28,8 +28,8 @@ - + diff --git a/doc/devel/uml/index_65.html b/doc/devel/uml/index_65.html index 3fce72879..c1c05066a 100644 --- a/doc/devel/uml/index_65.html +++ b/doc/devel/uml/index_65.html @@ -55,9 +55,9 @@ - - + + diff --git a/doc/devel/uml/index_66.html b/doc/devel/uml/index_66.html index 2d9540c91..592c6f15d 100644 --- a/doc/devel/uml/index_66.html +++ b/doc/devel/uml/index_66.html @@ -21,6 +21,7 @@ + @@ -34,8 +35,8 @@ - + diff --git a/doc/devel/uml/index_67.html b/doc/devel/uml/index_67.html index 08c04b765..996ed7eb6 100644 --- a/doc/devel/uml/index_67.html +++ b/doc/devel/uml/index_67.html @@ -19,6 +19,7 @@ + @@ -27,38 +28,40 @@ - - - - - - + + + + + + - - - - - - - + - - - - - + + - + + + + + + + + + + + + - + @@ -105,6 +108,7 @@ +
    NameKindDescription
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    aud_Aclass instance
    aud_aclass instance
    audioclass instance
    audio1class instance
    audio1class instance
    audio1class instance
    audio1class instance
    audio1class instance
    autoartifactMedia Object holding automation data
    AutoclassAutomation data for some parameter (i.e. a time varying function)
    Automation Entitiesclass diagram
    Backend Componentsclass view
    backend use casesuse case diagram
    backend-componentscomponent diagram
    Backend_Cacheclass
    BackendLayerpackage
    buildoperation
    build flowactivity diagram
    buildableartifactmarker interface denoting any MObject able to be treated by Tools
    buildEngineoperationMain Operation of the Builder: create a render engine for a given part of the timeline
    Buildercomponent
    Builderpackage
    builderpackagesourcecode package

    The Builder creating the Render Engine,
    located within the MObject Subsystem
    Builderpackage
    Builder Entitiesclass diagram
    Builder Workingsclass view
    BuilderFacadeclassProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade
    NameKindDescription
    Cachecomponent
    Cachecomponent view
    callerclass
    categoryrelationprimary tree like classification of the asset
    Categoryclasstree like classification of Assets
    categoryartifacttree like classification of Assets
    chainoperationcreate and add another Placement for this media object, thus increasingly constraining the (possible) position of this object.
    checked_inrelationchecked_in objects are subject of cache aging and must be not in use
    checked_outrelationthis list keeps all mappings which are in use, and thus prevents them from Cache aging
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    clearoperationclear current session contents
    without resetting overall session config.
    Afterwards, the session will contain only one
    empty EDL, while all Assets are retained.
    client codecomponent
    Clipclassbookkeeping (asset) view of a media clip.
    clipartifactbookkeeping (asset) view of a media clip.
    clipartifacta Media Clip
    clipartifactbookkeeping (asset) view of a media clip.
    Clipclass
    clipsrelation
    Codecclassdescription of some media data decoder or encoder facility
    createClipoperationcreate a (possibly compound) Clip refering to this media, ready to be added to the EDL.
    currEDLoperationThe EDL currently in focus. In most cases, Session and EDL are almost the same, just EDL emphasizes the collection aspect. But generally (for larger editing projects) one Session can contain several EDLs, which may even be nested. At any given time, only one of these EDLs has focus and recieves the editing commands.
    currentrelationStandard access path to get at the current session via the Session Manager, which acts as a "PImpl" smart pointer
    current_stateclass instance
    currFramerelation
    diff --git a/doc/devel/uml/index_68.html b/doc/devel/uml/index_68.html index 90bc7ba4d..e9e768a1e 100644 --- a/doc/devel/uml/index_68.html +++ b/doc/devel/uml/index_68.html @@ -32,8 +32,8 @@ designpackage designpackageAll things concering the big picture.
    Not a real code package, rather a container for design drafts, specifications, decisions. detect Channelsuse case -determine Render Paramsexpansion region determine Render Paramsopaque activity action +determine Render Paramsexpansion region devnullclass instance Dispatchercomponent dispatchOpoperation diff --git a/doc/devel/uml/index_69.html b/doc/devel/uml/index_69.html index 6c17d406d..c9eb2c76d 100644 --- a/doc/devel/uml/index_69.html +++ b/doc/devel/uml/index_69.html @@ -18,20 +18,21 @@ - + - + + diff --git a/doc/devel/uml/index_70.html b/doc/devel/uml/index_70.html index 78b986b1b..f328ad207 100644 --- a/doc/devel/uml/index_70.html +++ b/doc/devel/uml/index_70.html @@ -34,8 +34,8 @@ - + diff --git a/doc/devel/uml/index_73.html b/doc/devel/uml/index_73.html index 798945020..fa68d81e1 100644 --- a/doc/devel/uml/index_73.html +++ b/doc/devel/uml/index_73.html @@ -20,9 +20,10 @@ - + + diff --git a/doc/devel/uml/index_77.html b/doc/devel/uml/index_77.html index e6d8e8031..1428ef6eb 100644 --- a/doc/devel/uml/index_77.html +++ b/doc/devel/uml/index_77.html @@ -33,8 +33,8 @@ - + diff --git a/doc/devel/uml/index_78.html b/doc/devel/uml/index_78.html index 1cf51971d..8afac3d9f 100644 --- a/doc/devel/uml/index_78.html +++ b/doc/devel/uml/index_78.html @@ -20,6 +20,9 @@ + + + diff --git a/doc/devel/uml/index_79.html b/doc/devel/uml/index_79.html index 4ac4c3b33..f63687c5b 100644 --- a/doc/devel/uml/index_79.html +++ b/doc/devel/uml/index_79.html @@ -19,9 +19,9 @@ - - + + diff --git a/doc/devel/uml/index_80.html b/doc/devel/uml/index_80.html index ba34ae763..83ab6f76d 100644 --- a/doc/devel/uml/index_80.html +++ b/doc/devel/uml/index_80.html @@ -40,6 +40,7 @@ + @@ -51,6 +52,7 @@ + @@ -62,6 +64,9 @@ + + +
    NameKindDescription
    edlartifactthe (high level) Edit Decision List within the current Session
    EDLclass
    EDLcomponent
    EDLclass
    EDL Example1object diagramA simple example showing how the actual objects are placed in the Fixture (=definitive playlist). It shows a Video and Audio clip placed on two tracks
    EDL Example2object diagramMore complex example showing the Object graph in the EDL and how it is linked into the Fixture to yield the actual locations. In this example, an HUE Effect is applied on a part of the Clip
    edlsrelation
    EffectclassEffect or media processing component
    effectartifactEDL representation of a pluggable and automatable effect.
    effectartifactEffect or media processing component
    effectartifactEDL representation of a pluggable and automatable effect.
    Effectclass
    elementsrelationrelevant MObjects comprising this segment. TODO: actually necessary??
    enableoperationchange the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well
    endattributeend of the timerange (excl)
    Enginecomponent
    enginepackagesourcecode package

    The Core Render Engine
    Engine Detailsclass diagram
    Engine Example1object diagramExample1 (from EDL) continued: here the RenderEngine to be created by the Builder from the Input shown in Example1
    Engine Example2object diagramExample2 (from EDL) continued: notably in this RenderEngine the Effect has been partitioned into 2 segments with constant configuration.
    Engine Partsdeployment view
    FixedLocationclass
    Fixtureactivity object
    fixtureartifactthe (low level) representation of the EDL with concrete placement data
    Fixturecomponent
    Fixtureclass
    Fixturecomponent
    fork activity nodefork activity node
    FrameclassFrames are just a low level lump of continous memory, most parts are opaque. Frames are memory sensitive, they will be small constant sized structures which can be efficently managed in a pool.
    Framenode
    idattributeAsset primary key.
    In Memory Databaseclass diagram
    inFixtureactivity action pin
    inputclass instance
    inputclass instance
    inputclass instance
    inputclass instance
    InputDescriptorclass
    instanceoperation
    instructionsrelation
    Interfaceclass view
    MediaFactoryclassspecialized Asset Factory for configuring (new) media asset instances based on existing media files on disk; can create placeholder assets as well
    merge activity nodemerge activity node
    Metaclasskey abstraction: metadata and organisational asset
    metaartifactkey abstraction: metadata and organisational asset
    metaartifactabstract base class of all MObjects representing meta data or processing instructions
    metaartifactkey abstraction: metadata and organisational asset
    Metaclass
    mobjectartifactKey Abstraction: A Media Object in the Session
    mobjectpackagesourcecode package

    MObject Subsystem
    including the Session (EDL), Builder and Processing Controller
    nameattributeelement ID, comprehensible but sanitized. The tuple (category, name, org) is unique.
    need sub objectuse case
    nextrelationnext additional LocatingPin, if any
    next_adapterclass instance
    node1class instance
    node2class instance
    nodecreatertoolartifactcentral Tool implementing the Renderengine building
    NodeCreatorToolclassThis Tool implementation plays the central role in the buld process: given a MObject from Session, it is able to attach ProcNodes to the render engine under construction such as to reflect the properties of the MObject in the actual render.
    nodesrelation
    NameKindDescription
    offsetattributeOffset the actual position by this (time) value relative to the anchor point. TODO: Representation?
    orgattributeorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core Lumiera codebase is "lumi".
    ouputclass instance
    ouputclass instance
    ouputclass instance
    ouputclass instance
    ouputclass instance
    outPortrelationthe Port this MObject wants to be conected to
    outputrelation
    Overviewcomponent diagramThis drawing shows the top level compoents and relations
    pnodenode
    pointattributeidentifying the point where the nodes should be attached
    Posix Threads Abstractionclass viewC++ wrapers for pthreads
    predecessorsrelationpreconfigured table of all predecessor nodes, qualified
    with the output port on these nodes and time offset of the data
    we need for doing our calculations
    predicate implclass instance
    Prefetchclass
    Previewclassalternative version of the media data, probably with lower resolution
    procattributeholds the Processor (Render Engine Element) to be built by the current build step
    Proc-Asset Relationsclass diagram
    proc-componentscomponent diagram
    ProcDispatcherclass
    ProcessingLayerpackage
    Processorclass
    processorartifacta single render pipeline for one segment of the timeline
    ProjectorclassSpecial video processing node used to scale and translate image data.
    projectorartifactvideo ProcNode for scaling and translating image data
    providerrelation
    pulloperationtrigger data processing by "pulling" results from the node's output
    pulloperationtrigger data processing by "pulling" results from the node's output
    pull callcollaboration diagram
    diff --git a/doc/devel/uml/index_82.html b/doc/devel/uml/index_82.html index 1bade53e8..c807e8ca4 100644 --- a/doc/devel/uml/index_82.html +++ b/doc/devel/uml/index_82.html @@ -22,10 +22,11 @@ registryrelation@internal Table or DB holding all registered asset instances. relativelocationartifactPlacement implemnetaion providing various ways of attaching a MObject to another one RelativeLocationclass -RelTypeclassthe possible kinds of RelativePlacements relTypeattributethe kind of relation denoted by this Placement +RelTypeclassthe possible kinds of RelativePlacements removeoperationremove the given asset <i>together with all its dependants</i> from the internal DB Render Entitiesclass diagram +render processuse case view Render Requestactivity parameter RenderEngineclass renderengineartifacta complete network of processing nodes usable for rendering @@ -42,6 +43,7 @@ resolveoperation Resolvercomponent ResolverBaseclass +retrieveBuffersoperationinvoked from within the pull() - call of a node to set up the data buffers.
    @param requiredSource descriptor denoting the predecessors and the frames required from them rootCauseoperationIf this exception was caused by a chain of further exceptions,
    return the first one registered in this throw sequence.
    This works only, if every exceptions thrown as a consequence
    of another exception is propperly constructed by passing
    the original exception to the constructor Rule Basecomponent Rules accessclass diagram diff --git a/doc/devel/uml/index_83.html b/doc/devel/uml/index_83.html index e2f2fcea3..2edde4200 100644 --- a/doc/devel/uml/index_83.html +++ b/doc/devel/uml/index_83.html @@ -32,8 +32,8 @@ Service Componentsclass view Sessioncomponent sessionartifactInterface: the session edited by the user -Sessionclass view sessionpackagesourcecode package

    Everything concerning the EDL and Session, within the MObject Subsystem +Sessionclass view SessionclassPrimary Interface for all editing tasks.
    The session contains defaults, all the assets being edited, and a set of EDL with the individual MObjects to be manipulated and rendered. Session structureclass diagram sessionimplartifactholds the complete session data to be edited by the user @@ -56,8 +56,11 @@ startattributebegin of the timerange covered by this processor startattribute Statenode +Stateclass Stateclass -StateProxyclass +staterelation +StateAdapterclasslightweight value class used to manage the buffer associations for a single pull() call on a processing node +StateProxyclass stateproxyartifactKey Interface representing a render process and encapsulating state std::exceptionclass Structclasskey abstraction: structural asset diff --git a/doc/devel/uml/index_84.html b/doc/devel/uml/index_84.html index 14d928057..bfcae496d 100644 --- a/doc/devel/uml/index_84.html +++ b/doc/devel/uml/index_84.html @@ -34,20 +34,20 @@ trackrelation trackattribute trackrelation -trackartifactA grouping device within the EDL. The corresponding Placement
    by which this Track object is refered defines fallback placing
    properties to be used by all objects placed on this track in
    case they don't specify more concrete placements.
    Typically, tracks are used do make default Port connections,
    define a layer or pan for sound and for for disabling groups
    of clips. Note tracks are grouped in a tree like fashion.
    trackartifactstructural asset holding the configuration of a track in the EDL +trackartifactA grouping device within the EDL. The corresponding Placement
    by which this Track object is refered defines fallback placing
    properties to be used by all objects placed on this track in
    case they don't specify more concrete placements.
    Typically, tracks are used do make default Port connections,
    define a layer or pan for sound and for for disabling groups
    of clips. Note tracks are grouped in a tree like fashion.
    Trackclass tracksrelationelementary media assets comprising this compound Trafoclass trafoartifacttransforming processing Node treatoperation treatoperationThis operation is to be overloaded for the specific MObject subclasses to be treated. -treatoperation treatoperation treatoperation treatoperation -treatoperation +treatoperation treatoperation +treatoperation treatoperation TypeHandlerclass TypeHandler<Pipe>class diff --git a/doc/devel/uml/index_86.html b/doc/devel/uml/index_86.html index e3c5f01a9..364ff0811 100644 --- a/doc/devel/uml/index_86.html +++ b/doc/devel/uml/index_86.html @@ -20,23 +20,23 @@ versionattributeversion number of the thing or concept represented by this asset. Of each unique tuple (name, category, org) there will be only one version in the whole system. Version 0 is reserved for internal purposes. Versions are considered to be ordered, and any higher version is supposed to be fully backwards compatible to all previous versions. VFrameclass vframeartifacta buffer and render process holding a Video frame -vid1class instance vid1class instance -vid_Aclass instance -vid_Aclass instance +vid1class instance vid_aclass instance -vid_aclass instance +vid_Aclass instance vid_Aclass instance -videoclass instance +vid_aclass instance +vid_Aclass instance videoclass instance -videoclass instance videoclass instance -video1class instance -video1class instance -video1class instance -video1class instance +videoclass instance +videoclass instance video1class instance +video1class instance +video1class instance video1class instance +video1class instance +video1class instance Visitableclass visitorpackagesub-namespace for visitor library implementation visitorartifactAcyclic Visitor library diff --git a/doc/devel/uml/public_operations.html b/doc/devel/uml/public_operations.html index 697d67b52..03a780210 100644 --- a/doc/devel/uml/public_operations.html +++ b/doc/devel/uml/public_operations.html @@ -51,11 +51,14 @@ loadSessManagerreplace the current session by a new
    session loaded from serialized state. makeTypeHandler playRenderEngineTODO: will probably be handled differently (see Cehteh) +pullProcNodetrigger data processing by "pulling" results from the node's output +pullStateAdaptertrigger data processing by "pulling" results from the node's output removeAssetManagerremove the given asset <i>together with all its dependants</i> from the internal DB resetSessManagerreset all session config and
    start with a pristine default session. resolvePlacementcreate an actual (explicit) placement while trying to satisfy the network of adjacent objects and placements. resolveQueryHandler resolveQueryHandlerImpl +retrieveBuffersStateAdapterinvoked from within the pull() - call of a node to set up the data buffers.
    @param requiredSource descriptor denoting the predecessors and the frames required from them rootCauseErrorIf this exception was caused by a chain of further exceptions,
    return the first one registered in this throw sequence.
    This works only, if every exceptions thrown as a consequence
    of another exception is propperly constructed by passing
    the original exception to the constructor saveSessManagercreate a complete, serialized representation
    of the current session config and contents.
    @todo how to serialize, prameters, return value? treatApplicable diff --git a/uml/lumiera/128389.diagram b/uml/lumiera/128389.diagram index 5a6ad5049..741cf9ff5 100644 --- a/uml/lumiera/128389.diagram +++ b/uml/lumiera/128389.diagram @@ -14,7 +14,7 @@ classcanvas 128389 class_ref 131589 // ExitNode end classcanvas 128517 class_ref 131717 // ProcNode draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 462 264 2000 + xyz 462 257 2000 end classcanvas 129029 class_ref 131845 // Trafo draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default @@ -44,7 +44,7 @@ classcanvas 129797 class_ref 132613 // GLPipe draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 699 531 2000 end -classcanvas 132229 class_ref 132741 // StateProxy +classcanvas 132229 class_ref 132741 // State draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 36 374 2000 end @@ -97,29 +97,29 @@ relationcanvas 128901 relation_ref 131973 // multiplicity_a_pos 414 419 3000 no_multiplicity_b relationcanvas 129925 relation_ref 132101 // geometry VHV - from ref 128389 z 1999 to point 445 384 - line 130693 z 1999 to point 499 384 + from ref 128389 z 1999 to point 445 387 + line 130693 z 1999 to point 499 387 line 130821 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 130053 relation_ref 132229 // geometry VHV - from ref 129029 z 1999 to point 516 383 - line 130949 z 1999 to point 499 383 + from ref 129029 z 1999 to point 516 387 + line 130949 z 1999 to point 499 387 line 131077 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 130181 relation_ref 132357 // geometry VHV - from ref 129285 z 1999 to point 613 384 - line 131205 z 1999 to point 499 384 + from ref 129285 z 1999 to point 613 387 + line 131205 z 1999 to point 499 387 line 131333 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 130309 relation_ref 132485 // geometry VHV - from ref 129157 z 1999 to point 668 384 - line 131461 z 1999 to point 499 384 + from ref 129157 z 1999 to point 668 387 + line 131461 z 1999 to point 499 387 line 131589 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b @@ -179,14 +179,14 @@ relationcanvas 135429 relation_ref 134149 // no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 136965 relation_ref 134533 // - from ref 132229 z 1999 to point 306 465 + from ref 132229 z 1999 stereotype "<>" xyz 279 441 3000 to point 306 465 line 137093 z 1999 to ref 133765 role_a_pos 318 587 3000 no_role_b - no_multiplicity_a multiplicity_b_pos 124 427 3000 + multiplicity_a_pos 282 587 3000 multiplicity_b_pos 124 427 3000 relationcanvas 137349 relation_ref 134661 // geometry VHV - from ref 137221 z 1999 to point 763 384 - line 137477 z 1999 to point 499 384 + from ref 137221 z 1999 to point 763 387 + line 137477 z 1999 to point 499 387 line 137605 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b diff --git a/uml/lumiera/129285 b/uml/lumiera/129285 index 28f619bb6..7883c598c 100644 --- a/uml/lumiera/129285 +++ b/uml/lumiera/129285 @@ -1,6 +1,6 @@ format 40 "ProcessingLayer" // ProcessingLayer - revision 14 + revision 15 modified_by 5 "hiv" // class settings //class diagram settings diff --git a/uml/lumiera/131973.diagram b/uml/lumiera/131973.diagram new file mode 100644 index 000000000..9d11f2c5a --- /dev/null +++ b/uml/lumiera/131973.diagram @@ -0,0 +1,67 @@ +format 40 + +classcanvas 128005 class_ref 131717 // ProcNode + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 106 330 2004 + end +classcanvas 128517 class_ref 132741 // State + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 83 21 2000 + end +classcanvas 128645 class_ref 142085 // StateProxy + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 127 135 2000 + end +classcanvas 128773 class_ref 142213 // StateAdapter + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 36 216 2000 + end +classcanvas 129157 class_ref 142341 // InputDescriptor + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 183 446 2000 + end +classcanvas 129669 class_ref 133253 // Frame + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 267 221 3005 + end +relationcanvas 128901 relation_ref 148229 // + geometry VHV unfixed + from ref 128645 z 1999 to point 179 108 + line 131589 z 1999 to point 120 108 + line 131717 z 1999 to ref 128517 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 129029 relation_ref 148357 // + geometry VHV unfixed + from ref 128773 z 1999 to point 80 108 + line 131333 z 1999 to point 120 108 + line 131461 z 1999 to ref 128517 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 129285 relation_ref 148485 // + geometry HV + from ref 128005 z 1999 to point 228 367 + line 129541 z 1999 to ref 129157 + role_a_pos 240 421 3000 no_role_b + multiplicity_a_pos 216 421 3000 no_multiplicity_b +relationcanvas 129797 relation_ref 134533 // + from ref 128517 z 1999 to point 303 129 + line 130053 z 1999 stereotype "<>" xyz 248 128 3000 to ref 129669 + role_a_pos 312 194 3000 no_role_b + multiplicity_a_pos 281 158 3000 multiplicity_b_pos 171 82 3000 +relationcanvas 129925 relation_ref 148613 // + from ref 128773 z 1999 to ref 129669 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 130181 relation_ref 148741 // + from ref 128773 z 1999 to point 179 226 + line 130309 z 1999 to ref 128645 + role_a_pos 149 210 3000 no_role_b + no_multiplicity_a no_multiplicity_b +line 130437 -_-_ + from ref 128773 z 1999 to point 136 328 + line 130693 z 1999 to ref 128005 +line 130565 -_-_ + from ref 128773 z 1999 to ref 128005 +preferred_whz 414 544 1 +end diff --git a/uml/lumiera/132101.diagram b/uml/lumiera/132101.diagram new file mode 100644 index 000000000..39dd25211 --- /dev/null +++ b/uml/lumiera/132101.diagram @@ -0,0 +1,91 @@ +format 40 + +classinstancecanvas 128005 classinstance_ref 136069 // + xyz 144 217 2000 + end +classinstancecanvas 128133 classinstance_ref 136197 // node1 + xyz 169 309 2000 + end +classinstancecanvas 128261 classinstance_ref 136325 // node2 + xyz 485 277 2000 + end +classinstancecanvas 128389 classinstance_ref 136453 // next_adapter + xyz 388 216 2005 + end +classinstancecanvas 128901 classinstance_ref 136581 // current_state + xyz 114 20 2000 + end +classinstance 129285 class_ref 142469 // caller + name "" xyz 29 106 2000 +classinstance 129541 class_ref 142597 // Backend_Cache + name "" xyz 412 39 2000 +textcanvas 130565 "node1 using node2 as predecessor" + xyzwh 267 343 2000 133 24 +textcanvas 130693 "try to get frame from Cache first" + xyzwh 468 121 2000 89 43 +note 130821 "Triggered by pulling" + xyzwh 5 176 2005 118 38 +note 130949 "Buffers" + xyzwh 255 20 2005 61 35 +linkcanvas 128517 + from ref 128005 z 1999 to ref 128133 +dirscanvas 128645 z 1000 linkcanvas_ref 128517 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "2 pull()" xyz 217 255 3000 + backward_label "3 retrieveBuffers()" xyz 95 282 3000 +linkcanvas 128773 + from ref 128005 z 1999 to ref 128389 +dirscanvas 130053 z 1000 linkcanvas_ref 128773 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "4 create" xyz 281 192 3000 +linkcanvas 129029 + from ref 128005 z 1999 to ref 128901 +linkcanvas 129157 + from ref 128389 z 1999 to ref 128261 +dirscanvas 130309 z 1000 linkcanvas_ref 129157 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "6 pull()" xyz 515 246 3000 +linkcanvas 129413 + from ref 129285 z 1999 to ref 128005 +dirscanvas 129925 z 1000 linkcanvas_ref 129413 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "1 pull()" xyz 124 140 3000 +linkcanvas 129669 + from ref 128389 z 1999 to ref 129541 +dirscanvas 130181 z 1000 linkcanvas_ref 129669 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "5 try_fetch" xyz 386 132 3000 +linkcanvas 129797 + from ref 128005 z 1999 to ref 129541 +dirscanvas 130437 z 1000 linkcanvas_ref 129797 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "7 store" xyz 280 108 3000 +msgs + msg operation_ref 135685 // "pull(inout renderProcess : State) : void" + forward ranks 1 "1" dirscanvas_ref 129925 + msgs + msg operation_ref 135557 // "pull(inout renderProcess : State) : void" + forward ranks 2 "1.1" dirscanvas_ref 128645 + msgs + msg operation_ref 135813 // "retrieveBuffers(in requiredSource : vector const) : void" + backward ranks 3 "1.1.1" dirscanvas_ref 128645 + msgs + explicitmsg "create" + forward ranks 4 "1.1.1.1" dirscanvas_ref 130053 + msgs + explicitmsg "try_fetch" + forward ranks 5 "1.1.1.1.1" dirscanvas_ref 130181 + no_msg + msg operation_ref 135557 // "pull(inout renderProcess : State) : void" + forward ranks 6 "1.1.1.1.2" dirscanvas_ref 130309 + no_msg + msgsend + explicitmsg "store" + forward ranks 7 "1.1.1.2" dirscanvas_ref 130437 + no_msg + msgsend + msgsend + msgsend +msgsend +preferred_whz 599 408 1 +end diff --git a/uml/lumiera/5.session b/uml/lumiera/5.session index fc9677d8c..5f7a09a5a 100644 --- a/uml/lumiera/5.session +++ b/uml/lumiera/5.session @@ -1,14 +1,20 @@ window_sizes 1140 830 270 860 680 71 diagrams - active componentdiagram_ref 128005 // Overview - 702 640 80 4 2 0 + active collaborationdiagram_ref 132101 // pull call + 599 408 100 4 0 0 + classdiagram_ref 131973 // Engine Details + 414 544 100 4 0 0 + classdiagram_ref 128389 // Render Entities + 829 656 100 4 162 0 end show_stereotypes selected package_ref 129 // lumiera open - componentview_ref 128133 // interfaces - classview_ref 128005 // Session + + package_ref 128261 // MObject + classview_ref 128133 // Engine Workings + usecaseview_ref 128517 // render process class_ref 140677 // QueryHandler class_ref 140805 // TypeHandler class_ref 140933 // ResolverBase diff --git a/uml/lumiera/lumiera.prj b/uml/lumiera/lumiera.prj index dcdd63301..93cb8fa6f 100644 --- a/uml/lumiera/lumiera.prj +++ b/uml/lumiera/lumiera.prj @@ -1,6 +1,6 @@ format 40 "lumiera" - revision 44 + revision 45 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/renderengine.html b/wiki/renderengine.html index be449639b..09256ec75 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -556,10 +556,11 @@ is how to implement the relationship between [[MObject]]s and Assets. Do we use
    -
    +
    Assets are created by a Factories returning smart pointers; the Asset creation is bound to specific use cases and //only available// for these specific situations. There is no generic Asset Factory.
     
    -For every Asset we generate a __Ident tuple__ and a long ID (hash) derived from this Ident tuple. The constructor of the abstract base class {{{Asset}}} takes care of this step and automatically registeres the new Asset object with the AssetManager. Typically, the factory methods for concrete Asset classes provide some shortcuts providing sensible default values for some of the Ident tuple data fields. They may take additional parameters &mdash; for example the factory method for creating {{{asset::Media}}} takes a filename (and may at some point in the future aply "magic" based on examination of the file)
    +For every Asset we generate a __Ident tuple__ and a long ID (hash) derived from this Ident tuple. The constructor of the abstract base class {{{Asset}}} takes care of this step and automatically registeres the new Asset object with the AssetManager. Typically, the factory methods for concrete Asset classes provide some shortcuts providing sensible default values for some of the Ident tuple data fields. They may take additional parameters &mdash; for example the factory method for creating {{{asset::Media}}} takes a filename (and may at some point in the future aply "magic" based on examination of the file &rarr; LoadingMedia) +
    The Asset Manager provides an Interface to some internal Database holding all Assets in the current Session and System state. It may be a real Database at some point (and for the moment it's a Hashtable). Each [[Asset]] is registered automatically with the Asset Manager; it can be queried either by it's //identification tuple// or by it's unique ID.
    @@ -752,12 +753,12 @@ Note, //we still have to work out how exactly building, rendering and playback w [img[Colaborations in the Build Process|uml/fig128517.png]]
    -
    +
    Actually setting up and wiring a [[processing node|ProcNode]] involves several issues and is carried out at the lowest level of the build process.
    -It is closely related to &rarr; [[the way nodes are operated|NodeOperationProtocol]]
    +It is closely related to &rarr; [[the way nodes are operated|NodeOperationProtocol]] and the &rarr; [[mechanics of the render process|RenderMechanics]]
     
     !!!object creation
    -The Nodes are small polymorphic objects, carrying configuration data, but no state. They are [[specially allocated|ManagementRenderNodes]], and the object creation is accessible solely by the NodeFactory. They //must not be deallocated manually.// The decision of what concrete node type to create depends on the actual build situation and is worked out by the combination of [[mould|BuilderMould]] and [[processing pattern|ProcPatt]] at the current OperationPoint, issuing a call to one of NodeFactory's {{{operator()}}}
    +The Nodes are small polymorphic objects, carrying configuration data, but no state. They are [[specially allocated|ManagementRenderNodes]], and the object creation is accessible by means of the NodeFactory solely. They //must not be deallocated manually.// The decision of what concrete node type to create depends on the actual build situation and is worked out by the combination of [[mould|BuilderMould]] and [[processing pattern|ProcPatt]] at the current OperationPoint, issuing a call to one of NodeFactory's {{{operator()}}}
     
     !!!node, plugin and processing function
     Its a good idea to distinguish clearly between those concepts. A plugin is a piece of (possibly external) code we use to carry out operations. We have to //discover its properties and capabilities.// We don't have to discover anything regarding nodes, because we (Lumiera builder and renderengine) are creating, configuring and wiring them to fit the specific purpose. Both are to be distinguished from processing functions, which do the actual calculations on the media data. Every node typically encompasses at least one processing function, which may be an internal function in the node object, a library function from Lumiera or GAVL, or external code loaded from a plugin.
    @@ -880,12 +881,12 @@ While building, the application of such a visiting tool (especially the [[NodeCr
     
     
    -
    +
    Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounter several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool" or [[mould|BuilderMould]]. The palette of these moulds is called the ''tool kit'' of the builder. It is subject to configuration by rules.
     
     
     !!addressing a mould
    -All mould instances are owned and managed by the [[tool factory|BuilderToolFactory]], and can be referred to by their type ({{{PipeMould}}}, {{{CombiningMould}}}, {{{SourceChainMould}}}, {{{WiringMould}}}) and a concrete object instance (of suitable type). The returned mould (instance) acts as a handle to stick together the given object instance (from the high-level model) with the corresponding point in the low-level node network under construction. As consequence of this approach, the tool factory instance holds a snapshot of the current building state, including all the active spots in the build process. As the latter is driven by objects from the high-level model appearing (in a sensible order &rarr; see BuilderMechanics) within the NodeCreatorTool, new moulds will be created and fitted as necessary, and existing moulds will be exhausted when finished, until the render node network is complete.
    +All mould instances are owned and managed by the [[tool factory|BuilderToolFactory]], and can be referred to by their type (PipeMould, CombiningMould, SourceChainMould, WiringMould) and a concrete object instance (of suitable type). The returned mould (instance) acts as a handle to stick together the given object instance (from the high-level model) with the corresponding point in the low-level node network under construction. As consequence of this approach, the tool factory instance holds a snapshot of the current building state, including all the active spots in the build process. As the latter is driven by objects from the high-level model appearing (in a sensible order &rarr; see BuilderMechanics) within the NodeCreatorTool, new moulds will be created and fitted as necessary, and existing moulds will be exhausted when finished, until the render node network is complete.
     
     !!configuring a mould
     As each mould kind is different, it has a {{{prepare(...)}}} function with suitably typed parameters. The rest is intended to be  self-configuring (for example, a ~CombiningMould will detect the actual kind of Transition and select the internal mode of operation), so that it's sufficient to just call {{{operate()}}}
    @@ -1007,7 +1008,7 @@ This is an very important external Interface, because it links together all thre
     
    [[ProcLayer and Engine]]
     
    -
    +
    As detailed in the [[definition|DefaultsManagement]], {{{default(Obj)}}} is sort of a Joker along the lines "give me a suitable Object and I don't care for further details". Actually, default objects are implemented by the {{{mobject::session::DefsManager}}}, which remembers and keeps track of anything labeled as "default". This defaults manager is a singleton and can be accessed via the [[Session]] interface, meaning that the memory track regarding defaults is part of the session state. Accessing an object via the query for an default actually //tagges// this object (storing a weak ref in the ~DefsManager). Alongside with each object successfully queried via "default", the degree of constriction is remembered, i.e. the number of additional conditions contained in the query. This enables us to search for default objects starting with the most unspecific.
     
     !Skeleton
    @@ -1027,7 +1028,7 @@ Taken precisely, the "degree of constriction" yields only a partial or
     {{red{WARN}}} there is an interference with the (planned) Undo function. This is a general problem of the config queries; just ignoring this issue seems reasonable.
     
     !!!Problems with the (preliminary) mock implementation
    -As we don't have a Prolog interpreter on board yet, we utilize a mock store with preconfigured answers. (see {{{MockConfigQuery}}}). As this preliminary solution is lacking the ability to create new objects, we need to resort to some trickery here (please look away). The overall logic is quite broken, because the system isn't capable to do any real resolution &mdash; if we ignore this fact, the rest of the algorithm can be implemented, tested and used right now.
    +As we don't have a Prolog interpreter on board yet, we utilize a mock store with preconfigured answers. (see MockConfigQuery). As this preliminary solution is lacking the ability to create new objects, we need to resort to some trickery here (please look away). The overall logic is quite broken, because the system isn't capable to do any real resolution &mdash; if we ignore this fact, the rest of the algorithm can be implemented, tested and used right now.
     
    @@ -1306,7 +1307,7 @@ For this Lumiera design, we could consider making GOP just another raw media dat &rarr;see in [[Wikipedia|http://en.wikipedia.org/wiki/Group_of_pictures]]
    -
    +
    This wiki page is the entry point to detail notes covering some technical decisions, details and problems encountered in the course of the implementation of the Lumiera Renderengine, the Builder and the related parts.
     
     * [[Packages, Interfaces and Namespaces|InterfaceNamespaces]]
    @@ -1323,6 +1324,7 @@ For this Lumiera design, we could consider making GOP just another raw media dat
     * [[integrating the Config Query system|ConfigQueryIntegration]]
     * [[identifying the basic Builder operations|BasicBuildingOperations]] and [[planning the Implementation|PlanningNodeCreatorTool]]
     * [[how to handle »attached placement«|AttachedPlacementProblem]]
    +* working out the [[basic building situations|BuilderPrimitives]] and [[mechanics of rendering|RenderMechanics]]
     
    @@ -1679,7 +1681,7 @@ From experiences with other middle scale projects, I prefer having the test code [img[Example: Interfaces/Namespaces of the ~Session-Subsystems|uml/fig130053.png]]
    -
    +
    Opening and accessing media files on disk poses several problems, most of which belong to the domain of Lumiera's data backend. Here, we focus on the questions related to making media data available to the EDL and the render engine. Each media will be represented by an MediaAsset object, which indeed could be a compound object (in case of MultichannelMedia). Building this asset object thus includes getting informations from the real file on disk. For delegating this to the backend, we use the following query interface:
     * {{{queryFile(char* name)}}} requests accessing the file and yields some (opaque) handle when successful.
     * {{{queryChannel(fHandle, int)}}} will then be issued in sequence with ascending index numbers, until it returns {{{NULL}}}.
    @@ -1690,7 +1692,9 @@ From experiences with other middle scale projects, I prefer having the test code
     
     {{red{to be defined in more detail later...}}}
     
    -{{red{how to create a test stub for this interface...?}}}
    +&rarr; see "~MediaAccessFacade" for a (preliminary) interface definitioin +&rarr; see "~MediaAccessMock" for a mock/test implementaion +
    Used to actually implement the various kinds of [[Placement]] of ~MObjects. ~LocatingPin is the root of a hierarchy of different kinds of placing, constraining and locating a Media Object. Basically, this is an instance of the ''state pattern'': The user sees one Placement object with value semantics, but when the properties of the Placement are changed, actually a ~LocatingPin object (or rather a chain of ~LocatingPins) is changed within the Placement. Subclasses of ~LocatingPin implement different placing/constraining behaviour:
    @@ -1762,9 +1766,11 @@ __5/2008__: the allocation mechanism can surely be improved later, but for now I
     
     <style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;">loading <b>Proc-Layer</b> devel doku<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>
    -
    +
    The Interface asset::Media is a //key abstraction// It ties together several concepts and enables to deal with them on the interfaces in a uniform manner. Besides, as every Asset kind it belongs rather to the bookkeeping view: an asset::Media holds the specific properties and parametrisation of the media source it stands for. Regarding the __inward interface__ &mdash; as used from within the [[EDL]] or the [[Render Nodes|ProcNode]], it is irrelevant if any given asset::Media object stands for a complete media source, just a clip taken from this source or if a placeholder version of the real media source is used instead.
     [img[Asset Classess|uml/fig130437.png]]
    +
    +&rarr; see also LoadingMedia
     
    @@ -1824,12 +1830,12 @@ So, when creating a clip out of such a compound media asset, the clip has to be
    NodeCreaterTool is a [[visiting tool|VisitorUse]] used as second step in the [[Builder]]. Starting out from a [[Fixture]], the builder first [[divides the Timeline into segments|SegmentationTool]] and then processes each segment with the NodeCreaterTool to build a render nodes network (Render Engine) for this part of the timeline. While visiting individual Objects and Placements, the NodeCreaterTool creates and wires the necessary [[nodes|ProcNode]]
    -
    +
    The [[nodes|ProcNode]] are wired to form a "Directed Acyclic Graph"; each node knows its predecessor(s), but not its successor(s).  The RenderProcess is organized according to the ''pull principle'', thus we find an operation {{{pull()}}} at the core of this process. There is no such thing as an "engine object" calling nodes iteratively or table driven, rather, the nodes themselves issue recursive calls to their predecessor(s). For this to work, we need the nodes to adhere to a specific protocol:
    -# Node is pulled, providing a StateProxy object (encapsulating the access to the frames or buffers)
    +# Node is pulled, with a StateProxy object as parameter (encapsulating the access to the frames or buffers)
     # Node may now access current parameter values, using the state accessible via the StateProxy
    -# Node calles back into the StateProxy, providing the //input descriptor//
    -# StateProxy tries to get the input frames from the Cache in the Backend. If this fails, it forwards the call using the information in the input descriptor
    +# Node calles back into the StateProxy for getting the input buffer(s), providing it's //input descriptor//
    +# StateProxy tries to get the input frames from the Cache in the Backend. In case of failure, the call is forwarded according to the input descriptor
     # after this call returns, the Node is allowed to dereference the frame pointers and do its calculations
     # finally, when the {{{pull()}}} call returns, the StateProxy may push down the result frames to the cache
     some points to note:
    @@ -1839,7 +1845,7 @@ some points to note:
     * generally, a node may have N inputs and M output frames, which are expected to be processed in a single call
     
    -
    +
    We have to consider carefully how to handle the Creation of new class instances. Because, when done naively, it can defeat all efforts of separating subsystems, or &mdash; the other extreme &mdash; lead to a //switch-on-typeID//  programming style. We strive at a solution somewhere in the middle by utilizing __Abstract Factories__ on Interface or key abstraction classes, but providing specialized overloads for the different use cases. So in each use case we have to decide if we want to create a instance of some general concept (Interface), or if we have a direct collaboration and thus need the Factory to provide a more specific sub-Interface or even a concrete type.
     
     !Object creation use cases
    @@ -1850,7 +1856,8 @@ some points to note:
     |mark selection as clip|asset::Clip, session::Clip, Placement with unspec. LocatingPin| doesn't add to EDL|
     |loading Plugin|asset::Effect| usually at program startup|
     |create Session|asset::Track, asset::Pipe| |
    -&rarr; [[Creating and registering Assets|AssetCreation]]
    +&rarr; [[creating and registering Assets|AssetCreation]]
    +&rarr; [[loading media|LoadingMedia]]
     
     !![[MObjects|MObject]]
     |add media to EDL|asset::Clip, session::Clip, Placement with unspecified LocatingPin| creating whole-media clip on-the-fly |
    @@ -2628,11 +2635,11 @@ We need a way of addressing existing [[pipes|Pipe]]. Besides, as the Pipes and T
     //Note, we have yet to specify how exactly the building and rendering will work together with the backend. There are several possibilities how to structure the Playlist//
     
    -
    +
    Open issues, Things to be worked out, Problems still to be solved... 
     
     !!Parameter Handling
    -The requirements are not quite clear; obviously Parameters are the foundation for getting automation right and for providing effect editing interfaces, so it seems to me we need some sort of introspection, i.e. Parameters need to be discovered, enumerated and described at runtime.
    +The requirements are not quite clear; obviously Parameters are the foundation for getting automation right and for providing effect editing interfaces, so it seems to me we need some sort of introspection, i.e. Parameters need to be discovered, enumerated and described at runtime. (&rarr; see [[tag:automation|automation]])
     
     ''Automation Type'': Directly connected is the problem of handling the //type// of parameters sensible, including the value type of automation data. My first (somewhat naive) approach was to "make everything a double". But this soon leads into quite some of the same problems haunting the automation solution implemented in the current Cinelerra codebase. What makes the issue difficult is the fact we both need static diversity as well as dynamic flexibility. Usually, when combining hierarchies and templates, one has to be very careful; so I just note the problem down at the moment and will revisit it later, when I have a more clear understanding of the demands put onto the [[ProcNode]]s
     
    @@ -3019,12 +3026,35 @@ At first sight the link between asset and clip-MO is a simple logical relation b
     [img[Entities comprising the Render Engine|uml/fig128389.png]]
     
    -
    +
    +
    While with respect to the dependencies, the builder and the processing function, the render process is sufficiently characterized by referring to the ''pull principle'' and by defining a [[protocol|NodeOperationProtocol]] each node has to adhere to &mdash; for actually make it happen we have to care for some important details, especially //how to manage the buffers.// It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent within the inner pixel loop of these functions. But my guess is (as of 5/08), that the number of data moving and copying operations //will be//&nbsp; of importance.
    +
    +!reguirements
    +* operations should be "in place" as much as possible
    +* because caching necessitates a copy, the points where this happens should be controllable.
    +* buffers should accommodate automatically to provide the necessary space without clipping the image.
    +* the type of the media data can change while passing through the network, and so does the type of the buffers.
    +On the other hand, the processing function within the individual node needs to be shielded from these complexities. It can expect to get just //N~~I~~// input buffers and //N~O~// output buffers of required type. And, moreover, as the decision how to organize the buffers certainly depends on non-local circumstances, it should be preconfigured while building.
    +
    +!data flow
    +[>img[uml/fig131973.png]]
    +Not everything can be preconfigured though. The pull principle opens the possibility for the node to decide on a per call base what predecessor(s) to pull (if any). This decision may rely on automation parameters, which thus need to be accessible prior to 
    +requesting the buffer(s). Additionally, in a later version we plan to have the node network calculate some control values for adjusting the cache and backend timings &mdash; and of course at some point we'll want to utilize the GPU, resulting in the need to feed data from our processing buffers into some texture representation.
    +
    +!buffer management
    +Besides the StateProxy representing the actual render process and holding a couple of buffer (refs), we employ a lightweight adapter object in between. It is used //for a single {{{pull()}}}-call// &mdash; mapping the actual buffers to the input and output port numbers of the processing node and for dealing with the cache calls. While the StateProxy manages a pool of frame buffers, this interspersed adapter allows us to either use a buffer retrieved from the cache as an input, possibly use a new buffer located within the cache as output, or (in case no caching happens) to just use the same buffer as input and output for "in-place"-processing. The idea is that most of the configuration of this adapter object is prepared in the wiring step while building the node network. 
    +@@clear(right):display(block):@@
    +
    +
    +
    For each segment (of the effective timeline), there is a Processor holding the exit node(s) of a processing network, which is a "Directed Acyclic Graph" of small, preconfigured, stateless [[processing nodes|ProcNode]]. This network is operated according to the ''pull principle'', meaning that the rendering is just initiated by "pulling" output from the exit node, causing a cascade of recursive downcalls. Each node knows its predecessor(s) an can pull the necessary input from there. Consequently, there is no centralized "engine object" which may invoke nodes iteratively or table driven &mdash; rather, the rendering can be seen as a passive service provided for the backend, which may pull from the exit nodes at any time, in any order (?), and possibly multithreaded.
    -All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy acts as a gateway to the backend to handle the communication with the Cache.
    +All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy provides the buffers holding data to be processed and acts as a gateway to the backend to handle the communication with the Cache.
    +
     {{red{TODO: fill in more details of the Render Process.}}}
    +[img[uml/fig132101.png]]
     * see also
     &rarr; the [[Entities involved in Rendering|RenderEntities]]
    +&rarr; the [[mechanics of rendering and buffer management|RenderMechanics]]
     &rarr; the protocol [[how to operate the nodes|NodeOperationProtocol]]
     
    @@ -3338,8 +3368,8 @@ h1,h2,h3,h4,h5,h6 { /*}}}*/
    -
    -
    <<timeline better:true maxDays:55 maxEntries:30>>
    +
    +
    <<timeline better:true maxDays:55 maxEntries:45>>
    /***
    @@ -4420,10 +4450,10 @@ Using transitions is a very basic task and thus needs viable support by the GUI.
     Because of this experience, ichthyo wants to support a more general case of transitions, which have N output connections, behave similar to their "simple" counterpart, but leave out the mixing step. As a plus, such transitions can be inserted at the source ports of N clips or between any intermediary or final output pipes as well. Any transition processor capable of handling this situation should provide some flag, in order to decide if he can be placed in such a manner. (wichin the builder, encountering a  inconsistently placed transition is just an [[building error|BuildingError]])
     
    -
    +
    A ''~Meta-Clip'' or ''Virtual Clip'' (both are synonymous) denotes a clip which doesn't just pull media streams out of a source media asset, but rather provides the results of rendering a complete sub-network. In all other respects it behaves exactly like a "real" clip, i.e. it has [[source ports|ClipSourcePort]], can have attached effects (thus forming a local render pipe) and can be placed and combined with other clips. Depending on what is wired to the source ports, we get two flavours:
    -* a __placeholder clip__ has no "embedded" content. Rather, by virtue of placements and wiring requests, the output of some other pipe somewhere in the session will be wired to the clip's source ports. Thus, pulling data from this clip will effectively pull from these source pipes wired to it.
    -* a __nested EDL__ is like the other ~EDLs in the Session, just that any missing placement properties will be derived from the Virtual Clip, which is thought as to "contain" the objects of the nested EDL. Typically, you'd also [[configure the tracks|TrackHandling]] of the "inner" EDL such as to connect any output to the source ports of the Virtual Clip.
    +* a __placeholder clip__; has no "embedded" content. Rather, by virtue of placements and wiring requests, the output of some other pipe somewhere in the session will be wired to the clip's source ports. Thus, pulling data from this clip will effectively pull from these source pipes wired to it.
    +* a __nested EDL __ is like the other ~EDLs in the Session, just that any missing placement properties will be derived from the Virtual Clip, which is thought as to "contain" the objects of the nested EDL. Typically, you'd also [[configure the tracks|TrackHandling]] of the "inner" EDL such as to connect any output to the source ports of the Virtual Clip.
     
     Like any "real" clip, Virtual Clips have a start offset and a length, which will simply translate into an offset of the frame number pulled from the Virtual Clip's source connection or embedded EDL, making it possible to cut, splice, trim and roll them as usual. This of course implies we can have several instances of the same virtual clip with different start offset and length placed differently. The only limitation is that we can't handle cyclic dependencies for pulling data (which has to be detected and flagged as an error by the builder)
     
    From 0ac09411bcc834508816f7fa772dc8886e1ee70a Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 5 Jun 2008 20:27:53 +0100 Subject: [PATCH 128/245] Basic timeline with scrolling headers now works + Tidying work --- src/gui/Makefile.am | 2 + src/gui/lumiera_ui.rc | 19 +- src/gui/widgets/timeline-widget.cpp | 93 ++++++--- src/gui/widgets/timeline-widget.hpp | 19 +- src/gui/widgets/timeline/header-container.cpp | 193 ++++++++++++++++++ src/gui/widgets/timeline/header-container.hpp | 76 +++++++ src/gui/widgets/timeline/timeline-body.cpp | 32 +-- src/gui/widgets/timeline/timeline-body.hpp | 5 +- src/gui/widgets/timeline/track.cpp | 6 + src/gui/widgets/timeline/track.hpp | 3 +- src/gui/widgets/timeline/video-track.cpp | 18 +- src/gui/widgets/timeline/video-track.hpp | 3 +- src/gui/widgets/video-display-widget.cpp | 160 +++++++-------- 13 files changed, 480 insertions(+), 149 deletions(-) create mode 100644 src/gui/widgets/timeline/header-container.cpp create mode 100644 src/gui/widgets/timeline/header-container.hpp diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index b498fa3e8..fe4a1543f 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -58,6 +58,8 @@ lumigui_SOURCES = \ $(lumigui_srcdir)/widgets/video-display-widget.hpp \ $(lumigui_srcdir)/widgets/timeline-widget.cpp \ $(lumigui_srcdir)/widgets/timeline-widget.hpp \ + $(lumigui_srcdir)/widgets/timeline/header-container.cpp \ + $(lumigui_srcdir)/widgets/timeline/header-container.hpp \ $(lumigui_srcdir)/widgets/timeline/track.cpp \ $(lumigui_srcdir)/widgets/timeline/track.hpp \ $(lumigui_srcdir)/widgets/timeline/video-track.cpp \ diff --git a/src/gui/lumiera_ui.rc b/src/gui/lumiera_ui.rc index f37b4c12b..b2d951ae1 100644 --- a/src/gui/lumiera_ui.rc +++ b/src/gui/lumiera_ui.rc @@ -5,10 +5,13 @@ #---------- Styles for Standard Widgets ----------# -style "medium_bold_entry" +style "medium_text" { font_name = "sans bold 10" - +} + +style "medium_bold_entry" = "medium_text" +{ fg[NORMAL] = { 0.70, 0.70, 0.70 } fg[ACTIVE] = { 0.70, 0.70, 0.70 } @@ -115,5 +118,17 @@ style "timeline_body" gtkmm__CustomObject_TimelineBody::track_background = "#7E838B" } +style "timeline_header_base" = "default_base" +{ + fg[NORMAL] = { 0.77, 0.77, 0.72 } + bg[NORMAL] = { 0.18, 0.19, 0.22 } + bg[ACTIVE] = { 0.20, 0.20, 0.20 } + bg[PRELIGHT] = { 0.20, 0.20, 0.20 } + bg[INSENSITIVE] = { 0.20, 0.20, 0.20 } + bg[SELECTED] = { 0.20, 0.20, 0.20 } +} + class "gtkmm__CustomObject_TimelineBody" style:highest "timeline_body" +widget "*TimelineHeaderBaseUnselected" style:highest "timeline_header_base" + diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index e448f62f2..d201dd47f 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -31,6 +31,7 @@ namespace gui { namespace widgets { const int TimelineWidget::TrackPadding = 1; +const int TimelineWidget::HeaderWidth = 100; TimelineWidget::TimelineWidget() : Table(2, 2), @@ -41,68 +42,94 @@ TimelineWidget::TimelineWidget() : verticalScroll(verticalAdjustment), ruler("ruler") { - rowHeaderLayout.set_size_request(100, 0); - body = new TimelineBody(this); - + g_assert(body != NULL); + headerContainer = new HeaderContainer(this); + g_assert(headerContainer != NULL); + verticalAdjustment.signal_value_changed().connect( sigc::mem_fun(this, &TimelineWidget::on_scroll) ); attach(*body, 1, 2, 1, 2, FILL|EXPAND, FILL|EXPAND); attach(ruler, 1, 2, 0, 1, FILL|EXPAND, SHRINK); - attach(rowHeaderLayout, 0, 1, 1, 2, SHRINK, FILL|EXPAND); + attach(*headerContainer, 0, 1, 1, 2, SHRINK, FILL|EXPAND); attach(horizontalScroll, 1, 2, 2, 3, FILL|EXPAND, SHRINK); attach(verticalScroll, 2, 3, 1, 2, SHRINK, FILL|EXPAND); tracks.push_back(&video1); tracks.push_back(&video2); - - layout_tracks(); + + update_tracks(); } TimelineWidget::~TimelineWidget() { + g_assert(body != NULL); delete body; + g_assert(headerContainer != NULL); + delete headerContainer; } void TimelineWidget::on_scroll() { - move_headers(); + } - + void -TimelineWidget::layout_tracks() +TimelineWidget::on_size_allocate(Allocation& allocation) { + Widget::on_size_allocate(allocation); + + update_scroll(); + } + +void +TimelineWidget::update_tracks() + { + g_assert(headerContainer != NULL); + headerContainer->update_headers(); + + // Recalculate the total height of the timeline scrolled area + totalHeight = 0; vector::iterator i; for(i = tracks.begin(); i != tracks.end(); i++) - { - timeline::Track *track = *i; - g_assert(track != NULL); - rowHeaderLayout.put(track->get_header_widget(), 0, 0); - } - - move_headers(); + { + timeline::Track *track = *i; + g_assert(track != NULL); + totalHeight += track->get_height() + TrackPadding; + } + } + +void +TimelineWidget::update_scroll() + { + g_assert(body != NULL); + const Allocation body_allocation = body->get_allocation(); + + // Calculate the length that can be scrolled: + // the total height of all the tracks minus one screenful + int y_scroll_length = totalHeight - body_allocation.get_height(); + if(y_scroll_length < 0) y_scroll_length = 0; + + // If by resizing we're now over-scrolled, scroll back to + // maximum distance + if((int)verticalAdjustment.get_value() > y_scroll_length) + verticalAdjustment.set_value(y_scroll_length); + + verticalAdjustment.set_upper(y_scroll_length); + + // Hide the scrollbar if no scrolling is possible + if(y_scroll_length == 0 && verticalScroll.is_visible()) + verticalScroll.hide(); + else if(y_scroll_length != 0 && !verticalScroll.is_visible()) + verticalScroll.show(); } -void -TimelineWidget::move_headers() +int +TimelineWidget::get_y_scroll_offset() const { - int offset = 0; - const int y_scroll_offset = (int)verticalAdjustment.get_value(); - - vector::iterator i; - for(i = tracks.begin(); i != tracks.end(); i++) - { - timeline::Track *track = *i; - g_assert(track != NULL); - - const int height = track->get_track_height(); - rowHeaderLayout.move(track->get_header_widget(), 0, offset - y_scroll_offset); - offset += height + TrackPadding; - } - totalHeight = offset; - verticalAdjustment.set_upper(totalHeight); + return (int)verticalAdjustment.get_value(); } } // namespace widgets diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp index fb87f321b..502b3c535 100644 --- a/src/gui/widgets/timeline-widget.hpp +++ b/src/gui/widgets/timeline-widget.hpp @@ -26,6 +26,7 @@ #ifndef TIMELINE_WIDGET_HPP #define TIMELINE_WIDGET_HPP +#include "timeline/header-container.hpp" #include "timeline/timeline-body.hpp" #include "timeline/track.hpp" #include "timeline/video-track.hpp" @@ -47,12 +48,17 @@ class TimelineWidget : public Gtk::Table /* ===== Events ===== */ protected: void on_scroll(); + + void on_size_allocate(Gtk::Allocation& allocation); /* ===== Internals ===== */ protected: - void layout_tracks(); - - void move_headers(); + + void update_tracks(); + + void update_scroll(); + + int get_y_scroll_offset() const; protected: int totalHeight; @@ -61,10 +67,9 @@ class TimelineWidget : public Gtk::Table timeline::VideoTrack video2; std::vector tracks; - Gtk::Layout rowHeaderLayout; - Gtk::Label ruler; - timeline::TimelineBody *body; + timeline::HeaderContainer *headerContainer; + Gtk::Label ruler; Gtk::Adjustment horizontalAdjustment, verticalAdjustment; Gtk::HScrollbar horizontalScroll; @@ -73,8 +78,10 @@ class TimelineWidget : public Gtk::Table /* ===== Constants ===== */ protected: static const int TrackPadding; + static const int HeaderWidth; friend class timeline::TimelineBody; + friend class timeline::HeaderContainer; }; } // namespace widgets diff --git a/src/gui/widgets/timeline/header-container.cpp b/src/gui/widgets/timeline/header-container.cpp new file mode 100644 index 000000000..630f4be90 --- /dev/null +++ b/src/gui/widgets/timeline/header-container.cpp @@ -0,0 +1,193 @@ +/* + header-container.cpp - Implementation of the header container widget + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +#include "header-container.hpp" +#include "track.hpp" +#include "../timeline-widget.hpp" + +using namespace Gtk; +using namespace std; + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +HeaderContainer::HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline_widget) : + timelineWidget(timeline_widget) + { + set_flags(Gtk::NO_WINDOW); + set_redraw_on_allocate(false); + + timelineWidget->verticalAdjustment.signal_value_changed().connect( + sigc::mem_fun(this, &HeaderContainer::on_scroll) ); + } + +void +HeaderContainer::update_headers() + { + g_assert(timelineWidget != NULL); + + vector &tracks = timelineWidget->tracks; + vector::iterator i; + for(i = tracks.begin(); i != tracks.end(); i++) + { + timeline::Track *track = *i; + g_assert(track != NULL); + + Widget &header = track->get_header_widget(); + header.set_parent(*this); + header.show(); + } + + layout_headers(); + } + +void +HeaderContainer::on_realize() + { + set_flags(Gtk::NO_WINDOW); + + ensure_style(); + + // Call base class: + Gtk::Widget::on_realize(); + + // Create the GdkWindow: + GdkWindowAttr attributes; + memset(&attributes, 0, sizeof(attributes)); + + Allocation allocation = get_allocation(); + + // Set initial position and size of the Gdk::Window: + attributes.x = allocation.get_x(); + attributes.y = allocation.get_y(); + attributes.width = allocation.get_width(); + attributes.height = allocation.get_height(); + + attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + + gdkWindow = Gdk::Window::create(get_window() /* parent */, &attributes, + GDK_WA_X | GDK_WA_Y); + unset_flags(Gtk::NO_WINDOW); + set_window(gdkWindow); + + // Unset the background so as to make the colour match the parent window + unset_bg(STATE_NORMAL); + + // Make the widget receive expose events + gdkWindow->set_user_data(gobj()); + } + +void +HeaderContainer::on_unrealize() + { + gdkWindow.clear(); + + //Call base class: + Gtk::Widget::on_unrealize(); + } + +void +HeaderContainer::on_size_request (Requisition* requisition) + { + //Initialize the output parameter: + *requisition = Gtk::Requisition(); + + requisition->width = TimelineWidget::HeaderWidth; + requisition->height = 0; + } + +void +HeaderContainer::on_size_allocate (Allocation& allocation) + { + // Use the offered allocation for this container: + set_allocation(allocation); + + // Resize the widget's window + if(gdkWindow) + gdkWindow->resize(allocation.get_width(), allocation.get_height()); + + // Relayout the child widgets of the headers + layout_headers(); + } + +void +HeaderContainer::forall_vfunc(gboolean /* include_internals */, + GtkCallback callback, gpointer callback_data) + { + g_assert(timelineWidget != NULL); + + vector &tracks = timelineWidget->tracks; + vector::iterator i; + for(i = tracks.begin(); i != tracks.end(); i++) + { + timeline::Track *track = *i; + g_assert(track != NULL); + callback(track->get_header_widget().gobj(), + callback_data); + } + } + +void +HeaderContainer::on_scroll() + { + layout_headers(); + } + +void +HeaderContainer::layout_headers() + { + g_assert(timelineWidget != NULL); + + int offset = 0; + const int y_scroll_offset = timelineWidget->get_y_scroll_offset(); + + const Allocation container_allocation = get_allocation(); + + vector &tracks = timelineWidget->tracks; + vector::iterator i; + for(i = tracks.begin(); i != tracks.end(); i++) + { + timeline::Track *track = *i; + g_assert(track != NULL); + Widget &header = track->get_header_widget(); + + const int height = 100;//header->get_track_height(); + + Gtk::Allocation header_allocation; + header_allocation.set_x (0); + header_allocation.set_y (offset - y_scroll_offset); + header_allocation.set_width (container_allocation.get_width ()); + header_allocation.set_height (height); + header.size_allocate(header_allocation); + + offset += height + TimelineWidget::TrackPadding; + } + } + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera diff --git a/src/gui/widgets/timeline/header-container.hpp b/src/gui/widgets/timeline/header-container.hpp new file mode 100644 index 000000000..f82dc3dce --- /dev/null +++ b/src/gui/widgets/timeline/header-container.hpp @@ -0,0 +1,76 @@ +/* + header-container.hpp - Declaration of the header container widget + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + This program 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 2 of the + License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/** @file header-container.hpp + ** This file contains the definition of the header container + ** widget + */ + +#ifndef HEADER_CONTAINER_HPP +#define HEADER_CONTAINER_HPP + +#include +#include + +namespace lumiera { +namespace gui { +namespace widgets { + +class TimelineWidget; + +namespace timeline { + +class HeaderContainer : public Gtk::Container + { + public: + HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline_widget); + + void update_headers(); + + private: + void on_realize(); + void on_unrealize(); + + void on_size_allocate (Gtk::Allocation& allocation); + void on_size_request (Gtk::Requisition* requisition); + + void forall_vfunc(gboolean include_internals, GtkCallback callback, + gpointer callback_data); + + void on_scroll(); + + /* ===== Internals ===== */ + private: + void layout_headers(); + + private: + lumiera::gui::widgets::TimelineWidget *timelineWidget; + + Glib::RefPtr gdkWindow; + }; + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + +#endif // HEADER_CONTAINER_HPP + diff --git a/src/gui/widgets/timeline/timeline-body.cpp b/src/gui/widgets/timeline/timeline-body.cpp index e7c9e0b78..859abb0e8 100644 --- a/src/gui/widgets/timeline/timeline-body.cpp +++ b/src/gui/widgets/timeline/timeline-body.cpp @@ -91,7 +91,7 @@ TimelineBody::on_expose_event(GdkEventExpose* event) timeline::Track *track = *i; g_assert(track != NULL); - const int track_height = track->get_track_height(); + const int track_height = track->get_height(); // Draw the track background cairo->rectangle(0, 0, allocation.get_width(), track_height); @@ -112,23 +112,23 @@ TimelineBody::on_expose_event(GdkEventExpose* event) void TimelineBody::read_styles() -{ - GdkColor *colour; - - gtk_widget_style_get(Widget::gobj(), "track_background", &colour, NULL); - - // Did the color load successfully? - if(colour != NULL) - track_background = *colour; - else { - g_warning("track_background style value failed to load"); - track_background.red = 0x0000; - track_background.green = 0x0000; - track_background.blue = 0x0000; - track_background.pixel = 0x00000000; + GdkColor *colour; + + gtk_widget_style_get(Widget::gobj(), "track_background", &colour, NULL); + + // Did the color load successfully? + if(colour != NULL) + track_background = *colour; + else + { + g_warning("track_background style value failed to load"); + track_background.red = 0x0000; + track_background.green = 0x0000; + track_background.blue = 0x0000; + track_background.pixel = 0x00000000; + } } -} } // namespace timeline } // namespace widgets diff --git a/src/gui/widgets/timeline/timeline-body.hpp b/src/gui/widgets/timeline/timeline-body.hpp index c58323b1b..d3ba192ab 100644 --- a/src/gui/widgets/timeline/timeline-body.hpp +++ b/src/gui/widgets/timeline/timeline-body.hpp @@ -41,9 +41,6 @@ class TimelineBody : public Gtk::DrawingArea public: TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widget); - protected: - lumiera::gui::widgets::TimelineWidget *timelineWidget; - /* ===== Events ===== */ protected: void on_scroll(); @@ -56,6 +53,8 @@ class TimelineBody : public Gtk::DrawingArea private: GdkColor track_background; + + lumiera::gui::widgets::TimelineWidget *timelineWidget; }; } // namespace timeline diff --git a/src/gui/widgets/timeline/track.cpp b/src/gui/widgets/timeline/track.cpp index 510dfc798..6b915949d 100644 --- a/src/gui/widgets/timeline/track.cpp +++ b/src/gui/widgets/timeline/track.cpp @@ -37,6 +37,12 @@ Track::get_title() { return "Hello"; } + +int +Track::get_height() + { + return get_header_widget().get_allocation().get_height(); + } void Track::draw_track(Cairo::RefPtr cairo) diff --git a/src/gui/widgets/timeline/track.hpp b/src/gui/widgets/timeline/track.hpp index 15254ea00..5f368ea18 100644 --- a/src/gui/widgets/timeline/track.hpp +++ b/src/gui/widgets/timeline/track.hpp @@ -42,12 +42,11 @@ class Track virtual Gtk::Widget& get_header_widget() = 0; - virtual int get_track_height() = 0; + virtual int get_height(); virtual void draw_track(Cairo::RefPtr cairo); protected: - }; diff --git a/src/gui/widgets/timeline/video-track.cpp b/src/gui/widgets/timeline/video-track.cpp index 6fd55fea5..b20992543 100644 --- a/src/gui/widgets/timeline/video-track.cpp +++ b/src/gui/widgets/timeline/video-track.cpp @@ -32,20 +32,25 @@ namespace timeline { VideoTrack::VideoTrack() : headerWidget("HeaderTest") { - + headerFrame.add(headerWidget); + headerFrame.set_shadow_type (Gtk::SHADOW_ETCHED_OUT); + headerFrame.set_name ("TimelineHeaderBaseUnselected"); } -Gtk::Widget& VideoTrack::get_header_widget() +Gtk::Widget& +VideoTrack::get_header_widget() { - return headerWidget; + return headerFrame; } -int VideoTrack::get_track_height() +/*int +VideoTrack::get_height() { return 100; - } + }*/ -void VideoTrack::draw_track(Cairo::RefPtr cairo) +void +VideoTrack::draw_track(Cairo::RefPtr cairo) { } @@ -54,3 +59,4 @@ void VideoTrack::draw_track(Cairo::RefPtr cairo) } // namespace widgets } // namespace gui } // namespace lumiera + diff --git a/src/gui/widgets/timeline/video-track.hpp b/src/gui/widgets/timeline/video-track.hpp index d73a03b6e..fad2f77af 100644 --- a/src/gui/widgets/timeline/video-track.hpp +++ b/src/gui/widgets/timeline/video-track.hpp @@ -40,12 +40,13 @@ class VideoTrack : public Track virtual Gtk::Widget& get_header_widget(); - virtual int get_track_height(); + //virtual int get_height(); virtual void draw_track(Cairo::RefPtr cairo); protected: Gtk::Label headerWidget; + Gtk::Frame headerFrame; }; } // namespace timeline diff --git a/src/gui/widgets/video-display-widget.cpp b/src/gui/widgets/video-display-widget.cpp index 920ea379c..2c7be8111 100644 --- a/src/gui/widgets/video-display-widget.cpp +++ b/src/gui/widgets/video-display-widget.cpp @@ -36,123 +36,123 @@ namespace widgets { VideoDisplayWidget::VideoDisplayWidget() : gdkWindow(NULL), displayer(NULL) -{ - set_flags(Gtk::NO_WINDOW); -} + { + set_flags(Gtk::NO_WINDOW); + } VideoDisplayWidget::~VideoDisplayWidget() -{ - if(displayer != NULL) - delete displayer; -} + { + if(displayer != NULL) + delete displayer; + } void VideoDisplayWidget::on_realize() -{ - set_flags(Gtk::NO_WINDOW); + { + set_flags(Gtk::NO_WINDOW); - //Call base class: - Gtk::Widget::on_realize(); + // Call base class: + Gtk::Widget::on_realize(); - //Create the GdkWindow: - GdkWindowAttr attributes; - memset(&attributes, 0, sizeof(attributes)); + // Create the GdkWindow: + GdkWindowAttr attributes; + memset(&attributes, 0, sizeof(attributes)); - Gtk::Allocation allocation = get_allocation(); + Gtk::Allocation allocation = get_allocation(); - //Set initial position and size of the Gdk::Window: - attributes.x = allocation.get_x(); - attributes.y = allocation.get_y(); - attributes.width = allocation.get_width(); - attributes.height = allocation.get_height(); + // Set initial position and size of the Gdk::Window: + attributes.x = allocation.get_x(); + attributes.y = allocation.get_y(); + attributes.width = allocation.get_width(); + attributes.height = allocation.get_height(); - attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; + attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; - gdkWindow = Gdk::Window::create(get_window() /* parent */, &attributes, - GDK_WA_X | GDK_WA_Y); - unset_flags(Gtk::NO_WINDOW); - set_window(gdkWindow); + gdkWindow = Gdk::Window::create(get_window() /* parent */, &attributes, + GDK_WA_X | GDK_WA_Y); + unset_flags(Gtk::NO_WINDOW); + set_window(gdkWindow); - //set colors - modify_bg(Gtk::STATE_NORMAL, Gdk::Color("black")); + // Set colors + modify_bg(Gtk::STATE_NORMAL, Gdk::Color("black")); - //make the widget receive expose events - gdkWindow->set_user_data(gobj()); + // Make the widget receive expose events + gdkWindow->set_user_data(gobj()); - if(displayer != NULL) - delete displayer; - displayer = createDisplayer(this, 320, 240); + if(displayer != NULL) + delete displayer; + displayer = createDisplayer(this, 320, 240); - add_events(Gdk::ALL_EVENTS_MASK); -} + add_events(Gdk::ALL_EVENTS_MASK); + } void VideoDisplayWidget::on_unrealize() -{ - gdkWindow.clear(); + { + gdkWindow.clear(); - //Call base class: - Gtk::Widget::on_unrealize(); -} + //Call base class: + Gtk::Widget::on_unrealize(); + } bool VideoDisplayWidget::on_button_press_event (GdkEventButton* event) -{ - unsigned char buffer[320 * 240 * 4]; + { + unsigned char buffer[320 * 240 * 4]; - for(int i = 0; i < 320*240*4; i++) - buffer[i] = rand(); + for(int i = 0; i < 320*240*4; i++) + buffer[i] = rand(); - displayer->put((void*)buffer); + displayer->put((void*)buffer); - return true; -} + return true; + } bool VideoDisplayWidget::on_expose_event(GdkEventExpose* event) -{ - // This is where we draw on the window - /*Glib::RefPtr window = get_window(); - if(window) { - Cairo::RefPtr cr = window->create_cairo_context(); - if(event) + // This is where we draw on the window + /*Glib::RefPtr window = get_window(); + if(window) { - // clip to the area that needs to be re-exposed so we don't draw any - // more than we need to. - cr->rectangle(event->area.x, event->area.y, - event->area.width, event->area.height); - cr->clip(); - } + Cairo::RefPtr cr = window->create_cairo_context(); + if(event) + { + // clip to the area that needs to be re-exposed so we don't draw any + // more than we need to. + cr->rectangle(event->area.x, event->area.y, + event->area.width, event->area.height); + cr->clip(); + } - // Paint the background - cr->set_source_rgb(0.0, 0.0, 0.0); - cr->paint(); - }*/ - return true; -} + // Paint the background + cr->set_source_rgb(0.0, 0.0, 0.0); + cr->paint(); + }*/ + return true; + } Displayer* VideoDisplayWidget::createDisplayer( Gtk::Widget *drawingArea, int width, int height ) -{ - Displayer *displayer = NULL; - - displayer = new XvDisplayer( drawingArea, width, height ); - if ( !displayer->usable() ) { - delete displayer; - displayer = NULL; - } + Displayer *displayer = NULL; - if ( displayer == NULL ) - { - displayer = new GdkDisplayer( drawingArea, width, height ); - } + displayer = new XvDisplayer( drawingArea, width, height ); + if ( !displayer->usable() ) + { + delete displayer; + displayer = NULL; + } - return displayer; -} + if ( displayer == NULL ) + { + displayer = new GdkDisplayer( drawingArea, width, height ); + } + + return displayer; + } } // namespace widgets } // namespace gui From 85730b889e38f4504cb4a57873715807a9273b4c Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 5 Jun 2008 23:57:04 +0100 Subject: [PATCH 129/245] Fixed to assertion failures, and move the frame ownership to HeaderContainer --- src/gui/widgets/timeline-widget.cpp | 23 ++++++----- src/gui/widgets/timeline-widget.hpp | 4 +- src/gui/widgets/timeline/header-container.cpp | 38 +++++++++---------- src/gui/widgets/timeline/header-container.hpp | 1 + src/gui/widgets/timeline/track.cpp | 4 +- src/gui/widgets/timeline/track.hpp | 2 +- src/gui/widgets/timeline/video-track.cpp | 10 ++--- src/gui/widgets/timeline/video-track.hpp | 2 +- 8 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index d201dd47f..db8bcd614 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -42,17 +42,19 @@ TimelineWidget::TimelineWidget() : verticalScroll(verticalAdjustment), ruler("ruler") { - body = new TimelineBody(this); - g_assert(body != NULL); - headerContainer = new HeaderContainer(this); - g_assert(headerContainer != NULL); + TimelineBody *body_ptr = new TimelineBody(this); + body = Glib::RefPtr(body_ptr); + g_assert(body); + HeaderContainer *header_container_ptr = new HeaderContainer(this); + headerContainer = Glib::RefPtr(header_container_ptr); + g_assert(headerContainer); verticalAdjustment.signal_value_changed().connect( sigc::mem_fun(this, &TimelineWidget::on_scroll) ); - attach(*body, 1, 2, 1, 2, FILL|EXPAND, FILL|EXPAND); + attach(*body_ptr, 1, 2, 1, 2, FILL|EXPAND, FILL|EXPAND); attach(ruler, 1, 2, 0, 1, FILL|EXPAND, SHRINK); - attach(*headerContainer, 0, 1, 1, 2, SHRINK, FILL|EXPAND); + attach(*header_container_ptr, 0, 1, 1, 2, SHRINK, FILL|EXPAND); attach(horizontalScroll, 1, 2, 2, 3, FILL|EXPAND, SHRINK); attach(verticalScroll, 2, 3, 1, 2, SHRINK, FILL|EXPAND); @@ -64,10 +66,7 @@ TimelineWidget::TimelineWidget() : TimelineWidget::~TimelineWidget() { - g_assert(body != NULL); - delete body; - g_assert(headerContainer != NULL); - delete headerContainer; + } void @@ -87,7 +86,7 @@ TimelineWidget::on_size_allocate(Allocation& allocation) void TimelineWidget::update_tracks() { - g_assert(headerContainer != NULL); + g_assert(headerContainer); headerContainer->update_headers(); // Recalculate the total height of the timeline scrolled area @@ -104,7 +103,7 @@ TimelineWidget::update_tracks() void TimelineWidget::update_scroll() { - g_assert(body != NULL); + g_assert(body); const Allocation body_allocation = body->get_allocation(); // Calculate the length that can be scrolled: diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp index 502b3c535..cd752060a 100644 --- a/src/gui/widgets/timeline-widget.hpp +++ b/src/gui/widgets/timeline-widget.hpp @@ -67,8 +67,8 @@ class TimelineWidget : public Gtk::Table timeline::VideoTrack video2; std::vector tracks; - timeline::TimelineBody *body; - timeline::HeaderContainer *headerContainer; + Glib::RefPtr body; + Glib::RefPtr headerContainer; Gtk::Label ruler; Gtk::Adjustment horizontalAdjustment, verticalAdjustment; diff --git a/src/gui/widgets/timeline/header-container.cpp b/src/gui/widgets/timeline/header-container.cpp index 630f4be90..40c92698b 100644 --- a/src/gui/widgets/timeline/header-container.cpp +++ b/src/gui/widgets/timeline/header-container.cpp @@ -53,10 +53,15 @@ HeaderContainer::update_headers() { timeline::Track *track = *i; g_assert(track != NULL); + + Glib::RefPtr headerFrame(new Gtk::Frame()); + headerFrame->add(track->get_header_widget()); + headerFrame->set_shadow_type (Gtk::SHADOW_ETCHED_OUT); + headerFrame->set_name ("TimelineHeaderBaseUnselected"); + headerFrame->set_parent(*this); + headerFrame->show(); - Widget &header = track->get_header_widget(); - header.set_parent(*this); - header.show(); + rootHeaders.push_back(headerFrame); } layout_headers(); @@ -136,17 +141,13 @@ HeaderContainer::on_size_allocate (Allocation& allocation) void HeaderContainer::forall_vfunc(gboolean /* include_internals */, GtkCallback callback, gpointer callback_data) - { - g_assert(timelineWidget != NULL); - - vector &tracks = timelineWidget->tracks; - vector::iterator i; - for(i = tracks.begin(); i != tracks.end(); i++) + { + vector< Glib::RefPtr >::iterator i; + for(i = rootHeaders.begin(); i != rootHeaders.end(); i++) { - timeline::Track *track = *i; - g_assert(track != NULL); - callback(track->get_header_widget().gobj(), - callback_data); + Glib::RefPtr header = *i; + g_assert(header); + callback(header->gobj(), callback_data); } } @@ -166,13 +167,10 @@ HeaderContainer::layout_headers() const Allocation container_allocation = get_allocation(); - vector &tracks = timelineWidget->tracks; - vector::iterator i; - for(i = tracks.begin(); i != tracks.end(); i++) + vector >::iterator i; + for(i = rootHeaders.begin(); i != rootHeaders.end(); i++) { - timeline::Track *track = *i; - g_assert(track != NULL); - Widget &header = track->get_header_widget(); + Glib::RefPtr header = *i; const int height = 100;//header->get_track_height(); @@ -181,7 +179,7 @@ HeaderContainer::layout_headers() header_allocation.set_y (offset - y_scroll_offset); header_allocation.set_width (container_allocation.get_width ()); header_allocation.set_height (height); - header.size_allocate(header_allocation); + header->size_allocate(header_allocation); offset += height + TimelineWidget::TrackPadding; } diff --git a/src/gui/widgets/timeline/header-container.hpp b/src/gui/widgets/timeline/header-container.hpp index f82dc3dce..ed8fb82e8 100644 --- a/src/gui/widgets/timeline/header-container.hpp +++ b/src/gui/widgets/timeline/header-container.hpp @@ -63,6 +63,7 @@ class HeaderContainer : public Gtk::Container private: lumiera::gui::widgets::TimelineWidget *timelineWidget; + std::vector< Glib::RefPtr > rootHeaders; Glib::RefPtr gdkWindow; }; diff --git a/src/gui/widgets/timeline/track.cpp b/src/gui/widgets/timeline/track.cpp index 6b915949d..3ae90ff41 100644 --- a/src/gui/widgets/timeline/track.cpp +++ b/src/gui/widgets/timeline/track.cpp @@ -38,11 +38,11 @@ Track::get_title() return "Hello"; } -int +/*int Track::get_height() { return get_header_widget().get_allocation().get_height(); - } + }*/ void Track::draw_track(Cairo::RefPtr cairo) diff --git a/src/gui/widgets/timeline/track.hpp b/src/gui/widgets/timeline/track.hpp index 5f368ea18..7c338d7bb 100644 --- a/src/gui/widgets/timeline/track.hpp +++ b/src/gui/widgets/timeline/track.hpp @@ -42,7 +42,7 @@ class Track virtual Gtk::Widget& get_header_widget() = 0; - virtual int get_height(); + virtual int get_height() = 0; virtual void draw_track(Cairo::RefPtr cairo); diff --git a/src/gui/widgets/timeline/video-track.cpp b/src/gui/widgets/timeline/video-track.cpp index b20992543..4242f0e3f 100644 --- a/src/gui/widgets/timeline/video-track.cpp +++ b/src/gui/widgets/timeline/video-track.cpp @@ -32,22 +32,20 @@ namespace timeline { VideoTrack::VideoTrack() : headerWidget("HeaderTest") { - headerFrame.add(headerWidget); - headerFrame.set_shadow_type (Gtk::SHADOW_ETCHED_OUT); - headerFrame.set_name ("TimelineHeaderBaseUnselected"); + } Gtk::Widget& VideoTrack::get_header_widget() { - return headerFrame; + return headerWidget; } -/*int +int VideoTrack::get_height() { return 100; - }*/ + } void VideoTrack::draw_track(Cairo::RefPtr cairo) diff --git a/src/gui/widgets/timeline/video-track.hpp b/src/gui/widgets/timeline/video-track.hpp index fad2f77af..d72b4b1c9 100644 --- a/src/gui/widgets/timeline/video-track.hpp +++ b/src/gui/widgets/timeline/video-track.hpp @@ -40,7 +40,7 @@ class VideoTrack : public Track virtual Gtk::Widget& get_header_widget(); - //virtual int get_height(); + virtual int get_height(); virtual void draw_track(Cairo::RefPtr cairo); From 3952e27a8fbd4e083854136c5b5c5dc5fa5948c6 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Fri, 6 Jun 2008 00:30:31 +0100 Subject: [PATCH 130/245] Removed RefPtrs to make code more elegant --- src/gui/widgets/timeline-widget.cpp | 23 ++++++++++++----------- src/gui/widgets/timeline-widget.hpp | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index db8bcd614..5b3e73faa 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -42,19 +42,17 @@ TimelineWidget::TimelineWidget() : verticalScroll(verticalAdjustment), ruler("ruler") { - TimelineBody *body_ptr = new TimelineBody(this); - body = Glib::RefPtr(body_ptr); - g_assert(body); - HeaderContainer *header_container_ptr = new HeaderContainer(this); - headerContainer = Glib::RefPtr(header_container_ptr); - g_assert(headerContainer); + body = new TimelineBody(this); + g_assert(body != NULL); + headerContainer = new HeaderContainer(this); + g_assert(headerContainer != NULL); verticalAdjustment.signal_value_changed().connect( sigc::mem_fun(this, &TimelineWidget::on_scroll) ); - attach(*body_ptr, 1, 2, 1, 2, FILL|EXPAND, FILL|EXPAND); + attach(*body, 1, 2, 1, 2, FILL|EXPAND, FILL|EXPAND); attach(ruler, 1, 2, 0, 1, FILL|EXPAND, SHRINK); - attach(*header_container_ptr, 0, 1, 1, 2, SHRINK, FILL|EXPAND); + attach(*headerContainer, 0, 1, 1, 2, SHRINK, FILL|EXPAND); attach(horizontalScroll, 1, 2, 2, 3, FILL|EXPAND, SHRINK); attach(verticalScroll, 2, 3, 1, 2, SHRINK, FILL|EXPAND); @@ -66,7 +64,10 @@ TimelineWidget::TimelineWidget() : TimelineWidget::~TimelineWidget() { - + g_assert(body != NULL); + body->unreference(); + g_assert(headerContainer != NULL); + headerContainer->unreference(); } void @@ -86,7 +87,7 @@ TimelineWidget::on_size_allocate(Allocation& allocation) void TimelineWidget::update_tracks() { - g_assert(headerContainer); + g_assert(headerContainer != NULL); headerContainer->update_headers(); // Recalculate the total height of the timeline scrolled area @@ -103,7 +104,7 @@ TimelineWidget::update_tracks() void TimelineWidget::update_scroll() { - g_assert(body); + g_assert(body != NULL); const Allocation body_allocation = body->get_allocation(); // Calculate the length that can be scrolled: diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp index cd752060a..502b3c535 100644 --- a/src/gui/widgets/timeline-widget.hpp +++ b/src/gui/widgets/timeline-widget.hpp @@ -67,8 +67,8 @@ class TimelineWidget : public Gtk::Table timeline::VideoTrack video2; std::vector tracks; - Glib::RefPtr body; - Glib::RefPtr headerContainer; + timeline::TimelineBody *body; + timeline::HeaderContainer *headerContainer; Gtk::Label ruler; Gtk::Adjustment horizontalAdjustment, verticalAdjustment; From 98df76e919ec0b712e602726e587f0d0497013e3 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 7 Jun 2008 12:09:22 +0100 Subject: [PATCH 131/245] Added some documentation, and made a minor code correction in layout_headers --- src/gui/widgets/timeline-widget.cpp | 4 +- src/gui/widgets/timeline/header-container.cpp | 38 ++++++++----- src/gui/widgets/timeline/header-container.hpp | 57 ++++++++++++++++++- 3 files changed, 81 insertions(+), 18 deletions(-) diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index 5b3e73faa..799f1c736 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -107,7 +107,9 @@ TimelineWidget::update_scroll() g_assert(body != NULL); const Allocation body_allocation = body->get_allocation(); - // Calculate the length that can be scrolled: + //----- Vertical Scroll -----// + + // Calculate the vertical length that can be scrolled: // the total height of all the tracks minus one screenful int y_scroll_length = totalHeight - body_allocation.get_height(); if(y_scroll_length < 0) y_scroll_length = 0; diff --git a/src/gui/widgets/timeline/header-container.cpp b/src/gui/widgets/timeline/header-container.cpp index 40c92698b..a33562841 100644 --- a/src/gui/widgets/timeline/header-container.cpp +++ b/src/gui/widgets/timeline/header-container.cpp @@ -35,9 +35,11 @@ namespace timeline { HeaderContainer::HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline_widget) : timelineWidget(timeline_widget) { - set_flags(Gtk::NO_WINDOW); + set_flags(Gtk::NO_WINDOW); // This widget will not have a window at first set_redraw_on_allocate(false); + // Connect to the timeline widget's vertical scroll event, + // so that we get notified when the view shifts timelineWidget->verticalAdjustment.signal_value_changed().connect( sigc::mem_fun(this, &HeaderContainer::on_scroll) ); } @@ -47,8 +49,8 @@ HeaderContainer::update_headers() { g_assert(timelineWidget != NULL); - vector &tracks = timelineWidget->tracks; - vector::iterator i; + vector< Track* > &tracks = timelineWidget->tracks; + vector< Track* >::iterator i; for(i = tracks.begin(); i != tracks.end(); i++) { timeline::Track *track = *i; @@ -61,7 +63,8 @@ HeaderContainer::update_headers() headerFrame->set_parent(*this); headerFrame->show(); - rootHeaders.push_back(headerFrame); + const RootHeader header = { headerFrame, track }; + rootHeaders.push_back(header); } layout_headers(); @@ -93,7 +96,7 @@ HeaderContainer::on_realize() attributes.window_type = GDK_WINDOW_CHILD; attributes.wclass = GDK_INPUT_OUTPUT; - gdkWindow = Gdk::Window::create(get_window() /* parent */, &attributes, + gdkWindow = Gdk::Window::create(get_window(), &attributes, GDK_WA_X | GDK_WA_Y); unset_flags(Gtk::NO_WINDOW); set_window(gdkWindow); @@ -108,16 +111,17 @@ HeaderContainer::on_realize() void HeaderContainer::on_unrealize() { + // Unreference any window we may have created gdkWindow.clear(); - //Call base class: + // Call base class: Gtk::Widget::on_unrealize(); } void HeaderContainer::on_size_request (Requisition* requisition) { - //Initialize the output parameter: + // Initialize the output parameter: *requisition = Gtk::Requisition(); requisition->width = TimelineWidget::HeaderWidth; @@ -142,18 +146,20 @@ void HeaderContainer::forall_vfunc(gboolean /* include_internals */, GtkCallback callback, gpointer callback_data) { - vector< Glib::RefPtr >::iterator i; + vector< RootHeader >::iterator i; for(i = rootHeaders.begin(); i != rootHeaders.end(); i++) { - Glib::RefPtr header = *i; - g_assert(header); - callback(header->gobj(), callback_data); + RootHeader header = *i; + g_assert(header.widget); + callback(header.widget->gobj(), callback_data); } } void HeaderContainer::on_scroll() { + // If the scroll has changed, we will have to shift all the + // header widgets layout_headers(); } @@ -167,19 +173,21 @@ HeaderContainer::layout_headers() const Allocation container_allocation = get_allocation(); - vector >::iterator i; + vector< RootHeader >::iterator i; for(i = rootHeaders.begin(); i != rootHeaders.end(); i++) { - Glib::RefPtr header = *i; + RootHeader header = *i; + g_assert(header.widget); + g_assert(header.track != NULL); - const int height = 100;//header->get_track_height(); + const int height = header.track->get_height(); Gtk::Allocation header_allocation; header_allocation.set_x (0); header_allocation.set_y (offset - y_scroll_offset); header_allocation.set_width (container_allocation.get_width ()); header_allocation.set_height (height); - header->size_allocate(header_allocation); + header.widget->size_allocate(header_allocation); offset += height + TimelineWidget::TrackPadding; } diff --git a/src/gui/widgets/timeline/header-container.hpp b/src/gui/widgets/timeline/header-container.hpp index ed8fb82e8..69d13b953 100644 --- a/src/gui/widgets/timeline/header-container.hpp +++ b/src/gui/widgets/timeline/header-container.hpp @@ -38,13 +38,34 @@ class TimelineWidget; namespace timeline { +class Track; + +/** + * A helper class for the TimelineWidget. HeaderContainer is + * container widget for all the left-hand-side header widgets + * associated with timeline tracks. + */ class HeaderContainer : public Gtk::Container { public: + /** + * Constructor + * + * @param[in] timeline_widget A pointer to the owner timeline widget + */ HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline_widget); + /** + * Attaches the header all the header widgets of root + * tracks to this control. + * + * @note This must be called when the track list changes + * to synchronise the headers with the timeline body and + * the backend. + */ void update_headers(); + /* ===== Overrides ===== */ private: void on_realize(); void on_unrealize(); @@ -54,17 +75,49 @@ class HeaderContainer : public Gtk::Container void forall_vfunc(gboolean include_internals, GtkCallback callback, gpointer callback_data); - + + /* ===== Events ===== */ + private: void on_scroll(); /* ===== Internals ===== */ private: + + /** + * Moves all the header widgets to the correct position + * given scroll, stacking etc. + */ void layout_headers(); private: + + /** + * The owner TimelineWidget of which this class is a helper + */ lumiera::gui::widgets::TimelineWidget *timelineWidget; - std::vector< Glib::RefPtr > rootHeaders; + /** + * A structure to represent a header widget and it's + * associated track + */ + struct RootHeader + { + Glib::RefPtr widget; + Track *track; + }; + + /** + * Contains a list of the root currently present on + * the timeline view + */ + std::vector< RootHeader > rootHeaders; + + /** + * The widget's window object. + * + * @note This is needed for the sake of clipping when + * widgets are scrolled. + */ Glib::RefPtr gdkWindow; }; From 3b9d05a67d8570c7fb2135ee7dbd85ce0e05ec60 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 7 Jun 2008 13:53:17 +0100 Subject: [PATCH 133/245] Made use of boost and nobug, added some documentation, and tidied code --- src/gui/dialogs/render.cpp | 6 +- src/gui/gtk-lumiera.cpp | 9 +- src/gui/gtk-lumiera.hpp | 3 + src/gui/output/displayer.cpp | 55 ++-- src/gui/output/displayer.hpp | 36 +- src/gui/output/gdkdisplayer.cpp | 64 ++-- src/gui/output/gdkdisplayer.hpp | 2 +- src/gui/output/xvdisplayer.cpp | 311 +++++++++--------- src/gui/widgets/timeline-widget.cpp | 20 +- src/gui/widgets/timeline-widget.hpp | 2 +- src/gui/widgets/timeline/header-container.cpp | 30 +- src/gui/widgets/timeline/timeline-body.cpp | 43 ++- src/gui/widgets/video-display-widget.cpp | 21 +- src/gui/workspace/actions.hpp | 2 +- src/gui/workspace/workspace-window.cpp | 32 +- 15 files changed, 338 insertions(+), 298 deletions(-) diff --git a/src/gui/dialogs/render.cpp b/src/gui/dialogs/render.cpp index 6fadd82fb..25dafdc88 100644 --- a/src/gui/dialogs/render.cpp +++ b/src/gui/dialogs/render.cpp @@ -41,7 +41,7 @@ namespace dialogs { videoFrame(_("Video")) { VBox *v_box = get_vbox(); - g_assert(v_box != NULL); + ASSERT(v_box != NULL); // The Output File Row outputFileHBox.pack_start(outputFileLabel, PACK_SHRINK); @@ -91,9 +91,9 @@ namespace dialogs { dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); int result = dialog.run(); - g_message("%d", result); + INFO(gui, "%d", result); if(result == RESPONSE_OK) - g_message("RESPONSE_OK"); + INFO(gui, "%d", "RESPONSE_OK"); } } // namespace dialogs diff --git a/src/gui/gtk-lumiera.cpp b/src/gui/gtk-lumiera.cpp index 7178c4170..69cfe0a4a 100644 --- a/src/gui/gtk-lumiera.cpp +++ b/src/gui/gtk-lumiera.cpp @@ -21,6 +21,7 @@ * *****************************************************/ #include +#include #ifdef ENABLE_NLS # include @@ -31,6 +32,8 @@ #include "workspace/workspace-window.hpp" #include "model/project.hpp" +NOBUG_CPP_DEFINE_FLAG(gui); + using namespace Gtk; using namespace lumiera::gui; using namespace lumiera::gui::workspace; @@ -38,8 +41,8 @@ using namespace lumiera::gui::model; GtkLumiera the_application; - int - main (int argc, char *argv[]) +int +main (int argc, char *argv[]) { return the_application.main(argc, argv); } @@ -52,6 +55,8 @@ namespace gui { int GtkLumiera::main(int argc, char *argv[]) { + NOBUG_INIT; + Main kit(argc, argv); Glib::set_application_name(AppTitle); diff --git a/src/gui/gtk-lumiera.hpp b/src/gui/gtk-lumiera.hpp index a3586e0d1..6cf7d3acc 100644 --- a/src/gui/gtk-lumiera.hpp +++ b/src/gui/gtk-lumiera.hpp @@ -29,6 +29,9 @@ #define GTK_LUMIERA_HPP #include +#include + +NOBUG_DECLARE_FLAG(gui); #ifdef ENABLE_NLS # include diff --git a/src/gui/output/displayer.cpp b/src/gui/output/displayer.cpp index 567bc8748..f2b036116 100644 --- a/src/gui/output/displayer.cpp +++ b/src/gui/output/displayer.cpp @@ -22,6 +22,7 @@ * *****************************************************/ +#include "../gtk-lumiera.hpp" #include "displayer.hpp" #include "xvdisplayer.hpp" #include "gdkdisplayer.hpp" @@ -32,43 +33,53 @@ namespace output { bool Displayer::usable() -{ - return false; -} + { + return false; + } DisplayerInput Displayer::format() -{ - return DISPLAY_NONE; -} + { + return DISPLAY_NONE; + } int Displayer::preferredWidth() -{ - return imageWidth; -} + { + return imageWidth; + } int Displayer::preferredHeight() -{ - return imageHeight; -} + { + return imageHeight; + } void Displayer::calculateVideoLayout( int widget_width, int widget_height, int image_width, int image_height, int &video_x, int &video_y, int &video_width, int &video_height ) -{ - double ratio_width = ( double ) widget_width / ( double ) image_width; - double ratio_height = ( double ) widget_height / ( double ) image_height; - double ratio_constant = ratio_height < ratio_width ? - ratio_height : ratio_width; - video_width = ( int ) ( image_width * ratio_constant + 0.5 ); - video_height = ( int ) ( image_height * ratio_constant + 0.5 ); - video_x = ( widget_width - video_width ) / 2; - video_y = ( widget_height - video_height ) / 2; -} + { + REQUIRE(widget_width >= 0); + REQUIRE(widget_height >= 0); + REQUIRE(image_width >= 0); + REQUIRE(image_height >= 0); + + double ratio_width = ( double ) widget_width / ( double ) image_width; + double ratio_height = ( double ) widget_height / ( double ) image_height; + double ratio_constant = ratio_height < ratio_width ? + ratio_height : ratio_width; + video_width = ( int ) ( image_width * ratio_constant + 0.5 ); + video_height = ( int ) ( image_height * ratio_constant + 0.5 ); + video_x = ( widget_width - video_width ) / 2; + video_y = ( widget_height - video_height ) / 2; + + ENSURE(video_x >= 0 && video_x < widget_width) + ENSURE(video_y >= 0 && video_y < widget_height) + ENSURE(video_width <= widget_width) + ENSURE(video_width <= widget_width) + } } // namespace output } // namespace gui diff --git a/src/gui/output/displayer.hpp b/src/gui/output/displayer.hpp index c117d5cb9..2441c0798 100644 --- a/src/gui/output/displayer.hpp +++ b/src/gui/output/displayer.hpp @@ -38,8 +38,7 @@ namespace output { #define MAX_HEIGHT 576 /** Supported Displayer formats - */ - + */ typedef enum { DISPLAY_NONE, DISPLAY_YUV, @@ -68,14 +67,14 @@ namespace output { If the widget being written to doesn't need a fixed size, then rewrite the two other put methods as required. - */ + */ class Displayer { public: /** Indicates if an object can be used to render images on the running system. - */ + */ virtual bool usable(); /** Indicates the format required by the abstract put method. @@ -83,22 +82,37 @@ namespace output { virtual DisplayerInput format(); /** Expected width of input to put. - */ + */ virtual int preferredWidth(); /** Expected height of input to put. - */ + */ virtual int preferredHeight(); - /** Put an image of a given width and height with the expected input - format (as indicated by the format method). - - \param image image of correct format and specified width/height - */ + /** + * Put an image of a given width and height with the expected input + * format (as indicated by the format method). + * + * @param image image of correct format and specified width/height + */ virtual void put( void * ) = 0; protected: + /** + * Calculates the coordinates for placing a video image inside a widget + * + * @param[in] widget_width The width of the display widget + * @param[in] widget_height The height of the display widget + * @param[in] image_width The width of the video image + * @param[in] image_height The height of the video image + * @param[out] video_x The x-coordinate of the top left corner of + * the scaled video image + * @param[out] video_y The y-coordinate of the top left corner of + * the scaled video image + * @param[out] video_width The width of the scale video image + * @param[out] video_height The height of the scale video image + */ static void calculateVideoLayout( int widget_width, int widget_height, int image_width, int image_height, diff --git a/src/gui/output/gdkdisplayer.cpp b/src/gui/output/gdkdisplayer.cpp index 262d28d5b..68ad6d545 100644 --- a/src/gui/output/gdkdisplayer.cpp +++ b/src/gui/output/gdkdisplayer.cpp @@ -22,11 +22,8 @@ * *****************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif +#include "../gtk-lumiera.hpp" -#include #include #include using std::cerr; @@ -40,36 +37,49 @@ namespace output { GdkDisplayer::GdkDisplayer( Gtk::Widget *drawing_area, int width, int height ) : drawingArea( drawing_area ) -{ - imageWidth = width, imageHeight = height; -} + { + REQUIRE(drawing_area != NULL); + REQUIRE(imageWidth > 0); + REQUIRE(imageHeight > 0); + + imageWidth = width, imageHeight = height; + } bool GdkDisplayer::usable() -{ - return true; -} + { + return true; + } void GdkDisplayer::put( void *image ) -{ - int video_x = 0, video_y = 0, video_width = 0, video_height = 0; - calculateVideoLayout( - drawingArea->get_width(), - drawingArea->get_height(), - preferredWidth(), preferredHeight(), - video_x, video_y, video_width, video_height ); + { + int video_x = 0, video_y = 0, video_width = 0, video_height = 0; + calculateVideoLayout( + drawingArea->get_width(), + drawingArea->get_height(), + preferredWidth(), preferredHeight(), + video_x, video_y, video_width, video_height ); - GdkWindow *window = drawingArea->get_window()->gobj(); - GdkGC *gc = gdk_gc_new( window ); - GdkPixbuf *pix = gdk_pixbuf_new_from_data( (const guchar*)image, GDK_COLORSPACE_RGB, FALSE, 8, - preferredWidth(), preferredHeight(), preferredWidth() * 3, NULL, NULL ); - GdkPixbuf *im = gdk_pixbuf_scale_simple( pix, video_width, video_height, GDK_INTERP_NEAREST ); - gdk_draw_pixbuf( window, gc, im, 0, 0, video_x, video_y, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0 ); - g_object_unref( im ); - g_object_unref( pix ); - g_object_unref( gc ); -} + GdkWindow *window = drawingArea->get_window()->gobj(); + ASSERT(window != NULL); + + GdkGC *gc = gdk_gc_new( window ); + ASSERT(gc != NULL); + + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( (const guchar*)image, GDK_COLORSPACE_RGB, FALSE, 8, + preferredWidth(), preferredHeight(), preferredWidth() * 3, NULL, NULL ); + ASSERT(pixbuf != NULL); + + GdkPixbuf *scaled_image = gdk_pixbuf_scale_simple( pixbuf, video_width, video_height, GDK_INTERP_NEAREST ); + ASSERT(scaled_image != NULL); + + gdk_draw_pixbuf( window, gc, scaled_image, 0, 0, video_x, video_y, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0 ); + + g_object_unref( scaled_image ); + g_object_unref( pixbuf ); + g_object_unref( gc ); + } } // namespace output } // namespace gui diff --git a/src/gui/output/gdkdisplayer.hpp b/src/gui/output/gdkdisplayer.hpp index 7e72fa24e..40ef3b547 100644 --- a/src/gui/output/gdkdisplayer.hpp +++ b/src/gui/output/gdkdisplayer.hpp @@ -41,7 +41,7 @@ namespace lumiera { namespace gui { namespace output { - class GdkDisplayer : public Displayer +class GdkDisplayer : public Displayer { public: GdkDisplayer( Gtk::Widget *drawing_area, int width, int height ); diff --git a/src/gui/output/xvdisplayer.cpp b/src/gui/output/xvdisplayer.cpp index 428decc62..cf7eeb53f 100644 --- a/src/gui/output/xvdisplayer.cpp +++ b/src/gui/output/xvdisplayer.cpp @@ -22,15 +22,9 @@ * *****************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif +#include "../gtk-lumiera.hpp" -#include #include -#include -using std::cerr; -using std::endl; #include "xvdisplayer.hpp" @@ -42,191 +36,190 @@ XvDisplayer::XvDisplayer( Gtk::Widget *drawing_area, int width, int height ) : xvImage( NULL ), drawingArea( drawing_area ), gotPort( false ) -{ - cerr << ">> Trying XVideo at " << width << "x" << height << endl; - - imageWidth = width, imageHeight = height; - - shmInfo.shmaddr = NULL; - - Glib::RefPtr area_window = drawing_area->get_window(); - - window = gdk_x11_drawable_get_xid( area_window->gobj() ); - display = gdk_x11_drawable_get_xdisplay( area_window->gobj() ); - - unsigned int count; - XvAdaptorInfo *adaptorInfo; - - if ( XvQueryAdaptors( display, window, &count, &adaptorInfo ) == Success ) { + INFO(gui, "Trying XVideo at %d x %d", width, height); - cerr << ">>> XvQueryAdaptors count: " << count << endl; - for ( unsigned int n = 0; gotPort == false && n < count; ++n ) - { - // Diagnostics - cerr << ">>> Xv: " << adaptorInfo[ n ].name - << ": ports " << adaptorInfo[ n ].base_id - << " - " << adaptorInfo[ n ].base_id + - adaptorInfo[ n ].num_ports - 1 - << endl; + imageWidth = width, imageHeight = height; - for ( port = adaptorInfo[ n ].base_id; - port < adaptorInfo[ n ].base_id + adaptorInfo[ n ].num_ports; - port ++ ) + shmInfo.shmaddr = NULL; + + Glib::RefPtr area_window = drawing_area->get_window(); + + window = gdk_x11_drawable_get_xid( area_window->gobj() ); + display = gdk_x11_drawable_get_xdisplay( area_window->gobj() ); + + unsigned int count; + XvAdaptorInfo *adaptorInfo; + + if ( XvQueryAdaptors( display, window, &count, &adaptorInfo ) == Success ) { - if ( XvGrabPort( display, port, CurrentTime ) == Success ) - { - g_message("XvGrabPort == 0"); - int formats; - XvImageFormatValues *list; - list = XvListImageFormats( display, port, &formats ); - - cerr << ">>> formats supported: " << formats << endl; - - for ( int i = 0; i < formats; i ++ ) + INFO(gui, "XvQueryAdaptors count: %d", count); + for ( unsigned int n = 0; gotPort == false && n < count; ++n ) { - fprintf( stderr, ">>> 0x%x (%c%c%c%c) %s\n", - list[ i ].id, - ( list[ i ].id ) & 0xff, - ( list[ i ].id >> 8 ) & 0xff, - ( list[ i ].id >> 16 ) & 0xff, - ( list[ i ].id >> 24 ) & 0xff, - ( list[ i ].format == XvPacked ) ? "packed" : "planar" ); - if ( list[ i ].id == 0x32595559 && !gotPort ) - gotPort = true; + // Diagnostics + INFO(gui, "%s, %d, %d, %d", adaptorInfo[ n ].name, + adaptorInfo[ n ].base_id, adaptorInfo[ n ].num_ports - 1); + + for ( port = adaptorInfo[ n ].base_id; + port < adaptorInfo[ n ].base_id + adaptorInfo[ n ].num_ports; + port ++ ) + { + if ( XvGrabPort( display, port, CurrentTime ) == Success ) + { + int formats; + XvImageFormatValues *list; + + list = XvListImageFormats( display, port, &formats ); + + INFO(gui, "formats supported: %d", formats); + + for ( int i = 0; i < formats; i ++ ) + { + INFO(gui, "0x%x (%c%c%c%c) %s", + list[ i ].id, + ( list[ i ].id ) & 0xff, + ( list[ i ].id >> 8 ) & 0xff, + ( list[ i ].id >> 16 ) & 0xff, + ( list[ i ].id >> 24 ) & 0xff, + ( list[ i ].format == XvPacked ) ? "packed" : "planar" ); + if ( list[ i ].id == 0x32595559 && !gotPort ) + gotPort = true; + } + + if ( !gotPort ) + { + XvUngrabPort( display, port, CurrentTime ); + } + else + { + grabbedPort = port; + break; + } + } + } } - if ( !gotPort ) + if ( gotPort ) { - XvUngrabPort( display, port, CurrentTime ); + int num; + unsigned int unum; + XvEncodingInfo *enc; + + XvQueryEncodings( display, grabbedPort, &unum, &enc ); + for ( unsigned int index = 0; index < unum; index ++ ) + { + INFO(gui, "%d: %s, %ldx%ld rate = %d/%d", index, enc->name, + enc->width, enc->height, enc->rate.numerator, + enc->rate.denominator ); + } + + XvAttribute *xvattr = XvQueryPortAttributes( display, port, &num ); + for ( int k = 0; k < num; k++ ) + { + if ( xvattr[k].flags & XvSettable ) + { + if ( strcmp( xvattr[k].name, "XV_AUTOPAINT_COLORKEY") == 0 ) + { + Atom val_atom = XInternAtom( display, xvattr[k].name, False ); + if ( XvSetPortAttribute( display, port, val_atom, 1 ) != Success ) + ERROR(gui, "Couldn't set Xv attribute %s\n", xvattr[k].name); + } + else if ( strcmp( xvattr[k].name, "XV_COLORKEY") == 0 ) + { + Atom val_atom = XInternAtom( display, xvattr[k].name, False ); + if ( XvSetPortAttribute( display, port, val_atom, 0x010102 ) != Success ) + ERROR(gui, "Couldn't set Xv attribute %s\n", xvattr[k].name); + } + } + } } - else + + if ( gotPort ) { - grabbedPort = port; - break; - } - } - } - } + gc = XCreateGC( display, window, 0, &values ); - if ( gotPort ) - { - int num; - unsigned int unum; - XvEncodingInfo *enc; - - XvQueryEncodings( display, grabbedPort, &unum, &enc ); - for ( unsigned int index = 0; index < unum; index ++ ) - { - fprintf( stderr, ">>> %d: %s, %ldx%ld rate = %d/%d\n", index, enc->name, - enc->width, enc->height, enc->rate.numerator, - enc->rate.denominator ); - } - - XvAttribute *xvattr = XvQueryPortAttributes( display, port, &num ); - for ( int k = 0; k < num; k++ ) - { - if ( xvattr[k].flags & XvSettable ) - { - if ( strcmp( xvattr[k].name, "XV_AUTOPAINT_COLORKEY") == 0 ) - { - Atom val_atom = XInternAtom( display, xvattr[k].name, False ); - if ( XvSetPortAttribute( display, port, val_atom, 1 ) != Success ) - fprintf(stderr, "Couldn't set Xv attribute %s\n", xvattr[k].name); - } - else if ( strcmp( xvattr[k].name, "XV_COLORKEY") == 0 ) - { - Atom val_atom = XInternAtom( display, xvattr[k].name, False ); - if ( XvSetPortAttribute( display, port, val_atom, 0x010102 ) != Success ) - fprintf(stderr, "Couldn't set Xv attribute %s\n", xvattr[k].name); - } - } - } - } + xvImage = ( XvImage * ) XvShmCreateImage( display, port, 0x32595559, 0, width, height, &shmInfo ); - if ( gotPort ) - { - gc = XCreateGC( display, window, 0, &values ); - - xvImage = ( XvImage * ) XvShmCreateImage( display, port, 0x32595559, 0, width, height, &shmInfo ); - - shmInfo.shmid = shmget( IPC_PRIVATE, xvImage->data_size, IPC_CREAT | 0777 ); - if (shmInfo.shmid < 0) { - perror("shmget"); - gotPort = false; - } else { - shmInfo.shmaddr = ( char * ) shmat( shmInfo.shmid, 0, 0 ); - xvImage->data = shmInfo.shmaddr; - shmInfo.readOnly = 0; - if ( !XShmAttach( gdk_display, &shmInfo ) ) - { - gotPort = false; - } - XSync( display, false ); - shmctl( shmInfo.shmid, IPC_RMID, 0 ); + shmInfo.shmid = shmget( IPC_PRIVATE, xvImage->data_size, IPC_CREAT | 0777 ); + if (shmInfo.shmid < 0) { + perror("shmget"); + gotPort = false; + } + else + { + shmInfo.shmaddr = ( char * ) shmat( shmInfo.shmid, 0, 0 ); + xvImage->data = shmInfo.shmaddr; + shmInfo.readOnly = 0; + if ( !XShmAttach( gdk_display, &shmInfo ) ) + { + gotPort = false; + } + XSync( display, false ); + shmctl( shmInfo.shmid, IPC_RMID, 0 ); #if 0 - xvImage = ( XvImage * ) XvCreateImage( display, port, 0x32595559, pix, width , height ); + xvImage = ( XvImage * ) XvCreateImage( display, port, 0x32595559, pix, width , height ); #endif + } + } + } + else + { + gotPort = false; } - } } - else - { - gotPort = false; - } -} XvDisplayer::~XvDisplayer() -{ - cerr << ">> Destroying XV Displayer" << endl; - - if ( gotPort ) { - XvUngrabPort( display, grabbedPort, CurrentTime ); - } + ERROR(gui, "Destroying XV Displayer"); - //if ( xvImage != NULL ) - // XvStopVideo( display, port, window ); + if ( gotPort ) + { + XvUngrabPort( display, grabbedPort, CurrentTime ); + } - if ( shmInfo.shmaddr != NULL ) - { - XShmDetach( display, &shmInfo ); - shmctl( shmInfo.shmid, IPC_RMID, 0 ); - shmdt( shmInfo.shmaddr ); + //if ( xvImage != NULL ) + // XvStopVideo( display, port, window ); + + if ( shmInfo.shmaddr != NULL ) + { + XShmDetach( display, &shmInfo ); + shmctl( shmInfo.shmid, IPC_RMID, 0 ); + shmdt( shmInfo.shmaddr ); + } + + if ( xvImage != NULL ) + XFree( xvImage ); } - - if ( xvImage != NULL ) - XFree( xvImage ); -} bool XvDisplayer::usable() -{ - return gotPort; -} + { + return gotPort; + } void XvDisplayer::put( void *image ) -{ - g_assert(drawingArea != NULL); - - if(xvImage != NULL) { - int video_x = 0, video_y = 0, video_width = 0, video_height = 0; - calculateVideoLayout( - drawingArea->get_width(), - drawingArea->get_height(), - preferredWidth(), preferredHeight(), - video_x, video_y, video_width, video_height ); + REQUIRE(image != NULL); + ASSERT(drawingArea != NULL); + + if(xvImage != NULL) + { + int video_x = 0, video_y = 0, video_width = 0, video_height = 0; + calculateVideoLayout( + drawingArea->get_width(), + drawingArea->get_height(), + preferredWidth(), preferredHeight(), + video_x, video_y, video_width, video_height ); - memcpy( xvImage->data, image, xvImage->data_size ); + memcpy( xvImage->data, image, xvImage->data_size ); - XvShmPutImage( display, port, window, gc, xvImage, - 0, 0, preferredWidth(), preferredHeight(), - video_x, video_y, video_width, video_height, false ); + XvShmPutImage( display, port, window, gc, xvImage, + 0, 0, preferredWidth(), preferredHeight(), + video_x, video_y, video_width, video_height, false ); + } } -} } // namespace output } // namespace gui diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index 799f1c736..240cb09fb 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -22,6 +22,8 @@ #include "timeline-widget.hpp" +#include + using namespace Gtk; using namespace std; using namespace lumiera::gui::widgets::timeline; @@ -43,9 +45,9 @@ TimelineWidget::TimelineWidget() : ruler("ruler") { body = new TimelineBody(this); - g_assert(body != NULL); + ASSERT(body != NULL); headerContainer = new HeaderContainer(this); - g_assert(headerContainer != NULL); + ASSERT(headerContainer != NULL); verticalAdjustment.signal_value_changed().connect( sigc::mem_fun(this, &TimelineWidget::on_scroll) ); @@ -64,9 +66,9 @@ TimelineWidget::TimelineWidget() : TimelineWidget::~TimelineWidget() { - g_assert(body != NULL); + ASSERT(body != NULL); body->unreference(); - g_assert(headerContainer != NULL); + ASSERT(headerContainer != NULL); headerContainer->unreference(); } @@ -87,16 +89,14 @@ TimelineWidget::on_size_allocate(Allocation& allocation) void TimelineWidget::update_tracks() { - g_assert(headerContainer != NULL); + ASSERT(headerContainer != NULL); headerContainer->update_headers(); // Recalculate the total height of the timeline scrolled area totalHeight = 0; - vector::iterator i; - for(i = tracks.begin(); i != tracks.end(); i++) + BOOST_FOREACH( Track* track, tracks ) { - timeline::Track *track = *i; - g_assert(track != NULL); + ASSERT(track != NULL); totalHeight += track->get_height() + TrackPadding; } } @@ -104,7 +104,7 @@ TimelineWidget::update_tracks() void TimelineWidget::update_scroll() { - g_assert(body != NULL); + ASSERT(body != NULL); const Allocation body_allocation = body->get_allocation(); //----- Vertical Scroll -----// diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp index 502b3c535..a53ef6368 100644 --- a/src/gui/widgets/timeline-widget.hpp +++ b/src/gui/widgets/timeline-widget.hpp @@ -26,12 +26,12 @@ #ifndef TIMELINE_WIDGET_HPP #define TIMELINE_WIDGET_HPP +#include "../gtk-lumiera.hpp" #include "timeline/header-container.hpp" #include "timeline/timeline-body.hpp" #include "timeline/track.hpp" #include "timeline/video-track.hpp" -#include #include namespace lumiera { diff --git a/src/gui/widgets/timeline/header-container.cpp b/src/gui/widgets/timeline/header-container.cpp index a33562841..a52393860 100644 --- a/src/gui/widgets/timeline/header-container.cpp +++ b/src/gui/widgets/timeline/header-container.cpp @@ -20,6 +20,8 @@ * *****************************************************/ +#include + #include "header-container.hpp" #include "track.hpp" #include "../timeline-widget.hpp" @@ -35,6 +37,8 @@ namespace timeline { HeaderContainer::HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline_widget) : timelineWidget(timeline_widget) { + REQUIRE(timeline_widget != NULL); + set_flags(Gtk::NO_WINDOW); // This widget will not have a window at first set_redraw_on_allocate(false); @@ -47,14 +51,11 @@ HeaderContainer::HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline void HeaderContainer::update_headers() { - g_assert(timelineWidget != NULL); + ASSERT(timelineWidget != NULL); - vector< Track* > &tracks = timelineWidget->tracks; - vector< Track* >::iterator i; - for(i = tracks.begin(); i != tracks.end(); i++) + BOOST_FOREACH( Track* track, timelineWidget->tracks ) { - timeline::Track *track = *i; - g_assert(track != NULL); + ASSERT(track != NULL); Glib::RefPtr headerFrame(new Gtk::Frame()); headerFrame->add(track->get_header_widget()); @@ -146,11 +147,9 @@ void HeaderContainer::forall_vfunc(gboolean /* include_internals */, GtkCallback callback, gpointer callback_data) { - vector< RootHeader >::iterator i; - for(i = rootHeaders.begin(); i != rootHeaders.end(); i++) + BOOST_FOREACH( RootHeader &header, rootHeaders ) { - RootHeader header = *i; - g_assert(header.widget); + ASSERT(header.widget); callback(header.widget->gobj(), callback_data); } } @@ -166,21 +165,20 @@ HeaderContainer::on_scroll() void HeaderContainer::layout_headers() { - g_assert(timelineWidget != NULL); + ASSERT(timelineWidget != NULL); int offset = 0; const int y_scroll_offset = timelineWidget->get_y_scroll_offset(); const Allocation container_allocation = get_allocation(); - vector< RootHeader >::iterator i; - for(i = rootHeaders.begin(); i != rootHeaders.end(); i++) + BOOST_FOREACH( RootHeader &header, rootHeaders ) { - RootHeader header = *i; - g_assert(header.widget); - g_assert(header.track != NULL); + ASSERT(header.widget); + ASSERT(header.track != NULL); const int height = header.track->get_height(); + ASSERT(height >= 0); Gtk::Allocation header_allocation; header_allocation.set_x (0); diff --git a/src/gui/widgets/timeline/timeline-body.cpp b/src/gui/widgets/timeline/timeline-body.cpp index 859abb0e8..bbcca9a02 100644 --- a/src/gui/widgets/timeline/timeline-body.cpp +++ b/src/gui/widgets/timeline/timeline-body.cpp @@ -21,6 +21,7 @@ * *****************************************************/ #include +#include #include "timeline-body.hpp" #include "../timeline-widget.hpp" @@ -39,7 +40,7 @@ TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widge Glib::ObjectBase("TimelineBody"), timelineWidget(timeline_widget) { - g_assert(timelineWidget != NULL); + REQUIRE(timelineWidget != NULL); // Connect up some events timelineWidget->horizontalAdjustment.signal_value_changed().connect( @@ -84,28 +85,26 @@ TimelineBody::on_expose_event(GdkEventExpose* event) -(int)timelineWidget->verticalAdjustment.get_value()); // Interate drawing each track - vector::iterator i; - for(i = timelineWidget->tracks.begin(); - i != timelineWidget->tracks.end(); i++) - { - timeline::Track *track = *i; - g_assert(track != NULL); + BOOST_FOREACH( Track* track, timelineWidget->tracks ) + { + ASSERT(track != NULL); - const int track_height = track->get_height(); - - // Draw the track background - cairo->rectangle(0, 0, allocation.get_width(), track_height); - gdk_cairo_set_source_color(cairo->cobj(), &track_background); - cairo->fill(); - - // Render the track - cairo->save(); - track->draw_track(cairo); - cairo->restore(); + const int height = track->get_height(); + ASSERT(height >= 0); - // Shift for the next track - cairo->translate(0, track_height + TimelineWidget::TrackPadding); - } + // Draw the track background + cairo->rectangle(0, 0, allocation.get_width(), height); + gdk_cairo_set_source_color(cairo->cobj(), &track_background); + cairo->fill(); + + // Render the track + cairo->save(); + track->draw_track(cairo); + cairo->restore(); + + // Shift for the next track + cairo->translate(0, height + TimelineWidget::TrackPadding); + } return true; } @@ -122,7 +121,7 @@ TimelineBody::read_styles() track_background = *colour; else { - g_warning("track_background style value failed to load"); + WARN(gui, "track_background style value failed to load"); track_background.red = 0x0000; track_background.green = 0x0000; track_background.blue = 0x0000; diff --git a/src/gui/widgets/video-display-widget.cpp b/src/gui/widgets/video-display-widget.cpp index 2c7be8111..cbd4b38fd 100644 --- a/src/gui/widgets/video-display-widget.cpp +++ b/src/gui/widgets/video-display-widget.cpp @@ -24,6 +24,8 @@ #include #include +#include "../gtk-lumiera.hpp" + #include "../output/xvdisplayer.hpp" #include "../output/gdkdisplayer.hpp" @@ -137,19 +139,22 @@ VideoDisplayWidget::on_expose_event(GdkEventExpose* event) Displayer* VideoDisplayWidget::createDisplayer( Gtk::Widget *drawingArea, int width, int height ) { + REQUIRE(drawingArea != NULL); + REQUIRE(width >= 0 && height >= 0); + Displayer *displayer = NULL; - + displayer = new XvDisplayer( drawingArea, width, height ); if ( !displayer->usable() ) - { - delete displayer; - displayer = NULL; - } + { + delete displayer; + displayer = NULL; + } if ( displayer == NULL ) - { - displayer = new GdkDisplayer( drawingArea, width, height ); - } + { + displayer = new GdkDisplayer( drawingArea, width, height ); + } return displayer; } diff --git a/src/gui/workspace/actions.hpp b/src/gui/workspace/actions.hpp index c68ce8de4..891ae7757 100644 --- a/src/gui/workspace/actions.hpp +++ b/src/gui/workspace/actions.hpp @@ -29,7 +29,7 @@ #ifndef ACTIONS_HPP #define ACTIONS_HPP -#include +#include "../gtk-lumiera.hpp" namespace lumiera { namespace gui { diff --git a/src/gui/workspace/workspace-window.cpp b/src/gui/workspace/workspace-window.cpp index c2c46d61b..3e72d20d6 100644 --- a/src/gui/workspace/workspace-window.cpp +++ b/src/gui/workspace/workspace-window.cpp @@ -42,22 +42,24 @@ namespace lumiera { namespace gui { namespace workspace { - WorkspaceWindow::WorkspaceWindow(Project *source_project) : - project(source_project), - actions(*this) +WorkspaceWindow::WorkspaceWindow(Project *source_project) : + project(source_project), + actions(*this) { + REQUIRE(source_project != NULL); + layout = NULL; create_ui(); } - WorkspaceWindow::~WorkspaceWindow() +WorkspaceWindow::~WorkspaceWindow() { if(layout != NULL) g_object_unref(layout); } - void - WorkspaceWindow::create_ui() +void +WorkspaceWindow::create_ui() { //----- Configure the Window -----// set_title(AppTitle); @@ -106,23 +108,23 @@ namespace workspace { ""; try - { - uiManager->add_ui_from_string(ui_info); - } + { + uiManager->add_ui_from_string(ui_info); + } catch(const Glib::Error& ex) - { - g_error("Building menus failed: %s", ex.what().data()); - return; - } + { + ERROR(gui, "Building menus failed: %s", ex.what().data()); + return; + } //----- Set up the Menu Bar -----// Gtk::Widget* menu_bar = uiManager->get_widget("/MenuBar"); - g_assert(menu_bar != NULL); + ASSERT(menu_bar != NULL); base_container.pack_start(*menu_bar, Gtk::PACK_SHRINK); //----- Set up the Tool Bar -----// Gtk::Toolbar* toolbar = dynamic_cast(uiManager->get_widget("/ToolBar")); - g_assert(toolbar != NULL); + ASSERT(toolbar != NULL); toolbar->set_toolbar_style(TOOLBAR_ICONS); base_container.pack_start(*toolbar, Gtk::PACK_SHRINK); From 6f6fab38dc6eb17d502aa3815f47ff9fbb5444d8 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Tue, 10 Jun 2008 23:46:11 +0100 Subject: [PATCH 134/245] Corrected somethings in configure.ac that were in wrong order --- configure.ac | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index b06820e0e..641741e83 100644 --- a/configure.ac +++ b/configure.ac @@ -120,17 +120,6 @@ AC_CHECK_HEADER([boost/regex.hpp], AC_LANG_POP([C++]) - -# Print a summary -AC_MSG_RESULT([ -Configuration Summary:]) -AC_MSG_RESULT([ NoBug build level: $nobug_level]) -# Add more summary results here - -AC_MSG_RESULT([ -Configuration complete, you can now build Lumiera with 'make' -]) - ############## Internatinalization #GETTEXT_PACKAGE=gtk-lumiera #AC_SUBST(GETTEXT_PACKAGE) @@ -176,6 +165,15 @@ AC_SUBST(GTK_LUMIERA_LIBS) # END Gtk Dependancies +# Print a summary +AC_MSG_RESULT([ +Configuration Summary:]) +AC_MSG_RESULT([ NoBug build level: $nobug_level]) +# Add more summary results here + +AC_MSG_RESULT([ +Configuration complete, you can now build Lumiera with 'make' +]) AC_CONFIG_FILES(Makefile) AC_OUTPUT From e8378485cc5e5f48c97813ffce9fcdcd9b070b2f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 11 Jun 2008 05:44:10 +0200 Subject: [PATCH 135/245] planning the buffer management and render mechanics more precisely --- doc/devel/uml/class131589.html | 2 +- doc/devel/uml/class131717.html | 9 +- doc/devel/uml/class131845.html | 2 +- doc/devel/uml/class131973.html | 2 +- doc/devel/uml/class132101.html | 2 +- doc/devel/uml/class132229.html | 2 +- doc/devel/uml/class132357.html | 2 +- doc/devel/uml/class132485.html | 2 +- doc/devel/uml/class132613.html | 2 +- doc/devel/uml/class132741.html | 9 +- doc/devel/uml/class132869.html | 1 + doc/devel/uml/class132997.html | 1 + doc/devel/uml/class133125.html | 1 + doc/devel/uml/class133765.html | 2 +- doc/devel/uml/class135045.html | 2 +- doc/devel/uml/class142213.html | 27 --- doc/devel/uml/class142469.html | 9 +- doc/devel/uml/class142597.html | 12 +- .../{class142341.html => class142725.html} | 4 +- .../{class142085.html => class143109.html} | 10 +- doc/devel/uml/class143237.html | 20 ++ doc/devel/uml/classdiagrams.html | 2 +- doc/devel/uml/classes.html | 10 +- doc/devel/uml/classes_list.html | 10 +- doc/devel/uml/collaborationdiagrams.html | 2 +- doc/devel/uml/fig131973.png | Bin 16309 -> 18410 bytes doc/devel/uml/fig132101.png | Bin 18071 -> 0 bytes doc/devel/uml/fig132229.png | Bin 0 -> 36167 bytes doc/devel/uml/index.html | 46 +++-- doc/devel/uml/index_60.html | 4 +- doc/devel/uml/index_65.html | 10 +- doc/devel/uml/index_66.html | 2 +- doc/devel/uml/index_67.html | 43 ++-- doc/devel/uml/index_69.html | 5 +- doc/devel/uml/index_70.html | 1 + doc/devel/uml/index_73.html | 3 +- doc/devel/uml/index_78.html | 4 +- doc/devel/uml/index_79.html | 2 +- doc/devel/uml/index_80.html | 7 +- doc/devel/uml/index_82.html | 8 +- doc/devel/uml/index_83.html | 10 +- doc/devel/uml/index_84.html | 4 +- doc/devel/uml/index_86.html | 20 +- doc/devel/uml/public_operations.html | 14 +- uml/lumiera/128389 | 141 +++++++++++++- uml/lumiera/128901 | 65 ++++++- uml/lumiera/129285 | 89 ++++++++- uml/lumiera/131973.diagram | 98 +++++----- uml/lumiera/132101.diagram | 91 --------- uml/lumiera/132229.diagram | 184 ++++++++++++++++++ uml/lumiera/5.session | 18 +- uml/lumiera/lumiera.prj | 2 +- wiki/renderengine.html | 59 ++++-- 53 files changed, 749 insertions(+), 328 deletions(-) delete mode 100644 doc/devel/uml/class142213.html rename doc/devel/uml/{class142341.html => class142725.html} (84%) rename doc/devel/uml/{class142085.html => class143109.html} (64%) create mode 100644 doc/devel/uml/class143237.html delete mode 100644 doc/devel/uml/fig132101.png create mode 100644 doc/devel/uml/fig132229.png delete mode 100644 uml/lumiera/132101.diagram create mode 100644 uml/lumiera/132229.diagram diff --git a/doc/devel/uml/class131589.html b/doc/devel/uml/class131589.html index beefcf13d..86ae3636b 100644 --- a/doc/devel/uml/class131589.html +++ b/doc/devel/uml/class131589.html @@ -18,6 +18,6 @@

    Declaration :

    The output of the render pipeline. Pulling from such exit nodes actually ivokes the render process

    Artifact : exitnode

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class131717.html b/doc/devel/uml/class131717.html index 8952f6f05..93a92a0b1 100644 --- a/doc/devel/uml/class131717.html +++ b/doc/devel/uml/class131717.html @@ -20,9 +20,10 @@

    Key abstraction of the Render Engine: A Data processing Node

    Artifact : procnode

    Relation datasrc (<unidirectional association>)

    Declaration :

    The predecessor in a processing pipeline, i.e. a source to get data to be processed

    -
    Relation params (<directional aggregation by value>)

    Declaration :

    -
    Operation pull

    Declaration :

    • Uml : + pull(inout renderProcess : State) : void
    • C++ : public: void pull ()

    trigger data processing by "pulling" results from the node's output

    -
    Relation predecessors (<directional aggregation by value>)

    Declaration :

    preconfigured table of all predecessor nodes, qualified
    with the output port on these nodes and time offset of the data
    we need for doing our calculations

    -

    All public operations : pull

    +
    Relation params (<directional aggregation by value>)

    Declaration :

    +
    Relation predecessors (<directional aggregation by value>)

    Declaration :

    +
    Operation pull

    Declaration :

    • Uml : + pull() :
    • C++ : public: pull ()
    +
    Operation process

    Declaration :

    • Uml : + process() :
    • C++ : public: process ()
    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class131845.html b/doc/devel/uml/class131845.html index c59787b25..1a439ca08 100644 --- a/doc/devel/uml/class131845.html +++ b/doc/devel/uml/class131845.html @@ -19,6 +19,6 @@

    Declaration :

    Directly inherited by : CodecAdapter Mask PluginAdapter Projector

    Artifact : trafo

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class131973.html b/doc/devel/uml/class131973.html index 82d637b48..0ed7acaef 100644 --- a/doc/devel/uml/class131973.html +++ b/doc/devel/uml/class131973.html @@ -19,6 +19,6 @@

    Declaration :

    Directly inherited by : GLPipe

    Artifact : link

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132101.html b/doc/devel/uml/class132101.html index 50eae3f1b..f385d98c0 100644 --- a/doc/devel/uml/class132101.html +++ b/doc/devel/uml/class132101.html @@ -18,6 +18,6 @@

    Declaration :

    Artifact : hub

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132229.html b/doc/devel/uml/class132229.html index 28f198354..8fc999275 100644 --- a/doc/devel/uml/class132229.html +++ b/doc/devel/uml/class132229.html @@ -18,6 +18,6 @@

    Declaration :

    • C++ : class Projector : public Trafo

    Special video processing node used to scale and translate image data.

    Artifact : projector

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132357.html b/doc/devel/uml/class132357.html index 9dab6ff1f..1b054fe8f 100644 --- a/doc/devel/uml/class132357.html +++ b/doc/devel/uml/class132357.html @@ -18,6 +18,6 @@

    Declaration :

    • C++ : class Mask : public Trafo

    Artifact : mask

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132485.html b/doc/devel/uml/class132485.html index 2ccb92506..54bafe5c9 100644 --- a/doc/devel/uml/class132485.html +++ b/doc/devel/uml/class132485.html @@ -18,6 +18,6 @@

    Declaration :

    • C++ : class PluginAdapter : public Trafo

    Adapter used to integrage an effects processor in the render pipeline

    Artifact : pluginadapter

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132613.html b/doc/devel/uml/class132613.html index 763de044c..90fc0acbb 100644 --- a/doc/devel/uml/class132613.html +++ b/doc/devel/uml/class132613.html @@ -18,6 +18,6 @@

    Declaration :

    • C++ : class GLPipe : public Link

    specialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form

    Artifact : glpipe

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132741.html b/doc/devel/uml/class132741.html index f543def13..1efbe8fa1 100644 --- a/doc/devel/uml/class132741.html +++ b/doc/devel/uml/class132741.html @@ -16,9 +16,14 @@ -

    Declaration :

    • C++ : class State
    • Java : public interface State

    Directly inherited by : ARender GLRender StateAdapter StateProxy VRender

    +

    Declaration :

    • C++ : class State
    • Java : public interface State

    Directly inherited by : ARender GLRender StateAdapter StateProxy VRender

    Artifact : stateproxy, Component(s) : Builder

    -
    Relation currFrame (<unidirectional association>)

    Declaration :

    • Uml : # currFrame : Frame, multiplicity : 1..*
    • C++ : protected: vector<Frame *> currFrame
    +
    Relation currFrame (<unidirectional association>)

    Declaration :

    • Uml : # currFrame : Frame
    • C++ : protected: Frame * currFrame
    +
    Operation fetch

    Declaration :

    • Uml : + fetch() :
    • C++ : public: fetch ()
    +
    Operation allocateBuffer

    Declaration :

    • Uml : + allocateBuffer() :
    • C++ : public: allocateBuffer ()
    +
    Operation releaseBuffer

    Declaration :

    • Uml : + releaseBuffer() :
    • C++ : public: releaseBuffer ()
    +
    Operation isCalculated

    Declaration :

    • Uml : + isCalculated() :
    • C++ : public: isCalculated ()
    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

    diff --git a/doc/devel/uml/class132869.html b/doc/devel/uml/class132869.html index 2d6833c2a..a9d6b46c3 100644 --- a/doc/devel/uml/class132869.html +++ b/doc/devel/uml/class132869.html @@ -18,5 +18,6 @@

    Declaration :

    • C++ : class ARender : public State

    Representation of a Audio render process

    Artifact : arender

    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

    diff --git a/doc/devel/uml/class132997.html b/doc/devel/uml/class132997.html index a45d3c828..e59220a95 100644 --- a/doc/devel/uml/class132997.html +++ b/doc/devel/uml/class132997.html @@ -18,5 +18,6 @@

    Declaration :

    • C++ : class VRender : public State

    Representation of a Video render process. (Encapsulates the video buffers for the actual calculations)

    Artifact : vrender

    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

    diff --git a/doc/devel/uml/class133125.html b/doc/devel/uml/class133125.html index d1cf4b2b6..8c1acac1f 100644 --- a/doc/devel/uml/class133125.html +++ b/doc/devel/uml/class133125.html @@ -18,5 +18,6 @@

    Declaration :

    • C++ : class GLRender : public State

    Representation of a OpenGL accelerated Video render process

    Artifact : glrender

    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

    diff --git a/doc/devel/uml/class133765.html b/doc/devel/uml/class133765.html index 384101f0a..b6f9bde2d 100644 --- a/doc/devel/uml/class133765.html +++ b/doc/devel/uml/class133765.html @@ -18,6 +18,6 @@

    Declaration :

    Source Node: represents a media source to pull data from.

    Artifact : source

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class135045.html b/doc/devel/uml/class135045.html index a651d86b1..c91ed83fb 100644 --- a/doc/devel/uml/class135045.html +++ b/doc/devel/uml/class135045.html @@ -18,6 +18,6 @@

    Declaration :

    • C++ : class CodecAdapter : public Trafo

    Artifact : codecadapter

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class142213.html b/doc/devel/uml/class142213.html deleted file mode 100644 index a43acb9ac..000000000 --- a/doc/devel/uml/class142213.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -Class StateAdapter - - - - - -
    Class StateAdapter
    -

    - - - - -

    Declaration :

    • C++ : class StateAdapter : public State

    lightweight value class used to manage the buffer associations for a single pull() call on a processing node

    - -
    Operation pull

    Declaration :

    • Uml : + pull(inout renderProcess : State) : void
    • C++ : public: void pull ()

    trigger data processing by "pulling" results from the node's output

    -
    Operation retrieveBuffers

    Declaration :

    • Uml : + retrieveBuffers(in requiredSource : vector<InputDescriptor> const) : void
    • C++ : public: void retrieveBuffers (const vector<InputDescriptor> const& requiredSource)

    invoked from within the pull() - call of a node to set up the data buffers.
    @param requiredSource descriptor denoting the predecessors and the frames required from them

    -
    Relation <unidirectional association>

    Declaration :

    -
    Relation state (<unidirectional association>)

    Declaration :

    -

    All public operations : pull , retrieveBuffers

    - - diff --git a/doc/devel/uml/class142469.html b/doc/devel/uml/class142469.html index 9b6ed01a1..58c82f008 100644 --- a/doc/devel/uml/class142469.html +++ b/doc/devel/uml/class142469.html @@ -4,17 +4,20 @@ -Class caller +Class StateProxy -
    Class caller
    +
    Class StateProxy

    -

    Declaration :

    • C++ : class caller
    +

    Declaration :

    • C++ : class StateProxy : public State
    +
    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

    + diff --git a/doc/devel/uml/class142597.html b/doc/devel/uml/class142597.html index 6465a8cd5..69ed2147c 100644 --- a/doc/devel/uml/class142597.html +++ b/doc/devel/uml/class142597.html @@ -4,17 +4,23 @@ -Class Backend_Cache +Class StateAdapter -
    Class Backend_Cache
    +
    Class StateAdapter

    -

    Declaration :

    • C++ : class Backend_Cache
    +

    Declaration :

    • C++ : class StateAdapter : public State
    + +
    Operation retrieve

    Declaration :

    • Uml : + retrieve() :
    • C++ : public: retrieve ()
    +
    Relation state (<unidirectional association>)

    Declaration :

    +
    Relation <unidirectional association>

    Declaration :

    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer , retrieve

    + diff --git a/doc/devel/uml/class142341.html b/doc/devel/uml/class142725.html similarity index 84% rename from doc/devel/uml/class142341.html rename to doc/devel/uml/class142725.html index e9ac0ff67..2118cb163 100644 --- a/doc/devel/uml/class142341.html +++ b/doc/devel/uml/class142725.html @@ -15,6 +15,6 @@ - -

    Declaration :

    • C++ : class InputDescriptor

    Artifact : procnode

    + +

    Declaration :

    • C++ : class InputDescriptor
    diff --git a/doc/devel/uml/class142085.html b/doc/devel/uml/class143109.html similarity index 64% rename from doc/devel/uml/class142085.html rename to doc/devel/uml/class143109.html index 70fbc4c7b..f2696562b 100644 --- a/doc/devel/uml/class142085.html +++ b/doc/devel/uml/class143109.html @@ -4,19 +4,17 @@ -Class StateProxy +Class BackendCache -
    Class StateProxy
    +
    Class BackendCache

    - -

    Declaration :

    • C++ : class StateProxy : public State
    -
    - + +

    Declaration :

    • C++ : class BackendCache
    diff --git a/doc/devel/uml/class143237.html b/doc/devel/uml/class143237.html new file mode 100644 index 000000000..b1b5a8387 --- /dev/null +++ b/doc/devel/uml/class143237.html @@ -0,0 +1,20 @@ + + + + + + +Class Caller + + + + + +
    Class Caller
    +

    + + + + +

    Declaration :

    • C++ : class Caller
    + diff --git a/doc/devel/uml/classdiagrams.html b/doc/devel/uml/classdiagrams.html index c08c6d8a8..1df0fcd1d 100644 --- a/doc/devel/uml/classdiagrams.html +++ b/doc/devel/uml/classdiagrams.html @@ -20,7 +20,6 @@ Automation Entities Builder Entities Controller Entities -Engine Details File MappingShows whats used to access Frames HierarchyLumiera Exception hierarchy In Memory Database @@ -28,6 +27,7 @@ Media-Asset Relations Proc-Asset Relations Render Entities +Render Mechanics Rules access Session structure Struct-Asset Relations diff --git a/doc/devel/uml/classes.html b/doc/devel/uml/classes.html index e1343f56e..9375f3648 100644 --- a/doc/devel/uml/classes.html +++ b/doc/devel/uml/classes.html @@ -26,12 +26,12 @@ AssetinterfaceSuperinterface describing especially the bookeeping properties of Assets AssetManagerboundaryFacade for the Asset subsystem AutoAutomation data for some parameter (i.e. a time varying function) -Backend_Cache +BackendCache Buildableinterface BuilderFacadeboundaryProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade BuilderToolinterfaceUsed according to the visitor pattern: each Tool contains the concrete implementation for one task to be done to the various MObject classes BuildInstruct(Interface) building instructions to be executed by the Builder on the render node network under construction. -caller +Caller Categorytree like classification of Assets Clipbookkeeping (asset) view of a media clip. Clip @@ -76,7 +76,7 @@ GLPipespecialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form GLRenderRepresentation of a OpenGL accelerated Video render process Hub -InputDescriptor +InputDescriptor InterpolatorProvides the implementation for getting the acutal value of a time varying or automated effect/plugin parameter Invalid Label @@ -128,8 +128,8 @@ SourceSource Node: represents a media source to pull data from. Stateinterface State -StateAdapterlightweight value class used to manage the buffer associations for a single pull() call on a processing node -StateProxyimplementation +StateAdapter +StateProxyimplementation std::exceptionauxiliary Structkey abstraction: structural asset ThreadWe can basically reuse the Thread class design from Cinelerra2, Thread becomes a baseclass for all Threads diff --git a/doc/devel/uml/classes_list.html b/doc/devel/uml/classes_list.html index 153e47670..38b7af7d1 100644 --- a/doc/devel/uml/classes_list.html +++ b/doc/devel/uml/classes_list.html @@ -27,12 +27,12 @@ Asset
    AssetManager
    Auto
    -Backend_Cache
    +BackendCache
    Buildable
    BuilderFacade
    BuilderTool
    BuildInstruct
    -caller
    +Caller
    Category
    Clip
    Clip
    @@ -77,7 +77,7 @@ GLPipe
    GLRender
    Hub
    -InputDescriptor
    +InputDescriptor
    Interpolator
    Invalid
    Label
    @@ -129,8 +129,8 @@ Source
    State
    State
    -StateAdapter
    -StateProxy
    +StateAdapter
    +StateProxy
    std::exception
    Struct
    Thread
    diff --git a/doc/devel/uml/collaborationdiagrams.html b/doc/devel/uml/collaborationdiagrams.html index 9090762bc..5ccf1d4a5 100644 --- a/doc/devel/uml/collaborationdiagrams.html +++ b/doc/devel/uml/collaborationdiagrams.html @@ -18,7 +18,7 @@ - +
    "default" object
    build processThis figure shows the process of building and starting a RenderEngine
    pull call
    Render Process
    diff --git a/doc/devel/uml/fig131973.png b/doc/devel/uml/fig131973.png index 31b9b2a183d3c5ee8d642c4187e939b00921be56..7ed45dca7a110940795f165d53c21648bc62223e 100644 GIT binary patch literal 18410 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 literal 16309 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 diff --git a/doc/devel/uml/fig132229.png b/doc/devel/uml/fig132229.png new file mode 100644 index 0000000000000000000000000000000000000000..4cc4b71d5be185ffa2382bc0367a47569fc6e473 GIT binary patch literal 36167 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%0Dv2dWowyWAuA`Ggux`yM{A>(16G@ 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 literal 0 HcmV?d00001 diff --git a/doc/devel/uml/index.html b/doc/devel/uml/index.html index a054cc161..1cfd68cc1 100644 --- a/doc/devel/uml/index.html +++ b/doc/devel/uml/index.html @@ -116,7 +116,7 @@ Documentation
    Artifact Lumiera

    Depends on common

    Depends on gui

    Depends on proc

    Depends on backend

    the main executable to be built

    -

    executable associated with : placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter, effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation, mobject, source, frame

    +

    executable associated with : effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation, mobject, source, frame, placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter

    Artifact main

    Artifact source

    @@ -509,7 +509,7 @@ Documentation
    Artifact procnode

    Key abstraction of the Render Engine: a Processing Node

    -

    Artifact source associated with : ProcNode, InputDescriptor

    +

    Artifact source associated with : ProcNode

    Artifact trafo

    transforming processing Node

    @@ -764,6 +764,7 @@ Documentation
    Class Assembler
    +
    Class State
    Class Buildable
    @@ -876,6 +877,9 @@ reuse exiting Engine

    Selection :

      Transformation

      Automation Entities



      + +

      +

      Render Mechanics



      Class Processor
      Class ExitNode
      @@ -896,27 +900,9 @@ reuse exiting Engine

      Selection :

        Transformation
        Class VFrame
        Class GLBuf
        Class Source
        - -

        -

        Engine Details



        -
        Class State
        -
        -
        -
        -
        - -

        2.3.3 Use Case View render process

        -
        - -

        -

        pull call



        - -
        Class instance

        type :StateAdapter

        -
        Class instance node1

        type :ProcNode

        -
        Class instance node2

        type :ProcNode

        -
        Class instance next_adapter

        type :StateAdapter

        -
        Class instance current_state

        type :StateProxy

        Class caller
        -
        +
        +
        +
        @@ -1092,7 +1078,19 @@ reuse exiting Engine

        Selection :

          Transformation

          Class instance video

          type :ExitNode

          relations :

          +

          +

          +

          Render Process



          + +
          Class instance node1

          type :ProcNode

          +
          Class instance ad1

          type :StateAdapter

          +
          Class instance current

          type :StateProxy

          +
          Class instance node2

          type :ProcNode

          +
          Class instance ad2

          type :StateAdapter

          +
          Class Caller
          + +
          Class instance node3

          type :ProcNode

          +
          Class instance ad3

          type :StateAdapter

          3 Package BackendLayer

          diff --git a/doc/devel/uml/index_60.html b/doc/devel/uml/index_60.html index 8712d7074..cc286ecf2 100644 --- a/doc/devel/uml/index_60.html +++ b/doc/devel/uml/index_60.html @@ -28,10 +28,10 @@ <flow>transition <flow>transition <flow>transition -<flow>transition <flow>transition -<flow>transition +<flow>transition <flow>transition +<flow>transition <flow>transition <flow>transition <flow>transition diff --git a/doc/devel/uml/index_65.html b/doc/devel/uml/index_65.html index c1c05066a..8bc6b2fca 100644 --- a/doc/devel/uml/index_65.html +++ b/doc/devel/uml/index_65.html @@ -23,9 +23,13 @@ access Fileuse case activity finalactivity final activity finalactivity final +ad1class instance +ad2class instance +ad3class instance add new object to sessionuse case AFrameclass aframeartifacta buffer and render process holding a Audio frame +allocateBufferoperation allocationartifact Allocationclassa directive to place a MObject in a specific way anchorrelation @@ -52,12 +56,12 @@ Assetsclass view ATTACHattributeattach subject to anchor (e.g. an effect to a clip) au1class instance -aud_Aclass instance aud_aclass instance +aud_Aclass instance audioclass instance -audio1class instance -audio1class instance audio1class instance +audio1class instance +audio1class instance autoartifactMedia Object holding automation data AutoclassAutomation data for some parameter (i.e. a time varying function) Automation Entitiesclass diagram diff --git a/doc/devel/uml/index_66.html b/doc/devel/uml/index_66.html index 592c6f15d..f37527c49 100644 --- a/doc/devel/uml/index_66.html +++ b/doc/devel/uml/index_66.html @@ -21,7 +21,7 @@ Backend Componentsclass view backend use casesuse case diagram backend-componentscomponent diagram -Backend_Cacheclass +BackendCacheclass BackendLayerpackage buildoperation build flowactivity diagram diff --git a/doc/devel/uml/index_67.html b/doc/devel/uml/index_67.html index 996ed7eb6..2b841a011 100644 --- a/doc/devel/uml/index_67.html +++ b/doc/devel/uml/index_67.html @@ -19,7 +19,7 @@ NameKindDescription Cachecomponent Cachecomponent view -callerclass +Callerclass categoryrelationprimary tree like classification of the asset Categoryclasstree like classification of Assets categoryartifacttree like classification of Assets @@ -28,35 +28,34 @@ chainoperationcreate and add another Placement for this media object, thus increasingly constraining the (possible) position of this object. checked_inrelationchecked_in objects are subject of cache aging and must be not in use checked_outrelationthis list keeps all mappings which are in use, and thus prevents them from Cache aging -class instanceclass instance +class instanceclass instance class instanceclass instance -class instanceclass instance class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance clearoperationclear current session contents
          without resetting overall session config.
          Afterwards, the session will contain only one
          empty EDL, while all Assets are retained.
          client codecomponent Clipclassbookkeeping (asset) view of a media clip. @@ -96,8 +95,8 @@ constraintartifactLocatingPin representing an directive by the user that
          must not be violated Constraintclass Controllercomponent -Controllerpackage controllerpackagesourcecode package

          The Processing and Render Controller,
          located within the MObject Subsystem +Controllerpackage Controller Entitiesclass diagram Controller Workingsclass view ControllerFacadeclassProvides unified access to the Proc-Subsystem Controller. Especially, this Facade class provides the functions to get a render engine to carry out actual renderings. @@ -107,8 +106,8 @@ create specific objectuse case createClipoperationcreate a (possibly compound) Clip refering to this media, ready to be added to the EDL. currEDLoperationThe EDL currently in focus. In most cases, Session and EDL are almost the same, just EDL emphasizes the collection aspect. But generally (for larger editing projects) one Session can contain several EDLs, which may even be nested. At any given time, only one of these EDLs has focus and recieves the editing commands. +currentclass instance currentrelationStandard access path to get at the current session via the Session Manager, which acts as a "PImpl" smart pointer -current_stateclass instance currFramerelation diff --git a/doc/devel/uml/index_69.html b/doc/devel/uml/index_69.html index c9eb2c76d..6c17d406d 100644 --- a/doc/devel/uml/index_69.html +++ b/doc/devel/uml/index_69.html @@ -18,21 +18,20 @@ - + - + - diff --git a/doc/devel/uml/index_70.html b/doc/devel/uml/index_70.html index f328ad207..3d833b61f 100644 --- a/doc/devel/uml/index_70.html +++ b/doc/devel/uml/index_70.html @@ -18,6 +18,7 @@
          NameKindDescription
          edlartifactthe (high level) Edit Decision List within the current Session
          EDLcomponent
          EDLclass
          EDLcomponent
          EDL Example1object diagramA simple example showing how the actual objects are placed in the Fixture (=definitive playlist). It shows a Video and Audio clip placed on two tracks
          EDL Example2object diagramMore complex example showing the Object graph in the EDL and how it is linked into the Fixture to yield the actual locations. In this example, an HUE Effect is applied on a part of the Clip
          edlsrelation
          EffectclassEffect or media processing component
          effectartifactEffect or media processing component
          effectartifactEDL representation of a pluggable and automatable effect.
          effectartifactEffect or media processing component
          Effectclass
          elementsrelationrelevant MObjects comprising this segment. TODO: actually necessary??
          enableoperationchange the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well
          endattributeend of the timerange (excl)
          Enginecomponent
          enginepackagesourcecode package

          The Core Render Engine
          Engine Detailsclass diagram
          Engine Example1object diagramExample1 (from EDL) continued: here the RenderEngine to be created by the Builder from the Input shown in Example1
          Engine Example2object diagramExample2 (from EDL) continued: notably in this RenderEngine the Effect has been partitioned into 2 segments with constant configuration.
          Engine Partsdeployment view
          + diff --git a/doc/devel/uml/index_73.html b/doc/devel/uml/index_73.html index fa68d81e1..12fe67359 100644 --- a/doc/devel/uml/index_73.html +++ b/doc/devel/uml/index_73.html @@ -23,7 +23,7 @@ - + @@ -34,6 +34,7 @@ +
          NameKindDescription
          Factoryclassa template for generating functor-like Factory objects, used to encapsulate object creation and providing access via smart-pointers only.
          fetchoperation
          Fileclass
          filerelation
          File Mappingclass diagramShows whats used to access Frames
          inputclass instance
          inputclass instance
          inputclass instance
          InputDescriptorclass
          InputDescriptorclass
          instanceoperation
          instructionsrelation
          Interfaceclass view
          Invalidclass
          iporelation
          isActiveoperationweather this asset is swithced on and consequently included in the fixture and participates in rendering
          isCalculatedoperation
          diff --git a/doc/devel/uml/index_78.html b/doc/devel/uml/index_78.html index 8afac3d9f..d0f7bd42e 100644 --- a/doc/devel/uml/index_78.html +++ b/doc/devel/uml/index_78.html @@ -20,9 +20,9 @@ nameattributeelement ID, comprehensible but sanitized. The tuple (category, name, org) is unique. need sub objectuse case nextrelationnext additional LocatingPin, if any -next_adapterclass instance node1class instance -node2class instance +node2class instance +node3class instance nodecreatertoolartifactcentral Tool implementing the Renderengine building NodeCreatorToolclassThis Tool implementation plays the central role in the buld process: given a MObject from Session, it is able to attach ProcNodes to the render engine under construction such as to reflect the properties of the MObject in the actual render. nodesrelation diff --git a/doc/devel/uml/index_79.html b/doc/devel/uml/index_79.html index f63687c5b..bfec5f683 100644 --- a/doc/devel/uml/index_79.html +++ b/doc/devel/uml/index_79.html @@ -19,8 +19,8 @@ NameKindDescription offsetattributeOffset the actual position by this (time) value relative to the anchor point. TODO: Representation? orgattributeorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core Lumiera codebase is "lumi". -ouputclass instance ouputclass instance +ouputclass instance ouputclass instance outPortrelationthe Port this MObject wants to be conected to outputrelation diff --git a/doc/devel/uml/index_80.html b/doc/devel/uml/index_80.html index 83ab6f76d..0cff29b1c 100644 --- a/doc/devel/uml/index_80.html +++ b/doc/devel/uml/index_80.html @@ -40,7 +40,7 @@ pnodenode pointattributeidentifying the point where the nodes should be attached Posix Threads Abstractionclass viewC++ wrapers for pthreads -predecessorsrelationpreconfigured table of all predecessor nodes, qualified
          with the output port on these nodes and time offset of the data
          we need for doing our calculations
          +predecessorsrelation predicate implclass instance Prefetchclass Previewclassalternative version of the media data, probably with lower resolution @@ -53,6 +53,7 @@ Proc-Asset Relationsclass diagram proc-componentscomponent diagram ProcDispatcherclass +processoperation ProcessingLayerpackage Processorclass processorartifacta single render pipeline for one segment of the timeline @@ -64,9 +65,7 @@ ProjectorclassSpecial video processing node used to scale and translate image data. projectorartifactvideo ProcNode for scaling and translating image data providerrelation -pulloperationtrigger data processing by "pulling" results from the node's output -pulloperationtrigger data processing by "pulling" results from the node's output -pull callcollaboration diagram +pulloperation diff --git a/doc/devel/uml/index_82.html b/doc/devel/uml/index_82.html index c807e8ca4..7f2b69c16 100644 --- a/doc/devel/uml/index_82.html +++ b/doc/devel/uml/index_82.html @@ -22,11 +22,13 @@ registryrelation@internal Table or DB holding all registered asset instances. relativelocationartifactPlacement implemnetaion providing various ways of attaching a MObject to another one RelativeLocationclass -relTypeattributethe kind of relation denoted by this Placement +releaseBufferoperation RelTypeclassthe possible kinds of RelativePlacements +relTypeattributethe kind of relation denoted by this Placement removeoperationremove the given asset <i>together with all its dependants</i> from the internal DB Render Entitiesclass diagram -render processuse case view +Render Mechanicsclass diagram +Render Processcollaboration diagram Render Requestactivity parameter RenderEngineclass renderengineartifacta complete network of processing nodes usable for rendering @@ -43,7 +45,7 @@ resolveoperation Resolvercomponent ResolverBaseclass -retrieveBuffersoperationinvoked from within the pull() - call of a node to set up the data buffers.
          @param requiredSource descriptor denoting the predecessors and the frames required from them +retrieveoperation rootCauseoperationIf this exception was caused by a chain of further exceptions,
          return the first one registered in this throw sequence.
          This works only, if every exceptions thrown as a consequence
          of another exception is propperly constructed by passing
          the original exception to the constructor Rule Basecomponent Rules accessclass diagram diff --git a/doc/devel/uml/index_83.html b/doc/devel/uml/index_83.html index 2edde4200..c7b3fed84 100644 --- a/doc/devel/uml/index_83.html +++ b/doc/devel/uml/index_83.html @@ -47,20 +47,20 @@ SimpleClipclassElementary clip consisting of only one media stream SmartPointerclass SmartPointersclass view -sourcerelationthe media source this clip referes to sourcerelationmedia source of this clip +sourcerelationthe media source this clip referes to SourceclassSource Node: represents a media source to pull data from. sourceartifactRepresentation of a Media source Source Overviewdeployment diagram startattributestartpos in source startattributebegin of the timerange covered by this processor startattribute -Statenode Stateclass +Statenode Stateclass -staterelation -StateAdapterclasslightweight value class used to manage the buffer associations for a single pull() call on a processing node -StateProxyclass +staterelation +StateAdapterclass +StateProxyclass stateproxyartifactKey Interface representing a render process and encapsulating state std::exceptionclass Structclasskey abstraction: structural asset diff --git a/doc/devel/uml/index_84.html b/doc/devel/uml/index_84.html index bfcae496d..78e737858 100644 --- a/doc/devel/uml/index_84.html +++ b/doc/devel/uml/index_84.html @@ -42,12 +42,12 @@ trafoartifacttransforming processing Node treatoperation treatoperationThis operation is to be overloaded for the specific MObject subclasses to be treated. +treatoperation treatoperation treatoperation -treatoperation treatoperation -treatoperation treatoperation +treatoperation treatoperation TypeHandlerclass TypeHandler<Pipe>class diff --git a/doc/devel/uml/index_86.html b/doc/devel/uml/index_86.html index 364ff0811..c2ce0bff8 100644 --- a/doc/devel/uml/index_86.html +++ b/doc/devel/uml/index_86.html @@ -20,23 +20,23 @@ versionattributeversion number of the thing or concept represented by this asset. Of each unique tuple (name, category, org) there will be only one version in the whole system. Version 0 is reserved for internal purposes. Versions are considered to be ordered, and any higher version is supposed to be fully backwards compatible to all previous versions. VFrameclass vframeartifacta buffer and render process holding a Video frame -vid1class instance vid1class instance -vid_aclass instance -vid_Aclass instance -vid_Aclass instance -vid_aclass instance +vid1class instance vid_Aclass instance -videoclass instance -videoclass instance +vid_aclass instance +vid_Aclass instance +vid_Aclass instance +vid_aclass instance videoclass instance +videoclass instance videoclass instance -video1class instance -video1class instance -video1class instance +videoclass instance video1class instance +video1class instance video1class instance +video1class instance video1class instance +video1class instance Visitableclass visitorpackagesub-namespace for visitor library implementation visitorartifactAcyclic Visitor library diff --git a/doc/devel/uml/public_operations.html b/doc/devel/uml/public_operations.html index 03a780210..c252030f0 100644 --- a/doc/devel/uml/public_operations.html +++ b/doc/devel/uml/public_operations.html @@ -17,6 +17,7 @@ + @@ -29,6 +30,7 @@ + @@ -47,29 +49,31 @@ + - - + + + - + - + + - diff --git a/uml/lumiera/128389 b/uml/lumiera/128389 index 52c1b5245..20d07a18b 100644 --- a/uml/lumiera/128389 +++ b/uml/lumiera/128389 @@ -1,6 +1,6 @@ format 40 "RenderEngine" // ProcessingLayer::RenderEngine - revision 13 + revision 15 modified_by 5 "hiv" // class settings //class diagram settings @@ -82,6 +82,11 @@ format 40 size A4 end + classdiagram 131973 "Render Mechanics" + draw_all_relations no hide_attributes default hide_operations default show_members_full_definition yes show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + size A4 + end + class 131333 "RenderEngine" visibility package cpp_decl "${comment}${template}class ${name}${inherit} @@ -155,7 +160,7 @@ ${inlines} a package cpp default "#include in source" classrelation_ref 136325 // - b multiplicity "" parent class_ref 132741 // StateProxy + b multiplicity "" parent class_ref 132741 // State end attribute 129413 "start" @@ -233,6 +238,46 @@ ${members}}; classrelation_ref 137861 // params () b multiplicity "" parent class_ref 134533 // Parameter end + + classrelation 152581 // predecessors () + relation 149125 *--> + stereotype "vector" + a role_name "predecessors" multiplicity "*" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; +" + classrelation_ref 152581 // predecessors () + b multiplicity "" parent class_ref 142725 // InputDescriptor + end + + operation 135685 "pull" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end + + operation 136069 "process" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end end class 131845 "Trafo" @@ -415,7 +460,7 @@ ${inlines} a public cpp default "${type}" classrelation_ref 134661 // - b multiplicity "" parent class_ref 132741 // StateProxy + b multiplicity "" parent class_ref 132741 // State end end @@ -436,7 +481,7 @@ ${inlines} a public cpp default "${type}" classrelation_ref 134789 // - b multiplicity "" parent class_ref 132741 // StateProxy + b multiplicity "" parent class_ref 132741 // State end end @@ -457,7 +502,7 @@ ${inlines} a public cpp default "${type}" classrelation_ref 134917 // - b multiplicity "" parent class_ref 132741 // StateProxy + b multiplicity "" parent class_ref 132741 // State end end @@ -568,5 +613,91 @@ ${inlines} b multiplicity "" parent class_ref 136709 // Media end end + + class 142469 "StateProxy" + visibility package stereotype "implementation" + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 152453 // + relation 148997 ---|> + a public + cpp default "${type}" + classrelation_ref 152453 // + b multiplicity "" parent class_ref 132741 // State + end + end + + class 142597 "StateAdapter" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 152325 // + relation 148869 ---|> + a public + cpp default "${type}" + classrelation_ref 152325 // + b multiplicity "" parent class_ref 132741 // State + end + + operation 135557 "retrieve" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end + + classrelation 152709 // state () + relation 149253 ---> + a role_name "state" multiplicity "1" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 152709 // state () + b multiplicity "" parent class_ref 142469 // StateProxy + end + + classrelation 152837 // + relation 149381 ---> + a role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 152837 // + b multiplicity "" parent class_ref 133253 // Frame + end + end + + class 142725 "InputDescriptor" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + end end end diff --git a/uml/lumiera/128901 b/uml/lumiera/128901 index e4d919380..455fee7d7 100644 --- a/uml/lumiera/128901 +++ b/uml/lumiera/128901 @@ -1,6 +1,6 @@ format 40 "Builder" // ProcessingLayer::MObject::Builder - revision 14 + revision 16 modified_by 5 "hiv" // class settings //class diagram settings @@ -299,7 +299,7 @@ ${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} end end - class 132741 "StateProxy" + class 132741 "State" abstract visibility public stereotype "interface" cpp_decl "${comment}${template}class ${name}${inherit} { @@ -316,12 +316,73 @@ ${members}}; classrelation 135941 // currFrame () relation 134533 ---> + stereotype "vector" a role_name "currFrame" multiplicity "" protected cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 135941 // currFrame () b multiplicity "1" parent class_ref 133253 // Frame end + + operation 135813 "fetch" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end + + operation 135941 "allocateBuffer" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end + + operation 136197 "releaseBuffer" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end + + operation 136325 "isCalculated" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end end class 134021 "Buildable" diff --git a/uml/lumiera/129285 b/uml/lumiera/129285 index 7883c598c..72c222be4 100644 --- a/uml/lumiera/129285 +++ b/uml/lumiera/129285 @@ -1,6 +1,6 @@ format 40 "ProcessingLayer" // ProcessingLayer - revision 15 + revision 19 modified_by 5 "hiv" // class settings //class diagram settings @@ -602,5 +602,92 @@ format 40 classinstance_ref 134405 // ouput end end + + collaborationdiagram 132229 "Render Process" + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + size A4 + end + + classinstance 136197 "node1" + type class_ref 131717 // ProcNode + attributes + end + relations + end + end + + classinstance 136325 "ad1" + type class_ref 142597 // StateAdapter + attributes + end + relations + end + end + + classinstance 136453 "current" + type class_ref 142469 // StateProxy + attributes + end + relations + end + end + + classinstance 136581 "node2" + type class_ref 131717 // ProcNode + attributes + end + relations + end + end + + classinstance 136709 "ad2" + type class_ref 142597 // StateAdapter + attributes + end + relations + end + end + + class 143109 "BackendCache" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + end + + class 143237 "Caller" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + end + + classinstance 136837 "node3" + type class_ref 131717 // ProcNode + attributes + end + relations + end + end + + classinstance 136965 "ad3" + type class_ref 142597 // StateAdapter + attributes + end + relations + end + end end end diff --git a/uml/lumiera/131973.diagram b/uml/lumiera/131973.diagram index 9d11f2c5a..7a9c0af13 100644 --- a/uml/lumiera/131973.diagram +++ b/uml/lumiera/131973.diagram @@ -2,66 +2,66 @@ format 40 classcanvas 128005 class_ref 131717 // ProcNode draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 106 330 2004 + xyz 106 313 2004 end classcanvas 128517 class_ref 132741 // State draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 83 21 2000 - end -classcanvas 128645 class_ref 142085 // StateProxy - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 127 135 2000 - end -classcanvas 128773 class_ref 142213 // StateAdapter - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 36 216 2000 - end -classcanvas 129157 class_ref 142341 // InputDescriptor - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 183 446 2000 + xyz 79 -16 2000 end classcanvas 129669 class_ref 133253 // Frame draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 267 221 3005 end -relationcanvas 128901 relation_ref 148229 // - geometry VHV unfixed - from ref 128645 z 1999 to point 179 108 - line 131589 z 1999 to point 120 108 - line 131717 z 1999 to ref 128517 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 129029 relation_ref 148357 // - geometry VHV unfixed - from ref 128773 z 1999 to point 80 108 - line 131333 z 1999 to point 120 108 - line 131461 z 1999 to ref 128517 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 129285 relation_ref 148485 // - geometry HV - from ref 128005 z 1999 to point 228 367 - line 129541 z 1999 to ref 129157 - role_a_pos 240 421 3000 no_role_b - multiplicity_a_pos 216 421 3000 no_multiplicity_b +classcanvas 131845 class_ref 142469 // StateProxy + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 149 135 2000 + end +classcanvas 131973 class_ref 142597 // StateAdapter + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 43 225 3010 + end +classcanvas 132357 class_ref 142725 // InputDescriptor + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 233 434 2000 + end relationcanvas 129797 relation_ref 134533 // - from ref 128517 z 1999 to point 303 129 - line 130053 z 1999 stereotype "<>" xyz 248 128 3000 to ref 129669 - role_a_pos 312 194 3000 no_role_b - multiplicity_a_pos 281 158 3000 multiplicity_b_pos 171 82 3000 -relationcanvas 129925 relation_ref 148613 // - from ref 128773 z 1999 to ref 129669 + from ref 128517 z 1999 stereotype "<>" xyz 282 103 3000 to point 303 129 + line 130053 z 1999 to ref 129669 + role_a_pos 315 196 3000 no_role_b + no_multiplicity_a multiplicity_b_pos 175 84 3000 +relationcanvas 132101 relation_ref 148869 // + geometry VHV unfixed + from ref 131973 z 1999 to point 81 108 + line 134021 z 1999 to point 120 108 + line 134149 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b -relationcanvas 130181 relation_ref 148741 // - from ref 128773 z 1999 to point 179 226 - line 130309 z 1999 to ref 128645 - role_a_pos 149 210 3000 no_role_b +relationcanvas 132229 relation_ref 148997 // + geometry VHV + from ref 131845 z 1999 to point 201 126 + line 134277 z 1999 to point 120 126 + line 134405 z 1999 to ref 128517 + no_role_a no_role_b no_multiplicity_a no_multiplicity_b -line 130437 -_-_ - from ref 128773 z 1999 to point 136 328 - line 130693 z 1999 to ref 128005 -line 130565 -_-_ - from ref 128773 z 1999 to ref 128005 +relationcanvas 132485 relation_ref 149125 // + geometry HV + from ref 128005 z 1999 stereotype "<>" xyz 220 359 3000 to point 278 360 + line 133381 z 1999 to ref 132357 + role_a_pos 290 409 3000 no_role_b + multiplicity_a_pos 266 409 3000 no_multiplicity_b +relationcanvas 133509 relation_ref 149253 // + from ref 131973 z 1999 to point 200 215 + line 133637 z 1999 to ref 131845 + role_a_pos 180 222 3000 no_role_b + multiplicity_a_pos 185 199 3000 no_multiplicity_b +relationcanvas 134533 relation_ref 149381 // + from ref 131973 z 3004 to ref 129669 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +line 134661 -_-_ + from ref 131973 z 2003 to ref 128005 +line 134789 -_-_ + from ref 131973 z 2003 to point 137 322 + line 134917 z 2003 to ref 128005 preferred_whz 414 544 1 end diff --git a/uml/lumiera/132101.diagram b/uml/lumiera/132101.diagram deleted file mode 100644 index 39dd25211..000000000 --- a/uml/lumiera/132101.diagram +++ /dev/null @@ -1,91 +0,0 @@ -format 40 - -classinstancecanvas 128005 classinstance_ref 136069 // - xyz 144 217 2000 - end -classinstancecanvas 128133 classinstance_ref 136197 // node1 - xyz 169 309 2000 - end -classinstancecanvas 128261 classinstance_ref 136325 // node2 - xyz 485 277 2000 - end -classinstancecanvas 128389 classinstance_ref 136453 // next_adapter - xyz 388 216 2005 - end -classinstancecanvas 128901 classinstance_ref 136581 // current_state - xyz 114 20 2000 - end -classinstance 129285 class_ref 142469 // caller - name "" xyz 29 106 2000 -classinstance 129541 class_ref 142597 // Backend_Cache - name "" xyz 412 39 2000 -textcanvas 130565 "node1 using node2 as predecessor" - xyzwh 267 343 2000 133 24 -textcanvas 130693 "try to get frame from Cache first" - xyzwh 468 121 2000 89 43 -note 130821 "Triggered by pulling" - xyzwh 5 176 2005 118 38 -note 130949 "Buffers" - xyzwh 255 20 2005 61 35 -linkcanvas 128517 - from ref 128005 z 1999 to ref 128133 -dirscanvas 128645 z 1000 linkcanvas_ref 128517 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "2 pull()" xyz 217 255 3000 - backward_label "3 retrieveBuffers()" xyz 95 282 3000 -linkcanvas 128773 - from ref 128005 z 1999 to ref 128389 -dirscanvas 130053 z 1000 linkcanvas_ref 128773 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "4 create" xyz 281 192 3000 -linkcanvas 129029 - from ref 128005 z 1999 to ref 128901 -linkcanvas 129157 - from ref 128389 z 1999 to ref 128261 -dirscanvas 130309 z 1000 linkcanvas_ref 129157 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "6 pull()" xyz 515 246 3000 -linkcanvas 129413 - from ref 129285 z 1999 to ref 128005 -dirscanvas 129925 z 1000 linkcanvas_ref 129413 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "1 pull()" xyz 124 140 3000 -linkcanvas 129669 - from ref 128389 z 1999 to ref 129541 -dirscanvas 130181 z 1000 linkcanvas_ref 129669 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "5 try_fetch" xyz 386 132 3000 -linkcanvas 129797 - from ref 128005 z 1999 to ref 129541 -dirscanvas 130437 z 1000 linkcanvas_ref 129797 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "7 store" xyz 280 108 3000 -msgs - msg operation_ref 135685 // "pull(inout renderProcess : State) : void" - forward ranks 1 "1" dirscanvas_ref 129925 - msgs - msg operation_ref 135557 // "pull(inout renderProcess : State) : void" - forward ranks 2 "1.1" dirscanvas_ref 128645 - msgs - msg operation_ref 135813 // "retrieveBuffers(in requiredSource : vector const) : void" - backward ranks 3 "1.1.1" dirscanvas_ref 128645 - msgs - explicitmsg "create" - forward ranks 4 "1.1.1.1" dirscanvas_ref 130053 - msgs - explicitmsg "try_fetch" - forward ranks 5 "1.1.1.1.1" dirscanvas_ref 130181 - no_msg - msg operation_ref 135557 // "pull(inout renderProcess : State) : void" - forward ranks 6 "1.1.1.1.2" dirscanvas_ref 130309 - no_msg - msgsend - explicitmsg "store" - forward ranks 7 "1.1.1.2" dirscanvas_ref 130437 - no_msg - msgsend - msgsend - msgsend -msgsend -preferred_whz 599 408 1 -end diff --git a/uml/lumiera/132229.diagram b/uml/lumiera/132229.diagram new file mode 100644 index 000000000..af599827d --- /dev/null +++ b/uml/lumiera/132229.diagram @@ -0,0 +1,184 @@ +format 40 + +classinstancecanvas 128261 classinstance_ref 136197 // node1 + xyz 152 504 2000 + end +classinstancecanvas 128389 classinstance_ref 136325 // ad1 + xyz 191 393 2000 + end +classinstancecanvas 128517 classinstance_ref 136453 // current + xyz 188 92 2000 + end +classinstancecanvas 128645 classinstance_ref 136581 // node2 + xyz 388 393 2000 + end +classinstancecanvas 128773 classinstance_ref 136709 // ad2 + xyz 422 301 2000 + end +classinstance 128901 class_ref 143109 // BackendCache + name "" xyz 692 12 2000 +classinstance 129029 class_ref 143237 // Caller + name "" xyz 28 505 2000 +classinstancecanvas 130949 classinstance_ref 136837 // node3 + xyz 625 300 2000 + end +classinstancecanvas 131077 classinstance_ref 136965 // ad3 + xyz 665 199 2000 + end +textcanvas 133381 "node1 using node2 as predecessor; calculates in-place, will push result to Cache" + xyzwh 149 538 2000 408 21 +textcanvas 133509 "node2 using node3 as predecessor. Calculates without caching" + xyzwh 385 427 2005 350 18 +textcanvas 133637 "node3 doesn't calc, but fetch result from Cache" + xyzwh 564 329 2000 231 18 +linkcanvas 129157 + from ref 129029 z 1999 to ref 128261 +dirscanvas 129285 z 1000 linkcanvas_ref 129157 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "1 pull()" xyz 97 480 3000 +linkcanvas 129413 + from ref 128261 z 1999 to ref 128389 +dirscanvas 130309 z 1000 linkcanvas_ref 129413 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "2 retrieve()" xyz 141 437 3000 + backward_label "16 process()" xyz 236 471 3000 +linkcanvas 129541 + from ref 128389 z 1999 to ref 128517 +dirscanvas 131717 z 1000 linkcanvas_ref 129541 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "3 fetch() +11 allocateBuffer() +17 isCalculated()" xyz 128 228 3000 +linkcanvas 129669 + from ref 128389 z 1999 to ref 128645 +dirscanvas 130437 z 1000 linkcanvas_ref 129669 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "4 pull()" xyz 319 369 3000 +linkcanvas 129797 + from ref 128645 z 1999 to ref 128773 +dirscanvas 130693 z 1000 linkcanvas_ref 129797 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "5 retrieve()" xyz 379 349 3000 + backward_label "13 process()" xyz 469 372 3000 +linkcanvas 130181 + from ref 128773 z 1999 to ref 128517 +dirscanvas 133765 z 1000 linkcanvas_ref 130181 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "14 releaseBuffer()" xyz 285 227 3000 +linkcanvas 131205 + from ref 128773 z 1999 to ref 130949 +dirscanvas 131845 z 1000 linkcanvas_ref 131205 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "6 pull()" xyz 553 276 3000 +linkcanvas 131333 + from ref 130949 z 1999 to ref 131077 +dirscanvas 131973 z 1000 linkcanvas_ref 131333 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "7 retrieve()" xyz 615 236 3000 +linkcanvas 131461 + from ref 131077 z 1999 to ref 128517 +dirscanvas 132101 z 1000 linkcanvas_ref 131461 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "8 fetch()" xyz 449 179 3000 +linkcanvas 131589 + from ref 128517 z 1999 to point 295 24 + line 134277 z 1999 to ref 128901 +dirscanvas 132229 z 1000 linkcanvas_ref 134277 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "9 fetch +12 allocateNewFrame +15 releaseFrame +18 isCalculatedFrame +20 releaseFrame" xyz 487 29 3000 +linkcanvas 132357 + from ref 131077 z 1999 to point 515 211 + line 132613 z 1999 to ref 128773 +dirscanvas 132741 z 1000 linkcanvas_ref 132357 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default +linkcanvas 132485 + from ref 128773 z 1999 to point 280 312 + line 132869 z 1999 to ref 128389 +dirscanvas 132997 z 1000 linkcanvas_ref 132485 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "10 allocateBuffer()" xyz 306 293 3000 +linkcanvas 133893 + from ref 129029 z 1999 to point 49 155 + line 134021 z 1999 to ref 128517 +dirscanvas 134149 z 1000 linkcanvas_ref 134021 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "19 releaseBuffer()" xyz 65 100 3000 +msgs + msg operation_ref 135685 // "pull()" + forward ranks 1 "1" dirscanvas_ref 129285 + msgs + msg operation_ref 135557 // "retrieve()" + forward ranks 2 "1.1" dirscanvas_ref 130309 + msgs + msg operation_ref 135813 // "fetch()" + forward ranks 3 "1.1.1" dirscanvas_ref 131717 + no_msg + msg operation_ref 135685 // "pull()" + forward ranks 4 "1.1.2" dirscanvas_ref 130437 + msgs + msg operation_ref 135557 // "retrieve()" + forward ranks 5 "1.1.2.1" dirscanvas_ref 130693 + msgs + msg operation_ref 135685 // "pull()" + forward ranks 6 "1.1.2.1.1" dirscanvas_ref 131845 + msgs + msg operation_ref 135557 // "retrieve()" + forward ranks 7 "1.1.2.1.1.1" dirscanvas_ref 131973 + msgs + msg operation_ref 135813 // "fetch()" + forward ranks 8 "1.1.2.1.1.1.1" dirscanvas_ref 132101 + msgs + explicitmsg "fetch" + forward ranks 9 "1.1.2.1.1.1.1.1" dirscanvas_ref 132229 + no_msg + msgsend + msgsend + msgsend + msgsend + msgsend + msgsend + msgsend + msg operation_ref 135941 // "allocateBuffer()" + forward ranks 10 "2" dirscanvas_ref 132997 + msgs + msg operation_ref 135941 // "allocateBuffer()" + forward ranks 11 "2.1" dirscanvas_ref 131717 + msgs + explicitmsg "allocateNewFrame" + forward ranks 12 "2.1.1" dirscanvas_ref 132229 + no_msg + msgsend + msgsend + msg operation_ref 136069 // "process()" + backward ranks 13 "3" dirscanvas_ref 130693 + no_msg + msg operation_ref 136197 // "releaseBuffer()" + forward ranks 14 "4" dirscanvas_ref 133765 + msgs + explicitmsg "releaseFrame" + forward ranks 15 "4.1" dirscanvas_ref 132229 + no_msg + msgsend + msg operation_ref 136069 // "process()" + backward ranks 16 "5" dirscanvas_ref 130309 + no_msg + msg operation_ref 136325 // "isCalculated()" + forward ranks 17 "6" dirscanvas_ref 131717 + msgs + explicitmsg "isCalculatedFrame" + forward ranks 18 "6.1" dirscanvas_ref 132229 + no_msg + msgsend + msg operation_ref 136197 // "releaseBuffer()" + forward ranks 19 "7" dirscanvas_ref 134149 + msgs + explicitmsg "releaseFrame" + forward ranks 20 "7.1" dirscanvas_ref 132229 + no_msg + msgsend +msgsend +end diff --git a/uml/lumiera/5.session b/uml/lumiera/5.session index 5f7a09a5a..dc8936ef6 100644 --- a/uml/lumiera/5.session +++ b/uml/lumiera/5.session @@ -1,20 +1,20 @@ window_sizes 1140 830 270 860 680 71 diagrams - active collaborationdiagram_ref 132101 // pull call - 599 408 100 4 0 0 - classdiagram_ref 131973 // Engine Details - 414 544 100 4 0 0 - classdiagram_ref 128389 // Render Entities - 829 656 100 4 162 0 + classdiagram_ref 131973 // Render Mechanics + 428 623 100 4 2 0 + active collaborationdiagram_ref 132229 // Render Process + 817 644 100 4 0 0 end show_stereotypes selected package_ref 129 // lumiera open + class_ref 132741 // State - package_ref 128261 // MObject - classview_ref 128133 // Engine Workings - usecaseview_ref 128517 // render process + package_ref 129029 // Controller + class_ref 131717 // ProcNode + class_ref 142597 // StateAdapter + usecaseview_ref 128005 // Renderengine Use class_ref 140677 // QueryHandler class_ref 140805 // TypeHandler class_ref 140933 // ResolverBase diff --git a/uml/lumiera/lumiera.prj b/uml/lumiera/lumiera.prj index 93cb8fa6f..2b3a34ea7 100644 --- a/uml/lumiera/lumiera.prj +++ b/uml/lumiera/lumiera.prj @@ -1,6 +1,6 @@ format 40 "lumiera" - revision 45 + revision 46 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 09256ec75..6f55a4ef0 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -917,6 +917,15 @@ TertiaryMid: #99a TertiaryDark: #667 Error: #f88 +
          +
          The Connection Manager is a __Facade__ for querying information and deriving decisions regarding various aspects of data streams and possible connections.
          +* retrieve information about capabilities of a stream type given by ID
          +* decide if a connection is possible
          +* retrieve a //strategy// for implementing a connection
          +
          +In the intended implementation, a good deal of this functionality will actually be implemented by [[rules|ConfigRules]], while other parts need to be provided by hard wired logic, at least as a fallback. Anyway, the purpose of the Connection Manager ois to isolate the [[Builder]], which is client of this information and decision services, from these details
          +
          +
          Configuration Queries are requests to the system to "create or retrieve an object with //this and that // capabilities". They are resolved by a rule based system ({{red{planned feature}}}) and the user can extend the used rules for each Session. Syntactically, they are stated in ''prolog'' syntax as a conjunction (=logical and) of ''predicates'', for example {{{stream(mpeg), pipe(myPipe)}}}. Queries are typed to the kind of expected result object: {{{Query<Pipe> ("stream(mpeg)")}}} requests a pipe excepting/delivering mpeg stream data &mdash; and it depends on the current configuration what "mpeg" means. If there is any stream data producing component in the system, which advertises to deliver {{{stream(mpeg)}}}, and a pipe can be configured or connected with this component, then the [[defaults manager|DefaultsManagement]] will create/deliver a [[Pipe|PipeHandling]] object configured accordingly.
           &rarr; [[Configuration Rules system|ConfigRules]]
          @@ -1886,12 +1895,12 @@ But because I know the opinions on this topc are varying (users tend to be delig
           My proposed aproach is to treat OpenGL as a separate video raw data type, requiring separete and specialized [[Processing Nodes|ProcNode]] for all calculations. Thus the Builder could connect OpenGL nodes if it is possible to cover the whole render path for preview and fall back to the normal ~ProcNodes for all relevant renders
           
          -
          +
          A low-level abstraction within the [[Builder]] &mdash; it serves to encapsulate the details of making multi-channel connections between the render nodes: In some cases, a node can handle N channels internally, while in other cases we need to replicate the node N times and wire each channel individually.
           
           The operation point is provided by the current BuilderMould and used by the [[processing pattern|ProcPatt]] executing within this mould and conducting the current build step. The operation point's interface allows //to abstract//&nbsp; these details, as well as to //gain additional control//&nbsp; if necessary (e.g. addressing only one of the channels). The most prominent build instruction used within the processing patterns (which is the instruction {{{"attach"}}}) relies on the aforementioned //approach of abstracted handling,// letting the operation point determine automatically how to make the connection.
           
          -This is possible because the operation point has been provided (by the mould) with informations about the media stream type to be wired, while at the same time relying on the [[render node interface|ProcNode]] for finding out whats possible and making the desired connections.
          +This is possible because the operation point has been provided (by the mould) with informations about the media stream type to be wired, which, together with information accessible at the the [[render node interface|ProcNode]] and from the [[referred processing assets|ProcAsset]], with the help of the [[connection manager|ConManager]] allows to figure out what's possible and how to do the desired connections.
           
          @@ -3026,33 +3035,57 @@ At first sight the link between asset and clip-MO is a simple logical relation b [img[Entities comprising the Render Engine|uml/fig128389.png]]
          -
          -
          While with respect to the dependencies, the builder and the processing function, the render process is sufficiently characterized by referring to the ''pull principle'' and by defining a [[protocol|NodeOperationProtocol]] each node has to adhere to &mdash; for actually make it happen we have to care for some important details, especially //how to manage the buffers.// It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent within the inner pixel loop of these functions. But my guess is (as of 5/08), that the number of data moving and copying operations //will be//&nbsp; of importance.
          +
          +
          While the render process, with respect to the dependencies, the builder and the processing function is sufficiently characterized by referring to the ''pull principle'' and by defining a [[protocol|NodeOperationProtocol]] each node has to adhere to &mdash; for actually get it coded we have to care for some important details, especially //how to manage the buffers.// It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent at the inner pixel loop within these functions. But my guess is (as of 5/08), that the overall number of data moving and copying operations //will be//&nbsp; of importance.
           
           !reguirements
           * operations should be "in place" as much as possible
           * because caching necessitates a copy, the points where this happens should be controllable.
           * buffers should accommodate automatically to provide the necessary space without clipping the image.
           * the type of the media data can change while passing through the network, and so does the type of the buffers.
          -On the other hand, the processing function within the individual node needs to be shielded from these complexities. It can expect to get just //N~~I~~// input buffers and //N~O~// output buffers of required type. And, moreover, as the decision how to organize the buffers certainly depends on non-local circumstances, it should be preconfigured while building.
          +On the other hand, the processing function within the individual node needs to be shielded from these complexities. It can expect to get just //N~~I~~// input buffers and //N~~O~~// output buffers of required type. And, moreover, as the decision how to organize the buffers certainly depends on non-local circumstances, it should be preconfigured while building.
           
           !data flow
           [>img[uml/fig131973.png]]
          -Not everything can be preconfigured though. The pull principle opens the possibility for the node to decide on a per call base what predecessor(s) to pull (if any). This decision may rely on automation parameters, which thus need to be accessible prior to 
          -requesting the buffer(s). Additionally, in a later version we plan to have the node network calculate some control values for adjusting the cache and backend timings &mdash; and of course at some point we'll want to utilize the GPU, resulting in the need to feed data from our processing buffers into some texture representation.
          +Not everything can be preconfigured though. The pull principle opens the possibility for the node to decide on a per call base what predecessor(s) to pull (if any). This decision may rely on automation parameters, which thus need to be accessible prior to requesting the buffer(s). Additionally, in a later version we plan to have the node network calculate some control values for adjusting the cache and backend timings &mdash; and of course at some point we'll want to utilize the GPU, resulting in the need to feed data from our processing buffers into some texture representation.
           
           !buffer management
          -Besides the StateProxy representing the actual render process and holding a couple of buffer (refs), we employ a lightweight adapter object in between. It is used //for a single {{{pull()}}}-call// &mdash; mapping the actual buffers to the input and output port numbers of the processing node and for dealing with the cache calls. While the StateProxy manages a pool of frame buffers, this interspersed adapter allows us to either use a buffer retrieved from the cache as an input, possibly use a new buffer located within the cache as output, or (in case no caching happens) to just use the same buffer as input and output for "in-place"-processing. The idea is that most of the configuration of this adapter object is prepared in the wiring step while building the node network. 
          +Besides the StateProxy representing the actual render process and holding a couple of buffer (refs), we employ a lightweight adapter object in between. It is used //for a single {{{pull()}}}-call// &mdash; mapping the actual buffers to the input and output port numbers of the processing node and for dealing with the cache calls. While the StateProxy manages a pool of frame buffers, this interspersed adapter allows us to either use a buffer retrieved from the cache as an input, possibly use a new buffer located within the cache as output, or (in case no caching happens) to just use the same buffer as input and output for "in-place"-processing. The idea is that most of the configuration of this adapter object is prepared in the wiring step while building the node network.
          +
          +The usage patern of the buffers can be stack-like when processing nodes requiring multiple input buffers. In the standard case, which also is the simplest case, a pair of buffers (or a single buffer for "in-place" capable nodes) suffices to calculate a whole chain of nodes. But &mdash; as the recursive descent means depth-first processing &mdash; in case multiple input buffers are needed, we may encounter a situation where some of these input buffers already contain processed data, while we have to descend into yet another predecessor node chain to pull the data for the remaining buffers. Care has to be taken //to allocate the buffers as late as possible,// otherwise we could end up holding onto a buffer almost for each node in the network. Effectively this translates into the rule to allocate output buffers only after all input buffers are ready and filled with data; thus we shouldn't allocate buffers when //entering// the recursive call to the predecessor(s), rather we have to wait until we are about to return from the downcall chain.
          +Besides, these considerations also show we need a means of passing on the current buffer usage pattern while calling down. This usage pattern not only includes a record of what buffers are occupied, but also the intended use of these occupied buffers, especially if they can be modified in-place, and at which point they may be released and reused.
           @@clear(right):display(block):@@
           
          -
          +
          For each segment (of the effective timeline), there is a Processor holding the exit node(s) of a processing network, which is a "Directed Acyclic Graph" of small, preconfigured, stateless [[processing nodes|ProcNode]]. This network is operated according to the ''pull principle'', meaning that the rendering is just initiated by "pulling" output from the exit node, causing a cascade of recursive downcalls. Each node knows its predecessor(s) an can pull the necessary input from there. Consequently, there is no centralized "engine object" which may invoke nodes iteratively or table driven &mdash; rather, the rendering can be seen as a passive service provided for the backend, which may pull from the exit nodes at any time, in any order (?), and possibly multithreaded.
          -All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy provides the buffers holding data to be processed and acts as a gateway to the backend to handle the communication with the Cache.
          +All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy provides the buffers holding data to be processed and acts as a gateway to the backend to handle the communication with the Cache. In addition to this //top-level State,// each calculation step includes a small [[state adapter object|StateAdapter]] (stack allocated), which is pre-configured by the builder and serves the purpose to isolate the processing function from the detals of buffer management.
           
          -{{red{TODO: fill in more details of the Render Process.}}}
          -[img[uml/fig132101.png]]
          -* see also
          +!!Example: calculating a 3 node chain
          +[img[uml/fig132229.png]]
          +# Caller invokes calculation by pulling from exit node, providing the top-level StateProxy
          +# node1 (exit node) builds StateAdapter and calls retrieve() on it to get the desired output result
          +# this StateAdapter (ad1) knows he could get the result from Cache, so he tries, but it's a miss
          +# thus he pulls from the predecessor node2 according to the [[input descriptor|ProcNodeInputDescriptor]] of node1
          +# node2 builds its StateAdapter and calls retrieve()
          +# but because StateAdapter (ad2) is configured to directly forward the call down, it pulls from node3
          +# node3 builds its StateAdapter and calls retrieve()
          +# this StateAdapter (ad3) is configured to look into the Cache...
          +# this time producing a Cache hit
          +# now StateAdapter ad2 has input data, but needs a output buffer location, which re requests from its //parent state// (ad1)
          +# and, because ad1 is configured for Caching, it's clear that this output buffer will be located within the cache
          +# thus the allocation request is forwarded to the cache, which provides a new "slot"
          +# now node2 has both a valid input and a usable output buffer, thus the process function can be invoked
          +# and after the result has been rendered into the output buffer, the input is no longer needed
          +# and can be "unlocked" in the Cache
          +# now the input data for node1 is available, and as node1 is in-place-capable, no further buffer allocation is necessary prior to calculating
          +# the finished result is now in the buffer (which happens to be also the input buffer and is actually located within the Cache)
          +# thus it can be marked as ready for the Cache, which may now provide it to other processes (but isn't allowed to overwrite it)
          +# finally, when the caller is done with the data, it signalles this to the top-level State object
          +# which forwards this information to the cache, which in turn may now do with the released Buffer as he sees fit.
          +
          +
          +__see also__
           &rarr; the [[Entities involved in Rendering|RenderEntities]]
           &rarr; the [[mechanics of rendering and buffer management|RenderMechanics]]
           &rarr; the protocol [[how to operate the nodes|NodeOperationProtocol]]
          
          From eeb2d04dee6f109831c1874150a7df8a14d35ba2 Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Sat, 14 Jun 2008 04:19:58 +0200
          Subject: [PATCH 136/245] WIP trying to translate some of the planned pull()
           process into code...
          
          ---
           doc/devel/uml/fig131973.png                 | Bin 18410 -> 19757 bytes
           src/proc/engine/aframe.cpp                  |  34 --------
           src/proc/engine/aframe.hpp                  |  41 ----------
           src/proc/engine/arender.cpp                 |  34 --------
           src/proc/engine/arender.hpp                 |  44 ----------
           src/proc/engine/exitnode.cpp                |  33 --------
           src/proc/engine/exitnode.hpp                |  45 ----------
           src/proc/engine/glbuf.cpp                   |  34 --------
           src/proc/engine/glbuf.hpp                   |  39 ---------
           src/proc/engine/glrender.cpp                |  33 --------
           src/proc/engine/glrender.hpp                |  42 ----------
           src/proc/engine/processor.cpp               |   3 +-
           src/proc/engine/processor.hpp               |   2 +-
           src/proc/engine/procnode.hpp                |  86 ++++++++++++++++----
           src/proc/{ => engine}/stateproxy.cpp        |  10 +--
           src/proc/{ => engine}/stateproxy.hpp        |  21 ++---
           src/proc/engine/vframe.cpp                  |  33 --------
           src/proc/engine/vframe.hpp                  |  41 ----------
           src/proc/engine/vrender.cpp                 |  33 --------
           src/proc/engine/vrender.hpp                 |  47 -----------
           src/proc/mobject/controller/renderstate.cpp |  44 ----------
           src/proc/mobject/controller/renderstate.hpp |   7 +-
           src/proc/{frame.cpp => state.cpp}           |   5 +-
           src/proc/{frame.hpp => state.hpp}           |  31 ++++---
           uml/lumiera/131973.diagram                  |  40 ++++-----
           wiki/renderengine.html                      |  33 +++++---
           26 files changed, 155 insertions(+), 660 deletions(-)
           delete mode 100644 src/proc/engine/aframe.cpp
           delete mode 100644 src/proc/engine/aframe.hpp
           delete mode 100644 src/proc/engine/arender.cpp
           delete mode 100644 src/proc/engine/arender.hpp
           delete mode 100644 src/proc/engine/exitnode.cpp
           delete mode 100644 src/proc/engine/exitnode.hpp
           delete mode 100644 src/proc/engine/glbuf.cpp
           delete mode 100644 src/proc/engine/glbuf.hpp
           delete mode 100644 src/proc/engine/glrender.cpp
           delete mode 100644 src/proc/engine/glrender.hpp
           rename src/proc/{ => engine}/stateproxy.cpp (81%)
           rename src/proc/{ => engine}/stateproxy.hpp (73%)
           delete mode 100644 src/proc/engine/vframe.cpp
           delete mode 100644 src/proc/engine/vframe.hpp
           delete mode 100644 src/proc/engine/vrender.cpp
           delete mode 100644 src/proc/engine/vrender.hpp
           delete mode 100644 src/proc/mobject/controller/renderstate.cpp
           rename src/proc/{frame.cpp => state.cpp} (80%)
           rename src/proc/{frame.hpp => state.hpp} (56%)
          
          diff --git a/doc/devel/uml/fig131973.png b/doc/devel/uml/fig131973.png
          index 7ed45dca7a110940795f165d53c21648bc62223e..be9cb51564238eb28f1a53ac2650c41be296ed25 100644
          GIT binary patch
          literal 19757
          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
          OkMs+9XyLQBKK~0|cLhZN
          
          literal 18410
          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
          
          diff --git a/src/proc/engine/aframe.cpp b/src/proc/engine/aframe.cpp
          deleted file mode 100644
          index e8713897b..000000000
          --- a/src/proc/engine/aframe.cpp
          +++ /dev/null
          @@ -1,34 +0,0 @@
          -/*
          -  AFrame  -  buffer holding a Audio samples for the render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/aframe.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/aframe.hpp b/src/proc/engine/aframe.hpp
          deleted file mode 100644
          index 0d77e15ca..000000000
          --- a/src/proc/engine/aframe.hpp
          +++ /dev/null
          @@ -1,41 +0,0 @@
          -/*
          -  AFRAME.hpp  -  buffer holding a Audio samples for the render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_AFRAME_H
          -#define ENGINE_AFRAME_H
          -
          -#include "proc/frame.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  class AFrame : public proc_interface::Frame
          -    {};
          -
          -
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/arender.cpp b/src/proc/engine/arender.cpp
          deleted file mode 100644
          index ac7171998..000000000
          --- a/src/proc/engine/arender.cpp
          +++ /dev/null
          @@ -1,34 +0,0 @@
          -/*
          -  ARender  -  Representation of a Audio Render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/arender.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/arender.hpp b/src/proc/engine/arender.hpp
          deleted file mode 100644
          index 79c70c460..000000000
          --- a/src/proc/engine/arender.hpp
          +++ /dev/null
          @@ -1,44 +0,0 @@
          -/*
          -  ARENDER.hpp  -  Representation of a Audio Render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_ARENDER_H
          -#define ENGINE_ARENDER_H
          -
          -#include "proc/stateproxy.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -  
          -  
          -  /**
          -   * Representation of a Audio render process
          -   */
          -  class ARender : public proc_interface::StateProxy
          -    {};
          -    
          -    
          -    
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/exitnode.cpp b/src/proc/engine/exitnode.cpp
          deleted file mode 100644
          index 8c26b7cd9..000000000
          --- a/src/proc/engine/exitnode.cpp
          +++ /dev/null
          @@ -1,33 +0,0 @@
          -/*
          -  ExitNode  -  special Processing Node providing "pullable" output
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/exitnode.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/exitnode.hpp b/src/proc/engine/exitnode.hpp
          deleted file mode 100644
          index 1cb6e51c2..000000000
          --- a/src/proc/engine/exitnode.hpp
          +++ /dev/null
          @@ -1,45 +0,0 @@
          -/*
          -  EXITNODE.hpp  -  special Processing Node providing "pullable" output
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_EXITNODE_H
          -#define ENGINE_EXITNODE_H
          -
          -#include "proc/engine/procnode.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  /**
          -   * The output end of each render pipeline.
          -   * Pulling from such exit nodes actually ivokes the render process
          -   */
          -  class ExitNode : public ProcNode
          -    {};
          -
          -
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/glbuf.cpp b/src/proc/engine/glbuf.cpp
          deleted file mode 100644
          index 6970a3114..000000000
          --- a/src/proc/engine/glbuf.cpp
          +++ /dev/null
          @@ -1,34 +0,0 @@
          -/*
          -  GLBuf  -  a buffer and render process holding a Video frame for OpenGL rendering
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/glbuf.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/glbuf.hpp b/src/proc/engine/glbuf.hpp
          deleted file mode 100644
          index 8e8ee2ea5..000000000
          --- a/src/proc/engine/glbuf.hpp
          +++ /dev/null
          @@ -1,39 +0,0 @@
          -/*
          -  GLBUF.hpp  -  a buffer and render process holding a Video frame for OpenGL rendering
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_GLBUF_H
          -#define ENGINE_GLBUF_H
          -
          -#include "proc/frame.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  class GLBuf : public proc_interface::Frame
          -    {};
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/glrender.cpp b/src/proc/engine/glrender.cpp
          deleted file mode 100644
          index 32420201b..000000000
          --- a/src/proc/engine/glrender.cpp
          +++ /dev/null
          @@ -1,33 +0,0 @@
          -/*
          -  GLRender  -  Representation of a OpenGL accellerated Video render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/glrender.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/glrender.hpp b/src/proc/engine/glrender.hpp
          deleted file mode 100644
          index e9c73c3a3..000000000
          --- a/src/proc/engine/glrender.hpp
          +++ /dev/null
          @@ -1,42 +0,0 @@
          -/*
          -  GLRENDER.hpp  -  Representation of a OpenGL accellerated Video render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_GLRENDER_H
          -#define ENGINE_GLRENDER_H
          -
          -#include "proc/stateproxy.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  /**
          -   * Representation of a OpenGL accelerated Video render process
          -   */
          -  class GLRender : public proc_interface::StateProxy
          -    {};
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/processor.cpp b/src/proc/engine/processor.cpp
          index c8a228845..38ed34c5d 100644
          --- a/src/proc/engine/processor.cpp
          +++ b/src/proc/engine/processor.cpp
          @@ -22,8 +22,7 @@
           
           
           #include "proc/engine/processor.hpp"
          -#include "proc/engine/exitnode.hpp"
          -#include "proc/stateproxy.hpp"
          +#include "proc/state.hpp"
           
           namespace engine
             {
          diff --git a/src/proc/engine/processor.hpp b/src/proc/engine/processor.hpp
          index 164fa8bfa..3f0890c93 100644
          --- a/src/proc/engine/processor.hpp
          +++ b/src/proc/engine/processor.hpp
          @@ -25,7 +25,7 @@
           #define ENGINE_PROCESSOR_H
           
           #include "proc/lumiera.hpp"
          -#include "proc/stateproxy.hpp"
          +#include "proc/state.hpp"
           
           
           
          diff --git a/src/proc/engine/procnode.hpp b/src/proc/engine/procnode.hpp
          index e2a4c89b9..a3dc5d702 100644
          --- a/src/proc/engine/procnode.hpp
          +++ b/src/proc/engine/procnode.hpp
          @@ -26,6 +26,7 @@
           
           #include 
           
          +#include "proc/state.hpp"
           #include "proc/mobject/parameter.hpp"
           
           
          @@ -34,25 +35,63 @@
           namespace engine {
           
             using std::vector;
          +  using proc_interface::State;
             
             class ProcNode;
             class NodeFactory;
             
          -  typedef ProcNode* PNode;    ///< @todo handle ProcNode by pointer or by shared-ptr??
          -
          +  typedef ProcNode* PNode;
          +  
          +  
          +  /**
          +   * Description of the input and output ports and the
          +   * predecessor nodes for a given ProcNode.
          +   */
          +  struct WiringDescriptor
          +    {
          +      
          +    };
          +    
           
          +  /**
          +   * Adapter to shield the ProcNode from the actual buffer management,
          +   * allowing the processing function within ProcNode to use logical
          +   * buffer IDs. StateAdapter is created on the stack for each pull()
          +   * call, using setup/wiring data preconfigured by the builder.
          +   * Its job is to provide the actual implementation of the Cache
          +   * push / fetch and recursive downcall to render the source frames.
          +   */
          +  class StateAdapter
          +    : public State
          +    {
          +      State& parent_;
          +      State& current_;
          +      
          +    protected:
          +      StateAdapter (State& callingProcess, WiringDescriptor const&) 
          +        : parent_ (callingProcess),
          +          current_(callingProcess.getCurrentImplementation())
          +        { }
          +      
          +      friend class ProcNode; // both are sharing implementation details...
          +      
          +      
          +      virtual State& getCurrentImplementation () { return current_; }
          +      
          +      /** contains the details of Cache query and recursive calls
          +       *  to the predecessor node(s), eventually followed by the 
          +       *  ProcNode::process() callback
          +       */
          +      void retrieve();
          +    };
          +  
          +  
             /**
              * Key abstraction of the Render Engine: A Data processing Node
              */
             class ProcNode
               {
          -      typedef mobject::Parameter Param;
          -
          -      /** The predecessor in a processing pipeline.
          -       *  I.e. a source to get data to be processed
          -       */
          -      PNode datasrc;
          -
          +      typedef mobject::Parameter Param;   //////TODO: just a placeholder for automation as of 6/2008
                 vector params;
           
               protected:
          @@ -62,20 +101,35 @@ namespace engine {
                 friend class NodeFactory;
                 
                 
          -      /** do the actual calculations.
          +      /** Callback doing the actual calculations
          +       *  after input / output buffers are ready
                  *  @internal dispatch to implementation. 
          -       *            Client code should use #render()
          -       *  @todo obviously we need a parameter!!!
          +       *            Client code should use #pull()
                  */
          -      virtual void process() = 0;
          +      virtual void process(State&) = 0;
          +      
          +      friend void StateAdapter::retrieve();  // to issue the process() callback if necessary
          +      
          +      
          +      /** Extension point for subclasses to modify the input sources
          +       *  according to automation data and other state dependent properties. 
          +       */
          +      virtual WiringDescriptor const& getWiring (State&); 
          +      
           
               public:
                 static NodeFactory create;
                 
          -      /** render and pull output from this node.
          -       *  @todo define the parameter!!!
          +      /** Engine Core operation: render and pull output from this node.
          +       *  On return, currentProcess will hold onto output buffer(s)
          +       *  containing the calculated result frames.
                  */
          -      void render() { this->process(); }
          +      void 
          +      pull (State& currentProcess) 
          +        {
          +          StateAdapter thisStep (currentProcess, getWiring (currentProcess));
          +          thisStep.retrieve(); // fetch or calculate results
          +        }
           
               };
           
          diff --git a/src/proc/stateproxy.cpp b/src/proc/engine/stateproxy.cpp
          similarity index 81%
          rename from src/proc/stateproxy.cpp
          rename to src/proc/engine/stateproxy.cpp
          index f4125a41e..6e2566d3e 100644
          --- a/src/proc/stateproxy.cpp
          +++ b/src/proc/engine/stateproxy.cpp
          @@ -1,5 +1,5 @@
           /*
          -  StateProxy  -  Key Interface representing a render process and encapsulating state
          +  StateProxy  -  Encapsulation of the state corresponding to a render calculation
            
             Copyright (C)         Lumiera.org
               2008,               Hermann Vosseler 
          @@ -21,14 +21,12 @@
           * *****************************************************/
           
           
          -#include "proc/stateproxy.hpp"
          -#include "proc/frame.hpp"
          +#include "proc/engine/stateproxy.hpp"
           
          -namespace proc_interface
          -  {
          +namespace engine {
             
             /** */
             
             
             
          -} // namespace proc_interface
          +} // namespace engine
          diff --git a/src/proc/stateproxy.hpp b/src/proc/engine/stateproxy.hpp
          similarity index 73%
          rename from src/proc/stateproxy.hpp
          rename to src/proc/engine/stateproxy.hpp
          index 7c338bd1d..ff7d107d3 100644
          --- a/src/proc/stateproxy.hpp
          +++ b/src/proc/engine/stateproxy.hpp
          @@ -1,5 +1,5 @@
           /*
          -  STATEPROXY.hpp  -  Key Interface representing a render process and encapsulating state
          +  STATEPROXY.hpp  -  Encapsulation of the state corresponding to a render calculation
            
             Copyright (C)         Lumiera.org
               2008,               Hermann Vosseler 
          @@ -21,25 +21,26 @@
           */
           
           
          -#ifndef PROC_INTERFACE_STATEPROXY_H
          -#define PROC_INTERFACE_STATEPROXY_H
          -
          -#include "proc/frame.hpp"
          +#ifndef ENGINE_STATEPROXY_H
          +#define ENGINE_STATEPROXY_H
           
           
          +#include "proc/state.hpp"
          +
          +
          +namespace engine {
           
          -namespace proc_interface
          -  {
           
           
             class StateProxy
          +    : public proc_interface::State
               {
               protected:
          -      Frame * currFrame;
          -
          +      virtual State& getCurrentImplementation () { return *this; }
          +      
               };
               
               
               
          -} // namespace proc_interface
          +} // namespace engine
           #endif
          diff --git a/src/proc/engine/vframe.cpp b/src/proc/engine/vframe.cpp
          deleted file mode 100644
          index 180faca70..000000000
          --- a/src/proc/engine/vframe.cpp
          +++ /dev/null
          @@ -1,33 +0,0 @@
          -/*
          -  VFrame  -  a buffer holding a Video frame for the render process 
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/vframe.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/vframe.hpp b/src/proc/engine/vframe.hpp
          deleted file mode 100644
          index 6b1e8153b..000000000
          --- a/src/proc/engine/vframe.hpp
          +++ /dev/null
          @@ -1,41 +0,0 @@
          -/*
          -  VFRAME.hpp  -  a buffer holding a Video frame for the render process 
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_VFRAME_H
          -#define ENGINE_VFRAME_H
          -
          -#include "proc/frame.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  class VFrame : public proc_interface::Frame
          -    {
          -      ///////////////////////
          -    };
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/vrender.cpp b/src/proc/engine/vrender.cpp
          deleted file mode 100644
          index 2bed41099..000000000
          --- a/src/proc/engine/vrender.cpp
          +++ /dev/null
          @@ -1,33 +0,0 @@
          -/*
          -  VRender  -  Representation of a Video render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/vrender.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -  } // namespace engine
          diff --git a/src/proc/engine/vrender.hpp b/src/proc/engine/vrender.hpp
          deleted file mode 100644
          index c6a34bda2..000000000
          --- a/src/proc/engine/vrender.hpp
          +++ /dev/null
          @@ -1,47 +0,0 @@
          -/*
          -  VRENDER.hpp  -  Representation of a Video render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_VRENDER_H
          -#define ENGINE_VRENDER_H
          -
          -#include "proc/stateproxy.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  /**
          -   * Representation of a Video render process.
          -   * (Encapsulates the video buffers for the actual calculations)
          -   */
          -  class VRender : public proc_interface::StateProxy
          -    {
          -      /////////////
          -    };
          -
          -
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/mobject/controller/renderstate.cpp b/src/proc/mobject/controller/renderstate.cpp
          deleted file mode 100644
          index 98ca2ccd1..000000000
          --- a/src/proc/mobject/controller/renderstate.cpp
          +++ /dev/null
          @@ -1,44 +0,0 @@
          -/*
          -  RenderState  -  renderengine state manager
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program 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 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program 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 this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/mobject/controller/renderstate.hpp"
          -
          -
          -namespace mobject
          -  {
          -  namespace controller
          -    {
          -
          -
          -
          -    StateProxy&
          -    RenderState::getStateProxy ()
          -    {
          -      //////////////TODO
          -    }
          -
          -
          -
          -  } // namespace mobject::controller
          -
          -} // namespace mobject
          diff --git a/src/proc/mobject/controller/renderstate.hpp b/src/proc/mobject/controller/renderstate.hpp
          index c547772ea..833e2d347 100644
          --- a/src/proc/mobject/controller/renderstate.hpp
          +++ b/src/proc/mobject/controller/renderstate.hpp
          @@ -24,7 +24,7 @@
           #ifndef MOBJECT_CONTROLLER_RENDERSTATE_H
           #define MOBJECT_CONTROLLER_RENDERSTATE_H
           
          -#include "proc/stateproxy.hpp"
          +#include "proc/state.hpp"
           
           
           
          @@ -33,7 +33,7 @@ namespace mobject
             namespace controller
               {
           
          -    typedef proc_interface::StateProxy StateProxy;
          +    typedef proc_interface::State State;
           
           
               /**
          @@ -42,11 +42,12 @@ namespace mobject
                * The provided StateProxy serves to hold any mutalbe state used
                * in the render process, so the rest of the render engine 
                * can be stateless.
          +     * @todo probably the state management will work different (6/08)
                */
               class RenderState
                 {
                 public:
          -        StateProxy& getStateProxy () ;
          +        State& getRenderProcess () ;
                 };
           
           
          diff --git a/src/proc/frame.cpp b/src/proc/state.cpp
          similarity index 80%
          rename from src/proc/frame.cpp
          rename to src/proc/state.cpp
          index 46ad06950..fa9f32dc3 100644
          --- a/src/proc/frame.cpp
          +++ b/src/proc/state.cpp
          @@ -1,5 +1,5 @@
           /*
          -  Frame  -  Key Abstraction: render process and buffer holding frame data.
          +  State  -  Key Interface representing a render process and encapsulating state
            
             Copyright (C)         Lumiera.org
               2008,               Hermann Vosseler 
          @@ -21,11 +21,12 @@
           * *****************************************************/
           
           
          -#include "proc/frame.hpp"
          +#include "proc/state.hpp"
           
           namespace proc_interface
             {
             
          +  ////////////////////////////////TODO: State is a high -level interface, so can we get rid of this implementation file?
             /** */
             
             
          diff --git a/src/proc/frame.hpp b/src/proc/state.hpp
          similarity index 56%
          rename from src/proc/frame.hpp
          rename to src/proc/state.hpp
          index 239987e97..98fe1aa9f 100644
          --- a/src/proc/frame.hpp
          +++ b/src/proc/state.hpp
          @@ -1,5 +1,5 @@
           /*
          -  FRAME.hpp  -  Key Abstraction: render process and buffer holding frame data.
          +  STATE.hpp  -  Key Interface representing a render process and encapsulating state
            
             Copyright (C)         Lumiera.org
               2008,               Hermann Vosseler 
          @@ -21,23 +21,34 @@
           */
           
           
          -#ifndef PROC_INTERFACE_FRAME_H
          -#define PROC_INTERFACE_FRAME_H
          +#ifndef PROC_INTERFACE_STATE_H
          +#define PROC_INTERFACE_STATE_H
           
           
           
          +namespace engine { class StateAdapter; }
          +
           namespace proc_interface
             {
           
           
          -  /**
          -   * TODO: how to relate to Cehteh's Frame entity in the Backend?
          -   * The latter is the fundamental Frame entity, wheras this Object 
          -   * rather represents a buffer set containing frame date.
          -   */
          -  class Frame
          +  class State
               {
          -      /////////////////
          +    protected:
          +      virtual ~State() {};
          +      
          +      /** resolves to the State object currently "in charge".
          +       *  Intended as a performance shortcut to avoid calling
          +       *  up through a chain of virtual functions when deep down
          +       *  in chained ProcNode::pull() calls. This allows derived
          +       *  classes to proxy the state inteface.
          +       */ 
          +      virtual State& getCurrentImplementation () =0;
          +      
          +      friend class engine::StateAdapter;
          +      
          +    public:
          +      
               };
               
               
          diff --git a/uml/lumiera/131973.diagram b/uml/lumiera/131973.diagram
          index 7a9c0af13..42c38a979 100644
          --- a/uml/lumiera/131973.diagram
          +++ b/uml/lumiera/131973.diagram
          @@ -2,58 +2,58 @@ format 40
           
           classcanvas 128005 class_ref 131717 // ProcNode
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 106 313 2004
          +  xyz 103 405 2004
             end
           classcanvas 128517 class_ref 132741 // State
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 79 -16 2000
          +  xyz 77 18 2000
             end
           classcanvas 129669 class_ref 133253 // Frame
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 267 221 3005
          +  xyz 264 313 3005
             end
           classcanvas 131845 class_ref 142469 // StateProxy
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 149 135 2000
          +  xyz 146 227 2000
             end
           classcanvas 131973 class_ref 142597 // StateAdapter
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 43 225 3010
          +  xyz 40 317 3010
             end
           classcanvas 132357 class_ref 142725 // InputDescriptor
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 233 434 2000
          +  xyz 230 526 2000
             end
           relationcanvas 129797 relation_ref 134533 // 
          -  from ref 128517 z 1999 stereotype "<>" xyz 282 103 3000 to point 303 129
          +  from ref 128517 z 1999 stereotype "<>" xyz 277 115 3000 to point 300 136
             line 130053 z 1999 to ref 129669
          -  role_a_pos 315 196 3000 no_role_b
          -  no_multiplicity_a multiplicity_b_pos 175 84 3000
          +  role_a_pos 312 288 3000 no_role_b
          +  no_multiplicity_a multiplicity_b_pos 173 109 3000
           relationcanvas 132101 relation_ref 148869 // 
             geometry VHV unfixed
          -  from ref 131973 z 1999 to point 81 108
          -  line 134021 z 1999 to point 120 108
          +  from ref 131973 z 1999 to point 78 189
          +  line 134021 z 1999 to point 118 189
             line 134149 z 1999 to ref 128517
             no_role_a no_role_b
             no_multiplicity_a no_multiplicity_b
           relationcanvas 132229 relation_ref 148997 // 
             geometry VHV
          -  from ref 131845 z 1999 to point 201 126
          -  line 134277 z 1999 to point 120 126
          +  from ref 131845 z 1999 to point 198 189
          +  line 134277 z 1999 to point 118 189
             line 134405 z 1999 to ref 128517
             no_role_a no_role_b
             no_multiplicity_a no_multiplicity_b
           relationcanvas 132485 relation_ref 149125 // 
             geometry HV
          -  from ref 128005 z 1999 stereotype "<>" xyz 220 359 3000 to point 278 360
          +  from ref 128005 z 1999 stereotype "<>" xyz 217 451 3000 to point 275 452
             line 133381 z 1999 to ref 132357
          -  role_a_pos 290 409 3000 no_role_b
          -  multiplicity_a_pos 266 409 3000 no_multiplicity_b
          +  role_a_pos 287 501 3000 no_role_b
          +  multiplicity_a_pos 263 501 3000 no_multiplicity_b
           relationcanvas 133509 relation_ref 149253 // 
          -  from ref 131973 z 1999 to point 200 215
          +  from ref 131973 z 1999 to point 197 307
             line 133637 z 1999 to ref 131845
          -  role_a_pos 180 222 3000 no_role_b
          -  multiplicity_a_pos 185 199 3000 no_multiplicity_b
          +  role_a_pos 177 314 3000 no_role_b
          +  multiplicity_a_pos 182 291 3000 no_multiplicity_b
           relationcanvas 134533 relation_ref 149381 // 
             from ref 131973 z 3004 to ref 129669
             no_role_a no_role_b
          @@ -61,7 +61,7 @@ relationcanvas 134533 relation_ref 149381 // 
           line 134661 -_-_
             from ref 131973 z 2003 to ref 128005
           line 134789 -_-_
          -  from ref 131973 z 2003 to point 137 322
          +  from ref 131973 z 2003 to point 134 414
             line 134917 z 2003 to ref 128005
           preferred_whz 414 544 1
           end
          diff --git a/wiki/renderengine.html b/wiki/renderengine.html
          index 6f55a4ef0..6c6366bb0 100644
          --- a/wiki/renderengine.html
          +++ b/wiki/renderengine.html
          @@ -1839,14 +1839,16 @@ So, when creating a clip out of such a compound media asset, the clip has to be
           
          NodeCreaterTool is a [[visiting tool|VisitorUse]] used as second step in the [[Builder]]. Starting out from a [[Fixture]], the builder first [[divides the Timeline into segments|SegmentationTool]] and then processes each segment with the NodeCreaterTool to build a render nodes network (Render Engine) for this part of the timeline. While visiting individual Objects and Placements, the NodeCreaterTool creates and wires the necessary [[nodes|ProcNode]]
          -
          +
          The [[nodes|ProcNode]] are wired to form a "Directed Acyclic Graph"; each node knows its predecessor(s), but not its successor(s).  The RenderProcess is organized according to the ''pull principle'', thus we find an operation {{{pull()}}} at the core of this process. There is no such thing as an "engine object" calling nodes iteratively or table driven, rather, the nodes themselves issue recursive calls to their predecessor(s). For this to work, we need the nodes to adhere to a specific protocol:
           # Node is pulled, with a StateProxy object as parameter (encapsulating the access to the frames or buffers)
           # Node may now access current parameter values, using the state accessible via the StateProxy
          -# Node calles back into the StateProxy for getting the input buffer(s), providing it's //input descriptor//
          -# StateProxy tries to get the input frames from the Cache in the Backend. In case of failure, the call is forwarded according to the input descriptor
          -# after this call returns, the Node is allowed to dereference the frame pointers and do its calculations
          -# finally, when the {{{pull()}}} call returns, the StateProxy may push down the result frames to the cache
          +# using it's //input-output descriptor,// the Node creates a StateAdapter wrapping the StateProxy for accessing the output to pull and probably the input needed to calculate this output
          +# StateAdapter first tries to get the output frames from the Cache in the Backend. In case of failure, a {{{process()}}} call is prepared by generating {{{pull()}}} call(s) for the input
          +# as late as possible, typically on return, these recursive pull-calls have allocated a buffer containing the input data.
          +# after all input is ready and prior to the {{{process()}}} call, the output buffers will be allocated, either from the cache, or alternatively (if not caching) from the "parent" StateAdapter up the callstack.
          +# after all buffers are available, the StateAdapter issues the {{{process()}}} call back to the originating node, which now may dereference the frame pointers and do its calculations
          +# finally, when the {{{pull()}}} call returns, "parent" state originating the pull holds onto the buffers containing the calculated output result.
           some points to note:
           * the input descriptor is {{{const}}} and precalculated while building (remember another thread may call in parallel)
           * when a node is "inplace-capable", input and output buffer may actually point to the same location
          @@ -3035,7 +3037,7 @@ At first sight the link between asset and clip-MO is a simple logical relation b
           [img[Entities comprising the Render Engine|uml/fig128389.png]]
           
          -
          +
          While the render process, with respect to the dependencies, the builder and the processing function is sufficiently characterized by referring to the ''pull principle'' and by defining a [[protocol|NodeOperationProtocol]] each node has to adhere to &mdash; for actually get it coded we have to care for some important details, especially //how to manage the buffers.// It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent at the inner pixel loop within these functions. But my guess is (as of 5/08), that the overall number of data moving and copying operations //will be//&nbsp; of importance.
           
           !reguirements
          @@ -3054,15 +3056,8 @@ Besides the StateProxy representing the actual render process and holding a coup
           
           The usage patern of the buffers can be stack-like when processing nodes requiring multiple input buffers. In the standard case, which also is the simplest case, a pair of buffers (or a single buffer for "in-place" capable nodes) suffices to calculate a whole chain of nodes. But &mdash; as the recursive descent means depth-first processing &mdash; in case multiple input buffers are needed, we may encounter a situation where some of these input buffers already contain processed data, while we have to descend into yet another predecessor node chain to pull the data for the remaining buffers. Care has to be taken //to allocate the buffers as late as possible,// otherwise we could end up holding onto a buffer almost for each node in the network. Effectively this translates into the rule to allocate output buffers only after all input buffers are ready and filled with data; thus we shouldn't allocate buffers when //entering// the recursive call to the predecessor(s), rather we have to wait until we are about to return from the downcall chain.
           Besides, these considerations also show we need a means of passing on the current buffer usage pattern while calling down. This usage pattern not only includes a record of what buffers are occupied, but also the intended use of these occupied buffers, especially if they can be modified in-place, and at which point they may be released and reused.
          -@@clear(right):display(block):@@
          -
          -
          -
          -
          For each segment (of the effective timeline), there is a Processor holding the exit node(s) of a processing network, which is a "Directed Acyclic Graph" of small, preconfigured, stateless [[processing nodes|ProcNode]]. This network is operated according to the ''pull principle'', meaning that the rendering is just initiated by "pulling" output from the exit node, causing a cascade of recursive downcalls. Each node knows its predecessor(s) an can pull the necessary input from there. Consequently, there is no centralized "engine object" which may invoke nodes iteratively or table driven &mdash; rather, the rendering can be seen as a passive service provided for the backend, which may pull from the exit nodes at any time, in any order (?), and possibly multithreaded.
          -All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy provides the buffers holding data to be processed and acts as a gateway to the backend to handle the communication with the Cache. In addition to this //top-level State,// each calculation step includes a small [[state adapter object|StateAdapter]] (stack allocated), which is pre-configured by the builder and serves the purpose to isolate the processing function from the detals of buffer management.
           
           !!Example: calculating a 3 node chain
          -[img[uml/fig132229.png]]
           # Caller invokes calculation by pulling from exit node, providing the top-level StateProxy
           # node1 (exit node) builds StateAdapter and calls retrieve() on it to get the desired output result
           # this StateAdapter (ad1) knows he could get the result from Cache, so he tries, but it's a miss
          @@ -3083,6 +3078,18 @@ All State necessary for a given calculation process is encapsulated and accessib
           # thus it can be marked as ready for the Cache, which may now provide it to other processes (but isn't allowed to overwrite it)
           # finally, when the caller is done with the data, it signalles this to the top-level State object
           # which forwards this information to the cache, which in turn may now do with the released Buffer as he sees fit.
          +[img[uml/fig132229.png]]
          +
          +@@clear(right):display(block):@@
          +__see also__
          +&rarr; the [[Entities involved in Rendering|RenderEntities]]
          +&rarr; [[Memory management for render nodes|ManagementRenderNodes]]
          +&rarr; the protocol [[how to operate the nodes|NodeOperationProtocol]]
          +
          +
          +
          +
          For each segment (of the effective timeline), there is a Processor holding the exit node(s) of a processing network, which is a "Directed Acyclic Graph" of small, preconfigured, stateless [[processing nodes|ProcNode]]. This network is operated according to the ''pull principle'', meaning that the rendering is just initiated by "pulling" output from the exit node, causing a cascade of recursive downcalls. Each node knows its predecessor(s) an can pull the necessary input from there. Consequently, there is no centralized "engine object" which may invoke nodes iteratively or table driven &mdash; rather, the rendering can be seen as a passive service provided for the backend, which may pull from the exit nodes at any time, in any order (?), and possibly multithreaded.
          +All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy provides the buffers holding data to be processed and acts as a gateway to the backend to handle the communication with the Cache. In addition to this //top-level State,// each calculation step includes a small [[state adapter object|StateAdapter]] (stack allocated), which is pre-configured by the builder and serves the purpose to isolate the processing function from the detals of buffer management.
           
           
           __see also__
          
          From 3cc0f723898170913681553f5538ee03edecc927 Mon Sep 17 00:00:00 2001
          From: Joel Holdsworth 
          Date: Wed, 18 Jun 2008 23:57:47 +0100
          Subject: [PATCH 137/245] Trivial timeline now works - more work coming
          
          ---
           configure.ac                                |   4 +-
           src/gui/Makefile.am                         |   8 +-
           src/gui/gtk-lumiera.hpp                     |   2 +
           src/gui/lumiera_ui.rc                       |  24 +++--
           src/gui/output/gdkdisplayer.cpp             |   4 +-
           src/gui/widgets/timeline-widget.cpp         |   3 +-
           src/gui/widgets/timeline-widget.hpp         |   5 +-
           src/gui/widgets/timeline/timeline-body.cpp  |  23 ++--
           src/gui/widgets/timeline/timeline-body.hpp  |   6 +-
           src/gui/widgets/timeline/timeline-ruler.cpp | 112 ++++++++++++++++++++
           src/gui/widgets/timeline/timeline-ruler.hpp |  60 +++++++++++
           src/gui/widgets/video-display-widget.cpp    |   2 +-
           src/gui/window-manager.cpp                  |  51 ++++++---
           src/gui/window-manager.hpp                  |   8 +-
           src/gui/workspace/actions.cpp               |   1 -
           src/lib/Makefile.am                         |   5 +-
           src/lib/time.c                              |  54 ++++++++++
           src/lib/time.h                              |  38 +++++++
           18 files changed, 351 insertions(+), 59 deletions(-)
           create mode 100644 src/gui/widgets/timeline/timeline-ruler.cpp
           create mode 100644 src/gui/widgets/timeline/timeline-ruler.hpp
           create mode 100644 src/lib/time.c
           create mode 100644 src/lib/time.h
          
          diff --git a/configure.ac b/configure.ac
          index 641741e83..ae9e3ee89 100644
          --- a/configure.ac
          +++ b/configure.ac
          @@ -157,8 +157,8 @@ AC_CHECK_LIB(Xv, XvQueryAdaptors, ,
           # END X11 Dependancies
           
           
          -############## Gtk Dependancies
          -PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.6.1 cairomm-1.0 >= 0.6.0])
          +############## Pkg Dependancies
          +PKG_CHECK_MODULES(GTK_LUMIERA, [gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.6.1 cairomm-1.0 >= 0.6.0 gavl >= 0.2.5])
           
           AC_SUBST(GTK_LUMIERA_CFLAGS)
           AC_SUBST(GTK_LUMIERA_LIBS)
          diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am
          index fe4a1543f..b1560e485 100644
          --- a/src/gui/Makefile.am
          +++ b/src/gui/Makefile.am
          @@ -27,10 +27,6 @@ INCLUDES = \
           	-DPACKAGE_DATA_DIR=\""$(datadir)"\" \
           	$(GTK_LUMIERA_CFLAGS)
           
          -AM_CFLAGS =\
          -	 -Wall\
          -	 -g
          -
           bin_PROGRAMS += lumigui
           
           lumigui_SOURCES =                                               \
          @@ -66,6 +62,8 @@ lumigui_SOURCES =                                               \
               $(lumigui_srcdir)/widgets/timeline/video-track.hpp          \
               $(lumigui_srcdir)/widgets/timeline/timeline-body.cpp        \
               $(lumigui_srcdir)/widgets/timeline/timeline-body.hpp        \
          +    $(lumigui_srcdir)/widgets/timeline/timeline-ruler.cpp       \
          +    $(lumigui_srcdir)/widgets/timeline/timeline-ruler.hpp       \
               $(lumigui_srcdir)/model/project.cpp                         \
               $(lumigui_srcdir)/model/project.hpp                         \
               $(lumigui_srcdir)/output/displayer.cpp                      \
          @@ -76,7 +74,7 @@ lumigui_SOURCES =                                               \
               $(lumigui_srcdir)/output/xvdisplayer.hpp
           
           lumigui_LDFLAGS = 
          -lumigui_LDADD = $(GTK_LUMIERA_LIBS) 
          +lumigui_LDADD = $(GTK_LUMIERA_LIBS) liblumicommon.a liblumi.a
           
           lumigui_DEPENDENCIES =                                          \
               $(top_builddir)/lumiera_ui.rc                               \
          diff --git a/src/gui/gtk-lumiera.hpp b/src/gui/gtk-lumiera.hpp
          index 6cf7d3acc..fef358a34 100644
          --- a/src/gui/gtk-lumiera.hpp
          +++ b/src/gui/gtk-lumiera.hpp
          @@ -31,6 +31,8 @@
           #include 
           #include 
           
          +
          +
           NOBUG_DECLARE_FLAG(gui);
           
           #ifdef ENABLE_NLS
          diff --git a/src/gui/lumiera_ui.rc b/src/gui/lumiera_ui.rc
          index b2d951ae1..59a021ac5 100644
          --- a/src/gui/lumiera_ui.rc
          +++ b/src/gui/lumiera_ui.rc
          @@ -7,7 +7,7 @@
           
           style "medium_text"
           {
          - 	font_name = "sans bold 10"
          + 	font_name = "sans 10"
           }
            	
           style "medium_bold_entry" = "medium_text"
          @@ -115,20 +115,28 @@ class "GtkProgressBar" style:highest "lumiera_progressbars"
           
           style "timeline_body"
           {
          -  gtkmm__CustomObject_TimelineBody::track_background = "#7E838B"
          +  gtkmm__CustomObject_TimelineBody::background = "#7E838B"
          +}
          +
          +style "timeline_ruler" = "default_base"
          +{
          +#  gtkmm__CustomObject_TimelineRuler::background = "#0000FF"
          +#  gtkmm__CustomObject_TimelineRuler::annotations = "#00FF00"
           }
           
           style "timeline_header_base" = "default_base"
           {
          -  fg[NORMAL] = { 0.77, 0.77, 0.72 }	
          -  bg[NORMAL] = { 0.18, 0.19, 0.22 }
          -  bg[ACTIVE] = { 0.20, 0.20, 0.20 }	
          -  bg[PRELIGHT] = { 0.20, 0.20, 0.20 }
          -  bg[INSENSITIVE] = { 0.20, 0.20, 0.20 }
          -  bg[SELECTED] = { 0.20, 0.20, 0.20 }
          +#  fg[NORMAL] = { 0.77, 0.77, 0.72 }	
          +#  bg[NORMAL] = { 0.18, 0.19, 0.22 }
          +#  bg[ACTIVE] = { 0.20, 0.20, 0.20 }	
          +#  bg[PRELIGHT] = { 0.20, 0.20, 0.20 }
          +#  bg[INSENSITIVE] = { 0.20, 0.20, 0.20 }
          +#  bg[SELECTED] = { 0.20, 0.20, 0.20 }
           }
           
           class "gtkmm__CustomObject_TimelineBody" style:highest "timeline_body"
          +class "gtkmm__CustomObject_TimelineRuler" style:highest "timeline_ruler"
           
           widget "*TimelineHeaderBaseUnselected" style:highest "timeline_header_base"
           
          +
          diff --git a/src/gui/output/gdkdisplayer.cpp b/src/gui/output/gdkdisplayer.cpp
          index 68ad6d545..3718b9f1e 100644
          --- a/src/gui/output/gdkdisplayer.cpp
          +++ b/src/gui/output/gdkdisplayer.cpp
          @@ -39,8 +39,8 @@ GdkDisplayer::GdkDisplayer( Gtk::Widget *drawing_area, int width, int height ) :
               drawingArea( drawing_area )
             {
               REQUIRE(drawing_area != NULL);
          -    REQUIRE(imageWidth > 0);
          -    REQUIRE(imageHeight > 0);
          +    REQUIRE(width > 0);
          +    REQUIRE(height > 0);
               
               imageWidth = width, imageHeight = height;
             }
          diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp
          index 240cb09fb..0178a3f3c 100644
          --- a/src/gui/widgets/timeline-widget.cpp
          +++ b/src/gui/widgets/timeline-widget.cpp
          @@ -41,8 +41,7 @@ TimelineWidget::TimelineWidget() :
             horizontalAdjustment(0, 0, 0),
             verticalAdjustment(0, 0, 0),
             horizontalScroll(horizontalAdjustment),
          -  verticalScroll(verticalAdjustment),
          -  ruler("ruler")
          +  verticalScroll(verticalAdjustment)
             {
               body = new TimelineBody(this);
               ASSERT(body != NULL);
          diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp
          index a53ef6368..9943e85da 100644
          --- a/src/gui/widgets/timeline-widget.hpp
          +++ b/src/gui/widgets/timeline-widget.hpp
          @@ -29,6 +29,7 @@
           #include "../gtk-lumiera.hpp"
           #include "timeline/header-container.hpp"
           #include "timeline/timeline-body.hpp"
          +#include "timeline/timeline-ruler.hpp"
           #include "timeline/track.hpp"
           #include "timeline/video-track.hpp"
           
          @@ -67,9 +68,9 @@ class TimelineWidget : public Gtk::Table
               timeline::VideoTrack video2;
               std::vector tracks;
           
          -    timeline::TimelineBody *body;
               timeline::HeaderContainer *headerContainer;
          -    Gtk::Label ruler;
          +    timeline::TimelineBody *body;
          +    timeline::TimelineRuler ruler;
           
               Gtk::Adjustment horizontalAdjustment, verticalAdjustment;
               Gtk::HScrollbar horizontalScroll;
          diff --git a/src/gui/widgets/timeline/timeline-body.cpp b/src/gui/widgets/timeline/timeline-body.cpp
          index bbcca9a02..aaf0b9d26 100644
          --- a/src/gui/widgets/timeline/timeline-body.cpp
          +++ b/src/gui/widgets/timeline/timeline-body.cpp
          @@ -25,9 +25,11 @@
           
           #include "timeline-body.hpp"
           #include "../timeline-widget.hpp"
          +#include "../../window-manager.hpp"
           
           using namespace Gtk;
           using namespace std;
          +using namespace lumiera::gui;
           using namespace lumiera::gui::widgets;
           using namespace lumiera::gui::widgets::timeline;
           
          @@ -51,7 +53,7 @@ TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widge
               // Install style properties
               gtk_widget_class_install_style_property(
                 GTK_WIDGET_CLASS(G_OBJECT_GET_CLASS(gobj())), 
          -      g_param_spec_boxed("track_background",
          +      g_param_spec_boxed("background",
                   "Track Background",
                   "The background colour of timeline tracks",
                   GDK_TYPE_COLOR, G_PARAM_READABLE));
          @@ -94,7 +96,7 @@ TimelineBody::on_expose_event(GdkEventExpose* event)
                 
                   // Draw the track background
                   cairo->rectangle(0, 0, allocation.get_width(), height);
          -        gdk_cairo_set_source_color(cairo->cobj(), &track_background);
          +        gdk_cairo_set_source_color(cairo->cobj(), &background);
                   cairo->fill();
                 
                   // Render the track
          @@ -112,21 +114,8 @@ TimelineBody::on_expose_event(GdkEventExpose* event)
           void
           TimelineBody::read_styles()
             {
          -    GdkColor *colour;
          -
          -    gtk_widget_style_get(Widget::gobj(), "track_background", &colour, NULL);
          -
          -    // Did the color load successfully?
          -    if(colour != NULL)
          -      track_background = *colour;
          -    else
          -    {
          -      WARN(gui, "track_background style value failed to load");
          -      track_background.red   = 0x0000;
          -      track_background.green = 0x0000;
          -      track_background.blue  = 0x0000;
          -      track_background.pixel = 0x00000000;
          -    }
          +    background = WindowManager::read_style_colour_property(
          +      *this, "background", 0, 0, 0);
             }
           
           }   // namespace timeline
          diff --git a/src/gui/widgets/timeline/timeline-body.hpp b/src/gui/widgets/timeline/timeline-body.hpp
          index d3ba192ab..0b0e37aac 100644
          --- a/src/gui/widgets/timeline/timeline-body.hpp
          +++ b/src/gui/widgets/timeline/timeline-body.hpp
          @@ -26,7 +26,7 @@
           #ifndef TIMELINE_BODY_HPP
           #define TIMELINE_BODY_HPP
           
          -#include 
          +#include "../../gtk-lumiera.hpp"
           
           namespace lumiera {
           namespace gui {
          @@ -45,14 +45,14 @@ class TimelineBody : public Gtk::DrawingArea
             protected:
               void on_scroll();
           
          -    virtual bool on_expose_event(GdkEventExpose* event);
          +    bool on_expose_event(GdkEventExpose* event);
               
               /* ===== Internals ===== */
             private:
               void read_styles();
               
             private:
          -    GdkColor track_background;
          +    GdkColor background;
               
               lumiera::gui::widgets::TimelineWidget *timelineWidget;
             };
          diff --git a/src/gui/widgets/timeline/timeline-ruler.cpp b/src/gui/widgets/timeline/timeline-ruler.cpp
          new file mode 100644
          index 000000000..7970191c9
          --- /dev/null
          +++ b/src/gui/widgets/timeline/timeline-ruler.cpp
          @@ -0,0 +1,112 @@
          +/*
          +  timeline-ruler.cpp  -  Implementation of the time ruler widget
          + 
          +  Copyright (C)         Lumiera.org
          +    2008,               Joel Holdsworth 
          + 
          +  This program 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 2 of the
          +  License, or (at your option) any later version.
          + 
          +  This program 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 this program; if not, write to the Free Software
          +  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          + 
          +* *****************************************************/
          +
          +#include 
          +
          +#include "timeline-ruler.hpp"
          +#include "../../window-manager.hpp"
          +
          +extern "C" {
          +#include 
          +#include "../../../lib/time.h"
          +}
          +
          +using namespace Gtk;
          +using namespace std;
          +using namespace lumiera::gui;
          +using namespace lumiera::gui::widgets;
          +using namespace lumiera::gui::widgets::timeline;
          +
          +namespace lumiera {
          +namespace gui {
          +namespace widgets {
          +namespace timeline {
          +
          +TimelineRuler::TimelineRuler() :
          +    Glib::ObjectBase("TimelineRuler")
          +  {
          +    set_flags(Gtk::NO_WINDOW);  // This widget will not have a window
          +    set_size_request(-1, 20);
          +    
          +    // Install style properties
          +    timeScale = GAVL_TIME_SCALE / 200;
          +    timeOffset = 0;
          +  }
          +
          +bool
          +TimelineRuler::on_expose_event(GdkEventExpose* event)
          +  {
          +    // This is where we draw on the window
          +    Glib::RefPtr window = get_window();
          +    if(!window)
          +      return false;
          +    
          +    // Makes sure the widget styles have been loaded
          +    read_styles();
          +    
          +    // Prepare to render via cairo      
          +    Allocation allocation = get_allocation();
          +    Glib::RefPtr
          OperationClassDescription
          allocateBufferState
          applyBuildable
          applyVisitable
          buildAssembler
          currEDLSessionThe EDL currently in focus. In most cases, Session and EDL are almost the same, just EDL emphasizes the collection aspect. But generally (for larger editing projects) one Session can contain several EDLs, which may even be nested. At any given time, only one of these EDLs has focus and recieves the editing commands.
          dispatchOpVisitable
          enableAssetchange the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well
          fetchState
          findTypeHandler
          getAppconfigaccess the configuation value for a given key.
          @return empty string for unknown keys, else the corresponding configuration value
          get_reprAllocation
          getValueParamProvider
          howtoProcMedia@return descriptor how to build a render pipeline corresponding to this media
          isActiveAssetweather this asset is swithced on and consequently included in the fixture and participates in rendering
          isCalculatedState
          knownAssetManager@return true if the given id is registered in the internal asset DB
          loadSessManagerreplace the current session by a new
          session loaded from serialized state.
          makeTypeHandler
          playRenderEngineTODO: will probably be handled differently (see Cehteh)
          pullProcNodetrigger data processing by "pulling" results from the node's output
          pullStateAdaptertrigger data processing by "pulling" results from the node's output
          processProcNode
          pullProcNode
          releaseBufferState
          removeAssetManagerremove the given asset <i>together with all its dependants</i> from the internal DB
          resetSessManagerreset all session config and
          start with a pristine default session.
          resolvePlacementcreate an actual (explicit) placement while trying to satisfy the network of adjacent objects and placements.
          resolveQueryHandler
          resolveQueryHandlerImpl
          retrieveBuffersStateAdapterinvoked from within the pull() - call of a node to set up the data buffers.
          @param requiredSource descriptor denoting the predecessors and the frames required from them
          retrieveStateAdapter
          rootCauseErrorIf this exception was caused by a chain of further exceptions,
          return the first one registered in this throw sequence.
          This works only, if every exceptions thrown as a consequence
          of another exception is propperly constructed by passing
          the original exception to the constructor
          saveSessManagercreate a complete, serialized representation
          of the current session config and contents.
          @todo how to serialize, prameters, return value?
          treatApplicable
          treatBuilderToolThis operation is to be overloaded for the specific MObject subclasses to be treated.
          treatNodeCreatorTool
          treatNodeCreatorTool
          treatNodeCreatorTool
          treatNodeCreatorTool
          treatNodeCreatorTool
          treatSegmentationTool
          treatSegmentationTool
          treatSegmentationTool
          treatSegmentationTool
          useFileFileProviderAnnounces that the application intends to use this file with mode (READ|WRITE|READWRITE)
          useTemporaryStorageFileProviderProvides a pool for interminate frames
          whatError