← Back to team overview

kicad-developers team mailing list archive

[patch 1/1] kicad-py-binding-base.patch

 

4th patch: module handling

This patch adds the python module handling to pyhandler.cpp

to create a binding, just create a C global scope function, in which you 
'def' symbols
then register this function using PyHandler::AddToModule( modname, &func )

For now few functions are bound :

string common.ChooseFile( string title, string mask, int open ) : open a 
file selector dialog
common.Print( string message ) : base function, for now equivalent to 
'print', but will be
overloaded to print in the project log

---
common/pyhandler.cpp | 102 
+++++++++++++++++++++++++++++++++++++++++++++++----
include/pyhandler.h | 24 ++++++++++--
2 files changed, 114 insertions(+), 12 deletions(-)


 --------------030808010600020403090701 Content-Type: text/x-patch;
name="kicad-py-binding-base.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="kicad-py-binding-base.patch"

4th patch: module handling

This patch adds the python module handling to pyhandler.cpp

to create a binding, just create a C global scope function, in which you 'def' symbols
then register this function using PyHandler::AddToModule( modname, &func )

For now few functions are bound :

string common.ChooseFile( string title, string mask, int open ) : open a file selector dialog
common.Print( string message ) : base function, for now equivalent to 'print', but will be
overloaded to print in the project log


---
common/pyhandler.cpp | 102 +++++++++++++++++++++++++++++++++++++++++++++++----
include/pyhandler.h | 24 ++++++++++--
2 files changed, 114 insertions(+), 12 deletions(-)


Index: kicad-dev/common/pyhandler.cpp
===================================================================
--- kicad-dev.orig/common/pyhandler.cpp	2007-04-22 10:05:24.000000000 +0200
+++ kicad-dev/common/pyhandler.cpp	2007-04-22 19:46:30.000000000 +0200
@@ -21,6 +21,45 @@

using namespace boost::python;

+
+/*****************************************************************************/
+/* Common Python Binding */
+/*****************************************************************************/
+
+static object ChooseFile( str objTitle, str objMask, object objOpen )
+{
+ wxString title( extract<const char*>( objTitle ), wxConvLocal );
+ wxString mask ( extract<const char*>( objMask ), wxConvLocal );
+ int open = extract<int>( objOpen );
+
+ wxString script = EDA_FileSelector( title,
+ wxEmptyString,	/* Chemin par defaut */
+ wxEmptyString,	/* nom fichier par defaut */
+ mask,	/* extension par defaut */
+ mask, /* Masque d'affichage */
+ NULL,
+ open ? wxFD_OPEN : wxFD_SAVE,
+ FALSE
+ );
+
+ return str( std::string( script.fn_str() ).c_str() );
+}
+
+static void Print( str message ) { std::cout << extract<char *>(message); }
+
+static void init_base_utils(void)
+{
+ def ( "ChooseFile", &ChooseFile );
+ def ( "Print", &Print );
+}
+
+static void InitPyModules() { PyHandler::GetInstance()->InitNextModule(); } // Dummy boost callback
+
+/*****************************************************************************/
+/* PyHandler */
+/*****************************************************************************/
+
+
PyHandler* PyHandler::m_instance = NULL;

PyHandler * PyHandler::GetInstance()
@@ -36,7 +75,58 @@
PyHandler::PyHandler()
/* Init the Python env */
{
-	Py_Initialize();
+ Py_Initialize();
+ m_ModulesLoaded = false;
+ m_current = 0;
+
+ AddToModule ( wxT( "common" ), &init_base_utils );
+}
+
+void PyHandler::DoInitModules()
+{
+ if ( m_ModulesLoaded ) return;
+ m_ModulesLoaded = true;
+
+ for ( unsigned int i = 0; i < m_ModuleRegistry.size(); i ++ )
+ {
+ detail::init_module( m_ModuleRegistry[i].name.fn_str(), &InitPyModules );
+ }
+}
+
+int PyHandler::GetModuleIndex( const wxString & name ) const
+/* Returns the module index in the registry, -1 if not found*/
+{
+ for ( unsigned int i = 0; i < m_ModuleRegistry.size(); i ++ )
+ {
+ if ( m_ModuleRegistry[i].name == name ) return i;
+ }
+ return -1;
+}
+
+void PyHandler::AddToModule( const wxString & name, PyHandler::initfunc_t initfunc )
+/* Adds an init function to a python module */
+{
+ if (!initfunc) return;
+ int i = GetModuleIndex( name );
+
+ if ( -1 == i )
+ {
+ m_ModuleRegistry.push_back( ModuleRecord( name ) );
+ i = m_ModuleRegistry.size() - 1;
+ }
+
+ m_ModuleRegistry[i].registry.push_back( initfunc );
+}
+
+
+void PyHandler::InitNextModule()
+/* Called to initialize a module on py 'import module' */
+{
+ for ( unsigned int j = 0; j < m_ModuleRegistry[m_current].registry.size() ; j ++ )
+ {
+ m_ModuleRegistry[m_current].registry[j]();
+ }
+ m_current++;
}

PyHandler::~PyHandler()
@@ -74,12 +164,6 @@
}
}

-void PyHandler::AddModule( void (* initfunc)() )
-{
-	if (initfunc) initfunc();
-}
-
-
void PyHandler::RunScripts()
/* Run application startup scripts */
{
@@ -99,7 +183,9 @@
bool PyHandler::RunScript( const wxString & name )
/* Run the script specified by 'name' */
{
- object module(( handle<>(borrowed(PyImport_AddModule("__main__")))));
+ DoInitModules();
+
+ object module( handle<>(borrowed(PyImport_AddModule("__main__"))));
object ns = module.attr( "__dict__" );

FILE * file = fopen( name.fn_str(), "r" );
Index: kicad-dev/include/pyhandler.h
===================================================================
--- kicad-dev.orig/include/pyhandler.h	2007-04-22 10:05:27.000000000 +0200
+++ kicad-dev/include/pyhandler.h	2007-04-22 19:44:00.000000000 +0200
@@ -9,12 +9,17 @@
#include <Python.h>

#include <wx/string.h>
+#include <vector>

class PyHandler
{

+ typedef void (*initfunc_t )();
+
private:
static PyHandler * m_instance;
+ bool m_ModulesLoaded;
+ int m_current;

protected:
PyHandler();
@@ -22,6 +27,16 @@
wxString m_appName;
void RunBaseScripts( const wxString & base );

+ struct ModuleRecord
+ {
+ wxString name;
+ std::vector< initfunc_t > registry;
+
+ ModuleRecord( const wxString & modName ) : name(modName) {}
+ };
+ std::vector< ModuleRecord > m_ModuleRegistry;
+ void DoInitModules();
+
public:
// Singletton handling:
static PyHandler * GetInstance();
@@ -29,7 +44,9 @@

// Scope params/handling:
void SetAppName( const wxString & name );
-	void AddModule( void (* initfunc)(void) );
+
+ void AddToModule( const wxString & name, initfunc_t initfunc );
+ int GetModuleIndex( const wxString & name ) const;

// Script
void RunScripts();
@@ -38,10 +55,9 @@
// Common Informations
const char * GetVersion();

-};
-
+ void InitNextModule();

-#define KICAD_PY_BIND_MODULE( mod ) PyHandler::GetInstance()->AddModule( init#mod )
+};

// vim: set tabstop=4 :
#endif
 --------------030808010600020403090701--