Merge branch 'master' of git://git.pipapo.org/cinelerra3/ichthyo into library
This commit is contained in:
commit
9bccc7b29e
46 changed files with 3115 additions and 182 deletions
50
AUTHORS
Normal file
50
AUTHORS
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
Cinelerra(2) Authors
|
||||
====================
|
||||
|
||||
hv=Jack Crossfire <broadcast@earthling.net>
|
||||
j6t=Johannes Sixt <johannes.sixt@telecom.at>
|
||||
minmax=Andraz Tori <Andraz.tori1@guest.arnes.si>
|
||||
herman=Herman Robak <herman@skolelinux.no>
|
||||
baver=Richard Baverstock <baver@thebeever.com>
|
||||
pere=Petter Reinholdtsen <pere@hungry.com>
|
||||
tfheen=Tollef Fog Heen <tollef@add.no>
|
||||
andreask=Andreas Kielb <andreaskielb@web.de>
|
||||
theraz=Tyler Geddes <tgeddes@wgeddes.com>
|
||||
dyce=Gergely Erdelyi <dyce@rovidzar.hu>
|
||||
dreamlx=David Arendt <admin@prnet.org>
|
||||
ga=Gustavo Iniguez <ga@kutxa.homeunix.org>
|
||||
memenk=Michael Eric Menk <meklev@osys.grm.hia.no>
|
||||
benjif=Benjamin Flaming <cinelerra@solobanjo.com>
|
||||
cobra=Kevin Brosius <cobra@compuserve.com>
|
||||
taraba=Mark Taraba <m_taraba@yahoo.com>
|
||||
nate=Nathan Kurz <nate@verse.com>
|
||||
mammique=Camille Harang <mammique@garbure.org>
|
||||
kbielefe=Karl Bielefeldt <uhauufo02@sneakemail.com>
|
||||
alexf=Alex Ferrer <alex@ftconsult.com>
|
||||
pmdumuid=Pierre Dumuid <pierre.dumuid@adelaide.edu.au>
|
||||
giskard=Riccardo Setti <giskard@autistici.org>
|
||||
jstewart=Joe Stewart <jstewart@lurhq.com>
|
||||
doudou=Sylvain Joyeux <doudou@melix.net>
|
||||
rafael2k=Rafael Diniz <rafael@riseup.net>
|
||||
nicolasm=Nicolas Maufrais <e.conti@gmx.net>
|
||||
|
||||
Involved in Design Studies / Prototypes for Cinelerra-3
|
||||
=======================================================
|
||||
cehteh=Christian Thaeter <ct@pipapo.org>
|
||||
ichthyo=Hermann Vosseler <Ichthyostega@web.de>
|
||||
plouj=Michael Ploujnikov <ploujj@gmail.com>
|
||||
|
||||
_______________________________________________________________
|
||||
Further Credits
|
||||
|
||||
Parts of the Proc-Layer Implementation are heavily inspired by
|
||||
The Loki Library
|
||||
Copyright (c) 2001 by Andrei Alexandrescu
|
||||
Loki is governed by a MIT-License.
|
||||
See: http://loki-lib.sourceforge.net
|
||||
and the book:
|
||||
Alexandrescu, Andrei.
|
||||
"Modern C++ Design: Generic Programming and Design
|
||||
Patterns Applied". Copyright (c) 2001. Addison-Wesley.
|
||||
ISBN 0201704315
|
||||
340
COPYING
Normal file
340
COPYING
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
6
INSTALL
Normal file
6
INSTALL
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Running / Installing Cinelerra-3 Prototype
|
||||
==========================================
|
||||
|
||||
** to be written **
|
||||
|
||||
|
||||
17
LICENSE
Normal file
17
LICENSE
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
The Cinelerra source code is (C) by the original authors (see AUTHORS)
|
||||
|
||||
=======================================================================
|
||||
Cinelerra is free software -- you may use and redistribute it under the
|
||||
Terms and conditions of the GNU GENERAL PUBLIC LICENSE (GPL);
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
=======================================================================
|
||||
For a copy of the GPL Version 2 see the file "COPYING"
|
||||
|
||||
|
||||
In addition to the GPL's warranty stipulation, Cinelerra is distributed WITHOUT
|
||||
GUARANTEED SUPPORT; without even the guarantee of ADDITIONAL LABOR. Support
|
||||
that is not guaranteed includes technical support, compiler troubleshooting,
|
||||
debugging, version matching, updating, among other additional labor which
|
||||
may or may not be required to meet a user's requirements.
|
||||
|
||||
|
||||
37
README
Normal file
37
README
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
======================================
|
||||
Cinelerra -- the video NLE for Linux
|
||||
======================================
|
||||
|
||||
Cinelerra is a nonlinear video editing and compositing tool.
|
||||
It understands some of the common multimedia formats
|
||||
(quicktime, avi, ogg) and audio/video compression
|
||||
codecs (divx, xvid, mpeg1/2/4, ...)
|
||||
.
|
||||
It features non-destructive editing, compositing tools,
|
||||
a selection of effects plugins, processing in RGB, YUV
|
||||
and RGB-float colormodels and the ability to mix media
|
||||
with differing sizes and framerates.
|
||||
|
||||
For more information about Cinelerra visit http://cinelerra.org/
|
||||
|
||||
|
||||
------------------------------
|
||||
"Cinelerra-3" prototype code
|
||||
------------------------------
|
||||
|
||||
**This source tree doesn't contain a working video editing application**
|
||||
Rather, it contains some design studies and prototype code for improving
|
||||
some aspects of the Cinelerra Application. This work may eventually
|
||||
evolve into a new major release of Cinelerra.
|
||||
|
||||
As of 7/2007, we start here with some backend and render engine modules
|
||||
together with some unit tests. You should find a wiki with detailed
|
||||
design considerations and developer documentation and a UML model
|
||||
(usable with BOUML 2.29) in the sibling directories.
|
||||
|
||||
|
||||
Build Requirements
|
||||
------------------
|
||||
|
||||
*to be written*
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ def setupBasicEnvironment():
|
|||
, BINDIR=BINDIR
|
||||
, CPPPATH=["#"+SRCDIR] # used to find includes, "#" means always absolute to build-root
|
||||
, CPPDEFINES=['-DCINELERRA_VERSION='+VERSION ] # note: it's a list to append further defines
|
||||
, CCFLAGS='-Wall'
|
||||
, CCFLAGS='-Wall ' # -fdiagnostics-show-option
|
||||
)
|
||||
|
||||
handleNoBugSwitches(env)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@ using boost::algorithm::split;
|
|||
using boost::algorithm::join;
|
||||
using boost::algorithm::is_any_of;
|
||||
using boost::algorithm::token_compress_on;
|
||||
using boost::regex;
|
||||
using boost::smatch;
|
||||
using boost::regex_search;
|
||||
|
||||
using boost::regex;
|
||||
using boost::smatch;
|
||||
using boost::regex_search;
|
||||
|
||||
|
||||
|
||||
|
|
@ -59,12 +66,12 @@ namespace util
|
|||
*/
|
||||
Cmdline::Cmdline (const string cmdline)
|
||||
{
|
||||
boost::regex tokendef("[^ \r\n\t]+");
|
||||
boost::smatch match;
|
||||
regex tokendef("[^ \r\n\t]+");
|
||||
smatch match;
|
||||
string::const_iterator it = cmdline.begin();
|
||||
string::const_iterator end = cmdline.end();
|
||||
|
||||
while (boost::regex_search(it, end, match, tokendef))
|
||||
while (regex_search(it, end, match, tokendef))
|
||||
{
|
||||
string ss(match[0]);
|
||||
this->push_back(ss);
|
||||
|
|
@ -82,4 +89,4 @@ namespace util
|
|||
|
||||
|
||||
|
||||
} // namespace cinelerra
|
||||
} // namespace util
|
||||
|
|
|
|||
54
src/common/multithread.hpp
Normal file
54
src/common/multithread.hpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
MULTITHREAD.hpp - generic interface for multithreading primitives
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
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 CINELERRA_MULTITHREAD_H
|
||||
#define CINELERRA_MULTITHREAD_H
|
||||
|
||||
|
||||
|
||||
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 cinelerra backend layer.
|
||||
*
|
||||
* @todo actually implement this policy using the cinelerra databackend.
|
||||
*/
|
||||
struct Thread
|
||||
{
|
||||
template<class X>
|
||||
class Lock
|
||||
{
|
||||
public:
|
||||
Lock() { TODO ("aquire Thread Lock for Class"); }
|
||||
Lock(X*) { TODO ("aquire Thread Lock for Instance"); }
|
||||
~Lock() { TODO ("release Thread Lock"); }
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
} // namespace cinelerra
|
||||
#endif
|
||||
156
src/common/singleton.hpp
Normal file
156
src/common/singleton.hpp
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
SINGLETON.hpp - template for implementing the singleton pattern
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
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.
|
||||
|
||||
====================================================================
|
||||
This code is heavily inspired by
|
||||
The Loki Library (loki-lib/trunk/include/loki/Singleton.h)
|
||||
Copyright (c) 2001 by Andrei Alexandrescu
|
||||
This Loki code accompanies the book:
|
||||
Alexandrescu, Andrei. "Modern C++ Design: Generic Programming
|
||||
and Design Patterns Applied".
|
||||
Copyright (c) 2001. Addison-Wesley. ISBN 0201704315
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef CINELERRA_SINGLETON_H
|
||||
#define CINELERRA_SINGLETON_H
|
||||
|
||||
|
||||
#include "common/singletonpolicies.hpp" ///< several Policies usable together with singleton
|
||||
|
||||
#include "common/util.hpp"
|
||||
#include "nobugcfg.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
|
||||
namespace cinelerra
|
||||
{
|
||||
|
||||
/**
|
||||
* A configurable Template for implementing Singletons.
|
||||
* Actually this is a Functor object, which could be placed into a static field
|
||||
* of the Singleton (target) class or used directly.
|
||||
* @note internally uses static fields, so all functor instances share pInstance_
|
||||
*/
|
||||
template
|
||||
< class SI, // the class to make Singleton
|
||||
template <class> class Create = singleton::Static, // how to create/destroy the instance
|
||||
template <class> class Life = singleton::Automatic, // how to manage Singleton Lifecycle
|
||||
template <class> class Threading = singleton::IgnoreThreadsafety //TODO use Multithreaded!!!
|
||||
>
|
||||
class Singleton
|
||||
{
|
||||
typedef typename Threading<SI>::VolatileType SType;
|
||||
typedef typename Threading<SI>::Lock ThreadLock;
|
||||
static SType* pInstance_;
|
||||
static bool isDead_;
|
||||
|
||||
public:
|
||||
/** Interface to be used by Singleton's clients.
|
||||
* Manages internally the instance creation, lifecycle
|
||||
* and access handling in a multithreaded context.
|
||||
* @return "the" single instance of class S
|
||||
*/
|
||||
SI& operator() ()
|
||||
{
|
||||
if (!pInstance_)
|
||||
{
|
||||
ThreadLock guard SIDEEFFECT;
|
||||
if (!pInstance_)
|
||||
{
|
||||
if (isDead_)
|
||||
{
|
||||
Life<SI>::onDeadReference();
|
||||
isDead_ = false;
|
||||
}
|
||||
pInstance_ = Create<SI>::create();
|
||||
Life<SI>::scheduleDelete (&destroy);
|
||||
} }
|
||||
ENSURE (pInstance_);
|
||||
ENSURE (!isDead_);
|
||||
return *pInstance_;
|
||||
}
|
||||
|
||||
private:
|
||||
/** @internal helper used to delegate destroying the single instance
|
||||
* to the Create policy, at the same time allowing the Life policy
|
||||
* to control the point in the Application lifecycle when the
|
||||
* destruction of this instance occures.
|
||||
*/
|
||||
static void destroy()
|
||||
{
|
||||
REQUIRE (!isDead_);
|
||||
Create<SI>::destroy (pInstance_);
|
||||
pInstance_ = 0;
|
||||
isDead_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Storage for Singleton's static fields...
|
||||
template
|
||||
< class SI,
|
||||
template <class> class C,
|
||||
template <class> class L,
|
||||
template <class> class T
|
||||
>
|
||||
typename Singleton<SI,C,L,T>::SType*
|
||||
Singleton<SI,C,L,T>::pInstance_;
|
||||
|
||||
template
|
||||
< class SI,
|
||||
template <class> class C,
|
||||
template <class> class L,
|
||||
template <class> class T
|
||||
>
|
||||
bool Singleton<SI,C,L,T>::isDead_;
|
||||
|
||||
|
||||
|
||||
///// TODO: get rid of the static fields?
|
||||
///// is tricky because of invoking the destructors. If we rely on instance vars,
|
||||
///// the object may already have been released when the runtime system calls the
|
||||
///// destructors of static objects at shutdown.
|
||||
|
||||
/** @internal used to link together the Create policy and Life policy.
|
||||
* @return a functor object for invoking this->destroy() */
|
||||
/* singleton::DelFunc getDeleter()
|
||||
{
|
||||
return boost::bind (&Singleton<SI,Create,Life,Threading>::destroy,
|
||||
this);
|
||||
}
|
||||
*/
|
||||
|
||||
/* template<class T>
|
||||
class DelFunc
|
||||
{
|
||||
typedef void (T::*Fp)(void);
|
||||
T* t_;
|
||||
Fp fun_;
|
||||
public:
|
||||
DelFunc (T* t, Fp f) : t_(t), fun_(f) {}
|
||||
void operator() () { (t_->*fun_)(); }
|
||||
};
|
||||
*/
|
||||
} // namespace cinelerra
|
||||
#endif
|
||||
158
src/common/singletonpolicies.hpp
Normal file
158
src/common/singletonpolicies.hpp
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
SINGLETONPOLICIES.hpp - how to manage creation, lifecycle and multithreading
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
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.
|
||||
|
||||
====================================================================
|
||||
This code is heavily inspired by
|
||||
The Loki Library (loki-lib/trunk/include/loki/Singleton.h)
|
||||
Copyright (c) 2001 by Andrei Alexandrescu
|
||||
This Loki code accompanies the book:
|
||||
Alexandrescu, Andrei. "Modern C++ Design: Generic Programming
|
||||
and Design Patterns Applied".
|
||||
Copyright (c) 2001. Addison-Wesley. ISBN 0201704315
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef CINELERRA_SINGLETONPOLICIES_H
|
||||
#define CINELERRA_SINGLETONPOLICIES_H
|
||||
|
||||
#include "common/multithread.hpp"
|
||||
#include "common/error.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace cinelerra
|
||||
{
|
||||
namespace singleton
|
||||
{
|
||||
/* == several Policies usable in conjunction with cinelerra::Singleton == */
|
||||
|
||||
/**
|
||||
* Policy for creating the Singleton instance statically
|
||||
*/
|
||||
template<class S>
|
||||
struct Static
|
||||
{
|
||||
static S* create ()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
static uint callCount (0);
|
||||
ASSERT ( 0 == callCount++ );
|
||||
#endif
|
||||
static char buff[sizeof(S)];
|
||||
return new(buff) S();
|
||||
}
|
||||
static void destroy (S* pSi)
|
||||
{
|
||||
pSi-> ~S();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Policy for creating the Singleton instance heap allocated
|
||||
*/
|
||||
template<class S>
|
||||
struct Heap
|
||||
{
|
||||
static S* create () { return new S; }
|
||||
static void destroy (S* pS) { delete pS; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef void (*DelFunc)(void);
|
||||
using std::vector;
|
||||
|
||||
/**
|
||||
* Policy relying on the compiler/runtime system for Singleton Lifecycle
|
||||
*/
|
||||
template<class S>
|
||||
struct Automatic
|
||||
{
|
||||
/** implements the Singleton removal by calling
|
||||
* the provided deleter function(s) at application shutdown,
|
||||
* relying on the runtime system calling destructors of static
|
||||
* objects. Because this Policy class can be shared between
|
||||
* several Singletons, we need to memoize all registered
|
||||
* deleter functions for calling them at shutdown.
|
||||
*/
|
||||
static void scheduleDelete (DelFunc kill_the_singleton)
|
||||
{
|
||||
class DeleteTrigger
|
||||
{
|
||||
vector<DelFunc> dels_;
|
||||
|
||||
public:
|
||||
void schedule (DelFunc del)
|
||||
{
|
||||
dels_.push_back(del);
|
||||
}
|
||||
~DeleteTrigger()
|
||||
{
|
||||
vector<DelFunc>::iterator i = dels_.begin();
|
||||
for ( ; i != dels_.end(); ++i )
|
||||
(*i)(); // invoke deleter func
|
||||
}
|
||||
};
|
||||
|
||||
REQUIRE (kill_the_singleton);
|
||||
static DeleteTrigger finally;
|
||||
finally.schedule (kill_the_singleton);
|
||||
}
|
||||
|
||||
static void onDeadReference ()
|
||||
{
|
||||
throw error::Logic ("Trying to access the a Singleton instance that has "
|
||||
"already been released or finished its lifecycle.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Policy for handling multithreaded access to the singleton instance
|
||||
* @todo actually implement this policy using the cinelerra databackend.
|
||||
*/
|
||||
template<class S>
|
||||
struct Multithreaded
|
||||
{
|
||||
typedef volatile S* VolatileType;
|
||||
typedef cinelerra::Thread::Lock<S> Lock;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Policy just ignoring thread safety
|
||||
*/
|
||||
template<class S>
|
||||
struct IgnoreThreadsafety
|
||||
{
|
||||
typedef S VolatileType;
|
||||
struct Lock {};
|
||||
};
|
||||
|
||||
|
||||
} // namespace singleton
|
||||
|
||||
} // namespace cinelerra
|
||||
#endif
|
||||
72
src/common/util.cpp
Normal file
72
src/common/util.cpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
util.cpp - helper functions implementation
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
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 "common/util.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using boost::algorithm::trim_right_copy_if;
|
||||
using boost::algorithm::is_any_of;
|
||||
using boost::algorithm::is_alnum;
|
||||
using boost::algorithm::is_space;
|
||||
|
||||
|
||||
namespace util
|
||||
{
|
||||
|
||||
typedef boost::function<bool(string::value_type)> ChPredicate;
|
||||
ChPredicate operator! (ChPredicate p) { return ! boost::bind(p,_1); }
|
||||
|
||||
// character classes used for sanitizing a string
|
||||
ChPredicate isValid (is_alnum() || is_any_of("-_.:+$'()@")); ///< characters to be retained
|
||||
ChPredicate isPunct (is_space() || is_any_of(",;#*~´`?\\=/&%![]{}")); ///< punctuation to be replaced by '_'
|
||||
|
||||
|
||||
string
|
||||
sanitize (const string& org)
|
||||
{
|
||||
string res (trim_right_copy_if(org, !isValid ));
|
||||
string::iterator j = res.begin();
|
||||
string::const_iterator i = org.begin();
|
||||
string::const_iterator e = i + (res.length());
|
||||
while ( i != e )
|
||||
{
|
||||
while ( i != e && !isValid (*i) ) ++i;
|
||||
while ( i != e && isValid (*i) ) *(j++) = *(i++);
|
||||
if ( i != e && isPunct (*i) )
|
||||
{
|
||||
*j++ = '_';
|
||||
do ++i;
|
||||
while ( i != e && isPunct (*i));
|
||||
}
|
||||
}
|
||||
res.erase(j,res.end());
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace util
|
||||
|
||||
|
|
@ -27,6 +27,8 @@
|
|||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include "nobugcfg.h" ///////////////////TODO: just temporarily!!!!
|
||||
|
||||
|
||||
namespace util
|
||||
{
|
||||
|
|
@ -36,19 +38,22 @@ namespace util
|
|||
/** a family of util functions providing a "no value whatsoever" test.
|
||||
Works on strings and all STL containers, includes NULL test for pointers */
|
||||
template <class CONT>
|
||||
inline bool isnil(const CONT& container)
|
||||
inline bool
|
||||
isnil(const CONT& container)
|
||||
{
|
||||
return container.empty();
|
||||
}
|
||||
|
||||
template <class CONT>
|
||||
inline bool isnil(const CONT* pContainer)
|
||||
inline bool
|
||||
isnil(const CONT* pContainer)
|
||||
{
|
||||
return !pContainer || pContainer->empty();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool isnil(const char* pCStr)
|
||||
inline bool
|
||||
isnil(const char* pCStr)
|
||||
{
|
||||
return !pCStr || 0 == std::strlen(pCStr);
|
||||
}
|
||||
|
|
@ -56,14 +61,16 @@ namespace util
|
|||
|
||||
/** cut a numeric value to be >=0 */
|
||||
template <typename NUM>
|
||||
inline NUM noneg (NUM val)
|
||||
inline NUM
|
||||
noneg (NUM val)
|
||||
{
|
||||
return (0<val? val : 0);
|
||||
}
|
||||
|
||||
/** shortcut for containment test on a map */
|
||||
template <typename MAP>
|
||||
inline bool contains (MAP& map, typename MAP::key_type& key)
|
||||
inline bool
|
||||
contains (MAP& map, typename MAP::key_type& key)
|
||||
{
|
||||
return map.find(key) != map.end();
|
||||
}
|
||||
|
|
@ -74,16 +81,54 @@ namespace util
|
|||
*/
|
||||
template <typename Container, typename Oper>
|
||||
inline Oper
|
||||
for_each (Container& c, Oper& doIt)
|
||||
for_each (Container& c, Oper doIt)
|
||||
{
|
||||
return std::for_each (c.begin(),c.end(), doIt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** produce an identifier based on the given string.
|
||||
* remove non-standard-chars, reduce sequences of punctuation
|
||||
* and whitespace to single underscores. The sanitized string
|
||||
* will start with an alphanumeric character.
|
||||
*
|
||||
* @par Example Conversions
|
||||
\verbatim
|
||||
"Word" --> 'Word'
|
||||
"a Sentence" --> 'a_Sentence'
|
||||
"trailing Withespace \t \n" --> 'trailing_Withespace'
|
||||
"with a lot \nof Whitespace" --> 'with_a_lot_of_Whitespace'
|
||||
"with\"much (punctuation)[]!" --> 'withmuch_(punctuation)'
|
||||
"§&Ω%€ leading garbarge" --> 'leading_garbarge'
|
||||
"mixed Ω garbarge" --> 'mixed_garbarge'
|
||||
"Bääääh!!" --> 'Bh'
|
||||
\endverbatim
|
||||
*/
|
||||
string sanitize (const string& org);
|
||||
|
||||
|
||||
|
||||
|
||||
/** convienience shortcut: conversion to c-String via string.
|
||||
* usable for printf with objects providing to-string conversion.
|
||||
*/
|
||||
inline const char*
|
||||
cStr (const string& org)
|
||||
{
|
||||
return org.c_str();
|
||||
}
|
||||
|
||||
|
||||
} // namespace util
|
||||
|
||||
/* some common macro definitions */
|
||||
|
||||
/** supress "warning: unused variable" on vars, which
|
||||
* are introduced into a scope because of some sideeffect, i.e. Locking
|
||||
*/
|
||||
#define SIDEEFFECT __attribute__ ((unused));
|
||||
|
||||
/** this macro wraps its parameter into a cstring literal */
|
||||
#define STRINGIFY(TOKEN) __STRNGFY(TOKEN)
|
||||
#define __STRNGFY(TOKEN) #TOKEN
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@
|
|||
/* declare flags used throughout the code base... */
|
||||
NOBUG_DECLARE_FLAG(config);
|
||||
NOBUG_DECLARE_FLAG(test);
|
||||
NOBUG_DECLARE_FLAG(assetmem);
|
||||
NOBUG_DECLARE_FLAG(mobjectmem);
|
||||
|
||||
|
||||
#endif /*NOBUGCFG_H ======= (End) Part 1: DECLARATIONS ======== */
|
||||
|
|
@ -74,6 +76,8 @@
|
|||
/* flags used throughout the code base... */
|
||||
NOBUG_CPP_DEFINE_FLAG(config);
|
||||
NOBUG_CPP_DEFINE_FLAG(test);
|
||||
NOBUG_CPP_DEFINE_FLAG_LIMIT(assetmem, LOG_WARNING);
|
||||
NOBUG_CPP_DEFINE_FLAG_LIMIT(mobjectmem, LOG_WARNING);
|
||||
|
||||
#include "common/error.hpp"
|
||||
|
||||
|
|
|
|||
|
|
@ -22,48 +22,112 @@
|
|||
|
||||
|
||||
#include "proc/asset.hpp"
|
||||
#include "proc/asset/category.hpp"
|
||||
#include "proc/assetmanager.hpp"
|
||||
#include "common/util.hpp"
|
||||
|
||||
namespace proc_interface
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using boost::format;
|
||||
using util::cStr;
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
Asset::Ident::Ident(const string& n, const Category& cat, const string& o, const uint ver)
|
||||
: name(util::sanitize (n)),
|
||||
category(cat), org(o), version(ver)
|
||||
{ }
|
||||
|
||||
|
||||
/** Asset is a Interface class; usually, objects of
|
||||
* concrete subclasses are created via specialized Factories
|
||||
*/
|
||||
Asset::Asset (const Ident& idi)
|
||||
: ident(idi), id(AssetManager::reg (this, idi))
|
||||
{ TRACE (assetmem, "ctor Asset(id=%lu) : adr=%x %s", size_t(id), this, cStr(this->ident) );
|
||||
}
|
||||
|
||||
Asset::~Asset ()
|
||||
{
|
||||
TRACE (assetmem, "dtor Asset(id=%lu) : adr=%x", size_t(id), this );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List of entities this asset depends on or requires to be functional. May be empty. The head of this list can be considered the primary prerequisite
|
||||
Asset::Ident::operator string () const
|
||||
{
|
||||
format id_tuple("(%2%:%3%.%1% v%4%)");
|
||||
return str (id_tuple % name % category % org % version);
|
||||
}
|
||||
|
||||
|
||||
Asset::operator string () const
|
||||
{
|
||||
format id_tuple("Asset(%2%:%3%.%1% v%4%)");
|
||||
return str (id_tuple % ident.name % ident.category % ident.org % ident.version);
|
||||
}
|
||||
|
||||
|
||||
/** List of entities this asset depends on or requires to be functional.
|
||||
* May be empty. The head of this list can be considered the primary prerequisite
|
||||
*/
|
||||
vector<PAsset>
|
||||
Asset::getParents ()
|
||||
Asset::getParents () const
|
||||
{
|
||||
UNIMPLEMENTED ("Asset dependencies.");
|
||||
}
|
||||
|
||||
|
||||
/** All the other assets requiring this asset to be functional.
|
||||
* For example, all the clips depending on a given media file.
|
||||
* May be empty. The dependency relation is transitive.
|
||||
*/
|
||||
vector<PAsset>
|
||||
Asset::getDependant () const
|
||||
{
|
||||
UNIMPLEMENTED ("Asset dependencies.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* All the other assets requiring this asset to be functional. For example, all the clips depending on a given media file. May be empty. The dependency relation is transitive.
|
||||
*/
|
||||
vector<PAsset>
|
||||
Asset::getDependant ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* weather this asset is swithced on and consequently included in the fixture and participates in rendering
|
||||
* weather this asset is swithced on and consequently included
|
||||
* in the fixture and participates in rendering.
|
||||
*/
|
||||
bool
|
||||
Asset::isActive ()
|
||||
Asset::isActive () const
|
||||
{
|
||||
UNIMPLEMENTED ("enable/disable Assets.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* change the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well
|
||||
* change the enablement status of this asset.
|
||||
* @note the corresponding #isActive predicate may depend
|
||||
* on the enablement status of parent assets as well.
|
||||
*/
|
||||
void
|
||||
Asset::enable () throw(cinelerra::error::State)
|
||||
{
|
||||
UNIMPLEMENTED ("enable/disable Assets.");
|
||||
}
|
||||
|
||||
|
||||
/** release all links to other Asset objects held internally. */
|
||||
void
|
||||
Asset::unlink ()
|
||||
{
|
||||
UNIMPLEMENTED ("deleting Assets.");
|
||||
}
|
||||
|
||||
/** variant dropping only the links to the given Asset */
|
||||
void
|
||||
Asset::unlink (IDA target)
|
||||
{
|
||||
UNIMPLEMENTED ("deleting Assets.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace proc_interface
|
||||
|
||||
} // namespace asset
|
||||
|
|
|
|||
|
|
@ -20,62 +20,185 @@
|
|||
|
||||
*/
|
||||
|
||||
/** @file asset.hpp
|
||||
** Proc-Layer Interface: Assets.
|
||||
** Declares the Asset top level Interface, the Asset::Ident identification tuple
|
||||
** and the asset::ID primary key wrapper. Normally, Assets should be handled
|
||||
** using asset::PAsset, a ref counting smart pointer.
|
||||
**
|
||||
** These classes are placed into namespace asset and proc_interface.
|
||||
**
|
||||
** Assets are handled by a hierarchy of interfaces. Below the top level Asset interface
|
||||
** there are interfaces for various different <i>Kinds</i> of Assets, like asset::Media,
|
||||
** asset::Proc, etc. Code utilizing the specific properties of e.g. Media assets, will
|
||||
** be implemented directly against the asset::Media interface. To make this feasible
|
||||
** while at the same time being able to handle all asset Kinds in a uniform manner,
|
||||
** we use a hierarchy of ID classes. These IDs are actually just thin wrappers around
|
||||
** a hash value, but they carry a template parameter specifying the Asset Kind and the
|
||||
** Asset Kind subinterfaces provide a overloaded getID method with a covariant return
|
||||
** value. For example the asset::Media#getID returns an ID<Media>. By using the
|
||||
** templated query function AssetManager#getAsset, we can get at references to the more
|
||||
** specific subinterface asset::media just by using the ID value in a typesafe manner.
|
||||
** This helps avoiding dynamic typing and switch-on-type, leading to much more robust,
|
||||
** extensible and clear code.
|
||||
**
|
||||
** (Implementation detail: as g++ is not able to handle member function template
|
||||
** instantiations completely automatic, we need to trigger some template instantiations
|
||||
** at the end of assetmanager.cpp )
|
||||
**
|
||||
** @see assetmanager.hpp
|
||||
** @see media.hpp
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PROC_INTERFACE_ASSET_H
|
||||
#define PROC_INTERFACE_ASSET_H
|
||||
|
||||
|
||||
#include "proc/asset/category.hpp"
|
||||
#include "common/error.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include "common/error.hpp"
|
||||
#include <tr1/memory>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::set;
|
||||
|
||||
|
||||
namespace asset { class Category; }
|
||||
|
||||
|
||||
namespace proc_interface
|
||||
namespace asset
|
||||
{
|
||||
|
||||
typedef void* PAsset; //////TODO
|
||||
using std::size_t;
|
||||
using std::tr1::shared_ptr;
|
||||
|
||||
/**
|
||||
* Superinterface describing especially the bookeeping properties of Assets
|
||||
|
||||
/**
|
||||
* thin wrapper around a size_t hash ID
|
||||
* used as primary key for all Asset objects.
|
||||
* The Templace parameter is intended for tagging
|
||||
* the ID with type information, causing the
|
||||
* compiler to select specialized behaviour
|
||||
* for the different kinds of Assets.
|
||||
* @see Asset
|
||||
* @see AssetManager#getID generating ID values
|
||||
* @see asset::Media
|
||||
* @see ID<asset::Media>
|
||||
*/
|
||||
class Asset
|
||||
template<class KIND>
|
||||
class ID
|
||||
{
|
||||
public:
|
||||
/** Asset primary key. */
|
||||
const long id;
|
||||
const size_t hash;
|
||||
ID (size_t id) : hash(id) {}
|
||||
ID (const KIND& asset) : hash(asset.getID()) {}
|
||||
operator size_t() const { return hash; }
|
||||
};
|
||||
|
||||
class Asset;
|
||||
class AssetManager;
|
||||
typedef const ID<Asset>& IDA;
|
||||
|
||||
/** element ID, comprehensible but sanitized.
|
||||
* The tuple (category, name, org) is unique.
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Superinterface describing especially bookeeping properties.
|
||||
* As of 09/2007, there are four <b>Kinds</b> of Assets, each
|
||||
* comprising a sub-Interface of the Asset Interface:
|
||||
* <ul><li>asset::Media representing mediafiles</li>
|
||||
* <li>asset::Proc representing media data processing components (e.g. Effects)</li>
|
||||
* <li>asset::Struct representing structural components used in the sesion (e.g. Tracks)</li>
|
||||
* <li>asset::Meta representing meta objects created while editing (e.g. Automation)</li>
|
||||
* </ul>
|
||||
* And of course there are various concret Asset subclasses, like asset::Clip,
|
||||
* asset::Effect, asset::Codec, asset::Track, asset::Dataset.
|
||||
* @note Assets objects have a strict unique identity and because of this are non-copyable.
|
||||
* You can not create an Asset derived object without registering it with the AssetManager
|
||||
* automatically. I is possible to copy the PAsset (smart pointer) though.
|
||||
*
|
||||
* @since 09/2007
|
||||
* @author Ichthyo
|
||||
*/
|
||||
class Asset : private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* a POD comprised of all the information
|
||||
* sufficiently identifying any given Asset.
|
||||
*/
|
||||
const string name;
|
||||
struct Ident
|
||||
{
|
||||
/** element ID, comprehensible but sanitized.
|
||||
* The tuple (category, name, org) is unique.
|
||||
*/
|
||||
string name;
|
||||
|
||||
/** primary tree like classification of the asset.
|
||||
* Includes the distinction of different kinds of Assets,
|
||||
* like Media, Audio, Video, Effects... */
|
||||
asset::Category category;
|
||||
|
||||
/** 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".
|
||||
*/
|
||||
const string org;
|
||||
|
||||
/** version 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.
|
||||
*/
|
||||
const uint version;
|
||||
|
||||
/**primary tree like classification of the asset */
|
||||
const asset::Category* category;
|
||||
|
||||
/** 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".
|
||||
*/
|
||||
const string org;
|
||||
|
||||
/** version 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.
|
||||
*/
|
||||
const unsigned int version;
|
||||
|
||||
Ident (const string& n,
|
||||
const Category& cat,
|
||||
const string& o,
|
||||
const uint ver);
|
||||
|
||||
/** @note equality ignores version differences */
|
||||
bool operator== (const Ident& other) const
|
||||
{
|
||||
return org == other.org
|
||||
&& name == other.name
|
||||
&& category == other.category;
|
||||
}
|
||||
bool operator!= (const Ident& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
int compare (const Ident& other) const;
|
||||
|
||||
operator string () const;
|
||||
};
|
||||
|
||||
|
||||
/* ===== Asset ID and Datafields ===== */
|
||||
|
||||
public:
|
||||
const Ident ident; ///< Asset identification tuple
|
||||
|
||||
virtual const ID<Asset>& getID() const { return id; }
|
||||
|
||||
virtual operator string () const;
|
||||
|
||||
|
||||
protected:
|
||||
const ID<Asset> id; ///< Asset primary key.
|
||||
|
||||
/** additional classification, selections or departments this asset belongs to.
|
||||
* Groups are optional, non-exclusive and may be overlapping.
|
||||
*/
|
||||
|
|
@ -88,38 +211,107 @@ namespace proc_interface
|
|||
* perferably "in one line". To be localized. */
|
||||
const string longDesc;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
/** Asset is a Interface class; usually, objects of
|
||||
* concrete subclasses are created via specialized Factories.
|
||||
* Calling this base ctor causes registration with AssetManager.
|
||||
*/
|
||||
Asset (const Ident& idi);
|
||||
virtual ~Asset() = 0; ///< @note Asset is abstract
|
||||
|
||||
/** release all links to other Asset objects held internally.
|
||||
* The lifecycle of Asset objects is managed by smart pointers
|
||||
* and the Asset manager. Calling \c release() breaks interconnectons
|
||||
* to other Assets in the central Object network comprising the session.
|
||||
* It is up to the AssetManager to asure the notification of any other
|
||||
* components that may need to release references to the Asset object
|
||||
* beeing removed. The rationale is, after releasing all interlinkings,
|
||||
* when the AssetManager removes its DB entry for this asset, the
|
||||
* smart pointer goes out of scope and triggers cleanup.
|
||||
*/
|
||||
virtual void unlink ();
|
||||
|
||||
/** variant of #unlink() dropping only the links to the given specific
|
||||
* Asset, leaving all other links intact. Usable for propagating */
|
||||
virtual void unlink (IDA target);
|
||||
|
||||
friend class AssetManager;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
/** List of entities this asset depends on or requires to be functional.
|
||||
* May be empty. The head of this list can be considered the primary prerequisite
|
||||
*/
|
||||
vector<PAsset> getParents () ;
|
||||
vector<shared_ptr<Asset> >
|
||||
getParents () const;
|
||||
|
||||
/** All the other assets requiring this asset to be functional.
|
||||
* For example, all the clips depending on a given media file.
|
||||
* May be empty. The dependency relation is transitive.
|
||||
*/
|
||||
vector<PAsset> getDependant () ;
|
||||
vector<shared_ptr<Asset> >
|
||||
getDependant () const;
|
||||
|
||||
/** weather this asset is swithced on and consequently
|
||||
* included in the fixture and participates in rendering
|
||||
*/
|
||||
bool isActive () ;
|
||||
bool isActive () const;
|
||||
|
||||
/** change the enabled status of this asset.
|
||||
* Note the corresponding #isActive predicate may
|
||||
* depend on the enablement status of parent assets as well
|
||||
*/
|
||||
void enable () throw(cinelerra::error::State);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** shorthand for refcounting Asset pointers */
|
||||
typedef shared_ptr<Asset> PAsset;
|
||||
|
||||
/** ordering of Assets based on Ident tuple */
|
||||
inline bool operator< (const PAsset& a1, const PAsset& a2) { return a1 && a2 && (-1==a1->ident.compare(a2->ident));}
|
||||
inline bool operator> (const PAsset& a1, const PAsset& a2) { return a2 < a1; }
|
||||
inline bool operator>= (const PAsset& a1, const PAsset& a2) { return !(a1 < a2); }
|
||||
inline bool operator<= (const PAsset& a1, const PAsset& a2) { return !(a1 > a2); }
|
||||
|
||||
} // namespace proc_interface
|
||||
/** ordering of Asset Ident tuples.
|
||||
* @note version is irrelevant */
|
||||
inline int Asset::Ident::compare (const Asset::Ident& oi) const
|
||||
{
|
||||
int res;
|
||||
if (1 != (res=category.compare (oi.category))) return res;
|
||||
if (1 != (res=org.compare (oi.org))) return res;
|
||||
return name.compare (oi.name);
|
||||
}
|
||||
|
||||
|
||||
/** convienient for debugging */
|
||||
inline string str (const PAsset& a)
|
||||
{
|
||||
if (a)
|
||||
return string (*a.get());
|
||||
else
|
||||
return "Asset(NULL)";
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace asset
|
||||
|
||||
|
||||
|
||||
namespace asset
|
||||
namespace proc_interface
|
||||
{
|
||||
using proc_interface::Asset;
|
||||
using asset::Asset;
|
||||
using asset::Category;
|
||||
using asset::ID;
|
||||
using asset::IDA;
|
||||
using asset::PAsset;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,10 +22,49 @@
|
|||
|
||||
|
||||
#include "proc/asset/category.hpp"
|
||||
#include "common/util.hpp"
|
||||
#include "nobugcfg.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
using boost::algorithm::starts_with;
|
||||
using util::isnil;
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
|
||||
/** human readable representation of the asset::Category.
|
||||
* @todo to be localized.
|
||||
*/
|
||||
Category::operator string () const
|
||||
{
|
||||
char *kinds[6] = { "AUDIO"
|
||||
, "VIDEO"
|
||||
, "EFFECT"
|
||||
, "CODEC"
|
||||
, "STRUCT"
|
||||
, "META"
|
||||
};
|
||||
REQUIRE ( 0<=kind_ && kind_< 6 );
|
||||
string str (kinds[kind_]);
|
||||
if (!isnil (path_))
|
||||
str += "/"+path_;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** hierarchical inclusion test.
|
||||
* @return true if \c this can be considered
|
||||
* a subcategory of the given reference
|
||||
*/
|
||||
bool
|
||||
Category::isWithin (const Category& ref) const
|
||||
{
|
||||
return ( ref.hasKind (kind_)
|
||||
&& starts_with (path_, ref.path_)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
} // namespace asset
|
||||
|
|
|
|||
|
|
@ -24,17 +24,87 @@
|
|||
#ifndef ASSET_CATEGORY_H
|
||||
#define ASSET_CATEGORY_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
using std::string;
|
||||
using std::ostream;
|
||||
|
||||
/** top-level distinction of different Kinds of Assets.
|
||||
* For convienience, this classification is slightly denormalized,
|
||||
* as AUDIO, and VIDEO are both asset::Media objects, EFFECT and CODEC
|
||||
* are asset::Proc objects, while STRUCT and META refer directly to
|
||||
* the corresponding Interfaces asset::Struct and asset::Meta.
|
||||
*/
|
||||
enum Kind
|
||||
{
|
||||
AUDIO,
|
||||
VIDEO,
|
||||
EFFECT,
|
||||
CODEC,
|
||||
STRUCT,
|
||||
META
|
||||
};
|
||||
|
||||
/**
|
||||
* tree like classification of Assets
|
||||
* Tree like classification of Assets.
|
||||
* By virtue of the Category, Assets can be organized in nested bins (folders).
|
||||
* This includes the distinction of different kinds of Assets, like Audio, Video, Effects...
|
||||
*
|
||||
* @todo could be far more elaborate. could be a singleton like centralized tree, while
|
||||
* just holding references to Catetory nodes in the individual Asset. At the moment,
|
||||
* we use just the most simplistic implementation and handle Category objects
|
||||
* using value semantics.
|
||||
*/
|
||||
class Category
|
||||
{};
|
||||
|
||||
{
|
||||
public:
|
||||
|
||||
private:
|
||||
Kind kind_;
|
||||
string path_;
|
||||
|
||||
public:
|
||||
Category (const Kind root, string subfolder ="")
|
||||
: kind_(root), path_(subfolder) {};
|
||||
|
||||
bool operator== (const Category& other) const { return kind_== other.kind_ && path_== other.path_; }
|
||||
bool operator!= (const Category& other) const { return kind_!= other.kind_ || path_!= other.path_; }
|
||||
|
||||
bool hasKind (Kind refKind) const { return kind_ == refKind; }
|
||||
bool isWithin (const Category&) const;
|
||||
|
||||
|
||||
operator string () const;
|
||||
|
||||
|
||||
friend size_t hash_value (const Category& cat)
|
||||
{
|
||||
size_t hash = 0;
|
||||
boost::hash_combine(hash, cat.kind_);
|
||||
boost::hash_combine(hash, cat.path_);
|
||||
return hash;
|
||||
}
|
||||
|
||||
int compare (const Category& co) const
|
||||
{
|
||||
int res = int(kind_) - int(co.kind_);
|
||||
if (1 != res)
|
||||
return res;
|
||||
else
|
||||
return path_.compare (co.path_);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline ostream& operator<< (ostream& os, const Category& cago) { return os << string(cago); }
|
||||
|
||||
|
||||
|
||||
} // namespace asset
|
||||
#endif
|
||||
|
|
|
|||
130
src/proc/asset/db.hpp
Normal file
130
src/proc/asset/db.hpp
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
DB.hpp - registry holding known Asset instances.
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
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 ASSET_DB_H
|
||||
#define ASSET_DB_H
|
||||
|
||||
|
||||
#include "proc/asset.hpp"
|
||||
|
||||
#include <tr1/unordered_map>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
|
||||
|
||||
/* ===== hash implementations ===== */
|
||||
|
||||
size_t
|
||||
hash_value (const Asset::Ident& idi)
|
||||
{
|
||||
size_t hash = 0;
|
||||
boost::hash_combine(hash, idi.org);
|
||||
boost::hash_combine(hash, idi.name);
|
||||
boost::hash_combine(hash, idi.category);
|
||||
return hash;
|
||||
}
|
||||
|
||||
size_t
|
||||
hash_value (const Asset& asset)
|
||||
{
|
||||
return asset.getID();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* trivial hash functor.
|
||||
* returns any hash value unmodified.
|
||||
* For building a hashtable with keys
|
||||
* already containing valid hash values.
|
||||
*/
|
||||
struct IdentityHash
|
||||
: public std::unary_function<size_t, size_t>
|
||||
{
|
||||
size_t
|
||||
operator() (size_t val) const { return val; }
|
||||
};
|
||||
|
||||
typedef std::tr1::unordered_map<size_t, PAsset, IdentityHash> IdHashtable;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of the registry holding all Asset
|
||||
* instances known to the Asset Manager subsystem.
|
||||
* As of 8/2007 implemented by a hashtable.
|
||||
*/
|
||||
class DB : private boost::noncopyable
|
||||
{
|
||||
IdHashtable table;
|
||||
|
||||
DB () : table() {}
|
||||
~DB () {}
|
||||
|
||||
friend class cinelerra::singleton::Static<DB>;
|
||||
|
||||
|
||||
public:
|
||||
template<class KIND>
|
||||
void put (ID<KIND> hash, shared_ptr<KIND>& ptr) { table[hash] = static_pointer_cast (ptr); }
|
||||
void put (ID<Asset> hash, PAsset& ptr) { table[hash] = ptr; }
|
||||
|
||||
template<class KIND>
|
||||
shared_ptr<KIND>
|
||||
get (ID<KIND> hash) const
|
||||
{
|
||||
return dynamic_pointer_cast<KIND,Asset> (find (hash));
|
||||
}
|
||||
|
||||
|
||||
/** intended for diagnostics */
|
||||
void
|
||||
asList (list<PAsset>& output) const
|
||||
{
|
||||
IdHashtable::const_iterator i = table.begin();
|
||||
IdHashtable::const_iterator e = table.end();
|
||||
for ( ; i!=e ; ++i )
|
||||
output.push_back (i->second);
|
||||
}
|
||||
|
||||
private:
|
||||
const PAsset &
|
||||
find (size_t hash) const
|
||||
{
|
||||
static const PAsset NULLP;
|
||||
IdHashtable::const_iterator i = table.find (hash);
|
||||
if (i == table.end())
|
||||
return NULLP; // empty ptr signaling "not found"
|
||||
else
|
||||
return i->second;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace asset
|
||||
#endif
|
||||
|
|
@ -21,13 +21,127 @@
|
|||
* *****************************************************/
|
||||
|
||||
|
||||
#include "proc/assetmanager.hpp"
|
||||
#include "proc/asset/media.hpp"
|
||||
#include "proc/asset/clip.hpp"
|
||||
#include "proc/asset/unknown.hpp"
|
||||
#include "common/util.hpp"
|
||||
#include "nobugcfg.h"
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
using util::isnil;
|
||||
|
||||
using boost::regex;
|
||||
using boost::smatch;
|
||||
using boost::regex_search;
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
/** */
|
||||
namespace // Implementation details
|
||||
{
|
||||
/** helper: extract a name token out of a given path/filename
|
||||
* @return sanitized token based on the name (minus extension),
|
||||
* empty string if not the common filename pattern.
|
||||
*/
|
||||
string extractName (const string& path)
|
||||
{
|
||||
regex pathname_pattern("([^/\\.]+)(\\.\\w+)?$");
|
||||
smatch match;
|
||||
|
||||
if (regex_search (path, match, pathname_pattern))
|
||||
return util::sanitize (string (match[1]));
|
||||
else
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
MediaFactory Media::create; ///< storage for the static MediaFactory instance
|
||||
|
||||
|
||||
|
||||
/** Factory method for Media Asset instances. Depending on the filename given,
|
||||
* either a asset::Media object or an "Unknown" placeholder will be provided. If
|
||||
* the given Category already contains an "Unkown", we just get the
|
||||
* corresponding smart-ptr. Otherwise a new asset::Unknown is created.
|
||||
* @return an Media smart ptr linked to the internally registered smart ptr
|
||||
* created as a side effect of calling the concrete Media subclass ctor.
|
||||
*/
|
||||
MediaFactory::PType
|
||||
MediaFactory::operator() (Asset::Ident& key, const string& file)
|
||||
{
|
||||
asset::Media* pM (0);
|
||||
AssetManager& aMang = AssetManager::instance();
|
||||
|
||||
TODO ("check and fix Category if necessary");
|
||||
|
||||
if (isnil (file))
|
||||
{
|
||||
if (isnil (key.name)) key.name="nil";
|
||||
ID<Asset> id = aMang.getID (key);
|
||||
if (aMang.known (id))
|
||||
return aMang.getAsset(ID<Media>(id));
|
||||
else
|
||||
pM = new Unknown(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isnil (key.name)) key.name=extractName(file);
|
||||
TODO ("file exists?");
|
||||
pM = new Media (key,file);
|
||||
}
|
||||
ASSERT (pM);
|
||||
ENSURE (key.category.hasKind (VIDEO) || key.category.hasKind(AUDIO));
|
||||
ENSURE (!isnil (key.name));
|
||||
ENSURE (dynamic_cast<Media*>(pM) || (isnil (file) && dynamic_cast<Unknown*>(pM)));
|
||||
|
||||
return aMang.getAsset (pM->getID()); // note: because we query with an ID<Media>,
|
||||
// we get a Media smart ptr.
|
||||
}
|
||||
|
||||
|
||||
/** Variant of the Factory method for Media Assets, automatically
|
||||
* providing most of the Asset key fields based on the filename given
|
||||
*/
|
||||
MediaFactory::PType
|
||||
MediaFactory::operator() (const string& file, const Category& cat)
|
||||
{
|
||||
Asset::Ident key(extractName(file), cat, "cin3", 1);
|
||||
return operator() (key, file);
|
||||
}
|
||||
|
||||
MediaFactory::PType
|
||||
MediaFactory::operator() (const string& file, asset::Kind kind)
|
||||
{
|
||||
Category cat(kind);
|
||||
return operator() (file, cat);
|
||||
}
|
||||
|
||||
|
||||
MediaFactory::PType
|
||||
MediaFactory::operator() (const char* file, const Category& cat)
|
||||
{
|
||||
if (!file) file = "";
|
||||
return operator() (string(file),cat);
|
||||
}
|
||||
|
||||
MediaFactory::PType
|
||||
MediaFactory::operator() (const char* file, asset::Kind kind)
|
||||
{
|
||||
if (!file) file = "";
|
||||
return operator() (string(file),kind);
|
||||
}
|
||||
|
||||
MediaFactory::PType
|
||||
MediaFactory::operator() (Asset::Ident& key, const char* file)
|
||||
{
|
||||
if (!file) file = "";
|
||||
return operator() (key, string(file));
|
||||
}
|
||||
|
||||
|
||||
} // namespace asset
|
||||
|
|
|
|||
|
|
@ -21,26 +21,93 @@
|
|||
*/
|
||||
|
||||
|
||||
/** @file media.hpp
|
||||
** Media data is a specific Kind of Asset.
|
||||
** For the different <i>Kinds</i> of Assets, we use sub-intefaces inheriting
|
||||
** from the general Asset interface. To be able to get asset::Media instances
|
||||
** directly from the AssetManager, we define a specialization of the Asset ID.
|
||||
**
|
||||
** @see asset.hpp for explanation
|
||||
** @see MediaFactory creating concrete asset::Media instances
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef ASSET_MEDIA_H
|
||||
#define ASSET_MEDIA_H
|
||||
|
||||
#include "proc/asset.hpp"
|
||||
#include "common/factory.hpp"
|
||||
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
class Media;
|
||||
class MediaFactory;
|
||||
|
||||
|
||||
template<>
|
||||
class ID<Media> : public ID<Asset>
|
||||
{
|
||||
public:
|
||||
ID (size_t id);
|
||||
ID (const Media&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* key abstraction: media-like assets
|
||||
*/
|
||||
class Media : public proc_interface::Asset
|
||||
class Media : public Asset
|
||||
{
|
||||
string filename_;
|
||||
|
||||
public:
|
||||
static MediaFactory create;
|
||||
const string& getFilename () const { return filename_; }
|
||||
|
||||
virtual const ID<Media>& getID() const ///< @return ID of kind Media
|
||||
{
|
||||
return static_cast<const ID<Media>& > (Asset::getID());
|
||||
}
|
||||
|
||||
protected:
|
||||
Media (const Asset::Ident& idi, const string& file) : Asset(idi), filename_(file) {}
|
||||
friend class MediaFactory;
|
||||
};
|
||||
|
||||
|
||||
// definition of ID<Media> ctors is possible now,
|
||||
// after providing full definition of class Media
|
||||
|
||||
inline ID<Media>::ID(size_t id) : ID<Asset> (id) {};
|
||||
inline ID<Media>::ID(const Media& media) : ID<Asset> (media.getID()) {};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Factory specialized for createing Media Asset objects.
|
||||
*/
|
||||
class MediaFactory : public cinelerra::Factory<asset::Media>
|
||||
{
|
||||
public:
|
||||
typedef shared_ptr<asset::Media> PType;
|
||||
|
||||
PType operator() (Asset::Ident& key, const string& file="");
|
||||
PType operator() (const string& file, const Category& cat);
|
||||
PType operator() (const string& file, asset::Kind);
|
||||
|
||||
PType operator() (Asset::Ident& key, const char* file); ///< convienience overload using C-String
|
||||
PType operator() (const char* file, const Category& cat);
|
||||
PType operator() (const char* file, asset::Kind);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace asset
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,13 +21,37 @@
|
|||
* *****************************************************/
|
||||
|
||||
|
||||
#include "proc/assetmanager.hpp"
|
||||
#include "proc/asset/meta.hpp"
|
||||
#include "common/util.hpp"
|
||||
#include "nobugcfg.h"
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
/** */
|
||||
|
||||
namespace // Implementation details
|
||||
{
|
||||
/** helper: .....*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
MetaFactory Meta::create; ///< storage for the static MetaFactory instance
|
||||
|
||||
|
||||
|
||||
/** Factory method for Metadata Asset instances. ....
|
||||
* @todo actually define
|
||||
* @return an Meta smart ptr linked to the internally registered smart ptr
|
||||
* created as a side effect of calling the concrete Meta subclass ctor.
|
||||
*/
|
||||
MetaFactory::PType
|
||||
MetaFactory::operator() (Asset::Ident& key) ////TODO
|
||||
{
|
||||
UNIMPLEMENTED ("Meta-Factory");
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace asset
|
||||
|
|
|
|||
|
|
@ -21,26 +21,86 @@
|
|||
*/
|
||||
|
||||
|
||||
/** @file meta.hpp
|
||||
** Some Metatdata elements (e.g. Automation Datasets) can be treated as
|
||||
** specific Kind of Asset.
|
||||
** For the different <i>Kinds</i> of Assets, we use sub-intefaces inheriting
|
||||
** from the general Asset interface. To be able to get asset::Meta instances
|
||||
** directly from the AssetManager, we define a specialization of the Asset ID.
|
||||
**
|
||||
** @see asset.hpp for explanation
|
||||
** @see MetaFactory creating concrete asset::Meta instances
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef ASSET_META_H
|
||||
#define ASSET_META_H
|
||||
|
||||
#include "proc/asset.hpp"
|
||||
#include "common/factory.hpp"
|
||||
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
class Meta;
|
||||
class MetaFactory;
|
||||
|
||||
|
||||
template<>
|
||||
class ID<Meta> : public ID<Asset>
|
||||
{
|
||||
public:
|
||||
ID (size_t id);
|
||||
ID (const Meta&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* key abstraction: metadata and organisational asset
|
||||
* @todo just a stub, have to figure out what a asset::Proc is
|
||||
*/
|
||||
class Meta : public proc_interface::Asset
|
||||
class Meta : public Asset
|
||||
{
|
||||
public:
|
||||
static MetaFactory create;
|
||||
|
||||
virtual const ID<Meta>& getID() const ///< @return ID of kind Meta
|
||||
{
|
||||
return static_cast<const ID<Meta>& > (Asset::getID());
|
||||
}
|
||||
|
||||
protected:
|
||||
Meta (const Asset::Ident& idi) : Asset(idi) {} //////////////TODO
|
||||
friend class MetaFactory;
|
||||
};
|
||||
|
||||
|
||||
// definition of ID<Meta> ctors is possible now,
|
||||
// after providing full definition of class Proc
|
||||
|
||||
inline ID<Meta>::ID(size_t id) : ID<Asset> (id) {};
|
||||
inline ID<Meta>::ID(const Meta& meta) : ID<Asset> (meta.getID()) {};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Factory specialized for createing Metadata Asset objects.
|
||||
*/
|
||||
class MetaFactory : public cinelerra::Factory<asset::Meta>
|
||||
{
|
||||
public:
|
||||
typedef shared_ptr<asset::Meta> PType;
|
||||
|
||||
PType operator() (Asset::Ident& key); ////////////TODO define actual operation
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace asset
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@ namespace asset
|
|||
*/
|
||||
class Preview : public Media
|
||||
{
|
||||
|
||||
protected:
|
||||
Preview (const Asset::Ident& idi) : Media(idi,"") {}
|
||||
friend class MediaFactory;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,13 +21,37 @@
|
|||
* *****************************************************/
|
||||
|
||||
|
||||
#include "proc/assetmanager.hpp"
|
||||
#include "proc/asset/proc.hpp"
|
||||
#include "common/util.hpp"
|
||||
#include "nobugcfg.h"
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
/** */
|
||||
|
||||
namespace // Implementation details
|
||||
{
|
||||
/** helper: .....*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
ProcFactory Proc::create; ///< storage for the static ProcFactory instance
|
||||
|
||||
|
||||
|
||||
/** Factory method for Processor Asset instances. ....
|
||||
* @todo actually define
|
||||
* @return an Proc smart ptr linked to the internally registered smart ptr
|
||||
* created as a side effect of calling the concrete Proc subclass ctor.
|
||||
*/
|
||||
ProcFactory::PType
|
||||
ProcFactory::operator() (Asset::Ident& key) ////TODO
|
||||
{
|
||||
UNIMPLEMENTED ("Proc-Factory");
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace asset
|
||||
|
|
|
|||
|
|
@ -21,26 +21,85 @@
|
|||
*/
|
||||
|
||||
|
||||
/** @file proc.hpp
|
||||
** Data processing Plugins and Codecs can be treated as a specific Kind of Asset.
|
||||
** For the different <i>Kinds</i> of Assets, we use sub-intefaces inheriting
|
||||
** from the general Asset interface. To be able to get asset::Proc instances
|
||||
** directly from the AssetManager, we define a specialization of the Asset ID.
|
||||
**
|
||||
** @see asset.hpp for explanation
|
||||
** @see ProcFactory creating concrete asset::Proc instances
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef ASSET_PROC_H
|
||||
#define ASSET_PROC_H
|
||||
|
||||
#include "proc/asset.hpp"
|
||||
#include "common/factory.hpp"
|
||||
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
class Proc;
|
||||
class ProcFactory;
|
||||
|
||||
|
||||
template<>
|
||||
class ID<Proc> : public ID<Asset>
|
||||
{
|
||||
public:
|
||||
ID (size_t id);
|
||||
ID (const Proc&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* key abstraction: data processing asset
|
||||
* @todo just a stub, have to figure out what a asset::Proc is
|
||||
*/
|
||||
class Proc : public Asset
|
||||
{
|
||||
public:
|
||||
static ProcFactory create;
|
||||
|
||||
virtual const ID<Proc>& getID() const ///< @return ID of kind Proc
|
||||
{
|
||||
return static_cast<const ID<Proc>& > (Asset::getID());
|
||||
}
|
||||
|
||||
protected:
|
||||
Proc (const Asset::Ident& idi) : Asset(idi) {} //////////////TODO
|
||||
friend class ProcFactory;
|
||||
};
|
||||
|
||||
|
||||
// definition of ID<Proc> ctors is possible now,
|
||||
// after providing full definition of class Proc
|
||||
|
||||
inline ID<Proc>::ID(size_t id) : ID<Asset> (id) {};
|
||||
inline ID<Proc>::ID(const Proc& proc) : ID<Asset> (proc.getID()) {};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Factory specialized for createing Processor Asset objects.
|
||||
*/
|
||||
class ProcFactory : public cinelerra::Factory<asset::Proc>
|
||||
{
|
||||
public:
|
||||
typedef shared_ptr<asset::Proc> PType;
|
||||
|
||||
PType operator() (Asset::Ident& key); ////////////TODO define actual operation
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace asset
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,10 +21,38 @@
|
|||
* *****************************************************/
|
||||
|
||||
|
||||
#include "proc/assetmanager.hpp"
|
||||
#include "proc/asset/struct.hpp"
|
||||
#include "common/util.hpp"
|
||||
#include "nobugcfg.h"
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
namespace // Implementation details
|
||||
{
|
||||
/** helper: .....*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
StructFactory Struct::create; ///< storage for the static StructFactory instance
|
||||
|
||||
|
||||
|
||||
/** Factory method for Structural Asset instances. ....
|
||||
* @todo actually define
|
||||
* @return an Struct smart ptr linked to the internally registered smart ptr
|
||||
* created as a side effect of calling the concrete Struct subclass ctor.
|
||||
*/
|
||||
StructFactory::PType
|
||||
StructFactory::operator() (Asset::Ident& key) ////TODO
|
||||
{
|
||||
UNIMPLEMENTED ("Struct-Factory");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,23 +21,83 @@
|
|||
*/
|
||||
|
||||
|
||||
/** @file struct.hpp
|
||||
** Structural facilities of the EDL (e.g. Tracks) can be treated in the
|
||||
** "bookkeeping view" as a specific Kind of Asset.
|
||||
** For the different <i>Kinds</i> of Assets, we use sub-intefaces inheriting
|
||||
** from the general Asset interface. To be able to get asset::Struct instances
|
||||
** directly from the AssetManager, we define a specialization of the Asset ID.
|
||||
**
|
||||
** @see asset.hpp for explanation
|
||||
** @see StructFactory creating concrete asset::Struct instances
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ASSET_STRUCT_H
|
||||
#define ASSET_STRUCT_H
|
||||
|
||||
#include "proc/asset.hpp"
|
||||
#include "common/factory.hpp"
|
||||
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
class Struct;
|
||||
class StructFactory;
|
||||
|
||||
|
||||
template<>
|
||||
class ID<Struct> : public ID<Asset>
|
||||
{
|
||||
public:
|
||||
ID (size_t id);
|
||||
ID (const Struct&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* key abstraction: structural asset
|
||||
* @todo just a stub, have to figure out what a asset::Proc is
|
||||
*/
|
||||
class Struct : public Asset
|
||||
{
|
||||
public:
|
||||
static StructFactory create;
|
||||
|
||||
virtual const ID<Struct>& getID() const ///< @return ID of kind asset::Struct
|
||||
{
|
||||
return static_cast<const ID<Struct>& > (Asset::getID());
|
||||
}
|
||||
|
||||
protected:
|
||||
Struct (const Asset::Ident& idi) : Asset(idi) {} //////////////TODO
|
||||
friend class StructFactory;
|
||||
};
|
||||
|
||||
|
||||
// definition of ID<Struct> ctors is possible now,
|
||||
// after providing full definition of class Proc
|
||||
|
||||
inline ID<Struct>::ID(size_t id) : ID<Asset> (id) {};
|
||||
inline ID<Struct>::ID(const Struct& stru) : ID<Asset> (stru.getID()) {};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Factory specialized for createing Structural Asset objects.
|
||||
*/
|
||||
class StructFactory : public cinelerra::Factory<asset::Struct>
|
||||
{
|
||||
public:
|
||||
typedef shared_ptr<asset::Struct> PType;
|
||||
|
||||
PType operator() (Asset::Ident& key); ////////////TODO define actual operation
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ namespace asset
|
|||
*/
|
||||
class Unknown : public Preview
|
||||
{
|
||||
|
||||
protected:
|
||||
Unknown (const Asset::Ident& idi) : Preview(idi) {}
|
||||
friend class MediaFactory;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,29 +22,127 @@
|
|||
|
||||
|
||||
#include "proc/assetmanager.hpp"
|
||||
#include "proc/asset/db.hpp"
|
||||
|
||||
namespace proc_interface
|
||||
#include "common/multithread.hpp"
|
||||
#include "common/util.hpp"
|
||||
|
||||
//#include <boost/lambda/lambda.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using boost::format;
|
||||
using boost::bind;
|
||||
//using boost::lambda::_1;
|
||||
using util::for_each;
|
||||
|
||||
using cinelerra::Singleton;
|
||||
using cinelerra::Thread;
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
/**
|
||||
* AssetManager error responses, cause by querying
|
||||
* invalid Asset IDs from the internal DB.
|
||||
*/
|
||||
class IDErr : public cinelerra::error::Invalid
|
||||
{
|
||||
public:
|
||||
IDErr (const char* eID, format fmt)
|
||||
: cinelerra::error::Invalid(fmt.str(),eID) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* registers an asset object in the internal DB, providing its unique key
|
||||
|
||||
// ------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");
|
||||
|
||||
class UnknownID : public IDErr
|
||||
{
|
||||
public:
|
||||
UnknownID (ID<Asset> 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) {}
|
||||
};
|
||||
|
||||
class WrongKind : public IDErr
|
||||
{
|
||||
public:
|
||||
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)) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** get at the system-wide asset manager instance.
|
||||
* Implemented as singleton.
|
||||
*/
|
||||
long
|
||||
AssetManager::reg (string& name, string& category, string& org, uint version)
|
||||
//throw(cinelerra::error::Invalid)
|
||||
Singleton<AssetManager> AssetManager::instance;
|
||||
|
||||
AssetManager::AssetManager ()
|
||||
: registry (Singleton<asset::DB>() ())
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
/** provide the unique ID for given Asset::Ident tuple */
|
||||
ID<Asset>
|
||||
AssetManager::getID (const Asset::Ident& idi)
|
||||
{
|
||||
return asset::hash_value (idi);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* find and return corresponging object
|
||||
* registers an asset object in the internal DB, providing its unique key.
|
||||
* This includes creating the smart ptr in charge of the asset's lifecycle
|
||||
*/
|
||||
template<class KIND> ////TODO: does this work????
|
||||
KIND
|
||||
AssetManager::getAsset (long id) ////throw(cinelerra::Invalid)
|
||||
template<class KIND>
|
||||
ID<KIND>
|
||||
AssetManager::reg (KIND* obj, const Asset::Ident& idi)
|
||||
throw(cinelerra::error::Invalid)
|
||||
{
|
||||
typedef shared_ptr<KIND> PType;
|
||||
AssetManager& _aMang (AssetManager::instance());
|
||||
TODO ("check validity of Ident Category");
|
||||
ID<KIND> asset_id (getID (idi));
|
||||
|
||||
Thread::Lock<DB> guard SIDEEFFECT;
|
||||
TODO ("handle duplicate Registrations");
|
||||
PType smart_ptr (obj, &destroy);
|
||||
|
||||
_aMang.registry.put (asset_id, smart_ptr);
|
||||
return asset_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* find and return the object registered with the given ID.
|
||||
* @throws Invalid if nothing is found or if the actual KIND
|
||||
* of the stored object differs and can't be casted.
|
||||
*/
|
||||
template<class KIND>
|
||||
shared_ptr<KIND>
|
||||
AssetManager::getAsset (const ID<KIND>& id)
|
||||
throw(cinelerra::error::Invalid)
|
||||
{
|
||||
if (shared_ptr<KIND> obj = registry.get (id))
|
||||
return obj;
|
||||
else
|
||||
if (known (id)) // provide Ident tuple of existing Asset
|
||||
throw WrongKind (registry.get(ID<Asset>(id))->ident);
|
||||
else
|
||||
throw UnknownID (id);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -52,19 +150,83 @@ namespace proc_interface
|
|||
* @return true if the given id is registered in the internal asset DB
|
||||
*/
|
||||
bool
|
||||
AssetManager::known (long id)
|
||||
AssetManager::known (IDA id)
|
||||
{
|
||||
return ( registry.get (ID<Asset>(id)) );
|
||||
} // query most general Asset ID-kind and use implicit
|
||||
// conversion from shared_ptr to bool (test if empty)
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the given id is registered with the given Category
|
||||
*/
|
||||
bool
|
||||
AssetManager::known (IDA id, const Category& cat)
|
||||
{
|
||||
PAsset pA = registry.get (id);
|
||||
return ( pA && pA->ident.category.isWithin(cat));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AssetManager::detach_child (PAsset& pA, IDA id)
|
||||
{
|
||||
pA->unlink(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove the given asset <i>together with all its dependants</i> from the internal DB
|
||||
*/
|
||||
void
|
||||
AssetManager::remove (long id) /////throw(cinelerra::Invalid, cinelerra::State)
|
||||
{
|
||||
}
|
||||
AssetManager::remove (IDA id)
|
||||
throw(cinelerra::error::Invalid,
|
||||
cinelerra::error::State)
|
||||
{
|
||||
UNIMPLEMENTED ("remove Asset with all dependecies");
|
||||
|
||||
PAsset pA = getAsset (id);
|
||||
vector<PAsset> par = pA->getParents();
|
||||
boost::function<void(PAsset&)> func = bind(&detach_child, _1,id );
|
||||
for_each (par, func); // ,boost::lambda::var(id)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
list<PAsset>
|
||||
AssetManager::listContent() const
|
||||
{
|
||||
list<PAsset> res;
|
||||
registry.asList (res);
|
||||
res.sort();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
} // namespace asset
|
||||
|
||||
|
||||
|
||||
} // namespace proc_interface
|
||||
|
||||
/************************************************************/
|
||||
/* explicit template instantiations for various Asset Kinds */
|
||||
/************************************************************/
|
||||
|
||||
#include "proc/asset/media.hpp"
|
||||
#include "proc/asset/proc.hpp"
|
||||
#include "proc/asset/struct.hpp"
|
||||
#include "proc/asset/meta.hpp"
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
template ID<Asset> AssetManager::reg (Asset* obj, const Asset::Ident& idi);
|
||||
|
||||
|
||||
template shared_ptr<Asset> AssetManager::getAsset (const ID<Asset>& id) throw(cinelerra::error::Invalid);
|
||||
template shared_ptr<Media> AssetManager::getAsset (const ID<Media>& id) throw(cinelerra::error::Invalid);
|
||||
template shared_ptr<Proc> AssetManager::getAsset (const ID<Proc>& id) throw(cinelerra::error::Invalid);
|
||||
template shared_ptr<Struct> AssetManager::getAsset (const ID<Struct>& id) throw(cinelerra::error::Invalid);
|
||||
template shared_ptr<Meta> AssetManager::getAsset (const ID<Meta>& id) throw(cinelerra::error::Invalid);
|
||||
|
||||
} // namespace asset
|
||||
|
|
|
|||
|
|
@ -20,48 +20,112 @@
|
|||
|
||||
*/
|
||||
|
||||
/** @file assetmanager.hpp
|
||||
** Proc-Layer Interface: Asset Lookup and Organization.
|
||||
** Declares the AssetManager interface used to access individual
|
||||
** Asset instances.
|
||||
**
|
||||
** These classes are placed into namespace asset and proc_interface.
|
||||
**
|
||||
** @see asset.hpp
|
||||
** @see mobject.hpp
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PROC_INTERFACE_ASSETMANAGER_H
|
||||
#define PROC_INTERFACE_ASSETMANAGER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "proc/asset.hpp"
|
||||
#include "common/error.hpp"
|
||||
#include "common/singleton.hpp"
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
using std::string;
|
||||
using std::list;
|
||||
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
class DB;
|
||||
|
||||
|
||||
/**
|
||||
* Facade for the Asset subsystem
|
||||
*/
|
||||
class AssetManager : private boost::noncopyable
|
||||
{
|
||||
asset::DB & registry;
|
||||
|
||||
|
||||
public:
|
||||
static cinelerra::Singleton<AssetManager> instance;
|
||||
|
||||
/** provide the unique ID for given Asset::Ident tuple */
|
||||
static ID<Asset> getID (const Asset::Ident&);
|
||||
|
||||
|
||||
/** find and return corresponging object */
|
||||
template<class KIND>
|
||||
shared_ptr<KIND> getAsset (const ID<KIND>& id) throw(cinelerra::error::Invalid);
|
||||
|
||||
|
||||
/** @return true if the given id is registered in the internal asset DB */
|
||||
bool known (IDA id) ;
|
||||
|
||||
/** @return true if the given id is registered with the given Category */
|
||||
bool known (IDA id, const Category& cat) ;
|
||||
|
||||
/**remove the given asset from the internal DB.
|
||||
* <i>together with all its dependants</i> */
|
||||
void remove (IDA id) throw(cinelerra::error::Invalid,
|
||||
cinelerra::error::State);
|
||||
|
||||
/** extract a sorted list of all registered Assets */
|
||||
list<PAsset> listContent() const;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
/** registers an asset object in the internal DB, providing its unique key.
|
||||
* @internal used by the Asset base class ctor to create Asset::id.
|
||||
*/
|
||||
template<class KIND>
|
||||
static ID<KIND> reg (KIND* obj, const Asset::Ident& idi)
|
||||
throw(cinelerra::error::Invalid);
|
||||
|
||||
/** deleter function used by the Asset smart pointers to delet Asset objects */
|
||||
static void destroy (Asset* m) { delete m; }
|
||||
|
||||
friend Asset::Asset (const Asset::Ident& idi);
|
||||
|
||||
AssetManager ();
|
||||
|
||||
friend class cinelerra::singleton::Static<AssetManager>;
|
||||
|
||||
|
||||
private:
|
||||
static void detach_child (PAsset&, IDA);
|
||||
};
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
namespace proc_interface
|
||||
{
|
||||
using asset::AssetManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Facade for the Asset subsystem
|
||||
*/
|
||||
class AssetManager
|
||||
{
|
||||
int bla;
|
||||
public:
|
||||
/** registers an asset object in the internal DB, providing its unique key
|
||||
*/
|
||||
static long reg (string& name, string& category, string& org, uint version)
|
||||
;
|
||||
// throw(cinelerra::error::Invalid);
|
||||
|
||||
/** find and return corresponging object */
|
||||
template<class KIND>
|
||||
// void* /////////////////TODO
|
||||
KIND
|
||||
getAsset (long id) ;///throw(cinelerra::error::Invalid);
|
||||
|
||||
/** @return true if the given id is registered in the internal asset DB */
|
||||
bool known (long id) ;
|
||||
|
||||
/**remove the given asset from the internal DB.
|
||||
* <i>together with all its dependants</i>
|
||||
*/
|
||||
void remove (long id) ;///throw(cinelerra::error::Invalid, cinelerra::error::State);
|
||||
};
|
||||
|
||||
} // namespace proc_interface
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,8 +41,12 @@ out: 2|ä|
|
|||
out: 3|+|
|
||||
out: 4|€|
|
||||
out: -->oo _O()O_ ä + €
|
||||
out: wrapping cmdline:...
|
||||
out: -->
|
||||
out: wrapping cmdline:Ω ooΩ oΩo Ωoo...
|
||||
out: 0|Ω|
|
||||
out: 1|ooΩ|
|
||||
out: 2|oΩo|
|
||||
out: 3|Ωoo|
|
||||
out: -->Ω ooΩ oΩo Ωoo
|
||||
out: Standard Cmdlineformat:one two
|
||||
END
|
||||
|
||||
|
|
@ -133,3 +137,32 @@ out: --> Testgroup=TestGroupID
|
|||
out: --> Test-ID =SingleTestID
|
||||
out: --> remaining=SingleTestID spam --eggs
|
||||
END
|
||||
|
||||
|
||||
TEST "SanitizedIdentifier_test" SanitizedIdentifier_test <<END
|
||||
out: 'Word' --> 'Word'
|
||||
out: 'a Sentence' --> 'a_Sentence'
|
||||
out: 'trailing Withespace
|
||||
out: ' --> 'trailing_Withespace'
|
||||
out: 'with a lot
|
||||
out: of Whitespace' --> 'with_a_lot_of_Whitespace'
|
||||
out: 'with"much (punctuation)[]!' --> 'withmuch_(punctuation)'
|
||||
out: '§&Ω%€ leading garbarge' --> 'leading_garbarge'
|
||||
out: 'mixed Ω garbarge' --> 'mixed_garbarge'
|
||||
out: 'Bääääh!!' --> 'Bh'
|
||||
out: '§&Ω%€' --> ''
|
||||
END
|
||||
|
||||
|
||||
TEST "Singleton_test" Singleton_test 23 <<END
|
||||
out: testing TargetObj(23) as Singleton(statically allocated)
|
||||
out: ctor TargetObj(23) successfull
|
||||
out: calling a non-static method on the Singleton instance
|
||||
out: .....TargetObj(23): data="***********************", array[23]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,}
|
||||
out: testing TargetObj(24) as Singleton(heap allocated)
|
||||
out: ctor TargetObj(24) successfull
|
||||
out: calling a non-static method on the Singleton instance
|
||||
out: .....TargetObj(24): data="************************", array[24]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,}
|
||||
out: dtor ~TargetObj(23) successfull
|
||||
out: dtor ~TargetObj(24) successfull
|
||||
END
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ TESTING "Component Test Suite: Asset Manager" ./test-components --group=asset
|
|||
|
||||
|
||||
|
||||
PLANNED "CreateAsset_test" CreateAsset_test <<END
|
||||
TEST "CreateAsset_test" CreateAsset_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
||||
|
|
@ -12,3 +13,12 @@ END
|
|||
|
||||
PLANNED "DependantAssets_test" DependantAssets_test <<END
|
||||
END
|
||||
|
||||
|
||||
TEST "IdentityOfAssets_test" IdentityOfAssets_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
||||
PLANNED "OrderingOfAssets_test" OrderingOfAssets_test <<END
|
||||
END
|
||||
|
|
@ -48,7 +48,7 @@ moduledirs = globRootdirs('*')
|
|||
|
||||
#
|
||||
# have to treat the plugin-example specially.
|
||||
isnt_plugin = lambda dir : dir!='plugin'
|
||||
isnt_plugin = lambda dir : not (dir=='plugin' or dir=='locking')
|
||||
moduledirs = filter(isnt_plugin, moduledirs)
|
||||
pluginExe = treatPluginTestcase(env)
|
||||
|
||||
|
|
|
|||
69
tests/components/common/sanitizedidentifiertest.cpp
Normal file
69
tests/components/common/sanitizedidentifiertest.cpp
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
SanitizedIdentifier(Test) - remove non-standard-chars and punctuation
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
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 "nobugcfg.h"
|
||||
|
||||
#include "common/test/run.hpp"
|
||||
#include "common/util.hpp"
|
||||
|
||||
|
||||
#include <iostream>
|
||||
using std::cout;
|
||||
|
||||
|
||||
|
||||
namespace util
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
|
||||
class SanitizedIdentifier_test : public Test
|
||||
{
|
||||
virtual void run (Arg arg)
|
||||
{
|
||||
print_clean ("Word");
|
||||
print_clean ("a Sentence");
|
||||
print_clean ("trailing Withespace\n \t");
|
||||
print_clean ("with a \t lot\n of Whitespace");
|
||||
print_clean ("with\"much (punctuation)[]!");
|
||||
print_clean ("§&Ω%€ leading garbarge");
|
||||
print_clean ("mixed Ω garbarge");
|
||||
print_clean ("Bääääh!!");
|
||||
print_clean ("§&Ω%€");
|
||||
}
|
||||
|
||||
/** @test print the original and the sanitized string */
|
||||
void print_clean (const string org)
|
||||
{
|
||||
cout << "'" << org << "' --> '" << sanitize(org) << "'\n";
|
||||
}
|
||||
};
|
||||
|
||||
LAUNCHER (SanitizedIdentifier_test, "unit common");
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace util
|
||||
|
||||
140
tests/components/common/singletontest.cpp
Normal file
140
tests/components/common/singletontest.cpp
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
Singleton(Test) - unittest for our Singleton template
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
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 "common/testtargetobj.hpp"
|
||||
|
||||
#include "common/test/run.hpp"
|
||||
#include "common/singleton.hpp"
|
||||
#include "common/util.hpp"
|
||||
#include "nobugcfg.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using boost::lexical_cast;
|
||||
using boost::format;
|
||||
using util::isnil;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
||||
|
||||
namespace cinelerra
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Target object to be instantiated as Singleton
|
||||
* Allocates a variable amount of additional heap memory
|
||||
* and prints diagnostic messages.
|
||||
*/
|
||||
class TargetObj : public TestTargetObj
|
||||
{
|
||||
public:
|
||||
static int cnt;
|
||||
static void setCountParam (uint c) { TargetObj::cnt = c; }
|
||||
protected:
|
||||
TargetObj () : TestTargetObj(cnt) {}
|
||||
|
||||
friend class singleton::Static<TargetObj>;
|
||||
friend class singleton::Heap<TargetObj>;
|
||||
};
|
||||
|
||||
int TargetObj::cnt = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* @test implement a Singleton class using our Singleton Template.
|
||||
* Expected results: no memory leaks.
|
||||
* @see cinelerra::Singleton
|
||||
* @see cinelerra::singleton::Static
|
||||
* @see cinelerra::singleton::Heap
|
||||
*/
|
||||
class Singleton_test : public Test
|
||||
{
|
||||
typedef boost::function<TargetObj& ()> InstanceAccessFunc;
|
||||
InstanceAccessFunc instance;
|
||||
|
||||
virtual void run(Arg arg)
|
||||
{
|
||||
uint num= isnil(arg)? 1 : lexical_cast<uint>(arg[1]);
|
||||
|
||||
testStaticallyAllocatedSingleton (num++);
|
||||
testHeapAllocatedSingleton (num++);
|
||||
}
|
||||
|
||||
|
||||
/** @test parametrize the Singleton creation such as to create
|
||||
* the single TargetObj instance as a static variable.
|
||||
*/
|
||||
void testStaticallyAllocatedSingleton (uint num)
|
||||
{
|
||||
Singleton<TargetObj> single;
|
||||
instance = single;
|
||||
useInstance (num, "statically allocated");
|
||||
}
|
||||
|
||||
/** @test parametrize the Singleton creation such as to create
|
||||
* the single TargetObj instance allocated on the Heap
|
||||
* and deleted automatically at application shutdown.
|
||||
*/
|
||||
void testHeapAllocatedSingleton (uint num)
|
||||
{
|
||||
Singleton<TargetObj,singleton::Heap> single;
|
||||
instance = single;
|
||||
useInstance (num, "heap allocated");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void useInstance (uint num, string kind)
|
||||
{
|
||||
cout << format("testing TargetObj(%d) as Singleton(%s)\n") % num % kind;
|
||||
TargetObj::setCountParam(num);
|
||||
TargetObj& t1 = instance();
|
||||
TargetObj& t2 = instance();
|
||||
|
||||
ASSERT ( &t1 == &t2, "not a Singleton, got two different instances." );
|
||||
|
||||
cout << "calling a non-static method on the Singleton instance\n"
|
||||
<< string (t1) << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (Singleton_test, "unit common");
|
||||
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace cinelerra
|
||||
|
|
@ -54,7 +54,7 @@ namespace util
|
|||
testLine("\nspam");
|
||||
testLine("eat more spam");
|
||||
testLine(" oo _O()O_ ä + €");
|
||||
testLine("\0\too\0\to\0o\t\0oo");
|
||||
testLine("Ω\tooΩ\toΩo\tΩoo");
|
||||
|
||||
testStandardCmdlineformat();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace cinelerra
|
|||
namespace test
|
||||
{
|
||||
/**
|
||||
* Target object to be created by the Test-Factory.
|
||||
* Target object to be created by Test-Factories or as Singleton.
|
||||
* Allocates a variable amount of additional heap memory
|
||||
* and prints diagnostic messages.
|
||||
*/
|
||||
|
|
|
|||
73
tests/components/proc/asset/assetdiagnostics.hpp
Normal file
73
tests/components/proc/asset/assetdiagnostics.hpp
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
ASSETDIAGNOSTICS.hpp - collection of test and debug helpers
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
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 assetdiagnostics.hpp
|
||||
** Small helper and diagnosic functions related to Asset and AssetManager
|
||||
**
|
||||
** @see assetmanager.hpp
|
||||
** @see CreateAsset_test
|
||||
** @see IdentityOfAssets_test
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ASSET_ASSETDIAGNOSTICS_H
|
||||
#define ASSET_ASSETDIAGNOSTICS_H
|
||||
|
||||
|
||||
#include "proc/assetmanager.hpp"
|
||||
#include "common/util.hpp"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using util::for_each;
|
||||
using boost::format;
|
||||
using boost::bind;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
|
||||
inline void dump (const PAsset& aa)
|
||||
{
|
||||
if (!aa)
|
||||
cout << "Asset(NULL)\n";
|
||||
else
|
||||
{
|
||||
format fmt("%s %|50T.| id=%s adr=%x smart-ptr=%x use-count=%d");
|
||||
cout << fmt % str(aa) % aa->getID() % aa.get() % &aa % (aa.use_count() - 1) << "\n";
|
||||
} }
|
||||
|
||||
inline void dumpAssetManager ()
|
||||
{
|
||||
list<PAsset> assets (AssetManager::instance().listContent());
|
||||
cout << "----all-registered-Assets----\n";
|
||||
for_each (assets, bind (&dump, _1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace asset
|
||||
#endif
|
||||
|
|
@ -22,15 +22,16 @@
|
|||
|
||||
|
||||
#include "common/test/run.hpp"
|
||||
//#include "common/factory.hpp"
|
||||
//#include "common/util.hpp"
|
||||
#include "common/util.hpp"
|
||||
|
||||
//#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
#include "proc/assetmanager.hpp"
|
||||
#include "proc/asset/media.hpp"
|
||||
#include "proc/asset/proc.hpp"
|
||||
|
||||
//using boost::format;
|
||||
#include "proc/asset/assetdiagnostics.hpp"
|
||||
|
||||
using util::isnil;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
||||
|
||||
namespace asset
|
||||
|
|
@ -49,7 +50,135 @@ namespace asset
|
|||
{
|
||||
virtual void run(Arg arg)
|
||||
{
|
||||
}
|
||||
createMedia();
|
||||
factoryVariants();
|
||||
|
||||
if (!isnil (arg))
|
||||
dumpAssetManager();
|
||||
TRACE (assetmem, "leaving CreateAsset_test::run()");
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef shared_ptr<asset::Media> PM;
|
||||
|
||||
/** @test Creating and automatically registering Asset instances.
|
||||
* Re-Retrieving the newly created objects from AssetManager.
|
||||
* Checking AssetManager access functions, esp. getting
|
||||
* different kinds of Assets by ID, querying with the
|
||||
* wrong Category and querying unknown IDs.
|
||||
*/
|
||||
void createMedia()
|
||||
{
|
||||
Category cat(VIDEO,"bin1");
|
||||
Asset::Ident key("Name-1", cat, "ichthyo", 5);
|
||||
PM mm1 = asset::Media::create(key,"testfile.mov");
|
||||
PM mm2 = asset::Media::create("testfile1.mov", cat);
|
||||
PM mm3 = asset::Media::create("testfile2.mov", VIDEO);
|
||||
|
||||
// Assets have been registered and can be retrieved by ID
|
||||
AssetManager& aMang = AssetManager::instance();
|
||||
ASSERT (aMang.getAsset (mm1->getID()) == mm1);
|
||||
ASSERT (aMang.getAsset (mm2->getID()) == mm2);
|
||||
ASSERT (aMang.getAsset (mm3->getID()) == mm3);
|
||||
|
||||
ASSERT (aMang.getAsset (mm1->getID()) != mm2);
|
||||
|
||||
PAsset aa1 = aMang.getAsset (ID<Asset>(mm1->getID())); // note we get an Asset ref
|
||||
ASSERT (aa1 == mm1);
|
||||
PM mX1 = aMang.getAsset (mm1->getID()); // ..and now we get a Media ref
|
||||
ASSERT (mX1 == mm1);
|
||||
ASSERT (mX1 == aa1);
|
||||
|
||||
ASSERT (aMang.known (mm1->getID()));
|
||||
ASSERT (aMang.known (mm2->getID()));
|
||||
ASSERT (aMang.known (mm3->getID()));
|
||||
|
||||
ASSERT ( !aMang.known (mm3->getID(), Category(AUDIO))); // not found within AUDIO-Category
|
||||
try
|
||||
{ // can't be found if specifying wrong Asset kind....
|
||||
aMang.getAsset (ID<asset::Proc>(mm1->getID()));
|
||||
NOTREACHED;
|
||||
}
|
||||
catch (cinelerra::error::Invalid& xxx) {ASSERT (xxx.getID()==CINELERRA_ERROR_WRONG_ASSET_KIND);}
|
||||
try
|
||||
{ // try accessing nonexistant ID
|
||||
aMang.getAsset (ID<Asset> (1234567890));
|
||||
NOTREACHED;
|
||||
}
|
||||
catch (cinelerra::error::Invalid& xxx) {ASSERT (xxx.getID()==CINELERRA_ERROR_UNKNOWN_ASSET_ID);}
|
||||
|
||||
|
||||
// checking the Ident-Fields
|
||||
ASSERT (mm1->ident.name == "Name-1");
|
||||
ASSERT (mm2->ident.name == "testfile1");
|
||||
ASSERT (mm3->ident.name == "testfile2");
|
||||
|
||||
ASSERT (cat == Category (VIDEO,"bin1"));
|
||||
ASSERT (mm1->ident.category == Category (VIDEO,"bin1"));
|
||||
ASSERT (mm2->ident.category == Category (VIDEO,"bin1"));
|
||||
ASSERT (mm3->ident.category == Category (VIDEO ));
|
||||
|
||||
ASSERT (mm1->ident.org == "ichthyo");
|
||||
ASSERT (mm2->ident.org == "cin3");
|
||||
ASSERT (mm3->ident.org == "cin3");
|
||||
|
||||
ASSERT (mm1->ident.version == 5);
|
||||
ASSERT (mm2->ident.version == 1);
|
||||
ASSERT (mm3->ident.version == 1);
|
||||
|
||||
ASSERT (mm1->getFilename() == "testfile.mov");
|
||||
ASSERT (mm2->getFilename() == "testfile1.mov");
|
||||
ASSERT (mm3->getFilename() == "testfile2.mov");
|
||||
|
||||
|
||||
TRACE (assetmem, "leaving test method scope");
|
||||
}
|
||||
|
||||
|
||||
/** @test different variants of calling the MediaFactory,
|
||||
* with focus on the behaviour of the basic Asset
|
||||
* creation machinery. Covers filling out Asset's
|
||||
* datafields, amending missing pieces of information.
|
||||
*/
|
||||
void factoryVariants()
|
||||
{
|
||||
PM candi;
|
||||
|
||||
Asset::Ident key1("Au-1", Category(AUDIO), "ichthyo", 5);
|
||||
candi = asset::Media::create(key1);
|
||||
ASSERT ( checkProperties (candi, key1, ""));
|
||||
|
||||
candi = asset::Media::create(key1, string("testfile.wav"));
|
||||
ASSERT ( checkProperties (candi, key1, "testfile.wav"));
|
||||
|
||||
Asset::Ident key2("", Category(AUDIO), "ichthyo", 5);
|
||||
candi = asset::Media::create(key2, string("testfile2.wav"));
|
||||
ASSERT ( checkProperties (candi, key2, "testfile2.wav"));
|
||||
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)
|
||||
, "testfile3.wav"));
|
||||
|
||||
candi = asset::Media::create("some/path/testfile4.wav", Category(AUDIO));
|
||||
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"), "cin3", 1)
|
||||
, ""));
|
||||
|
||||
candi = asset::Media::create("", AUDIO);
|
||||
ASSERT ( checkProperties (candi, Asset::Ident("nil", Category(AUDIO), "cin3", 1)
|
||||
, ""));
|
||||
}
|
||||
|
||||
bool checkProperties (PM object, Asset::Ident identity, string filename)
|
||||
{
|
||||
return identity == object->ident
|
||||
&& filename == object->getFilename();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
108
tests/components/proc/asset/identityofassetstest.cpp
Normal file
108
tests/components/proc/asset/identityofassetstest.cpp
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
IdentityOfAssets(Test) - Asset object identity and versioning
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
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 "common/test/run.hpp"
|
||||
#include "common/util.hpp"
|
||||
|
||||
#include "proc/assetmanager.hpp"
|
||||
#include "proc/asset/media.hpp"
|
||||
#include "proc/asset/proc.hpp"
|
||||
|
||||
#include "proc/asset/assetdiagnostics.hpp"
|
||||
|
||||
using util::isnil;
|
||||
using std::string;
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* @test creating several Assets and checking object identity,
|
||||
* detection of duplicates and version handling.
|
||||
* @see proc_interface::AssetManager#reg
|
||||
* @todo to be written; features are missing as of 9/07
|
||||
*/
|
||||
class IdentityOfAssets_test : public Test
|
||||
{
|
||||
virtual void run(Arg arg)
|
||||
{
|
||||
createDuplicate();
|
||||
|
||||
if (!isnil (arg))
|
||||
dumpAssetManager();
|
||||
TRACE (assetmem, "leaving IdentityOfAssets_test::run()");
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef shared_ptr<asset::Media> PM;
|
||||
|
||||
/** @test produce an ID clash.
|
||||
* documents the current behaviour of the code as of 9/07
|
||||
* @todo this test is expected to break when the detection
|
||||
* of duplicate registrations is implemented.
|
||||
*/
|
||||
void createDuplicate()
|
||||
{
|
||||
PM mm1 = asset::Media::create ("testfile1.mov", VIDEO);
|
||||
|
||||
Asset::Ident idi (mm1->ident); // duplicate Ident record
|
||||
PM mm1X = asset::Media::create (idi); // note: we actually don't call any ctor
|
||||
ASSERT (mm1 == mm1X); // instead, we got mm1 back.
|
||||
|
||||
PM mm2 = asset::Media::create (idi,"testfile2.mov");
|
||||
|
||||
ASSERT (mm1->getID() == mm2->getID()); // different object, same hash
|
||||
|
||||
AssetManager& aMang = AssetManager::instance();
|
||||
ASSERT (aMang.getAsset (mm1->getID()) == mm2); // record of mm1 was replaced by mm2
|
||||
ASSERT (aMang.getAsset (mm2->getID()) == mm2);
|
||||
|
||||
ASSERT (aMang.known (mm1->getID()));
|
||||
ASSERT (aMang.known (mm2->getID()));
|
||||
ASSERT (mm1->ident.name == "testfile1");
|
||||
ASSERT (mm2->ident.name == "testfile1");
|
||||
ASSERT (mm1->getFilename() == "testfile1.mov");
|
||||
ASSERT (mm2->getFilename() == "testfile2.mov");
|
||||
|
||||
|
||||
TRACE (assetmem, "leaving test method scope");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (IdentityOfAssets_test, "unit asset");
|
||||
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace asset
|
||||
125
tests/components/proc/asset/orderingofassetstest.cpp
Normal file
125
tests/components/proc/asset/orderingofassetstest.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
OrderingOfAssets(Test) - equality and comparisons
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
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 "common/test/run.hpp"
|
||||
#include "common/util.hpp"
|
||||
|
||||
#include "proc/assetmanager.hpp"
|
||||
#include "proc/asset/media.hpp"
|
||||
#include "proc/asset/proc.hpp"
|
||||
|
||||
#include "proc/asset/assetdiagnostics.hpp"
|
||||
|
||||
using util::isnil;
|
||||
using std::string;
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************
|
||||
* @test validate the equality and order relations of
|
||||
* Asset::Ident and Asset objects.
|
||||
* @see Asset::Ident#compare
|
||||
*/
|
||||
class OrderingOfAssets_test : public Test
|
||||
{
|
||||
virtual void run(Arg arg)
|
||||
{
|
||||
typedef shared_ptr<asset::Media> PM;
|
||||
|
||||
Asset::Ident key1("Au-1", Category(AUDIO), "ichthyo", 5);
|
||||
PM mm1 = asset::Media::create(key1, "Name-1");
|
||||
|
||||
Asset::Ident key2("Au-1", Category(AUDIO), "ichthyo", 7);
|
||||
PM mm2 = asset::Media::create(key2, "Name-2");
|
||||
|
||||
Asset::Ident key3("Au-2", Category(AUDIO), "ichthyo", 5);
|
||||
PM mm3 = asset::Media::create(key3, "Name-3");
|
||||
|
||||
Asset::Ident key4("Au-2", Category(AUDIO), "stega", 5);
|
||||
PM mm4 = asset::Media::create(key4, "Name-4");
|
||||
|
||||
Asset::Ident key5("Au-1", Category(VIDEO), "ichthyo", 5);
|
||||
PM mm5 = asset::Media::create(key5, "Name-5");
|
||||
|
||||
|
||||
// ordering of keys
|
||||
ASSERT (key1 == key2);
|
||||
ASSERT (key2 != key3);
|
||||
ASSERT (key3 != key4);
|
||||
ASSERT (key4 != key5);
|
||||
ASSERT (key1 != key5);
|
||||
|
||||
ASSERT (-1 == key2.compare(key3));
|
||||
ASSERT (+1 == key3.compare(key2));
|
||||
|
||||
ASSERT (-1 == key3.compare(key4));
|
||||
ASSERT (-1 == key4.compare(key5));
|
||||
ASSERT (-1 == key1.compare(key5));
|
||||
ASSERT (-1 == key2.compare(key5));
|
||||
ASSERT (-1 == key3.compare(key5));
|
||||
ASSERT (-1 == key1.compare(key3));
|
||||
ASSERT (-1 == key1.compare(key4));
|
||||
ASSERT (-1 == key2.compare(key4));
|
||||
|
||||
|
||||
// ordering of Asset smart ptrs
|
||||
ASSERT (mm1 == mm2);
|
||||
ASSERT (mm2 != mm3);
|
||||
ASSERT (mm3 != mm4);
|
||||
ASSERT (mm4 != mm5);
|
||||
ASSERT (mm1 != mm5);
|
||||
|
||||
ASSERT (mm2 < mm3);
|
||||
ASSERT (mm2 <= mm3);
|
||||
ASSERT (mm3 > mm2);
|
||||
ASSERT (mm3 >= mm2);
|
||||
|
||||
ASSERT (mm3 < mm4);
|
||||
ASSERT (mm4 < mm5);
|
||||
ASSERT (mm1 < mm5);
|
||||
ASSERT (mm2 < mm5);
|
||||
ASSERT (mm3 < mm5);
|
||||
ASSERT (mm1 < mm3);
|
||||
ASSERT (mm1 < mm4);
|
||||
ASSERT (mm2 < mm4);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (OrderingOfAssets_test, "unit asset");
|
||||
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace asset
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
format 40
|
||||
"AssetManager" // ProcessingLayer::AssetManager
|
||||
revision 4
|
||||
"Asset" // ProcessingLayer::Asset
|
||||
revision 6
|
||||
modified_by 5 "hiv"
|
||||
// class settings
|
||||
//class diagram settings
|
||||
|
|
@ -228,18 +228,13 @@ ${members}};
|
|||
explicit_switch_type ""
|
||||
|
||||
comment "Facade for the Asset subsystem"
|
||||
operation 132357 "register"
|
||||
class_operation public explicit_return_type "long"
|
||||
nparams 4
|
||||
param inout name "name" explicit_type "string"
|
||||
param inout name "category" explicit_type "string"
|
||||
param inout name "org" explicit_type "string"
|
||||
param inout name "uint" explicit_type "version"
|
||||
nexceptions 1
|
||||
explicit_exception "Invalid"
|
||||
cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${t0} & ${p0}, ${t1} & ${p1}, ${t2} & ${p2}, ${t3}& ${p3}${)}${const}${volatile} ${throw}${abstract};"
|
||||
operation 133125 "getID"
|
||||
class_operation public explicit_return_type ""
|
||||
nparams 1
|
||||
param in name "idi" type class_ref 136453 // Asset
|
||||
cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};"
|
||||
cpp_def "${comment}${inline}${type}
|
||||
${class}::${name} ${(}${t0} & ${p0}, ${t1} & ${p1}, ${t2} & ${p2}, ${t3}& ${p3}${)}${const}${volatile} ${throw}${staticnl}
|
||||
${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl}
|
||||
{
|
||||
${body}
|
||||
}
|
||||
|
|
@ -247,7 +242,6 @@ ${class}::${name} ${(}${t0} & ${p0}, ${t1} & ${p1}, ${t2} & ${p2}, ${t3}& ${p3}$
|
|||
"
|
||||
|
||||
|
||||
comment "registers an asset object in the internal DB, providing its unique key"
|
||||
end
|
||||
|
||||
operation 132485 "getAsset"
|
||||
|
|
@ -307,6 +301,38 @@ ${class}::${name} ${(}${t0} ${p0}${)}${const}${volatile} ${throw}${staticnl}
|
|||
|
||||
comment "remove the given asset <i>together with all its dependants</i> from the internal DB"
|
||||
end
|
||||
|
||||
operation 132357 "reg"
|
||||
class_operation protected explicit_return_type "long"
|
||||
nparams 4
|
||||
param inout name "name" explicit_type "string"
|
||||
param inout name "category" explicit_type "string"
|
||||
param inout name "org" explicit_type "string"
|
||||
param inout name "uint" explicit_type "version"
|
||||
nexceptions 1
|
||||
explicit_exception "Invalid"
|
||||
cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${t0} & ${p0}, ${t1} & ${p1}, ${t2} & ${p2}, ${t3}& ${p3}${)}${const}${volatile} ${throw}${abstract};"
|
||||
cpp_def "${comment}${inline}${type}
|
||||
${class}::${name} ${(}${t0} & ${p0}, ${t1} & ${p1}, ${t2} & ${p2}, ${t3}& ${p3}${)}${const}${volatile} ${throw}${staticnl}
|
||||
{
|
||||
${body}
|
||||
}
|
||||
|
||||
"
|
||||
|
||||
|
||||
comment "registers an asset object in the internal DB, providing its unique key"
|
||||
end
|
||||
|
||||
classrelation 142085 // registry (<unidirectional association>)
|
||||
relation 140293 --->
|
||||
a role_name "registry" multiplicity "1" protected
|
||||
comment "@internal Table or DB holding all registered asset instances."
|
||||
cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value};
|
||||
"
|
||||
classrelation_ref 142085 // registry (<unidirectional association>)
|
||||
b multiplicity "1" parent class_ref 138373 // DB
|
||||
end
|
||||
end
|
||||
|
||||
class 136709 "Media"
|
||||
|
|
@ -585,5 +611,19 @@ ${inlines}
|
|||
b multiplicity "" parent class_ref 137093 // Meta
|
||||
end
|
||||
end
|
||||
|
||||
class 138373 "DB"
|
||||
visibility package
|
||||
cpp_decl "${comment}${template}class ${name}${inherit}
|
||||
{
|
||||
${members} };
|
||||
${inlines}
|
||||
"
|
||||
java_decl ""
|
||||
idl_decl ""
|
||||
explicit_switch_type ""
|
||||
|
||||
comment "Implementation of the registry holding all Asset instances known to the Asset Manager subsystem. As of 8/2007 implemented by a hashtable."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
format 40
|
||||
"asset" // design::codegen::proc::asset
|
||||
revision 4
|
||||
revision 5
|
||||
modified_by 5 "hiv"
|
||||
// class settings
|
||||
//class diagram settings
|
||||
|
|
@ -544,5 +544,44 @@ ${namespace_end}"
|
|||
end
|
||||
comment "structural asset holding the configuration of a track in the EDL"
|
||||
end
|
||||
|
||||
artifact 137861 "db"
|
||||
stereotype "source"
|
||||
cpp_h "/*
|
||||
${NAME}.hpp - ${description}
|
||||
@{CopyrightClaim}@{GPLHeader}
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ${NAMESPACE}_${NAME}_H
|
||||
#define ${NAMESPACE}_${NAME}_H
|
||||
|
||||
${includes}
|
||||
${declarations}
|
||||
|
||||
|
||||
${namespace_start}
|
||||
|
||||
${definition}
|
||||
${namespace_end}
|
||||
#endif
|
||||
"
|
||||
cpp_src "/*
|
||||
${Name} - ${description}
|
||||
@{CopyrightClaim}@{GPLHeader}
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
${includes}
|
||||
${namespace_start}
|
||||
|
||||
|
||||
${members}
|
||||
${namespace_end}"
|
||||
associated_classes
|
||||
class_ref 138373 // DB
|
||||
end
|
||||
comment "registry holding known Asset instances."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ classcanvas 128005 class_ref 136453 // Asset
|
|||
end
|
||||
classcanvas 128133 class_ref 136581 // AssetManager
|
||||
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 class drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
|
||||
xyz 289 26 2000
|
||||
xyz 290 16 2005
|
||||
end
|
||||
packagecanvas 128517
|
||||
package_ref 128133 // AssetManager
|
||||
xyzwh 217 182 1994 575 534
|
||||
package_ref 128133 // Asset
|
||||
show_context_mode namespace xyzwh 217 182 1994 575 534
|
||||
classcanvas 128645 class_ref 136709 // Media
|
||||
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 273 347 2005
|
||||
|
|
@ -63,6 +63,10 @@ classcanvas 132997 class_ref 138245 // Dataset
|
|||
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 719 445 2000
|
||||
end
|
||||
classcanvas 133253 class_ref 138373 // DB
|
||||
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 486 233 2000
|
||||
end
|
||||
relationcanvas 129157 relation_ref 138117 // <realization>
|
||||
geometry VHV
|
||||
from ref 128645 z 1999 to point 293 315
|
||||
|
|
@ -127,7 +131,13 @@ relationcanvas 133125 relation_ref 139781 // <generalisation>
|
|||
from ref 132997 z 1999 to ref 129029
|
||||
no_role_a no_role_b
|
||||
no_multiplicity_a no_multiplicity_b
|
||||
relationcanvas 133381 relation_ref 140293 // <unidirectional association>
|
||||
geometry HV
|
||||
from ref 128133 z 1999 to point 506 93
|
||||
line 133637 z 1999 to ref 133253
|
||||
role_a_pos 518 208 3000 no_role_b
|
||||
multiplicity_a_pos 492 208 3000 multiplicity_b_pos 386 104 3000
|
||||
line 128261 -_-_ geometry HV
|
||||
from ref 128005 z 1999 to point 330 150
|
||||
from ref 128005 z 1999 to point 331 150
|
||||
line 128389 z 1999 to ref 128133
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,20 +1,34 @@
|
|||
window_sizes 1140 783 270 860 584 120
|
||||
window_sizes 1140 783 270 860 633 71
|
||||
diagrams
|
||||
active classdiagram_ref 130309 // Asset Kinds
|
||||
860 584 100 4 0 0
|
||||
classdiagram_ref 130309 // Asset Kinds
|
||||
860 607 100 4 0 0
|
||||
classdiagram_ref 130437 // Media-Asset Relations
|
||||
688 506 100 4 0 0
|
||||
classdiagram_ref 128133 // Session structure
|
||||
688 506 100 4 60 0
|
||||
classdiagram_ref 128389 // Render Entities
|
||||
688 506 100 4 120 0
|
||||
objectdiagram_ref 128901 // EDL Example2
|
||||
688 506 100 4 132 0
|
||||
objectdiagram_ref 128773 // EDL Example1
|
||||
688 506 100 4 0 0
|
||||
active objectdiagram_ref 129029 // Engine Example1
|
||||
860 633 100 4 28 0
|
||||
end
|
||||
show_stereotypes
|
||||
selected
|
||||
package_ref 129 // cinelerra3
|
||||
selected objectdiagram_ref 129029 // Engine Example1
|
||||
open
|
||||
|
||||
package_ref 128005 // design
|
||||
class_ref 136453 // Asset
|
||||
class_ref 136581 // AssetManager
|
||||
operation_ref 133125 // getID
|
||||
operation_ref 132357 // reg
|
||||
class_ref 136709 // Media
|
||||
class_ref 137349 // Clip
|
||||
classview_ref 128005 // Session
|
||||
classview_ref 128133 // Engine Workings
|
||||
class_ref 138501 // SpecialWish
|
||||
|
||||
package_ref 128389 // RenderEngine
|
||||
usecaseview_ref 128005 // Renderengine Use
|
||||
class_ref 135685 // Logic
|
||||
class_ref 135813 // Config
|
||||
class_ref 135941 // State
|
||||
|
|
|
|||
|
|
@ -514,12 +514,13 @@ ColorPalette
|
|||
|
||||
SiteUrl</pre>
|
||||
</div>
|
||||
<div title="Asset" modifier="Ichthyostega" modified="200709021530" created="200708100337" tags="def classes" changecount="9">
|
||||
<div title="Asset" modifier="Ichthyostega" modified="200709040256" created="200708100337" tags="def classes" changecount="11">
|
||||
<pre>Asset management is a subsystem on its own. Assets are "things" that can be loaded into a session, like Media, Clips, Effects, Transitions. It is the "bookkeeping view", while the EDL is the "manipulation and process view". Some Assets can be //loaded// and a collection of Assets is saved with eatch Session. Besides, there is a collection of basic Assets allways available by default.
|
||||
|
||||
The Assets are important reference points holding the information needed to access external resources. For example, an Clip asset can reference a Media asset, which in turn holds the external filename from which to get the media stream. For Effects, the situatin is similar. Assets thus serve two quite distinct purposes. One is to load, list, group serarch and browse them, and to provide an entry point to create new or get at existing MObjects in the EDL, while the other purpose is to provide attribute and property informations to the inner parts of the engine, while at the same time isolating and decoupling them from environmental details.
|
||||
The Assets are important reference points holding the information needed to access external resources. For example, an Clip asset can reference a Media asset, which in turn holds the external filename from which to get the media stream. For Effects, the situation is similar. Assets thus serve two quite distinct purposes. One is to load, list, group search and browse them, and to provide an entry point to create new or get at existing MObjects in the EDL, while the other purpose is to provide attribute and property informations to the inner parts of the engine, while at the same time isolating and decoupling them from environmental details.
|
||||
|
||||
We can distinguish several different Kinds of Assets, each one with specific properties. While all these Kinds of Assets implement the basic Asset interface, they themselfs are the __key abstractions__ of the asset management view. Mostly, their interfaces will be used directly, because they are quite different in behaviour. Thus it is common to see asset related operations being templated on the Asset Kind.
|
||||
&rarr; see also [[Creating and registering Assets|AssetCreation]]
|
||||
[img[Asset Classess|uml/fig130309.png]]
|
||||
|
||||
!Media Asset
|
||||
|
|
@ -547,9 +548,16 @@ Some additional, virtual facilities created in the course of the editing process
|
|||
&rarr; MetaAsset {{red{to be defined}}}
|
||||
|
||||
!!!!still to be worked out..
|
||||
is how to implement the relationship between [[MObject]]s and Assets. Do we use direct pointers, or do we prefer an ID + central registry approach? And how to handle the removal of an Asset (&rarr; see also [[analysis of mem management|ManagementAssetRelation]])
|
||||
is how to implement the relationship between [[MObject]]s and Assets. Do we use direct pointers, or do we prefer an ID + central registry approach? And how to handle the removal of an Asset
|
||||
&rarr; see also [[analysis of mem management|ManagementAssetRelation]]
|
||||
&rarr; see also [[Creating Objects|ObjectCreation]], especially [[Assets|AssetCreation]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="AssetCreation" modifier="Ichthyostega" created="200709040307" changecount="1">
|
||||
<pre>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)</pre>
|
||||
</div>
|
||||
<div title="Automation" modifier="Ichthyostega" modified="200708100315" created="200706250751" tags="def" changecount="5">
|
||||
<pre>Automation is treated as a function over time. It is always tied to a specific Parameter (which can thus be variable over the course of the timeline). All details //how// this function is defined are completely abstracted away. The Parameter uses a ParamProvider to get the value for a given Time (point). Typically, this will use linear or bezier interpolation over a set of keyframes internally. Parameters can be configured to have different value ranges and distribution types (on-off, stepped, continuous, bounded)
|
||||
|
||||
|
|
@ -940,11 +948,13 @@ For this Cinelerra3 design, we could consider making GOP just another raw media
|
|||
&rarr;see in [[Wikipedia|http://en.wikipedia.org/wiki/Group_of_pictures]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="ImplementationDetails" modifier="Ichthyostega" modified="200708100408" created="200708080322" tags="overview" changecount="4">
|
||||
<div title="ImplementationDetails" modifier="Ichthyostega" modified="200709040256" created="200708080322" tags="overview" changecount="6">
|
||||
<pre>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 Cinelerra Renderengine, the Builder and the related parts.
|
||||
|
||||
* [[Packages, Interfaces and Namespaces|InterfaceNamespaces]]
|
||||
* [[Memory Management Issues|MemoryManagement]]
|
||||
* [[Creating and registering Assets|AssetCreation]]
|
||||
* [[Creating new Objects|ObjectCreation]]
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1298,8 +1308,8 @@ From experiences with other middle scale projects, I prefer having the test code
|
|||
* {{red{and what else?}}}
|
||||
</pre>
|
||||
</div>
|
||||
<div title="MObjects" modifier="MichaelPloujnikov" modified="200706271500" created="200706190636" tags="overview" changecount="7">
|
||||
<pre>The MObjects Subsystem contains everything related to the [[EDL]] and the various Media Objects placed within it. Examples for [[MObjects|MObject]] being:
|
||||
<div title="MObjects" modifier="Ichthyostega" modified="200709030128" created="200706190636" tags="overview" changecount="8">
|
||||
<pre>The ~MObjects Subsystem contains everything related to the [[EDL]] and the various Media Objects placed within. It is complemented by the Asset Management (see &rarr; [[Asset]]). Examples for [[MObjects|MObject]] being:
|
||||
* audio/video clips
|
||||
* effects and plugins
|
||||
* special facilities like mask and projector
|
||||
|
|
@ -1377,6 +1387,27 @@ For the case in question this seems to be the ''resource allocation is construct
|
|||
And, last but not least, doing all actual allocations is the job of the backend. Exceptions being long-lived objects, like the Session or the EDL, which are created once and don't bear the danger of causing memory pressure. Besides that, the ProcLayer code shouldn't issue "new" and "delete", rather it should use some central [[Factories]] for all allocation and freeing, so we can redirect these calls down to the backend, which may use pooling or special placement allocators or the like. The rationale is, for modern hardware/architectures, care has to be taken with heap allocations, esp. with many small objects and irregular usage patterns.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="ObjectCreation" modifier="Ichthyostega" modified="200709040257" created="200709030139" tags="impl design" changecount="10">
|
||||
<pre>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 representant of some general concept (Interface), or if we have a direct colaboration and thus need the Factory to provide
|
||||
a more specific sub-Interface or even a concrete type.
|
||||
|
||||
!Object creation use cases
|
||||
!![[Assets|Asset]]
|
||||
|!Action|>|!creates |
|
||||
|loading a media file|asset::Media, asset::Codec| |
|
||||
|viewing media|asset::Clip| for the whole Media, if not already existant|
|
||||
|mark selection as clip|asset::Clip| doesn't add to EDL|
|
||||
|loading Plugin|asset::Effect| usually at program startup|
|
||||
|create Session|asset::Track, asset::OutPort| |
|
||||
&rarr; [[Creating and registering Assets|AssetCreation]]
|
||||
|
||||
!![[MObjects|MObject]]
|
||||
|add media to EDL|asset::Clip, session::Clip, FixedPlacement| creating whole-media clip on-the-fly |
|
||||
|add Clip|session::Clip, FixedPlacement| |
|
||||
|attach Effect|session::Effect, RelativePlacement| |
|
||||
|start using Automation|session::Auto, asset::Dataset, RelativePlacement| |
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OpenGL" modifier="Ichthyostega" modified="200706220359" created="200706220345" tags="def discuss" changecount="3">
|
||||
<pre>Cinelerra2 introduced OpenGL support for rendering previews. I must admit, I am very unhappy with this, because
|
||||
* it just supports some hardware
|
||||
|
|
@ -1392,8 +1423,9 @@ 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
|
||||
</pre>
|
||||
</div>
|
||||
<div title="Overview" modifier="Ichthyostega" modified="200706220216" created="200706190300" tags="overview" changecount="3">
|
||||
<pre>[img[Block Diagram|uml/fig128005.png]]
|
||||
<div title="Overview" modifier="Ichthyostega" modified="200709030125" created="200706190300" tags="overview" changecount="4">
|
||||
<pre>The Cinelerra-3 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.
|
||||
[img[Block Diagram|uml/fig128005.png]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OverviewRenderEngine" modifier="MichaelPloujnikov" modified="200706271432" created="200706190647" tags="overview" changecount="17">
|
||||
|
|
@ -2344,7 +2376,7 @@ Instead, we should try to just connect the various subsystems via Interfaces and
|
|||
* to shield the rendering code of all complexities of thread communication and synchronization, we use the StateProxy
|
||||
</pre>
|
||||
</div>
|
||||
<div title="StyleSheet" modifier="Ichthyostega" modified="200706260459" created="200701131624" tags="MPTWTheme excludeMissing" server.type="file" server.host="file:///home/ct/.homepage/home.html" server.page.revision="200706090017" changecount="6">
|
||||
<div title="StyleSheet" modifier="Ichthyostega" modified="200709040043" created="200701131624" tags="MPTWTheme excludeMissing" server.type="file" server.host="file:///home/ct/.homepage/home.html" server.page.revision="200706090017" changecount="14">
|
||||
<pre>/*{{{*/
|
||||
/* a contrasting background so I can see where one tiddler ends and the other begins */
|
||||
body {
|
||||
|
|
@ -2509,6 +2541,10 @@ h1,h2,h3,h4,h5,h6 {
|
|||
color: #ff2210;
|
||||
padding: 0px 0.8ex;
|
||||
}
|
||||
|
||||
.viewer th {
|
||||
background: #91a6af;
|
||||
}
|
||||
/*}}}*/
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue