-- <<<- ------------------------------------------------------------------------ ------------------------------------------------------------------------ -- Load this build script "!mkprods.sx" into a fresh invocation of ScriptX, -- to build all the Dream products in the "products" folder. -- For each sub-folder "products/", it creates a TitleContainer -- named "rooms/.sxt", holding the product description and media. ------------------------------------------------------------------------ -- Load the dream.sxl library and the DreamBuilder tool module. fileIn theScriptDir \ name: "builder.sx" \ debugInfo: false in module DreamBuilder ------------------------------------------------------------------------ -- Declare a global that may have been defined elsewhere. global theProductsToDo -- These globals are so the product databases can know what container -- they're being stored into. theProductContainer := undefined ------------------------------------------------------------------------ ( local startTime := theCalendarClock.time -- Remember the folder this script is being loaded in from. theContainerDir := theScriptDir -- Get ahold of the products folder. local productsDir := spawn theScriptDir "products" local productOutDir := spawn (parentDir theScriptDir) "products" -- Subdue the garbage collector. setGCIncrement 30 -- If theProductsToDo is defined, then it's a list of products to build. -- Otherwise build all of the products in the "products" folder. -- Each product has a "!makeme.sx" script that loads the Dream library, -- defines theProductsToDo to contain the name of the product folder, and -- runs this "!mkprods.sx" script. By dragging and dropping the -- "!makeme.sx" script from a particular productinto ScriptX, you can -- build just that product. local productNames if (isDefined theProductsToDo) then ( productNames := theProductsToDo ) else ( productNames := getContents productsDir ) -- if -- Compile each of the products in the productNames array. for productName in productNames do ( -- Only process folders, ignore other files. if (isDir productsDir productName) do ( -- Get ahold of the product sub-folder. local productDir := spawn productsDir productName -- Get a list of the files in productDir. local productFiles := getContents productDir | (str -> str as NameClass) -- Set theProductId to be the product folder name. theProductId := (getLowerCase productName) as StringConstant -- You can prevent a product from being built by putting a file -- called "ignore" into its folder. if (isMember productFiles @ignore) then ( print #("Ignoring product", theProductId) ) else ( print #("Making product", theProductId) -- The name of the product TitleContainer is the folder name -- with the suffix ".sxt". local theProductFileName := (theProductId + ".sxt") print #(" creating", theProductFileName) -- Create the new product TitleContainer. local tc := new TitleContainer \ dir: productOutDir \ path: theProductFileName \ targetCollection: #(:) \ mode: @create -- This is the container to store the stuff in. local cont := tc -- This is so the product database.sx files can refer to -- the title container they're being stored in. theProductContainer := tc -- Make a module for the product, whose name is "DreamProduct" -- plus the product id. local modName := ("DreamProduct" + theProductId) as NameClass theProductModule := makeDreamPluginModule modName -- Store the id in the title container, where we can -- find it later. tc[@id] := theProductId -- Import the code and media specified in the "database.sx" file -- from the productDir. The database is loaded in theProductModule, -- and returns a keyed list specifying the media to be imported -- and stored in the container tc. The last argument is the inner -- startup function, compiled in theProductModule, which is stored -- in the tc container. local database := importDreamPluginDatabase \ "database.sx" \ productDir \ tc \ theProductModule \ (fileIn "(tc -> local products := tc[@products] load products if (products != empty) do ( registerProducts theWarehouse products ) )" module: theProductModule) -- Put the array of product descriptions into the -- title container. If it's a function instead of an -- array, apply the function to the two args tc and -- database, in the hopes that it will return an array -- of product descriptions. This defered evaluation -- mechanism makes it possible to build an array of -- product descriptions based on the imported media, -- like the puppets in a director file, or the images -- in tc[@images], so we can make factory templates that -- are parameterized by the database and imported media. -- See the file "factory.sx" for some examples. local products := database[@products] if (products == empty) do ( products := #() ) if (isAKindOf products AbstractFunction) do ( products := products tc database ) -- Loop over the product descriptions, adding the title -- container to the keyed list, with the key @container. forEach products (prodDesc xxx -> prodDesc[@container] := tc ) ok -- forEach -- Put the new keyed list of products into the title container. tc[@products] := products -- Make it nice for the next person. garbageCollect() update tc close tc ) -- if (isMember productFiles @ignore) ) -- if (isDir productsDir productName) ) -- for productName in productNames local endTime := theCalendarClock.time print #("Time for !mkprods", endTime - startTime) ) ------------------------------------------------------------------------ ok -- >>>