Mercurial > hg > svcore
comparison transform/TransformFactory.cpp @ 457:ef14acd6d102
* Add beginnings of capability to search plugins that are not yet
installed -- lots more work to do here, though
author | Chris Cannam |
---|---|
date | Tue, 14 Oct 2008 16:36:35 +0000 |
parents | 804601e50fd5 |
children | 93fb1ebff76b |
comparison
equal
deleted
inserted
replaced
456:64e64e304a12 | 457:ef14acd6d102 |
---|---|
22 | 22 |
23 #include "vamp-sdk/Plugin.h" | 23 #include "vamp-sdk/Plugin.h" |
24 #include "vamp-sdk/PluginHostAdapter.h" | 24 #include "vamp-sdk/PluginHostAdapter.h" |
25 #include "vamp-sdk/hostext/PluginWrapper.h" | 25 #include "vamp-sdk/hostext/PluginWrapper.h" |
26 | 26 |
27 #include "rdf/PluginRDFIndexer.h" | |
28 #include "rdf/PluginRDFDescription.h" | |
29 | |
27 #include "base/XmlExportable.h" | 30 #include "base/XmlExportable.h" |
28 | 31 |
29 #include <iostream> | 32 #include <iostream> |
30 #include <set> | 33 #include <set> |
31 | 34 |
42 TransformFactory::getInstance() | 45 TransformFactory::getInstance() |
43 { | 46 { |
44 return m_instance; | 47 return m_instance; |
45 } | 48 } |
46 | 49 |
50 TransformFactory::TransformFactory() : | |
51 m_transformsPopulated(false), | |
52 m_uninstalledTransformsPopulated(false) | |
53 { | |
54 } | |
55 | |
47 TransformFactory::~TransformFactory() | 56 TransformFactory::~TransformFactory() |
48 { | 57 { |
49 } | 58 } |
50 | 59 |
51 TransformList | 60 TransformList |
52 TransformFactory::getAllTransformDescriptions() | 61 TransformFactory::getAllTransformDescriptions() |
53 { | 62 { |
54 if (m_transforms.empty()) populateTransforms(); | 63 if (!m_transformsPopulated) populateTransforms(); |
55 | 64 |
56 std::set<TransformDescription> dset; | 65 std::set<TransformDescription> dset; |
57 for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); | 66 for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); |
58 i != m_transforms.end(); ++i) { | 67 i != m_transforms.end(); ++i) { |
59 // cerr << "inserting transform into set: id = " << i->second.identifier.toStdString() << endl; | 68 // cerr << "inserting transform into set: id = " << i->second.identifier.toStdString() << endl; |
71 } | 80 } |
72 | 81 |
73 TransformDescription | 82 TransformDescription |
74 TransformFactory::getTransformDescription(TransformId id) | 83 TransformFactory::getTransformDescription(TransformId id) |
75 { | 84 { |
76 if (m_transforms.empty()) populateTransforms(); | 85 if (!m_transformsPopulated) populateTransforms(); |
77 | 86 |
78 if (m_transforms.find(id) == m_transforms.end()) { | 87 if (m_transforms.find(id) == m_transforms.end()) { |
79 return TransformDescription(); | 88 return TransformDescription(); |
80 } | 89 } |
81 | 90 |
82 return m_transforms[id]; | 91 return m_transforms[id]; |
83 } | 92 } |
84 | 93 |
94 TransformList | |
95 TransformFactory::getUninstalledTransformDescriptions() | |
96 { | |
97 if (!m_uninstalledTransformsPopulated) populateUninstalledTransforms(); | |
98 | |
99 std::set<TransformDescription> dset; | |
100 for (TransformDescriptionMap::const_iterator i = m_uninstalledTransforms.begin(); | |
101 i != m_uninstalledTransforms.end(); ++i) { | |
102 // cerr << "inserting transform into set: id = " << i->second.identifier.toStdString() << endl; | |
103 dset.insert(i->second); | |
104 } | |
105 | |
106 TransformList list; | |
107 for (std::set<TransformDescription>::const_iterator i = dset.begin(); | |
108 i != dset.end(); ++i) { | |
109 // cerr << "inserting transform into list: id = " << i->identifier.toStdString() << endl; | |
110 list.push_back(*i); | |
111 } | |
112 | |
113 return list; | |
114 } | |
115 | |
116 TransformDescription | |
117 TransformFactory::getUninstalledTransformDescription(TransformId id) | |
118 { | |
119 if (!m_uninstalledTransformsPopulated) populateUninstalledTransforms(); | |
120 | |
121 if (m_uninstalledTransforms.find(id) == m_uninstalledTransforms.end()) { | |
122 return TransformDescription(); | |
123 } | |
124 | |
125 return m_uninstalledTransforms[id]; | |
126 } | |
127 | |
128 TransformFactory::TransformInstallStatus | |
129 TransformFactory::getTransformInstallStatus(TransformId id) | |
130 { | |
131 if (!m_transformsPopulated) populateTransforms(); | |
132 if (!m_uninstalledTransformsPopulated) populateUninstalledTransforms(); | |
133 | |
134 if (m_transforms.find(id) != m_transforms.end()) { | |
135 return TransformInstalled; | |
136 } | |
137 if (m_uninstalledTransforms.find(id) != m_uninstalledTransforms.end()) { | |
138 return TransformNotInstalled; | |
139 } | |
140 return TransformUnknown; | |
141 } | |
142 | |
143 | |
85 std::vector<QString> | 144 std::vector<QString> |
86 TransformFactory::getAllTransformTypes() | 145 TransformFactory::getAllTransformTypes() |
87 { | 146 { |
88 if (m_transforms.empty()) populateTransforms(); | 147 if (!m_transformsPopulated) populateTransforms(); |
89 | 148 |
90 std::set<QString> types; | 149 std::set<QString> types; |
91 for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); | 150 for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); |
92 i != m_transforms.end(); ++i) { | 151 i != m_transforms.end(); ++i) { |
93 types.insert(i->second.type); | 152 types.insert(i->second.type); |
102 } | 161 } |
103 | 162 |
104 std::vector<QString> | 163 std::vector<QString> |
105 TransformFactory::getTransformCategories(QString transformType) | 164 TransformFactory::getTransformCategories(QString transformType) |
106 { | 165 { |
107 if (m_transforms.empty()) populateTransforms(); | 166 if (!m_transformsPopulated) populateTransforms(); |
108 | 167 |
109 std::set<QString> categories; | 168 std::set<QString> categories; |
110 for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); | 169 for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); |
111 i != m_transforms.end(); ++i) { | 170 i != m_transforms.end(); ++i) { |
112 if (i->second.type == transformType) { | 171 if (i->second.type == transformType) { |
129 } | 188 } |
130 | 189 |
131 std::vector<QString> | 190 std::vector<QString> |
132 TransformFactory::getTransformMakers(QString transformType) | 191 TransformFactory::getTransformMakers(QString transformType) |
133 { | 192 { |
134 if (m_transforms.empty()) populateTransforms(); | 193 if (!m_transformsPopulated) populateTransforms(); |
135 | 194 |
136 std::set<QString> makers; | 195 std::set<QString> makers; |
137 for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); | 196 for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); |
138 i != m_transforms.end(); ++i) { | 197 i != m_transforms.end(); ++i) { |
139 if (i->second.type == transformType) { | 198 if (i->second.type == transformType) { |
214 desc.name = tn; | 273 desc.name = tn; |
215 } | 274 } |
216 | 275 |
217 m_transforms[identifier] = desc; | 276 m_transforms[identifier] = desc; |
218 } | 277 } |
278 | |
279 m_transformsPopulated = true; | |
219 } | 280 } |
220 | 281 |
221 void | 282 void |
222 TransformFactory::populateFeatureExtractionPlugins(TransformDescriptionMap &transforms) | 283 TransformFactory::populateFeatureExtractionPlugins(TransformDescriptionMap &transforms) |
223 { | 284 { |
446 } | 507 } |
447 } | 508 } |
448 } | 509 } |
449 } | 510 } |
450 | 511 |
512 void | |
513 TransformFactory::populateUninstalledTransforms() | |
514 { | |
515 if (!m_uninstalledTransforms.empty()) return; | |
516 if (m_transforms.empty()) populateTransforms(); | |
517 | |
518 //!!! This will be amazingly slow | |
519 | |
520 QStringList ids = PluginRDFIndexer::getInstance()->getIndexedPluginIds(); | |
521 | |
522 for (QStringList::const_iterator i = ids.begin(); i != ids.end(); ++i) { | |
523 | |
524 PluginRDFDescription desc(*i); | |
525 | |
526 QString name = desc.getPluginName(); | |
527 // if (name == "") { | |
528 // std::cerr << "TransformFactory::populateUninstalledTransforms: " | |
529 // << "No name available for plugin " << i->toStdString() | |
530 // << ", skipping" << std::endl; | |
531 // continue; | |
532 // } | |
533 | |
534 QString description = desc.getPluginDescription(); | |
535 QString maker = desc.getPluginMaker(); | |
536 | |
537 QStringList oids = desc.getOutputIds(); | |
538 | |
539 for (QStringList::const_iterator j = oids.begin(); j != oids.end(); ++j) { | |
540 | |
541 TransformId tid = Transform::getIdentifierForPluginOutput(*i, *j); | |
542 | |
543 if (m_transforms.find(tid) != m_transforms.end()) { | |
544 std::cerr << "TransformFactory::populateUninstalledTransforms: " | |
545 << tid.toStdString() << " is installed, skipping" << std::endl; | |
546 continue; | |
547 } | |
548 | |
549 std::cerr << "TransformFactory::populateUninstalledTransforms: " | |
550 << "adding " << tid.toStdString() << std::endl; | |
551 | |
552 QString oname = desc.getOutputName(*j); | |
553 if (oname == "") oname = *j; | |
554 | |
555 TransformDescription td; | |
556 td.type = tr("Analysis"); //!!! should be enum or something | |
557 td.category = ""; | |
558 td.identifier = tid; | |
559 | |
560 if (oids.size() == 1) { | |
561 td.name = name; | |
562 } else if (name != "") { | |
563 td.name = tr("%1: %2").arg(name).arg(oname); | |
564 } | |
565 | |
566 td.friendlyName = name; //!!!??? | |
567 td.description = description; | |
568 td.longDescription = ""; //!!! | |
569 td.maker = maker; | |
570 td.units = ""; | |
571 td.configurable = false; | |
572 | |
573 m_uninstalledTransforms[tid] = td; | |
574 } | |
575 } | |
576 | |
577 m_uninstalledTransformsPopulated = true; | |
578 } | |
451 | 579 |
452 Transform | 580 Transform |
453 TransformFactory::getDefaultTransformFor(TransformId id, size_t rate) | 581 TransformFactory::getDefaultTransformFor(TransformId id, size_t rate) |
454 { | 582 { |
455 Transform t; | 583 Transform t; |
785 | 913 |
786 PluginXml(plugin).setParametersFromXml(xml); | 914 PluginXml(plugin).setParametersFromXml(xml); |
787 setParametersFromPlugin(t, plugin); | 915 setParametersFromPlugin(t, plugin); |
788 delete plugin; | 916 delete plugin; |
789 } | 917 } |
790 /* | |
791 TransformFactory::SearchResults | |
792 TransformFactory::search(QStringList keywords) | |
793 { | |
794 SearchResults results; | |
795 SearchResults partial; | |
796 for (int i = 0; i < keywords.size(); ++i) { | |
797 partial = search(keywords[i]); | |
798 for (SearchResults::const_iterator j = partial.begin(); | |
799 j != partial.end(); ++j) { | |
800 if (results.find(j->first) == results.end()) { | |
801 results[j->first] = j->second; | |
802 } else { | |
803 results[j->first].score += j->second.score; | |
804 results[j->first].fragments << j->second.fragments; | |
805 } | |
806 } | |
807 } | |
808 return results; | |
809 } | |
810 */ | |
811 | 918 |
812 TransformFactory::SearchResults | 919 TransformFactory::SearchResults |
813 TransformFactory::search(QString keyword) | 920 TransformFactory::search(QString keyword) |
814 { | 921 { |
815 QStringList keywords; | 922 QStringList keywords; |
826 // Additional score for all keywords in a row | 933 // Additional score for all keywords in a row |
827 keywords.push_back(keywords.join(" ")); | 934 keywords.push_back(keywords.join(" ")); |
828 } | 935 } |
829 | 936 |
830 SearchResults results; | 937 SearchResults results; |
938 TextMatcher matcher; | |
831 | 939 |
832 for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); | 940 for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); |
833 i != m_transforms.end(); ++i) { | 941 i != m_transforms.end(); ++i) { |
834 | 942 |
835 Match match; | 943 TextMatcher::Match match; |
836 | 944 |
837 match.transform = i->first; | 945 match.key = i->first; |
838 | 946 |
839 searchTest(match, keywords, i->second.type, tr("Plugin type"), 10); | 947 matcher.test(match, keywords, i->second.type, tr("Plugin type"), 5); |
840 searchTest(match, keywords, i->second.category, tr("Category"), 20); | 948 matcher.test(match, keywords, i->second.category, tr("Category"), 20); |
841 searchTest(match, keywords, i->second.identifier, tr("System Identifier"), 5); | 949 matcher.test(match, keywords, i->second.identifier, tr("System Identifier"), 6); |
842 searchTest(match, keywords, i->second.name, tr("Name"), 30); | 950 matcher.test(match, keywords, i->second.name, tr("Name"), 30); |
843 searchTest(match, keywords, i->second.description, tr("Description"), 20); | 951 matcher.test(match, keywords, i->second.description, tr("Description"), 20); |
844 searchTest(match, keywords, i->second.maker, tr("Maker"), 10); | 952 matcher.test(match, keywords, i->second.maker, tr("Maker"), 10); |
845 searchTest(match, keywords, i->second.units, tr("Units"), 10); | 953 matcher.test(match, keywords, i->second.units, tr("Units"), 10); |
846 | 954 |
847 if (match.score > 0) results[i->first] = match; | 955 if (match.score > 0) results[i->first] = match; |
848 } | 956 } |
849 | 957 |
958 if (m_uninstalledTransforms.empty()) populateUninstalledTransforms(); | |
959 | |
960 for (TransformDescriptionMap::const_iterator i = m_uninstalledTransforms.begin(); | |
961 i != m_uninstalledTransforms.end(); ++i) { | |
962 | |
963 TextMatcher::Match match; | |
964 | |
965 match.key = i->first; | |
966 | |
967 matcher.test(match, keywords, i->second.type, tr("Plugin type"), 2); | |
968 matcher.test(match, keywords, i->second.category, tr("Category"), 10); | |
969 matcher.test(match, keywords, i->second.identifier, tr("System Identifier"), 3); | |
970 matcher.test(match, keywords, i->second.name, tr("Name"), 15); | |
971 matcher.test(match, keywords, i->second.description, tr("Description"), 10); | |
972 matcher.test(match, keywords, i->second.maker, tr("Maker"), 5); | |
973 matcher.test(match, keywords, i->second.units, tr("Units"), 5); | |
974 | |
975 if (match.score > 0) results[i->first] = match; | |
976 } | |
977 | |
850 return results; | 978 return results; |
851 } | 979 } |
852 | 980 |
853 void | |
854 TransformFactory::searchTest(Match &match, QStringList keywords, QString text, | |
855 QString textType, int score) | |
856 { | |
857 /* | |
858 if (text.toLower() == keyword.toLower()) { | |
859 match.score += score * 1.5; | |
860 match.fragments << tr("%1: <b>%2</b>").arg(textType).arg(text); | |
861 return; | |
862 } | |
863 */ | |
864 int len = text.length(); | |
865 int prevEnd = 0; | |
866 QString fragment; | |
867 | |
868 while (1) { | |
869 | |
870 bool first = (prevEnd == 0); | |
871 | |
872 int idx = -1; | |
873 QString keyword; | |
874 | |
875 for (int ki = 0; ki < keywords.size(); ++ki) { | |
876 int midx = text.indexOf(keywords[ki], prevEnd, Qt::CaseInsensitive); | |
877 if (midx >= 0 && midx < len) { | |
878 if (midx < idx || idx == -1) { | |
879 idx = midx; | |
880 keyword = keywords[ki]; | |
881 } | |
882 } | |
883 } | |
884 | |
885 if (idx < 0 || idx >= len) break; | |
886 | |
887 int klen = keyword.length(); | |
888 | |
889 if (first) { | |
890 match.score += score; | |
891 } else { | |
892 match.score += score / 4; | |
893 } | |
894 | |
895 int start = idx; | |
896 int end = start + klen; | |
897 | |
898 if (start == 0) match.score += 1; | |
899 if (end == len) match.score += 1; | |
900 | |
901 if (start > prevEnd + 14) { | |
902 QString s = text.right((len - start) + 10); | |
903 s = XmlExportable::encodeEntities(s.left(10)) + "<b>" + | |
904 XmlExportable::encodeEntities(s.left(klen + 10).right(klen)) | |
905 + "</b>"; | |
906 fragment += tr("...%1").arg(s); | |
907 } else { | |
908 QString s = text.right(len - prevEnd); | |
909 s = XmlExportable::encodeEntities(s.left(start - prevEnd)) + "<b>" + | |
910 XmlExportable::encodeEntities(s.left(end - prevEnd).right(klen)) | |
911 + "</b>"; | |
912 fragment += s; | |
913 } | |
914 | |
915 prevEnd = end; | |
916 } | |
917 | |
918 if (prevEnd > 0 && prevEnd < len) { | |
919 int n = len - prevEnd; | |
920 fragment += | |
921 XmlExportable::encodeEntities(text.right(n).left(n < 8 ? n : 8)); | |
922 } | |
923 | |
924 if (fragment != "") { | |
925 match.fragments[textType] = fragment; | |
926 } | |
927 } | |
928 | |
929 bool | |
930 TransformFactory::Match::operator<(const Match &m) const | |
931 { | |
932 if (score != m.score) { | |
933 return score < m.score; | |
934 } | |
935 if (transform != m.transform) { | |
936 return transform < m.transform; | |
937 } | |
938 if (fragments.size() != m.fragments.size()) { | |
939 return fragments.size() < m.fragments.size(); | |
940 } | |
941 | |
942 for (FragmentMap::const_iterator | |
943 i = fragments.begin(), | |
944 j = m.fragments.begin(); | |
945 i != fragments.end(); ++i, ++j) { | |
946 if (i->first != j->first) return i->first < j->first; | |
947 if (i->second != j->second) return i->second < j->second; | |
948 } | |
949 | |
950 return false; | |
951 } | |
952 |