More SWIG improvements.

SWIG support for BOARD_ITEM_CONTAINER.
Split board.i into smaller included *.i files.
Add depencies on these smaller *.i files to CMakeLists.txt
This commit is contained in:
Dick Hollenbeck 2016-09-20 20:07:41 -05:00 committed by Wayne Stambaugh
parent c57fd7ccbf
commit 1718ac1083
19 changed files with 344 additions and 206 deletions

View File

@ -3,7 +3,6 @@
%include kiway_player.h
%{
#include <kiway_player.h>
%}

View File

@ -371,9 +371,23 @@ if( KICAD_SCRIPTING )
DEPENDS swig/pcbnew.i
DEPENDS swig/board.i
DEPENDS swig/board_item.i
DEPENDS swig/board_item_container.i
DEPENDS swig/dimension.i
DEPENDS swig/drawsegment.i
DEPENDS swig/edge_mod.i
DEPENDS swig/marker_pcb.i
DEPENDS swig/mire.i
DEPENDS swig/module.i
DEPENDS swig/netclass.i
DEPENDS swig/netinfo.i
DEPENDS swig/pad.i
DEPENDS swig/pcb_text.i
DEPENDS swig/plugins.i
DEPENDS swig/text_mod.i
DEPENDS swig/track.i
DEPENDS swig/units.i
DEPENDS swig/zone.i
DEPENDS ../common/swig/dlist.i
DEPENDS ../common/swig/kicad.i
DEPENDS ../common/swig/wx.i
@ -412,10 +426,28 @@ if( KICAD_SCRIPTING_MODULES )
set( SWIG_MODULE_pcbnew_EXTRA_DEPS
swig/board.i
swig/board_item.i
swig/board_item_container.i
swig/dimension.i
swig/drawsegment.i
swig/edge_mod.i
swig/marker_pcb.i
swig/mire.i
swig/module.i
swig/netclass.i
swig/netinfo.i
swig/pad.i
swig/pcb_text.i
swig/plugins.i
swig/text_mod.i
swig/track.i
swig/units.i
../common/swig/ki_exception.i
swig/zone.i
../common/swig/dlist.i
../common/swig/kicad.i
../common/swig/wx.i
../common/swig/ki_exception.i
../scripting/kicadplugins.i
)
swig_add_module( pcbnew

View File

@ -2,6 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo <miguelangel@nbee.es>
* Copyright (C) 2016 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
@ -33,132 +34,82 @@
By default we do not translate exceptions for EVERY C++ function since not every
C++ function throws, and that would be unused and very bulky mapping code.
Therefore please help gather the subset of C++ functions for this class that do
throw and add them here, before the class declarations.
throw and add them here, each before its respective class declaration.
*/
HANDLE_EXCEPTIONS(BOARD::TracksInNetBetweenPoints)
%include <class_board_design_settings.h>
%{
#include <class_board_design_settings.h>
%}
%{
#include <class_board.h>
#include <layers_id_colors_and_visibility.h>
#include <class_board_design_settings.h>
%}
%import dlist.h
// Organize the two forms of include side by side so that it is easier to
// migrate each grouping into a separate *.i file later.
%include class_board_item.h
%{
#include <class_board_item.h>
%}
%include board_item.i
%include board_item_container.i
%include class_board_connected_item.h
%{
#include <class_board_connected_item.h>
%}
%include pad_shapes.h
%include class_pad.h
%{
#include <class_pad.h>
%}
%include class_module.h
%{
#include <class_module.h>
%}
%include class_track.h
%{
#include <class_track.h>
%}
%include class_zone.h
%include zones.h
%{
#include <class_zone.h>
#include <zones.h>
%}
%include pad.i
%include track.i
%include zone.i
%include layers_id_colors_and_visibility.h
// Extend LSET by 2 methods to add or remove layers from the layer list
// Mainly used to add or remove layers of a pad layer list
%extend LSET
{
LSET addLayer( LAYER_ID aLayer) { return self->set(aLayer); }
LSET removeLayer( LAYER_ID aLayer) { return self->reset(aLayer); }
LSET addLayerSet( LSET aLayerSet) { return *self |= aLayerSet; }
LSET removeLayerSet( LSET aLayerSet) { return *self &= ~aLayerSet; }
%include class_pcb_text.h
%{
#include <class_pcb_text.h>
%}
%pythoncode
%{
def AddLayer(self, layer):
return self.addLayer( layer )
%include class_dimension.h
def AddLayerSet(self, layers):
return self.addLayerSet( layers )
def RemoveLayer(self, layer):
return self.removeLayer( layer )
def RemoveLayerSet(self, layers):
return self.removeLayerSet( layers )
%}
}
%{
#include <class_dimension.h>
#include <layers_id_colors_and_visibility.h>
%}
%include class_drawsegment.h
%{
#include <class_drawsegment.h>
%}
%include pcb_text.i
%include dimension.i
%include drawsegment.i
%include marker_pcb.i
%include mire.i
%include text_mod.i
%include edge_mod.i
%include class_marker_pcb.h
%{
#include <class_marker_pcb.h>
%}
%include class_mire.h
%{
#include <class_mire.h>
%}
%include class_text_mod.h
%{
#include <class_text_mod.h>
%}
%include class_edge_mod.h
%{
#include <class_edge_mod.h>
%}
%include class_zone_settings.h
%{
#include <class_zone_settings.h>
%}
%include class_netinfo.h
%include class_netclass.h
%{
#include <class_netinfo.h>
#include <class_netclass.h>
%}
%include netinfo.i
%include netclass.i
// this is to help python with the * accessor of DLIST templates
%rename(Get) operator BOARD_ITEM*;
%rename(Get) operator TRACK*;
%rename(Get) operator D_PAD*;
%rename(Get) operator MODULE*;
// we must translate C++ templates to scripting languages
%template(BOARD_ITEM_List) DLIST<BOARD_ITEM>;
%template(MODULE_List) DLIST<MODULE>;
%template(TRACK_List) DLIST<TRACK>;
%template(PAD_List) DLIST<D_PAD>;
// std::vector templates
%template(VIA_DIMENSION_Vector) std::vector<VIA_DIMENSION>;
@ -166,8 +117,6 @@ HANDLE_EXCEPTIONS(BOARD::TracksInNetBetweenPoints)
%include class_board.h
%extend BOARD
{
%pythoncode
@ -181,14 +130,6 @@ HANDLE_EXCEPTIONS(BOARD::TracksInNetBetweenPoints)
def Save(self,filename):
return SaveBoard(filename,self,IO_MGR.KICAD)
#
# add function, clears the thisown to avoid python from deleting
# the object in the garbage collector
#
def Add(self,item):
item.thisown=0
self.AddNative(item)
def GetNetClasses(self):
return self.GetDesignSettings().m_NetClasses
@ -234,32 +175,6 @@ HANDLE_EXCEPTIONS(BOARD::TracksInNetBetweenPoints)
}
%extend DRAWSEGMENT
{
%pythoncode
%{
def GetShapeStr(self):
return self.ShowShape(self.GetShape())
%}
}
%extend BOARD_ITEM
{
%pythoncode
%{
def SetPos(self,p):
self.SetPosition(p)
self.SetPos0(p)
def SetStartEnd(self,start,end):
self.SetStart(start)
self.SetStart0(start)
self.SetEnd(end)
self.SetEnd0(end)
%}
}
%feature("notabstract") NETINFO_ITEM;
// http://swig.10945.n7.nabble.com/std-containers-and-pointers-td3728.html

View File

@ -24,75 +24,157 @@
/**
* @file board_item.i
* @brief board_item helpers, mainly for casting down to all child classes
* @brief board_item helpers, mainly for casting down to all derived classes
*/
/* Cast downs from EDA_ITEM/BOARD_ITEM to childs */
%include class_board_item.h // generate code for this interface
// this is to help python with the * accessor of DLIST templates
%rename(Get) operator BOARD_ITEM*;
%template(BOARD_ITEM_List) DLIST<BOARD_ITEM>;
%{
#include <class_board_item.h>
%}
%inline
{
/// Cast down from EDA_ITEM/BOARD_ITEM to child
BOARD_ITEM* Cast_to_BOARD_ITEM(EDA_ITEM* base) { return dynamic_cast<BOARD_ITEM*>(base); }
}
%{
class TEXTE_PCB;
class DIMENSION;
class MODULE;
class TEXTE_MODULE;
class DRAWSEGMENT;
class MARKER_PCB;
class BOARD;
class EDGE_MODULE;
class D_PAD;
class TRACK;
class VIA;
class ZONE_CONTAINER;
class PCB_TARGET;
#ifdef __cplusplus
extern "C" {
#endif
static TEXTE_PCB* Cast_to_TEXTE_PCB( BOARD_ITEM* );
static DIMENSION* Cast_to_DIMENSION( BOARD_ITEM* );
static MODULE* Cast_to_MODULE( BOARD_ITEM* );
static TEXTE_MODULE* Cast_to_TEXTE_MODULE( BOARD_ITEM* );
static DRAWSEGMENT* Cast_to_DRAWSEGMENT( BOARD_ITEM* );
static MARKER_PCB* Cast_to_MARKER_PCB( BOARD_ITEM* );
static BOARD* Cast_to_BOARD( BOARD_ITEM* );
static EDGE_MODULE* Cast_to_EDGE_MODULE( BOARD_ITEM* );
static D_PAD* Cast_to_D_PAD( BOARD_ITEM* );
static TRACK* Cast_to_TRACK( BOARD_ITEM* );
static VIA* Cast_to_VIA( BOARD_ITEM* );
static ZONE_CONTAINER* Cast_to_ZONE_CONTAINER( BOARD_ITEM* );
static PCB_TARGET* Cast_to_PCB_TARGET( BOARD_ITEM* );
#ifdef __cplusplus
} // extern "C"
#endif
%}
static TEXTE_PCB* Cast_to_TEXTE_PCB( BOARD_ITEM* );
static DIMENSION* Cast_to_DIMENSION( BOARD_ITEM* );
static MODULE* Cast_to_MODULE( BOARD_ITEM* );
static TEXTE_MODULE* Cast_to_TEXTE_MODULE( BOARD_ITEM* );
static DRAWSEGMENT* Cast_to_DRAWSEGMENT( BOARD_ITEM* );
static MARKER_PCB* Cast_to_MARKER_PCB( BOARD_ITEM* );
static BOARD* Cast_to_BOARD( BOARD_ITEM* );
static EDGE_MODULE* Cast_to_EDGE_MODULE( BOARD_ITEM* );
static D_PAD* Cast_to_D_PAD( BOARD_ITEM* );
static TRACK* Cast_to_TRACK( BOARD_ITEM* );
static VIA* Cast_to_VIA( BOARD_ITEM* );
static ZONE_CONTAINER* Cast_to_ZONE_CONTAINER( BOARD_ITEM* );
static PCB_TARGET* Cast_to_PCB_TARGET( BOARD_ITEM* );
%extend BOARD_ITEM
{
TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast<TEXTE_PCB*>(self); }
DIMENSION* Cast_to_DIMENSION() { return dynamic_cast<DIMENSION*>(self); }
MODULE* Cast_to_MODULE() { return dynamic_cast<MODULE*>(self); }
TEXTE_MODULE* Cast_to_TEXTE_MODULE() { return dynamic_cast<TEXTE_MODULE*>(self); }
DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast<DRAWSEGMENT*>(self); }
MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast<MARKER_PCB*>(self); }
BOARD* Cast_to_BOARD() { return dynamic_cast<BOARD*>(self); }
EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast<EDGE_MODULE*>(self); }
D_PAD* Cast_to_D_PAD() { return dynamic_cast<D_PAD*>(self); }
TRACK* Cast_to_TRACK() { return dynamic_cast<TRACK*>(self); }
VIA* Cast_to_VIA() { return dynamic_cast<VIA*>(self); }
ZONE_CONTAINER* Cast_to_ZONE_CONTAINER() { return dynamic_cast<ZONE_CONTAINER*>(self);}
PCB_TARGET* Cast_to_PCB_TARGET() { return dynamic_cast<PCB_TARGET*>(self); }
%pythoncode
{
%{
def Cast(self):
ct = self.GetClass()
if ct=="PTEXT":
return self.Cast_to_TEXTE_PCB()
return Cast_to_TEXTE_PCB(self)
elif ct=="BOARD":
return self.Cast_to_BOARD()
return Cast_to_BOARD(self)
elif ct=="DIMENSION":
return self.Cast_to_DIMENSION()
return Cast_to_DIMENSION(self)
elif ct=="DRAWSEGMENT":
return self.Cast_to_DRAWSEGMENT()
return Cast_to_DRAWSEGMENT(self)
elif ct=="MGRAPHIC":
return self.Cast_to_EDGE_MODULE()
return Cast_to_EDGE_MODULE(self)
elif ct=="MODULE":
return self.Cast_to_MODULE()
return Cast_to_MODULE(self)
elif ct=="PAD":
return self.Cast_to_D_PAD()
return Cast_to_D_PAD(self)
elif ct=="MTEXT":
return self.Cast_to_TEXTE_MODULE()
return Cast_to_TEXTE_MODULE(self)
elif ct=="VIA":
return self.Cast_to_VIA()
return Cast_to_VIA(self)
elif ct=="TRACK":
return self.Cast_to_TRACK()
return Cast_to_TRACK(self)
elif ct=="PCB_TARGET":
return self.Cast_to_PCB_TARGET()
return Cast_to_PCB_TARGET(self)
elif ct=="ZONE_CONTAINER":
return self.Cast_to_ZONE_CONTAINER()
return Cast_to_ZONE_CONTAINER(self)
else:
return None
def Duplicate(self):
ct = self.GetClass()
if ct=="BOARD":
return None
else:
return Cast_to_BOARD_ITEM(self.Clone()).Cast()
}
def SetPos(self,p):
self.SetPosition(p)
self.SetPos0(p)
def SetStartEnd(self,start,end):
self.SetStart(start)
self.SetStart0(start)
self.SetEnd(end)
self.SetEnd0(end)
%}
}
// Use %wrapper code generation section so that this block of C++ comes after all referenced
// classes and therefore will C++ compile due to the respective headers which will go into
// the %header section. See section 5.6.2 of SWIG 3.0 documentation.
%wrapper %{
static TEXTE_PCB* Cast_to_TEXTE_PCB( BOARD_ITEM* self ) { return dynamic_cast<TEXTE_PCB*>(self); }
static DIMENSION* Cast_to_DIMENSION( BOARD_ITEM* self ) { return dynamic_cast<DIMENSION*>(self); }
static MODULE* Cast_to_MODULE( BOARD_ITEM* self ) { return dynamic_cast<MODULE*>(self); }
static TEXTE_MODULE* Cast_to_TEXTE_MODULE( BOARD_ITEM* self ) { return dynamic_cast<TEXTE_MODULE*>(self); }
static DRAWSEGMENT* Cast_to_DRAWSEGMENT( BOARD_ITEM* self ) { return dynamic_cast<DRAWSEGMENT*>(self); }
static MARKER_PCB* Cast_to_MARKER_PCB( BOARD_ITEM* self ) { return dynamic_cast<MARKER_PCB*>(self); }
static BOARD* Cast_to_BOARD( BOARD_ITEM* self ) { return dynamic_cast<BOARD*>(self); }
static EDGE_MODULE* Cast_to_EDGE_MODULE( BOARD_ITEM* self ) { return dynamic_cast<EDGE_MODULE*>(self); }
static D_PAD* Cast_to_D_PAD( BOARD_ITEM* self ) { return dynamic_cast<D_PAD*>(self); }
static TRACK* Cast_to_TRACK( BOARD_ITEM* self ) { return dynamic_cast<TRACK*>(self); }
static VIA* Cast_to_VIA( BOARD_ITEM* self ) { return dynamic_cast<VIA*>(self); }
static ZONE_CONTAINER* Cast_to_ZONE_CONTAINER( BOARD_ITEM* self ) { return dynamic_cast<ZONE_CONTAINER*>(self); }
static PCB_TARGET* Cast_to_PCB_TARGET( BOARD_ITEM* self ) { return dynamic_cast<PCB_TARGET*>(self); }
%}

View File

@ -0,0 +1,47 @@
// Rename Add(), Remove() and Delete() to {Add,Remove,Delete}Native() and
// then implement Add() Remove() and Delete() in python so we can manage
// the ownership flag: thisown.
%rename(AddNative) BOARD_ITEM_CONTAINER::Add;
%rename(RemoveNative) BOARD_ITEM_CONTAINER::Remove;
%rename(DeleteNative) BOARD_ITEM_CONTAINER::Delete;
%include board_item_container.h
%{
#include <board_item_container.h>
%}
%extend BOARD_ITEM_CONTAINER
{
%pythoncode
%{
def Add(self,item):
"""
Add a BOARD_ITEM to this BOARD_ITEM_CONTAINER, clear the thisown to prevent
python from deleting the object in the garbage collector
Add(BOARD_ITEM_CONTAINER self, BOARD_ITEM aItem, ADD_MODE aMode=ADD_INSERT)
Add(BOARD_ITEM_CONTAINER self, BOARD_ITEM aItem)
"""
item.thisown=0
self.AddNative(item)
def Remove(self,item):
"""
Remove a BOARD_ITEM from this BOARD_ITEM_CONTAINER, set the thisdown flag so that
the python wrapper owns the C++ BOARD_ITEM
Remove(self, BOARD_ITEM)
"""
self.RemoveNative(item)
item.thisown=1
def Delete(self,item):
"""
Remove a BOARD_ITEM from this BOARD_ITEM_CONTAINER, set the thisdown flag so that
the python wrapper does not owns the C++ BOARD_ITEM
Delete(self, BOARD_ITEM)
"""
item.thisown=0 # C++'s BOARD_ITEM_CONTAINER::Delete() will delete
self.DeleteNative(item)
item.this = None
%}
}

6
pcbnew/swig/dimension.i Normal file
View File

@ -0,0 +1,6 @@
%include class_dimension.h
%{
#include <class_dimension.h>
%}

14
pcbnew/swig/drawsegment.i Normal file
View File

@ -0,0 +1,14 @@
%include class_drawsegment.h
%extend DRAWSEGMENT
{
%pythoncode
%{
def GetShapeStr(self):
return self.ShowShape(self.GetShape())
%}
}
%{
#include <class_drawsegment.h>
%}

5
pcbnew/swig/edge_mod.i Normal file
View File

@ -0,0 +1,5 @@
%include class_edge_mod.h
%{
#include <class_edge_mod.h>
%}

6
pcbnew/swig/marker_pcb.i Normal file
View File

@ -0,0 +1,6 @@
%include class_marker_pcb.h
%{
#include <class_marker_pcb.h>
%}

6
pcbnew/swig/mire.i Normal file
View File

@ -0,0 +1,6 @@
%include class_mire.h
%{
#include <class_mire.h>
%}

View File

@ -27,11 +27,23 @@
* @brief Specific BOARD extensions and templates
*/
%import dlist.i
%include class_module.h
%rename(Get) operator MODULE*;
%template(MODULE_List) DLIST<MODULE>;
%{
#include <class_module.h>
%}
%extend MODULE
{
%pythoncode
%{
%pythoncode
%{
#def SaveToLibrary(self,filename):
# return SaveModuleToLibrary(filename,self)
@ -51,13 +63,12 @@
elif type(itemC) in [ TEXTE_PCB, DIMENSION, TEXTE_MODULE, DRAWSEGMENT,EDGE_MODULE]:
item.thisown = 0
self.GraphicalItems().PushBack(item)
%}
%}
}
%pythoncode
{
%pythoncode
%{
def GetPluginForPath(lpath):
return IO_MGR.PluginFind(IO_MGR.LEGACY)
@ -88,7 +99,7 @@
def FootprintIsWritable(lpath):
plug = GetPluginForPath(lpath)
plug.FootprintLibIsWritable(lpath)
}
%}
%{
MODULE *PyModule_to_MODULE(PyObject *obj0)
@ -106,5 +117,4 @@
return NULL;
}
%}

5
pcbnew/swig/netclass.i Normal file
View File

@ -0,0 +1,5 @@
%include class_netclass.h
%{
#include <class_netclass.h>
%}

5
pcbnew/swig/netinfo.i Normal file
View File

@ -0,0 +1,5 @@
%include class_netinfo.h
%{
#include <class_netinfo.h>
%}

10
pcbnew/swig/pad.i Normal file
View File

@ -0,0 +1,10 @@
%include pad_shapes.h
%include class_pad.h
%rename(Get) operator D_PAD*;
%template(PAD_List) DLIST<D_PAD>;
%{
#include <class_pad.h>
%}

7
pcbnew/swig/pcb_text.i Normal file
View File

@ -0,0 +1,7 @@
%include class_pcb_text.h
%{
#include <class_pcb_text.h>
%}

View File

@ -54,15 +54,6 @@ class BASE_SET {};
%ignore BASE_SET;
// rename the Add method of classes to Add native, so we will handle
// the Add method in python
%rename(AddNative) *::Add;
// fix method names conflicts
%rename(AddChild) MODULE::Add;
%rename(RemoveChild) MODULE::Remove;
%rename(DeleteChild) MODULE::Delete;
// this is what it must be included in the wrapper .cxx code to compile
@ -124,29 +115,3 @@ HANDLE_EXCEPTIONS(PLUGIN::FootprintDelete)
%include units.i
// Extend LSET by 2 methods to add or remove layers from the layer list
// Mainly used to add or remove layers of a pad layer list
%extend LSET
{
LSET addLayer( LAYER_ID aLayer) { return self->set(aLayer); }
LSET removeLayer( LAYER_ID aLayer) { return self->reset(aLayer); }
LSET addLayerSet( LSET aLayerSet) { return *self |= aLayerSet; }
LSET removeLayerSet( LSET aLayerSet) { return *self &= ~aLayerSet; }
%pythoncode
%{
def AddLayer(self, layer):
return self.addLayer( layer )
def AddLayerSet(self, layers):
return self.addLayerSet( layers )
def RemoveLayer(self, layer):
return self.removeLayer( layer )
def RemoveLayerSet(self, layers):
return self.removeLayerSet( layers )
%}
}

6
pcbnew/swig/text_mod.i Normal file
View File

@ -0,0 +1,6 @@
%include class_text_mod.h
%{
#include <class_text_mod.h>
%}

9
pcbnew/swig/track.i Normal file
View File

@ -0,0 +1,9 @@
%include class_track.h
%rename(Get) operator TRACK*;
%template(TRACK_List) DLIST<TRACK>;
%{
#include <class_track.h>
%}

9
pcbnew/swig/zone.i Normal file
View File

@ -0,0 +1,9 @@
%include class_zone.h
%include zones.h
%{
#include <class_zone.h>
#include <zones.h>
%}