|
|
namespace SCH {
/** @mainpage
This file describes the design of a new Distributed Library System for KiCad'sEESCHEMA. Many of the concepts can be adapted with modest modification to PCBNEWalso, in the future.
@author Dick Hollenbeck <dick@softplc.com>
@date October 2010 - January 2011
@section intr_sec Introduction
Schematic <b>parts</b> are frequently needed to complete a circuit designschematic. Computer data entry of parts can be a rate limiting step in thedesign of an overall PCB. Having ready made access to all needed parts in adesign significantly improves the productivity of a circuit designer. Sharingparts within an organization is one step in the right direction, but there isopportunity to share across organizational boundaries to improve productivityeven more. Using a part that someone else in another organization has alreadyentered into the computer can eliminate the first data input process for thatpart. The more complicated the part and the board, the larger the positiveimpact on productivity because the larger the time savings.
<p> Sharing parts within an organization is best done by directly accessing aknown internal source for those parts, say on a company network. Sharing partsacross organizational boundaries is best done using the Internet in real-time.Having the ability to search for a part based on arbitrary search criteria canspeed up the pace at which new parts are found and used.
<p> Electronic component manufacturers need and look for ways to differentiatetheir products from their competitors. With this Distributed Library Systemfacility in KiCad, one way for manufacturers to differentiate themselves andtheir parts is to publish a part library on the Internet and save theircustomers the work of doing the data entry of the part into the KiCad designsystem.
<p> Maintaining a comprehensive part library is a fairly labor intensiveactivity. New parts come into the market everyday. By being able to publish asuperior library on the Internet, it may be possible to make a for profitbusiness out of doing this. The KiCad eco-system would benefit should thishappen, and there could even be competition between such businesses. Or therecan be library specializations or niches.
<p> Often a found part is close to what is needed but not exactly what isneeded. This Distributed Library System design incorporates the concept of partinheritance using a part description language called <b>Sweet</b>. Sweet isbased on s-expression syntax. Inheritance is the ability to incrementally changean existing part without completely re-designing it. It is sometimes easier tomodify an existing part than it is to create the new part entirely from scratch.
<p> This Distributed Library System design will have the capability tosignificantly benefit the KiCad eco-system, and that should mean expanding thenumbers of users and contributors to the project, and hopefully making for abetter KiCad tool-set for all.
@section definitions Definitions
Only new terms or changes in the definition of terms are given here.
<dl>
<dt>S-Expression</dt><dd>This is a syntactical textual envelop in the same vain asXML. It may be used to express any number of domain specific grammars. It usesparentheses to indicate the start and end of an element. A domain specificgrammar is a set of rules that dictate what keywords may be used, and in whatcontext. A grammar also establishes the allowed places and types of constants.There can be any number of grammars which all use s-expressions to hold theindividual elements within the grammar. A grammar is at a higher level thans-expressions, in the same way that a sentence will have grammatical rules whichare at a higher level than the rules used to spell words. Technically, grammarsnest within grammars. So once you are inside a grammatical element, it will haveits own set of rules as to which nested elements it may hold, and once you enterone of those nested elements, then that nested element's grammar pertains,etc.<p> In the case of the grammar for a part, the grammar itself is being giventhe name Sweet. The name does not extend to the grammar for the schematic,only the part grammar.</dd>
<dt>Schematic</dt><dd>This consists of one or more sheets and will be differentin three ways from existing schematics. <ul>
<li>All sheets will be in one file, thus the entire schematic is in one file.
<li>The schematic file will have its own s-expression grammar.
<li> There will be a <b>parts list</b> within the schematic, and within the parts list will be <b>all</b> the parts for the schematic. yes <b>all</b> of them. See class PARTS_LIST.</ul>
Within the sheets of the schematic will be components.</dd>
<dt>Component</dt><dd>A component is an instantiated part. The keyword forcomponent is (comp). A component does not have any of its own properties otherthan: <ul> <li>rerence designator <li>part pointer or reference into the partslist <li>location <li>rotation <li>stuff i.e. DNS or do stuff the part<li>visual textual effect overrides </ul> Note that the (comp) may not have anyproperties or fields of its own, and that it may not exist without acorresponding part in the parts_list. A reason for this is to ensure that aBOM can be made simply from the parts_list.</dd>
<dt>Component, again for good measure.</dt><dd>A component is an instantiationof a part. A component exists within a schematic which has a parts listcontaining the part from which the component is instantiated. A component has aunique reference designator, part ref, its own location, orientation,stuff/DNS, and text attributes but <b>not</b> its own text fields/strings (otherthan reference designator). The part which is instantiated must exist in theparts list of the same schematic.</dd>
<dt>Inheritance</dt><dd>Is the ability to mimic form and function from anotherentity. In our case we use it only for parts. One part may "inherit from" or"extend" another single part.</dd>
<dt>Part</dt><dd>A part is a symbolic schematic circuit element found within anEESCHEMA library (or within a parts list). It is re-usable and may beinstantiated more than once within a schematic. For it to be instantiated, itmust be copied or inherited into the parts list of the instantiating schematic.If inherited into the parts list, then only a concise reference is needed intothe originating library. If instead it is copied into the parts list, then thepart is fully autonomous and need have no reference to its original copy.</dd>
<dt>Parts List</dt><dd>A parts list, keyword (parts_list), is an entirely newconstruct. It exists within a schematic and is the complete set of parts usedwithin a particular schematic. Each schematic has exactly one parts listcontained within it. A parts list is also a library source and a library sinkfor the current schematic. A parts list in any schematic may also be a librarysource for any other schematic, but not a library sink. The parts list constructmakes it almost wholly unnecessary to write to other types of librarysinks.</dd>
<dt>Library</dt><dd>A library is no longer a file. It is a memory cache ofparts, consistent with the normal definition of memory cache. Each library isbacked up with a <b>library source</b>. In rare cases, some libraries may alsohave a <b>library sink</b>.</dd>
<dt>Library Source</dt><dd>A library source is an abstract read only repositoryof parts. The repository itself might exist on the moon. The difference betweena library source and a library sink is that a source is a readable entity.</dd>
<dt>Library Sink</dt><dd>A library sink is an abstract place that parts can bewritten to for future reading. The difference between a library source and alibrary sink is that a library sink is a writable entity.</dd>
<dt>Symbol</dt><dd>The term "symbol" is not used in a specific way in thisdocument. There is no symbol in any of the grammars, so use of it on thedevelopers list will not be understood without explanation. Of course it ispossible to have multiple parts all extend a common base part, and you can thinkof the base part as having most if not all the graphical lines for anyderivatives. But we do not need to use the term symbol to describe thatrelationship, the term "part" is sufficient.</dd>
<dt>LPID</dt><dd>This stands for "Logical Part ID", and is a reference to anypart within any known library. The term "logical" is used because the containedlibrary name is logical, not a full library name. The LPID consists of 3 mainportions: logical library name, part name, and revision number.</dd>
<dt>Library Table</dt><dd>This is a lookup table that maps a logical libraryname (i.e. a short name) into a fully specified library name and library type.An applicable library table consists of rows from (at least) two sources:<ol><li>A schematic resident library table.<li>A personal library table.</ol>
These rows from the two sources are conceptually concatonated (although they maynot be physically concatonated in the implementation, TBD). The schematicresident rows take presedence over the personal library table if there arelogical library names duplicately defined. (Or we will simply ask that any remote(i.e. public) libraries use uppercase first letters in logical names, TBD.)
<p> Eventually there will be an external publicly available internet basedlogical library table also, but this will need to be glued down at a hard codedURL that we have control over. The internet based library table allows us toadvertise remote libraries without having to issue an update to KiCad.</dd>
<dt>Query Language</dt><dd>This is a means of searching for something that iscontained within a container. Since some library sources are remote, it isimportant to be able to ask the library source for a part that matches somecriteria, for performance reasons.</dd>
</dl>
@section changes Required Changes
In order fulfill the vision embodied by this Distributed Library System design,it will be necessary to change many APIs and file formats within EESCHEMA. Infact, the entire schematic file format will be new, based on s-expressions,the schematic grammar, and the Sweet language for parts.
Here are some of the changes required: <ul>
<li> All sheets which make up a schematic will go into a single s-expressionfile. The multiple sheet support will still exist, but all the sheets for asingle schematic are all in a single file.
<li> A "library" is a collection of "parts". The unit of retrieval from alibrary is a part as a textual string in the Sweet language. Sweet is aparticular "grammar" expressed in s-expression form, and can be used to fullydescribe parts. Because EESCHEMA does not actually see a "library file",(remember, EESCHEMA can only ask for a part), the actual file format for alibrary is no longer pertinent nor visible to the core of EESCHEMA. The unit ofretrieval from the API is the part, so EESCHEMA gets an entire part s-expressionand must then parse it as a RAM resident Sweet string.
<li>EESCHEMA knows of no library files, instead there is a library API whichabstracts the actual part storage strategy used within any libraryimplementation. The API can be implemented by anyone wanting to provide alibrary under a given storage strategy. The API provides a storage strategyabstraction in classes LIB_SOURCE and LIB_SINK. The actual storage strategy usedin any particular library implementation is not technically part of theconceptual core of EESCHEMA. This is an important concept to grasp. Eventuallythe library implementations may be jetisoned into a plug-in structure, butinitially they are statically linked into EESCHEMA. Should the plug-in strategyever get done, the boundary of the plug-in interface will remain the C++ libraryAPI as given here (mostly in class LIB_SOURCE). The only reason to introduce aplug-in design is to allow proprietary closed source library implementations,and this could eventually come about if a part vendor wanted to provide one forthe KiCad project. If a Texas Instruments type of company wants to maintain aKiCad library, we will be positioned to accommodate them. Until then, theLIB_SOURCE implementations can be statically linked into EESCHEMA and there isno conceptual disruption either way.
<li> Most library implementations are read only. There are only two librarytypes that are writable, the "dir" type, and the "parts list". All other typesare read only from the perspective of the API. Stuffing those read onlylibraries and maintaining them will be done using the normal update mechanismspertinent to the library's respective type of repository. The most common placeto do incremental enhancements to a part before using it is not in the externallibrary, but now in the parts list with this new design.
<li> The design will support classical clipboard usage. The part in the Sweetlanguage can be placed onto the clipboard for use by other applications andinstances of EESCHEMA. Eventually larger blocks of components may also besupported on the clipboard, since the Sweet language allows these blocks to bedescributed textually in a very readable fashion. (Clipboard support beyond partmanipulation is not currently in this revision of the design however, it can bea future separate enhancement. Perhaps someday complete sheets may be passedthrough the clipboard.)
<li> The cumulative set of required changes are significant, and are tantamountto saying that EESCHEMA will need its part handling foundations re-written. Aconversion program will convert everything over to the new architecture. Theconversion program can simplify things by simply putting all schematic partsinto a parts list within each schematic.
<li> An Internet connection is required to use some of the library sources. Itwill be possible to omit these library sources and run KiCad by doing aconfiguration change. Eventually, some library sources will spring up and willnot technically be part of the KiCad project, so they will remain remote, butfully usable to those with an internet connection and permission from thelibrary source's owner.
<li>By far, even as radical as the distributed library concept is, complete withremote access, the most significant conceptual change is the introduction of the<b>parts list</b>. This is a special library that exists in a schematic, and isthe complete record of all parts used within that same schematic. It isimpossible to put a component into a schematic without that component's partfirst existing within the parts list of that schematic.
<li> Because of inheritance, multi-body-form parts, alternate body styles, seealso references, and other needs, it is necessary to have a <b>part referencemechanism</b>. A component has to reference a part, the one it "is". A part hasto be able to reference another part, either in the same library or elsewhere.Enter the Logical Part ID, or LPID to serve this need. An LPID consists of alogical library name, a part name, and an optional revision. It is used toreference parts, from anywhere. If the reference is from a sheet's component,then the logical library name of the LPID is not needed. Why? Well if you'vebeen paying attention you know. A comp can only be based on a part that existswithin the parts_list of the same schematic in which it resides. Likewise, apart within any library that references another part in that <b>same</b> librarywill also omit the logical library name from the LPID, and it must omit it. Why?Well because it makes renaming the library easier, for one. Two, the logicallibrary name is only a lookup key into a "library table". The library table mapsthe logical library name into an actual library source [and sink, iff writable].See LIB_SOURCE and LIB_SINK.
<p> In the case of the component referencing the part that it "is", there is norevision number allowed in the LPID. This is because that reference is to thepart in the parts list, and the parts list only holds a single revision of anypart (where "revision" is what you understand from version control systems).
<li> There needs to be a new query language designed and each library sourceneeds to support it. See LIB_SOURCE::FindParts() for a brief description of one.
</ul>
@section philosophy Design Philosophies
<p> Class names are chosen to be as concise as possible. Separate namespaces can beused should these same class names be needed in both EESCHEMA and PCBNEW (later).However, this design does not yet address PCBNEW. Suggested namespaces areSCH for EESCHEMA, and PCB for PCBNEW.
<p> Since most if not all the APIs deal with file or non-volatile storage, only8 bit string types are used. For international strings, UTF-8 is used, andthat is what is currently in use within the KiCad file storage formats.
<p> The typedef <b>STRINGS</b> is used frequently as a holder for multiplestd::strings. After some research, I chose std::dequeue<STRING> to hold a list ofSTRINGs. I thought it best when considering overall speed, memoryfragmentation, memory efficiency, and speed of insertion and expansion.
<p> A part description language is introduced called <b>(Sweet)</b>. It supportsinheritance and its syntax is based on s-expressions.
<p> Since a part can be based on another part using inheritance, it is importantto understand the idea of library dependencies. A part in one library can bedependent on another part in another library, or on another part in the samelibrary as itself. There are several library sources, some far away and somevery close to the schematic. The closest library to the schematic is the<b>(parts list)</b> class PARTS_LIST. Circular dependencies are not allowed. Alldependencies must be resolvable in a straight forward way. This means that apart in a remote library cannot be dependent on any part which is not alwaysresolvable.
<p> NRVO described: http://msdn.microsoft.com/en-us/library/ms364057%28VS.80%29.aspx
Even with NRVO provided by most C++ compilers, I don't see it being as lean ashaving class LIB keep expanded members STRING fetch and STRINGS vfetch for theaResults values. But at the topmost API, client convenience is worth a minorsacrifice in speed, so the topmost API does return these complex string objectsfor convenience. So there is a different strategy underneath the hood than whatis used on the hood ornament. When aResults pointer is passed as an argument, Iwon't refer to this as 'returning' a value, but rather 'fetching' a result todistinguish between the two strategies.
<p> Functions named as lookupSomething() or LookupSomething() are to be understoodas "find and load if needed". This is different than a simple find operation only, inthat an implied load operation is also done, but only if needed.
@section architecture Architecture
This document set later shows some <b>library sources</b> derived from classLIB_SOURCE. A library source is the backing to a library. The class name for alibrary in the new design is LIB.
<p><IMG SRC="../drawing.png" ALT="You should see design architecture here">
*/
/**
* @defgroup string_types STRING Types * Provide some string types for use within the API. */
/**
* @defgroup exception_types Exception Types * Provide some exception types for use within the API. */
/**
* Class HTTP_LIB_SOURCE * implements a LIB_SOURCE to access a remote document root repository using http protocol. */class HTTP_LIB_SOURCE : public LIB_SOURCE{ friend class LIB_TABLE; ///< constructor the LIB uses these functions.
protected:
/**
* Constructor ( const STRING& aHttpURL ) * sets up a LIB_SOURCE using aHttpURI which points to a subversion * repository. * @see LIB_TABLE::LookupPart() * * @param aHttpURL is a full URL of a document root repo directory. Example might * be "http://kicad.org/libs" * * @param aOptions is the options string from the library table. It can be any * string that the LIB_SOURCE can parse and understand, perhaps using comma separation * between options. Options and their syntax is LIB_SOURCE implementation specific. */ HTTP_LIB_SOURCE( const STRING& aHttpURL, const STRING& aOptions ) throws( IO_ERROR );};
/**
* Class SVN_LIB_SOURCE * implements a LIB_SOURCE to access a [remote or local] subversion repository * using subversion client protocol. */class SVN_LIB_SOURCE : public LIB_SOURCE{ friend class LIB_TABLE; ///< constructor the LIB uses these functions.
protected:
/**
* Constructor SVN_LIB_SOURCE( const STRING& aSvnURL ) * sets up a LIB_SOURCE using aSvnURI which points to a subversion * repository. * @see LIB_TABLE::LookupPart(). * * @param aSvnURL is a full URL of a subversion repo directory. Example might * be "svn://kicad.org/repos/library/trunk" * * @param aOptions is the options string from the library table. It can be any * string that the LIB_SOURCE can parse and understand, perhaps using comma separation * between options. Options and their syntax is LIB_SOURCE implementation specific. */ SVN_LIB_SOURCE( const STRING& aSvnURL, const STRING& aOptions ) throws( IO_ERROR );};
/**
* Class SCHEMATIC_LIB_SOURCE * implements a LIB_SOURCE in by reading a parts list from schematic file * unrelated to the schematic currently being edited. */class SCHEMATIC_LIB_SOURCE : public LIB_SOURCE{ friend class LIB_TABLE; ///< constructor the LIB uses these functions.
protected:
/**
* Constructor SCHEMATIC_LIB_SOURCE( const STRING& aSchematicFile ) * sets up a LIB_SOURCE using aSchematicFile which is a full path and filename * for a schematic not related to the schematic being editing in * this EESCHEMA session. * @see LIB_TABLE::LookupPart(). * * @param aSchematicFile is a full path and filename. Example: * "/home/user/kicadproject/design.sch" * * @param aOptions is the options string from the library table. It can be any * string that the LIB_SOURCE can parse and understand, perhaps using comma separation * between options. Options and their syntax is LIB_SOURCE implementation specific. */ SCHEMATIC_LIB_SOURCE( const STRING& aSchematicFile, const STRING& aOptions ) throws( IO_ERROR );};
/**
* Class PARTS_LIST * is a LIB which resides in a SCHEMATIC, and it is a table model for a * spread sheet both. When columns are added or removed to/from the spreadsheet, * this is adding or removing fields/properties to/from ALL the contained PARTS. */class PARTS_LIST : public LIB{public:
/**
* Function GetModel * returns a spreadsheet table model that allows both reading and writing to * rows in a spreadsheet. The UI holds the actual screen widgets, but * this is the table model, i.e. the PARTS_LIST is. */ SPREADSHEET_TABLE_MODEL* GetModel();};
} // namespace SCH
/// @todo remove endsWithRev() in favor of EndsWithRev(), find home for it.
/// @todo add simple unit test infrastructure.
/// @todo review: http://www.sfml-dev.org/tutorials/1.2/graphics-wxwidgets.php
// EOF
|