Stream:all - add 'inval' arg, so it can be used with musical patterns
[supercollider.git] / SCClassLibrary / Common / Quarks / packages.sc
blob94f9358dd156ea4be6064acc4ae2ecc28c9f8a16
2 + Main {
3         // a package is either a quark or a folder in SCClassLibrary or extensions folders
5         // a class is in a 'package' determined by where its Class file is
6         // all folders in class library :
7                 // Common
8                 // JITlib
9                 // crucial
10                 // your own
11         // all folders in system extension
12         // all folders in user extension
13         // all quarks
14         // any loose files are placed in a packaged calle SCClassLibrary or Extensions
15                 // possiblity for error: if you have loose files in user extensions and system extensions
16                 // they will both be placed in the same package: Extensions
18         // [ name -> folderPath, name -> folderPath ... ]
19         *packages {
21                 var platform,scClassLibrary,looseFiles;
22                 var packages,f;
24                 // cache
25                 packages = Library.at(Quarks,\packages);
26                 if(packages.notNil,{ ^packages });
28                 platform = thisProcess.platform;
30                 f = { arg dir;
31                         var folders,packages,paths,files;
32                         dir = dir.withTrailingSlash;
33                         paths = (dir++"*").pathMatch;
34                         folders = paths.reject({ |p| p.last != $/ or: {PathName(p).folderName == "quarks"} });
35                         files = paths.select({ |p| p.last != $/ });
36                         packages = folders.collect({ |p| (PathName(p).folderName).asSymbol -> p });
37                         if(files.notEmpty,{
38                                 // if there are any loose files then create a package called dir
39                                 packages = packages.add( PathName(dir).folderName.asSymbol -> dir )
40                         });
41                         packages
42                 };
44                 packages =
45                         (f.value(platform.classLibraryDir)
47                         ++
49                         f.value(platform.systemExtensionDir)
51                         ++
53                         Quarks.installed.collect({ |q|
54                                 q.name.asSymbol -> (platform.userExtensionDir++"/quarks/" ++ q.path)
55                         }))
56                         .sort({ |a,b| a.value.size > b.value.size }) // sort longer paths first
58                         ++
60                         f.value(platform.userExtensionDir);
61                 Library.put(Quarks,\packages,packages);
62                 ^packages
63         }
66 + Class {
67         package {
68                 var path;
69                 path = this.filenameSymbol.asString;
70                 Main.packages.do({ |namepath|
71                         if(path.copyRange(0,namepath.value.size-1) == namepath.value,{
72                                 ^namepath.key
73                         })
74                 });
75                 Error("Discrepancy: Package not found for class !").throw;
76         }
80         method
81                 extensions:
82                         may not be the package that its class is in
84 + Method {
85         package {
86                 var path;
87                 path = this.filenameSymbol.asString;
88                 Main.packages.do({ |namepath|
89                         if(path.copyRange(0,namepath.value.size-1) == namepath.value,{
90                                 ^namepath.key
91                         })
92                 });
93                 Error("Discrepancy: Package not found for method !").throw;
94         }
98 + Quark {
100         definesClasses {
101                 var myPath,end;
102                 myPath = thisProcess.platform.userExtensionDir++"/quarks/" ++ this.path;
103                 end = myPath.size-1;
104                 ^Class.allClasses.reject(_.isMetaClass).select({ |class|
105                         class.filenameSymbol.asString.copyRange(0,end) == myPath
106                 })
107         }
108         definesExtensionMethods {
109                 // all methods whose path is in this quark folder
110                 // where the class is not in this quark
111                 var myPath,end;
112                 myPath = thisProcess.platform.userExtensionDir++"/quarks/" ++ this.path;
113                 end = myPath.size-1;
114                 ^Class.allClasses.collect({ |c| c.methods }).reject(IsNil).flat
115                         .select({ |method|
116                                 method.filenameSymbol.asString.copyRange(0,end) == myPath
117                                 and: {
118                                         method.ownerClass.filenameSymbol.asString.copyRange(0,end) != myPath
119                                 }
120                         })
121         }
122         // of the classes you defined, what packages are the superclasses in ?
123         // of the extension methods you defined, what packages are the super classes in ?
124         /*      checkDependencies {
126         }*/
129 + Quarks {
130         // the equivalent to Quark-definesClasses
131         // but works for non-quarks like Quarks.classesInPackage("JITlib")
132         *classesInPackage { |packageName|
133                 var myPath,end,package;
134                 package = Main.packages.detect({ |pk| pk.key == packageName });
135                 if(package.isNil,{ Error("Package not found:"+packageName).throw });
137                 myPath = package.value;
138                 end = myPath.size-1;
139                 ^Class.allClasses.select({ |class|
140                         class.isMetaClass.not and: {
141                                 class.filenameSymbol.asString.copyRange(0,end) == myPath
142                         }
143                 })
144         }