Catalog(3U)

πŸ’– Catalog(3U) β€” InterViews Reference Manual πŸ’–

okay bestie, pull up a chair because we're talking about Catalog from the Unidraw crew, and honestly? it's giving glow-up energy ✨


🌸 NAME 🌸

Catalog β€” stores and retrieves named objects πŸŽ€


✨ SYNOPSIS ✨

#include <Unidraw/catalog.h>

πŸ¦‹ DESCRIPTION πŸ¦‹

So like, a catalog is literally a little matchmaker for names and objects πŸ’…. It hands out independent name-to-object mappings for four whole categories of things:

  • component subjects
  • commands
  • tools
  • editor info objects

Not one shared pile of names, no no β€” each of those gets its own separate mapping, okay? Independent. As in, they don't step on each other. Periodt.

And here's the iconic part: once you've named an object, you can retrieve it later. Not just "later in the same session" later β€” like, even if the application has been exited and restarted 😭πŸ”₯. The app dies, you reboot your whole vibe, and the object is still there waiting for you like a loyal bestie.

the catalog is therefore the way you save objects in non-volatile form for subsequent retrieval β€” i.e. it doesn't forget your stuff when the lights go out 🫢

so yeah. non-volatile. no cap. the catalog is the one keeping receipts so your objects don't evaporate into the void πŸ’€βœ¨


✨ PUBLIC OPERATIONS ✨

ok bestie this is the big one, the whole menu of what a Catalog can actually do πŸ’… every single one is here, no skips, no cap.

  • Catalog(const char* domainName, Creator*, float version) β€” builds you a whole catalog fr. you hand it an application-unique domain name, a creator object, and a version number. Unidraw objects can use that domain name to check file types, and they can lean on the version number to deal with storage formats that keep evolving on us. it's giving ✨future-proof✨

  • virtual boolean Save(EditorInfo*, const char*)
  • virtual boolean Save(Component*, const char*)
  • virtual boolean Save(Command*, const char*)
  • virtual boolean Save(Tool*, const char*)

save an object instance under whatever name you picked. the catalog writes a textual representation of the object into a file with that name β€” so yes, a name with embedded slashes is literally a path name for the file holding the textual representation. these return false if the file couldn't be written. 😭


  • virtual boolean Retrieve(const char*, EditorInfo*&)
  • virtual boolean Retrieve(const char*, Component*&)
  • virtual boolean Retrieve(const char*, Command*&)
  • virtual boolean Retrieve(const char*, Tool*&)

grab an object instance back by its name πŸŽ€ the catalog reconstructs an instance of the object from the corresponding file the first time you retrieve it. every retrieval after that with the same name just hands you a reference to the instance that's already chilling in memory. these return false if the instance couldn't be reconstructed from the file. so basically, it's a glow-up of a cache 🌸


  • virtual void Forget(EditorInfo*, const char* = nil)
  • virtual void Forget(Component*, const char* = nil)
  • virtual void Forget(Command*, const char* = nil)
  • virtual void Forget(Tool*, const char* = nil)

forget the name-to-object mapping for the instance you pass in 🫢 and if you also pass that optional string, the catalog forgets one specific name-to-object mapping instead β€” which is exactly what you want when an instance got saved under a bunch of different names. we love a selective memory moment πŸ’­


  • virtual const char* GetName(EditorInfo*)
  • virtual const char* GetName(Component*)
  • virtual const char* GetName(Command*)
  • virtual const char* GetName(Tool*)

get a name that's associated with an instance. heads up tho: these operations do not specify which name comes back for instances that were saved under more than one name. so like, it's a mystery, and honestly we respect the mystery πŸ™ˆ


  • virtual boolean Valid(const char*, EditorInfo*&)
  • virtual boolean Valid(const char*, Component*&)
  • virtual boolean Valid(const char*, Command*&)
  • virtual boolean Valid(const char*, Tool*&)

tell you whether that given name already has an instance associated with it β€” i.e. it's been saved or retrieved at some point β€” and if it has, it drops that instance into the second parameter. vibe check: passed βœ…


  • virtual Component* Copy(Component*)
  • virtual Command* Copy(Command*)
  • virtual Tool* Copy(Tool*)

copy an instance the sneaky-but-clean way: save it under a temporary name, retrieve it, then forget the temporary name. a component, command, or tools subclass can call the matching one of these to implement their own Copy function easily β€” possibly at the expense of run-time performance. worth it for the convenience ngl πŸ¦‹


  • virtual boolean Exists(const char*) β€” returns whether a file with the given name exists. but bestie, listen: a true here does not necessarily mean an object has been saved under that name. don't get it twisted πŸ’€
  • virtual boolean Writable(const char*) β€” returns whether it's permitted to save an object under the given name. permission check, slay πŸ”₯
  • void SetClipboard(Clipboard*)
  • Clipboard* GetClipboard() β€” set or get a globally-accessible clipboard object. global clipboard rights for everyone πŸŽ€
  • void SetEditorInfo(EditorInfo*)
  • EditorInfo* GetEditorInfo() β€” set or get a globally-accessible editor info object. same energy, different object ✨
  • const char* GetName()
  • Creator* GetCreator()
  • float GetVersion() β€” return the values of the parameters you gave the constructor. throwback moment πŸ“Ό
  • float FileVersion() β€” returns the Unidraw version number of the file that's being read right now. live read, no cap πŸ‘‘
  • const char* GetAttribute(const char*) β€” return the value of a user preference with that name, as stored in the global PropertySheet. it's equivalent to the World operation of the same name. twins fr πŸ’œ

πŸ“ the write squad

  • void WriteVersion(int, ostream&)
  • void WriteClassId(ClassId, ostream&, int id = 0)
  • void WriteComponent(Component*, ostream&)
  • void WriteCommand(Command*, ostream&)
  • void WriteTool(Tool*, ostream&)
  • void WriteStateVar(StateVar*, ostream&)
  • void WriteTransferFunct(TransferFunct*, ostream&)
  • void WriteBgFilled(boolean, ostream&)
  • void WriteBrush(PSBrush*, ostream&)
  • void WriteColor(PSColor*, ostream&)
  • void WriteFont(PSFont*, ostream&)
  • void WritePattern(PSPattern*, ostream&)
  • void WriteTransformer(Transformer*, ostream&)
  • void WriteString(const char*, ostream&)
  • void WriteControlInfo(ControlInfo*, ostream&)
  • void WriteEditorInfo(EditorInfo*, ostream&)
  • void WriteBitmap(Bitmap*, ostream&)
  • void WriteBitmapData(Bitmap*, ostream&)
  • void WriteGraymap(Raster*, ostream&)
  • void WriteGraymapData(Raster*, ostream&)
  • void WriteRaster(Raster*, ostream&)
  • void WriteRasterData(Raster*, ostream&)

πŸ“– the read squad

  • int ReadVersion(istream&)
  • ClassId ReadClassId(istream&, int& id)
  • Component* ReadComponent(istream&)
  • Command* ReadCommand(istream&)
  • Tool* ReadTool(istream&)
  • StateVar* ReadStateVar(istream&)
  • TransferFunct* ReadTransferFunct(istream&)
  • int ReadBgFilled(istream&)
  • PSBrush* ReadBrush(istream&)
  • PSColor* ReadColor(istream&)
  • PSFont* ReadFont(istream&)
  • PSPattern* ReadPattern(istream&)
  • Transformer* ReadTransformer(istream&)
  • char* ReadString(istream&)
  • ControlInfo* ReadControlInfo(istream&)
  • EditorInfo* ReadEditorInfo(istream&)
  • Bitmap* ReadBitmap(istream&)
  • Bitmap* ReadBitmapData(istream&)
  • Raster* ReadGraymap(istream&)
  • Raster* ReadGraymapData(istream&)
  • Raster* ReadRaster(istream&)
  • Raster* ReadRasterData(istream&)

write and read info through streams, that's the whole gig πŸ’« catalog-managed classes call these inside their own Write and Read functions to write and read the objects they contain. and the ones for bitmaps and rasters come with accompanying operations that write and read only the ASCII data β€” like, omitting transformation and other Unidraw format-specific data β€” that encodes their information content. so you get the raw tea or the full tea 🍡


🎨 paint objects from your preferences

  • PSBrush* ReadBrush(const char* definition, int index)
  • PSColor* ReadColor(const char* definition, int index)
  • PSFont* ReadFont(const char* definition, int index)
  • PSPattern* ReadPattern(const char*, int index)

these return a PostScript paint object that matches a user preference with the given definition and index number, as stored in the global PropertySheet. every string in the X defaults database shaped like

<applicationName>.resource:definition

sets a resource. here's the full rundown of resource names and their definitions, bestie, and I mean full:

  • brushi β€” define the *i*th brush resource. the ReadBrush operation retrieves the brush object for this resource given a definition. the definition usually specifies two numbers: a 16-bit hexadecimal number defining the brush's line style (each 1 bit draws a dash and each 0 bit produces a gap), and a decimal integer defining the brush's width in pixels. for example, ffff 1 defines a single pixel wide solid line. and if the definition specifies only the string none, then it defines the nonexistent brush. πŸ’€
  • fgcolori β€” define the *i*th foreground color resource. the ReadColor operation retrieves the color object for this resource given a definition. the definition contains a string naming the color, optionally followed by three decimal numbers between 0 and 65535 defining the red, green, and blue components of the color's intensity. the intensities override the name β€” that is, the catalog will only look the name up in the database of common colors if you omit the intensities. for example, Indigo 48896 0 65280 defines a color that's a mixture of red and blue. you can define shades of gray by using equal proportions of each primary color. 🌈
  • bgcolori β€” the background color resource definition is specified in the same manner as the foreground color. copy-paste energy, we love consistency πŸ’…
  • fonti β€” define the *i*th font resource. the ReadFont operation retrieves the font object for this resource given a definition. the definition contains three strings separated by whitespace. the first string defines the font's name, the second string the corresponding print font, and the third string the print size. for example, 8x13bold Courier-Bold 13 defines the third font entry. ✍️
  • patterni β€” define the *i*th pattern resource. the ReadPattern operation retrieves the pattern object for this resource given a definition. the definition can specify the pattern for a 16x16 bitmap, a 8x8 bitmap, a 4x4 bitmap, a grayscale number, or the string none. you specify the 16x16 bitmap with sixteen 16-bit hexadecimal numbers, the 8x8 bitmap with eight 8-bit hexadecimal numbers, the 4x4 bitmap with a single 16-bit hexadecimal number, and the grayscale number with a single floating point number. that floating point number must contain a period to distinguish itself from the single hexadecimal number, and it must lie between 0.0 and 1.0, where 0.0 corresponds to a solid pattern and 1.0 to a clear pattern. on the printer, the bitmap patterns appear as bitmaps, the grayscale patterns appear as halftoned shades, and the none patterns never obscure underlying graphics. for example, pattern8:8421 defines a diagonally hatched pattern. πŸ”₯

πŸ” finders keepers

  • PSBrush* FindNoneBrush()
  • PSBrush* FindBrush(int, int)
  • PSColor* FindColor(const char*, int = 0, int = 0, int = 0)
  • PSFont* FindFont(const char*, const char*, const char*)
  • PSPattern* FindNonePattern()
  • PSPattern* FindGrayLevel(float)
  • PSPattern* FindPattern(int[], int)

return a PostScript paint object with the matching attributes. if no object with those attributes exists yet, these operations hand you a brand new paint object β€” otherwise they return an existing instance that already matches. bestie it's literally an intern, it remembers everything 🧚


  • void Skip(istream&)
  • void Mark(ostream&)

Mark injects a synchronization sequence defined by MARK (peep globals(3U)) into the output stream. Skip searches for that exact same sequence in the given input stream and positions the stream immediately after that sequence. hide and seek but make it file I/O πŸŽ€

πŸ›‘οΈ PROTECTED OPERATIONS πŸ›‘οΈ

okay bestie so these ones are the backstage girlies β€” they exist, they're real, they're just not meant to be your first move. but no gatekeeping here, we're gonna walk through them anyway πŸ’…

  • void Register(EditorInfo*, const char*) β€” drop an EditorInfo into the catalog's internal maps under a particular name, so it can be found again later.
  • void Register(Component*, const char*) β€” same energy, but for a Component. name it, stash it, iconic.
  • void Register(Command*, const char*) β€” yep, Commands get registered too. under a name. in the internal maps. periodt.
  • void Register(Tool*, const char*) β€” and Tools. same deal. πŸ“Œ

so like, what even is Register doing? it's putting an object under a particular name in the catalog's internal maps. the important part: objects are normally registered automatically when they are stored or retrieved ✨ so you usually don't have to lift a finger β€” the catalog handles it while you're just living your life storing and retrieving stuff. Register is the manual override for when you want to be the main character about it. 🫢

  • int GetToken(istream&, char* buf, int buf_size) β€” this one goes digging through an input stream looking for a sequence of characters that's defined in the buffer buf, which is buf_size big. πŸ”

and what does it hand back? GetToken returns the number of characters matched. that's the whole tea. πŸ’–

ngl these are protected for a reason β€” they're the catalog's own little private rituals. you're allowed to see them, you're just not supposed to be rummaging around in there unless you know what you're doing. πŸšͺ✨

πŸ‘€ SEE ALSO πŸ‘€

go read these next, bestie, they're all part of the same friend group πŸ¦‹

  • Clipboard(3U)
  • Command(3U)
  • Component(3U)
  • ControlInfo(3U)
  • Creator(3U)
  • EditorInfo(3U)
  • Graphic(3U)
  • PropertySheet(3I)
  • StateVar(3U)
  • Tool(3U)
  • TransferFunct(3U)
  • World(3I)
  • globals(3U)
  • istream(3C++)
  • ostream(3C++)

and that's the whole page, babe, we made it 🌈 the whole thing came from Unidraw, and the vibe is officially dated 11 June 1990 β€” yeah, this manual page is a whole elder, older than most of us, and it still ate. no cap. πŸ’œ πŸŽ€ go forth and catalog responsibly βœ¨πŸ‘‘