← Back to team overview

kicad-developers team mailing list archive

Was: request for comments on work package list, is now: IO_MGR

 

Javier,

I copy the KiCad developers mailing list too on this one.

Here is a revision of the IO_MGR and PLUGIN support that we talked about.  Changes:

A) Added another function parameter to both Save() and Load(), a "catch all" PROPERTIES
associative array argument which can carry things particular to a plugin down in there so
you can tell the plugin to jump through particular hoops or tune how it works.

http://docs.wxwidgets.org/trunk/classwx_hash_map.html

B) I also added specific comments about the IO_ERROR exception throwing.  This should
allow us to keep all the UI code out of the plugin functions.  The basic idea is that if
an error happens in a plugin, the loading or saving stops, the exception is filled in with
as much detail as possible, and thrown.  Caller sits way up above, catches exception, uses
the UI to report the problem in one place using a try catch.  ( You know, just like an
actual C++ program. :) )


This formerly pie in the sky facility is now more immediately pertinent because I have
volunteered to re-do the native file loading in support of the increased BIU resolution as
I work with Vladimir.

And this seemed like a good place to do it in.  I still would wish for an s-expression
version of KiCad BOARD files in the near future also, but this is simply an evolutionary
format which will merely add higher resolution and perhaps change the meaning of stored
angles.  Otherwise its the same format basically.

If there is anything Tom or anyone sees in this interface that is unsuitable, ..... easy
improvements welcomed.

More importantly, it may affect one of your Workpackage write ups.

I really think one of the best Workpackages might be the new EAGLE XML support, done
through this interface.

Thanks for your support,

Dick




#include <io_mgr.h>


class KICAD_PLUGIN : public PLUGIN
{
    BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES* aProperties = NULL );

    void Save( const wxString* aFileName, BOARD* aBoard, PROPERTIES* aProperties = NULL );
};



// some day plugins could be in separate DLL/DSOs, until then, use the simplest method:

static KICAD_PLUGIN kicad_plugin;

//static EAGLE_PLUGIN eagle_plugin;


PLUGIN* IO_MGR::FindPlugin( PCB_FILE_T aFileType )
{
    switch( aFileType )
    {
    case KICAD:     return &kicad_plugin;

//    case EAGLE:     return &eagle_plugin;
    }

    throw IO_ERROR( );
}


BOARD* IO_MGR::Load( PCB_FILE_T aFileType, const wxString& aFileName,
        BOARD* aAppendToMe, PROPERTIES* aProperties )
{
    PLUGIN* pi = FindPlugin( aFileType );

    // Want to use an exception based error reporting mechanism, without UI in it,
    // so that calling code gets a detailed description of what any errors are.

    if( pi )
        return pi->Load( aFileName, aAppendToMe, aProperties );  // virtual

    throw IO_ERROR( /* @todo say what went wrong: missing plugin */ );
}

#ifndef IO_MGR_H_
#define IO_MGR_H_

#include <wx/string.h>
#include <wx/hashmap.h>
#include <richio.h>


// http://docs.wxwidgets.org/trunk/classwx_hash_map.html
WX_DECLARE_STRING_HASH_MAP( wxString, PROPERTIES );

class BOARD;
class SCHEMATIC;


/**
 * Class PLUGIN
 * is a base class that BOARD loading and saving plugins should derive from.
 * Implementations can provide either Load() or Save() functions, or both.
 */
class PLUGIN
{
public:

    //-----<BOARD STUFF>----------------------------------------------------

    /**
     * Function Load
     * loads a board file from some input file format that this implementation
     * knows about.
     *
     * @param aFileName is the name of the file to load and may be foreign in
     *  nature or native in nature.
     *
     * @param aAppendToMe is an existing BOARD to append to but is often NULL
     *  meaning do not append.
     *
     * @param aProperties is an associative array that can be used to tell the
     *  loader how to load the file, because it can take any number of
     *  additional named arguments that the plugin is known to support.
     *
     * @return BOARD* - the successfully loaded board, and caller owns it.
     *
     * @throw IO_ERROR if there is a problem loading, and its contents should
     *  say what went wrong.
     */
    virtual BOARD*  Load( const wxString& aFileName, BOARD* aAppendToMe,
                        PROPERTIES* aProperties = NULL )
    {
        // not pure virtual so that plugins only have to implement
        // Load() or Save() but not both.
    }

    /**
     * Function Save
     * will write a full aBoard to a storage file in a format that only this
     * implementation knows about.  Or it can be used to write a portion of
     * aBoard to a special kind of export file.
     *
     * @param aFileName is the name of a file to save to on disk.
     * @param aBoard is the BOARD document (data tree) to save or export to disk.
     *
     * @param aProperties is an associative array that can be used to tell the
     *  saver how to save the file, because it can take any number of
     *  additional named arguments that the plugin is known to support.
     *
     * @throw IO_ERROR if there is a problem loading.
     */
    virtual void Save( const wxString* aFileName, BOARD* aBoard,
                    PROPERTIES* aProperties = NULL )
    {
        // not pure virtual so that plugins only have to implement
        // Load() or Save() but not both.
    }

    //-----</BOARD STUFF>---------------------------------------------------

#if 0
    ///--------- Might split into two PLUGIN base types here, rather than being combined like this

    //-----<SCHEMATIC STUFF>------------------------------------------------

    /**
     * Function Load
     * loads a file from some special input file format that
     * only this implementation knows about.
     * @param aFileName is the name of the file to load and may be foreign in nature or native in nature.
     * @param aAppendToMe is an existing SCHEMATIC to append to but may be NULL.
     */
    virtual SCHEMATIC*  Load( const wxString& aFileName, SCHEMATIC* aAppendToMe,
                            PROPERTIES* aProperties = NULL )
    {
        // not pure virtual so that plugins only have to implement
        // Load() or Save() but not both.
    }

    /**
     * Function Save
     * will write aBoard to a storage file in a format that only this
     * implementation knows about.
     *
     * @param aFileName is the name of a file to save to on disk.
     *
     * @param aBoard is the SCHEMATIC document (ram data tree) to save or export to disk.
     */
    virtual void Save( const wxString* aFileName, SCHEMATIC* aSchematic,
                    PROPERTIES* aProperties = NULL )
    {
        // not pure virtual so that plugins only have to implement
        // Load() or Save() but not both.
    }

    //-----</SCHEMATIC STUFF>----------------------------------------------
#endif
};


/**
 * Class IO_MGR
 * is factory which returns an instance of a PLUGIN DSO/DLL.
 */
class IO_MGR
{
public:

    /**
     * Enum PCB_FILE_T
     * is a set of file types that the IO_MGR knows about, and for which there
     * has been a plugin written.
     */
    enum PCB_FILE_T
    {
        KICAD,
        // EAGLE,
        // ALTIUM,
        // etc.
    };

    /**
     * Function FindPlugin
     * returns a PLUGIN which the caller can use to import, export, save, or load
     * design documents.  The caller does not own the returned PLUGIN, so no
     * need to delete it.
     *
     * @param aFileType is from PCB_FILE_T and tells which plugin to find.
     *
     * @return PLUGIN* - the plugin corresponding to aFileType or NULL if not found.
     *  Caller does not own the returned object, do not delete it.
     */
    static PLUGIN* FindPlugin( PCB_FILE_T aFileType );

    /**
     * Function Load
     * finds the requested plugin and loads a BOARD, or throws an exception trying.
     *
     * @param aFileType is the type of file to load.
     *
     * @param aFileName is the name of the file to load.
     *
     * @param aAppendToMe is an existing BOARD to append to, use NULL if fresh
     *  board load wanted.
     *
     * @param aProperties is an associative array that allows the caller to
     *  pass additional tuning parameters to the plugin.
     *
     * @return BOARD* - caller owns it, never NULL because exception thrown if error.
     *
     * @throw IO_ERROR if the pluging cannot be found, file cannot be found,
     *  or file cannot be loaded.
     */
    static BOARD* Load( PCB_FILE_T aFileType, const wxString& aFileName,
            BOARD* aAppendToMe = NULL, PROPERTIES* aProperties = NULL );

    // etc.
};

#endif // IO_MGR_H_


Follow ups