File indexing completed on 2024-05-19 04:49:56

0001 /****************************************************************************************
0002  * Copyright (c) 2008-2012 Soren Harward <stharward@gmail.com>                          *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #ifndef APG_GENERIC_MATCHING_CONSTRAINT
0018 #define APG_GENERIC_MATCHING_CONSTRAINT
0019 
0020 #include "playlistgenerator/Constraint.h"
0021 
0022 #include "core/meta/forward_declarations.h"
0023 
0024 #include <QBitArray>
0025 
0026 /* The basic ConstraintGroup logic works properly only if all the
0027  * constraints in the group are independent.  Constraints that work by
0028  * matching track attributes to fixed values need additional logic, because
0029  * it is possible (and even likely) that the user will create a group in
0030  * which two or more constraints match against the same attribute, and are
0031  * thus interdependent.
0032  *
0033  * For example, let's say that the user creates a "match any" group, and
0034  * adds two constraints: one for "genre: Rock" and the other for "genre:
0035  * Rap".  These two constraints are interdependent.  Without this
0036  * workaround, the solver algorithm will fill up the playlist with either
0037  * Rock tracks or Rap tracks, but not a mixture of both, because it is
0038  * trying to maximize the individual satisfactions and not the joint
0039  * satisfaction.  For "match all" groups, the solver adds tracks that
0040  * improve only the least-satisfied constraint, instead of adding tracks
0041  * that improve all constraints.
0042  * 
0043  * Interdependent constraints should have their results combined (using the
0044  * appropriate boolean operator) and the satisfaction value should be the
0045  * value of the combined results.  From a programming standpoint, it would
0046  * make sense just to prohibit the user from adding interdependent
0047  * constraints to a group.  But that approach would add a restriction to
0048  * constraint trees which is difficult for the user to understand, and an
0049  * even bigger departure from other audio player programs than the
0050  * constraint tree already is.  It might not even be any easier to program
0051  * than this logic workaround.  Thus the decision to make the code the way
0052  * it is.
0053  *
0054  * Thus far, the only Constraint that actually needs this workaround is
0055  * TagMatch.  More (like SimilarityMatch) might come later.  -- sth */
0056 
0057 namespace ConstraintTypes {
0058     class MatchingConstraint : public Constraint {
0059         public:
0060             virtual const QBitArray whatTracksMatch(const Meta::TrackList&) = 0;
0061             virtual int constraintMatchType() const = 0;
0062 
0063         protected:
0064             MatchingConstraint(ConstraintNode*);
0065     };
0066 }
0067 #endif // MATCHINGCONSTRAINT_H