Wait the debug thread has terminated before freeing PLC to avoid random segmentation fault.
Store working directory to globals copy, in order to be used in runtime.py.
import os, shutil, sys
base_folder = os.path.split(sys.path[0])[0]
sys.path.append(os.path.join(base_folder, "wxsvg", "SVGUIEditor"))
sys.path.append(os.path.join(base_folder, "plcopeneditor", "graphics"))
import wx, subprocess
from SVGUIGenerator import *
from SVGUIControler import *
from SVGUIEditor import *
from FBD_Objects import *
from PLCGenerator import PLCGenException
from wxPopen import ProcessLogger
from wx.wxsvg import SVGDocument
from docutils import *
[ID_SVGUIEDITORFBDPANEL,
] = [wx.NewId() for _init_ctrls in range(1)]
SVGUIFB_Types = {ITEM_CONTAINER : "Container",
ITEM_BUTTON : "Button",
ITEM_TEXT : "TextCtrl",
ITEM_SCROLLBAR : "ScrollBar",
ITEM_ROTATING : "RotatingCtrl",
ITEM_NOTEBOOK : "NoteBook",
ITEM_TRANSFORM : "Transform"}
class _SVGUIEditor(SVGUIEditor):
"""
This Class add IEC specific features to the SVGUIEditor :
- FDB preview
- FBD begin drag
"""
def _init_coll_EditorGridSizer_Items(self, parent):
SVGUIEditor._init_coll_EditorGridSizer_Items(self, parent)
parent.AddWindow(self.FBDPanel, 0, border=0, flag=wx.GROW)
def _init_ctrls(self, prnt):
SVGUIEditor._init_ctrls(self, prnt, False)
self.FBDPanel = wx.Panel(id=ID_SVGUIEDITORFBDPANEL,
name='FBDPanel', parent=self.EditorPanel, pos=wx.Point(0, 0),
size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
self.FBDPanel.SetBackgroundColour(wx.WHITE)
self.FBDPanel.Bind(wx.EVT_LEFT_DOWN, self.OnFBDPanelClick)
self.FBDPanel.Bind(wx.EVT_PAINT, self.OnPaintFBDPanel)
setattr(self.FBDPanel, "GetScaling", lambda: None)
setattr(self.FBDPanel, "IsOfType", self.IsOfType)
setattr(self.FBDPanel, "GetBlockType", self.GetBlockType)
self._init_sizers()
def __init__(self, parent, controler = None, fileOpen = None):
SVGUIEditor.__init__(self, parent, controler, fileOpen)
self.FBDBlock = None
def IsOfType(self, type, reference):
return self.Controler.GetPlugRoot().IsOfType(type, reference)
def GetBlockType(self, type, inputs = None):
return self.Controler.GetPlugRoot().GetBlockType(type, inputs)
def RefreshView(self, select_id = None):
SVGUIEditor.RefreshView(self, select_id)
self.FBDPanel.Refresh()
def OnPaintFBDPanel(self,event):
dc = wx.ClientDC(self.FBDPanel)
dc.Clear()
selected = self.GetSelected()
if selected is not None:
selected_type = self.Controler.GetElementType(selected)
if selected_type is not None:
self.FBDBlock = FBD_Block(parent=self.FBDPanel,type=SVGUIFB_Types[selected_type],name=self.Controler.GetElementName(selected))
width, height = self.FBDBlock.GetMinSize()
self.FBDBlock.SetSize(width,height)
clientsize = self.FBDPanel.GetClientSize()
x = (clientsize.width - width) / 2
y = (clientsize.height - height) / 2
self.FBDBlock.SetPosition(x, y)
self.FBDBlock.Draw(dc)
else:
self.FBDBlock = None
event.Skip()
def OnFBDPanelClick(self, event):
if self.FBDBlock:
data = wx.TextDataObject(str((self.FBDBlock.GetType(), "functionBlock", self.FBDBlock.GetName())))
DropSrc = wx.DropSource(self.FBDPanel)
DropSrc.SetData(data)
DropSrc.DoDragDrop()
event.Skip()
def OnInterfaceTreeItemSelected(self, event):
self.FBDPanel.Refresh()
SVGUIEditor.OnInterfaceTreeItemSelected(self, event)
def OnGenerate(self,event):
self.SaveProject()
self.Controler.PlugGenerate_C(sys.path[0],(0,0,4,5),None)
event.Skip()
TYPECONVERSION = {"BOOL" : "X", "SINT" : "B", "INT" : "W", "DINT" : "D", "LINT" : "L",
"USINT" : "B", "UINT" : "W", "UDINT" : "D", "ULINT" : "L", "REAL" : "D", "LREAL" : "L",
"STRING" : "B", "BYTE" : "B", "WORD" : "W", "DWORD" : "D", "LWORD" : "L", "WSTRING" : "W"}
CTYPECONVERSION = {"BOOL" : "IEC_BOOL", "UINT" : "IEC_UINT", "STRING" : "IEC_STRING", "REAL" : "IEC_REAL"}
CPRINTTYPECONVERSION = {"BOOL" : "d", "UINT" : "d", "STRING" : "s", "REAL" : "f"}
class RootClass(SVGUIControler):
def __init__(self):
SVGUIControler.__init__(self)
filepath = os.path.join(self.PlugPath(), "gui.xml")
if os.path.isfile(filepath):
svgfile = os.path.join(self.PlugPath(), "gui.svg")
if os.path.isfile(svgfile):
self.SvgFilepath = svgfile
self.OpenXMLFile(filepath)
else:
self.CreateNewInterface()
self.SetFilePath(filepath)
def GetElementIdFromName(self, name):
element = self.GetElementByName(name)
if element is not None:
return element.getid()
return None
_View = None
def _OpenView(self):
if not self._View:
def _onclose():
self._View = None
def _onsave():
self.GetPlugRoot().SaveProject()
self._View = _SVGUIEditor(self.GetPlugRoot().AppFrame, self)
self._View._onclose = _onclose
self._View._onsave = _onsave
self._View.Show()
def _ImportSVG(self):
if not self._View:
dialog = wx.FileDialog(self.GetPlugRoot().AppFrame, "Choose a SVG file", os.getcwd(), "", "SVG files (*.svg)|*.svg|All files|*.*", wx.OPEN)
if dialog.ShowModal() == wx.ID_OK:
svgpath = dialog.GetPath()
if os.path.isfile(svgpath):
shutil.copy(svgpath, os.path.join(self.PlugPath(), "gui.svg"))
else:
self.logger.write_error("No such SVG file: %s\n"%svgpath)
dialog.Destroy()
def _ImportXML(self):
if not self._View:
dialog = wx.FileDialog(self.GetPlugRoot().AppFrame, "Choose a XML file", os.getcwd(), "", "XML files (*.xml)|*.xml|All files|*.*", wx.OPEN)
if dialog.ShowModal() == wx.ID_OK:
xmlpath = dialog.GetPath()
if os.path.isfile(xmlpath):
shutil.copy(xmlpath, os.path.join(self.PlugPath(), "gui.xml"))
else:
self.logger.write_error("No such XML file: %s\n"%xmlpath)
dialog.Destroy()
def _StartInkscape(self):
svgfile = os.path.join(self.PlugPath(), "gui.svg")
if not os.path.isfile(svgfile):
svgfile = None
open_svg(svgfile)
PluginMethods = [
{"bitmap" : os.path.join("images","HMIEditor"),
"name" : "HMI Editor",
"tooltip" : "HMI Editor",
"method" : "_OpenView"},
{"bitmap" : os.path.join("images","ImportSVG"),
"name" : "Import SVG",
"tooltip" : "Import SVG",
"method" : "_ImportSVG"},
{"bitmap" : os.path.join("images","ImportDEF"),
"name" : "Import XML",
"tooltip" : "Import XML",
"method" : "_ImportXML"},
{"bitmap" : os.path.join("images","ImportSVG"),
"name" : "Inkscape",
"tooltip" : "Create HMI",
"method" : "_StartInkscape"},
]
def OnPlugSave(self):
self.SaveXMLFile(os.path.join(self.PlugPath(), "gui.xml"))
return True
def PlugGenerate_C(self, buildpath, locations):
progname = "SVGUI_%s"%"_".join(map(str, self.GetCurrentLocation()))
doc = SVGDocument(self.GetSVGFilePath())
root_element = doc.GetRootElement()
window_size = (int(float(root_element.GetAttribute("width"))),
int(float(root_element.GetAttribute("height"))))
# svgfilepath = self.GetSVGFilePath()
# xmlfilepath = self.GetFilePath()
# shutil.copy(svgfilepath, buildpath)
# shutil.copy(xmlfilepath, buildpath)
SVGFilePath = self.GetSVGFilePath()
SVGFileBaseName = os.path.split(SVGFilePath)[1]
FilePath = self.GetFilePath()
FileBaseName = os.path.split(FilePath)[1]
generator = _SVGUICGenerator(self, self.GetElementsByType(),
os.path.split(self.GetSVGFilePath())[1],
os.path.split(self.GetFilePath())[1],
self.GetCurrentLocation())
generator.GenerateProgram(window_size, buildpath, progname)
Gen_C_file = os.path.join(buildpath, progname+".cpp" )
if wx.Platform == '__WXMSW__':
cxx_flags = "-I..\\lib\\wx\\include\\msw-unicode-release-2.8 -I..\\include\\wx-2.8 -I..\\..\\matiec\\lib -DWXUSINGDLL -D__WXMSW__ -mthreads"
libs = "\"..\\lib\\libwxsvg.a\" \"..\\lib\\libwxsvg_agg.a\" \"..\\lib\\libagg.a\" \"..\\lib\\libaggplatformwin32.a\" \"..\\lib\\libaggfontwin32tt.a\" -L..\\lib -mwindows -mthreads -Wl,--subsystem,windows -mwindows -lwx_mswu_richtext-2.8 -lwx_mswu_aui-2.8 -lwx_mswu_xrc-2.8 -lwx_mswu_qa-2.8 -lwx_mswu_html-2.8 -lwx_mswu_adv-2.8 -lwx_mswu_core-2.8 -lwx_baseu_xml-2.8 -lwx_baseu_net-2.8 -lwx_baseu-2.8"
else:
status, result, err_result = ProcessLogger(self.logger, "wx-config --cxxflags", no_stdout=True).spin()
if status:
self.logger.write_error("Unable to get wx cxxflags\n")
cxx_flags = result.strip() + " -I../matiec/lib"
status, result, err_result = ProcessLogger(self.logger, "wx-config --libs", no_stdout=True).spin()
if status:
self.logger.write_error("Unable to get wx libs\n")
libs = result.strip() + " -lwxsvg"
return [(Gen_C_file, cxx_flags)],libs,True,(SVGFileBaseName, file(SVGFilePath, "rb")), (FileBaseName, file(FilePath, "rb"))
def BlockTypesFactory(self):
SVGUIBlock_Types = []
def GetSVGUIBlockType(type):
for category in SVGUIBlock_Types:
for blocktype in category["list"]:
if blocktype["name"] == type:
return blocktype
setattr(self, "GetSVGUIBlockType", GetSVGUIBlockType)
def generate_svgui_block(generator, block, body, link, order=False):
name = block.getinstanceName()
block_id = self.GetElementIdFromName(name)
if block_id == None:
raise PLCGenException, "Undefined SVGUI Block \"%s\""%name
type = block.gettypeName()
block_infos = GetSVGUIBlockType(type)
current_location = ".".join(map(str, self.GetCurrentLocation()))
if not generator.ComputedBlocks.get(block, False) and not order:
generator.ComputedBlocks[block] = True
for num, variable in enumerate(block.inputVariables.getvariable()):
connections = variable.connectionPointIn.getconnections()
if connections is not None:
input_info = (generator.TagName, "block", block.getlocalId(), "input", num)
parameter = "%sQ%s%s.%d.%d"%("%", TYPECONVERSION[block_infos["inputs"][num][1]], current_location, block_id, num+1)
value = generator.ComputeExpression(body, connections)
generator.Program += [(generator.CurrentIndent, ()),
(parameter, input_info),
(" := ", ())]
generator.Program += generator.ExtractModifier(variable, value, input_info)
generator.Program += [(";\n", ())]
if link:
connectionPoint = link.getposition()[-1]
for num, variable in enumerate(block.outputVariables.getvariable()):
blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY()
output_info = (generator.TagName, "block", block.getlocalId(), "output", num)
parameter = "%sI%s%s.%d.%d"%("%", TYPECONVERSION[block_infos["outputs"][num][1]], current_location, block_id, num+1)
if block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety():
return generator.ExtractModifier(variable, [(parameter, output_info)], output_info)
raise PLCGenException, "No corresponding output variable found on SVGUI Block \"%s\""%name
else:
return None
def initialise_block(type, name, block = None):
block_id = self.GetElementIdFromName(name)
if block_id == None:
raise PLCGenException, "Undefined SVGUI Block \"%s\""%name
block_infos = GetSVGUIBlockType(type)
current_location = ".".join(map(str, self.GetCurrentLocation()))
variables = []
if block is not None:
input_variables = block.inputVariables.getvariable()
output_variables = block.outputVariables.getvariable()
else:
input_variables = None
output_variables = None
for num, (input_name, input_type, input_modifier) in enumerate(block_infos["inputs"]):
if input_variables is not None and num < len(input_variables):
connections = input_variables[num].connectionPointIn.getconnections()
if input_variables is None or connections and len(connections) == 1:
variables.append((input_type, None, "%sQ%s%s.%d.%d"%("%", TYPECONVERSION[input_type], current_location, block_id, num+1), None))
for num, (output_name, output_type, output_modifier) in enumerate(block_infos["outputs"]):
variables.append((output_type, None, "%sI%s%s.%d.%d"%("%", TYPECONVERSION[input_type], current_location, block_id, num+1), None))
return variables
SVGUIBlock_Types.extend([{"name" : "SVGUI function blocks", "list" :
[{"name" : "Container", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none")],
"outputs" : [],
"comment" : "SVGUI Container",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "Button", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("Value","BOOL","none")],
"outputs" : [("State","BOOL","none")],
"comment" : "SVGUI Button",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "TextCtrl", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetText","STRING","none")],
"outputs" : [("Text","STRING","none")],
"comment" : "SVGUI Text Control",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "ScrollBar", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetThumb","UINT","none"),("SetRange","UINT","none"),("SetPosition","UINT","none")],
"outputs" : [("Position","UINT","none")],
"comment" : "SVGUI ScrollBar",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "NoteBook", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetSelected","BOOL","none")],
"outputs" : [("Selected","UINT","none")],
"comment" : "SVGUI Notebook",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "RotatingCtrl", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetAngle","REAL","none")],
"outputs" : [("Angle","REAL","none")],
"comment" : "SVGUI Rotating Control",
"generate" : generate_svgui_block, "initialise" : initialise_block},
{"name" : "Transform", "type" : "functionBlock", "extensible" : False,
"inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetX","REAL","none"),("SetY","REAL","none"),("SetXScale","REAL","none"),("SetYScale","REAL","none"),("SetAngle","REAL","none")],
"outputs" : [("X","REAL","none"),("Y","REAL","none")],
"comment" : "SVGUI Transform",
"generate" : generate_svgui_block, "initialise" : initialise_block},
]}
])
return SVGUIBlock_Types
class _SVGUICGenerator(SVGUICGenerator):
def __init__(self, controler, elements, svgfile, xmlfile, current_location):
SVGUICGenerator.__init__(self, elements, svgfile, xmlfile)
self.CurrentLocation = current_location
self.Controler = controler
def GenerateProgramHeadersPublicVars(self):
text = """
void OnPlcOutEvent(wxEvent& event);
void Retrieve();
void Publish();
void Initialize();
"""
# text += " void Print();\n"
return text
def GenerateIECVars(self):
text = ""
for element in self.Elements:
text += "STATE_TYPE out_state_%d;\n"%element.getid()
text += "STATE_TYPE in_state_%d;\n"%element.getid()
text +="\n"
current_location = "_".join(map(str, self.CurrentLocation))
#Declaration des variables
for element in self.Elements:
block_infos = self.Controler.GetSVGUIBlockType(SVGUIFB_Types[GetElementType(element)])
block_id = element.getid()
for i, input in enumerate(block_infos["inputs"]):
element_c_type = CTYPECONVERSION[input[1]]
variable = "__Q%s%s_%d_%d"%(TYPECONVERSION[input[1]], current_location, block_id, i + 1)
text += "%s beremiz%s;\n"%(element_c_type, variable)
text += "%s* %s = &beremiz%s;\n"%(element_c_type, variable, variable)
text += "%s _copy%s;\n"%(element_c_type, variable)
for i, output in enumerate(block_infos["outputs"]):
element_c_type = CTYPECONVERSION[output[1]]
variable = "__I%s%s_%d_%d"%(TYPECONVERSION[output[1]], current_location, block_id, i + 1)
text += "%s beremiz%s;\n"%(element_c_type, variable)
text += "%s* %s = &beremiz%s;\n"%(element_c_type, variable, variable)
text += "%s _copy%s;\n"%(element_c_type, variable)
text +="\n"
return text
def GenerateGlobalVarsAndFuncs(self, size):
text = """#include "iec_types.h"
#ifdef __WXMSW__
#define COMPARE_AND_SWAP_VAL(Destination, comparand, exchange) InterlockedCompareExchange(Destination, exchange, comparand)
#define THREAD_RETURN_TYPE DWORD WINAPI
#define STATE_TYPE long int
#else
#define COMPARE_AND_SWAP_VAL(Destination, comparand, exchange) __sync_val_compare_and_swap(Destination, comparand, exchange)
#define THREAD_RETURN_TYPE void*
#define STATE_TYPE volatile int
#endif
"""
text += self.GenerateIECVars()
text += """IMPLEMENT_APP_NO_MAIN(SVGViewApp);
SVGViewApp *myapp = NULL;
wxSemaphore MyInitSem;
#ifdef __WXMSW__
HANDLE wxMainLoop;
DWORD wxMainLoopId;
#else
pthread_t wxMainLoop;
#endif
"""
text += """int myargc = 0;
char** myargv = NULL;
#define UNCHANGED 1
#define PLC_BUSY 2
#define CHANGED 3
#define GUI_BUSY 4
#ifdef __WXMSW__
#else
#endif
bool refresh = false;
bool refreshing = false;
THREAD_RETURN_TYPE InitWxEntry(void* args)
{
wxEntry(myargc,myargv);
myapp = NULL;
MyInitSem.Post();
return 0;
}
"""
text += """
bool SVGViewApp::OnInit()
{
#ifndef __WXMSW__
setlocale(LC_NUMERIC, "C");
#endif
"""
text += """ frame = new MainFrame(NULL, wxT("Program"),wxDefaultPosition, wxSize(%d, %d));
frame->Show();
myapp = this;
"""%size
text += """ return true;
}
extern "C" {
int __init_%(location)s(int argc, char** argv)
{
myargc = argc;
myargv = argv;
#ifdef __WXMSW__
wxMainLoop = CreateThread(NULL, 0, InitWxEntry, 0, 0, &wxMainLoopId);
#else
pthread_create(&wxMainLoop, NULL, InitWxEntry, NULL);
#endif
MyInitSem.Wait();
return 0;
}
void __cleanup_%(location)s()
{
if(myapp){
wxCloseEvent event(wxEVT_CLOSE_WINDOW);
myapp->frame->AddPendingEvent(event);
myapp = NULL;
}
MyInitSem.Wait();
}
void __retrieve_%(location)s()
{
if(myapp){
myapp->frame->m_svgCtrl->Retrieve();
}
}
void __publish_%(location)s()
{
if(myapp){
myapp->frame->m_svgCtrl->Publish();
}
}
}
IEC_STRING wxStringToIEC_STRING(wxString s)
{
IEC_STRING res = {0,""};
int i;
for(i = 0; i<s.Length() && i<STR_MAX_LEN; i++)
res.body[i] = s.GetChar(i);
res.len = i;
return res;
}
"""%{"location" : "_".join(map(str, self.CurrentLocation))}
return text
def GenerateProgramEventTable(self):
text = """BEGIN_DECLARE_EVENT_TYPES()
DECLARE_LOCAL_EVENT_TYPE( EVT_PLC, wxNewEventType() )
END_DECLARE_EVENT_TYPES()
DEFINE_LOCAL_EVENT_TYPE( EVT_PLC )
"""
#Event Table Declaration
text += "BEGIN_EVENT_TABLE(Program, SVGUIWindow)\n"
for element in self.Elements:
element_type = GetElementType(element)
element_name = element.getname()
if element_type == ITEM_BUTTON:
text += " EVT_BUTTON (SVGUIID(\"%s\"), Program::On%sClick)\n"%(element_name, element_name)
elif element_type in [ITEM_SCROLLBAR, ITEM_ROTATING, ITEM_TRANSFORM]:
text += " EVT_COMMAND_SCROLL_THUMBTRACK (SVGUIID(\"%s\"), Program::On%sChanging)\n"%(element_name, element_name)
elif element_type == ITEM_NOTEBOOK:
text += " EVT_NOTEBOOK_PAGE_CHANGED (SVGUIID(\"%s\"), Program::On%sTabChanged)\n"%(element_name, element_name)
text += " EVT_CUSTOM(EVT_PLC, wxID_ANY, Program::OnPlcOutEvent)\n"
text += "END_EVENT_TABLE()\n\n"
return text
def GenerateProgramInitFrame(self):
text = """MainFrame::MainFrame(wxWindow *parent, const wxString& title, const wxPoint& pos,const wxSize& size, long style): wxFrame(parent, wxID_ANY, title, pos, size, style)
{
wxFileName svgfilepath(wxTheApp->argv[1], wxT("%s"));
wxFileName xmlfilepath(wxTheApp->argv[1], wxT("%s"));
m_svgCtrl = new Program(this);
if (m_svgCtrl->LoadFiles(svgfilepath.GetFullPath(), xmlfilepath.GetFullPath()))
{
Show(true);
m_svgCtrl->SetFocus();
m_svgCtrl->SetFitToFrame(true);
m_svgCtrl->InitScrollBars();
m_svgCtrl->Initialize();
m_svgCtrl->Update();
}
else
{
printf("Error while opening SVGUI files\\n");
}
}
"""%(self.SVGFilePath, self.XMLFilePath)
return text
def GenerateProgramInitProgram(self):
text = "Program::Program(wxWindow* parent):SVGUIWindow(parent)\n{\n"
for element in self.Elements:
text += " out_state_%d = UNCHANGED;\n"%element.getid()
text += " in_state_%d = UNCHANGED;\n"%element.getid()
text += "}\n\n"
return text
def GenerateProgramEventFunctions(self):
text = ""
current_location = "_".join(map(str, self.CurrentLocation))
for element in self.Elements:
element_type = GetElementType(element)
element_lock = """
if (COMPARE_AND_SWAP_VAL(&in_state_%d, CHANGED, GUI_BUSY) == CHANGED ||
COMPARE_AND_SWAP_VAL(&in_state_%d, UNCHANGED, GUI_BUSY) == UNCHANGED) {
"""%(element.getid(), element.getid())
element_unlock = """
COMPARE_AND_SWAP_VAL(&in_state_%d, GUI_BUSY, CHANGED);
event.Skip();
}else{
/* re post event for idle */
AddPendingEvent(event);
}
}
"""%element.getid()
element_name = element.getname()
if element_type == ITEM_BUTTON:
text += """void Program::On%sClick(wxCommandEvent& event)
{
SVGUIButton* button = (SVGUIButton*)GetElementByName(wxT("%s"));\n"""%(element_name, element_name)
text += element_lock
text += " _copy__IX%s_%d_1 = button->GetToggle();\n"%(current_location, element.getid())
text += element_unlock
elif element_type == ITEM_ROTATING:
text += """void Program::On%sChanging(wxScrollEvent& event)
{
SVGUIRotatingCtrl* rotating = (SVGUIRotatingCtrl*)GetElementByName(wxT("%s"));
"""%(element_name, element_name)
text += element_lock
text += " _copy__ID%s_%d_1 = rotating->GetAngle();\n"%(current_location, element.getid())
text += element_unlock
elif element_type == ITEM_NOTEBOOK:
text += """void Program::On%sTabChanged(wxNotebookEvent& event)
{
SVGUINoteBook* notebook = (SVGUINoteBook*)GetElementByName(wxT("%s"));
"""%(element_name, element_name)
text += element_lock
text += " _copy__IB%s_%d_1 = notebook->GetCurrentPage();\n"%(current_location, element.getid())
text += element_unlock
elif element_type == ITEM_TRANSFORM:
text += """void Program::On%sChanging(wxScrollEvent& event)
{
SVGUITransform* transform = (SVGUITransform*)GetElementByName(wxT("%s"));
"""%(element_name, element_name)
text += element_lock
text += " _copy__ID%s_%d_1 = transform->GetX();\n"%(current_location, element.getid())
text += " _copy__ID%s_%d_2 = transform->GetY();\n"%(current_location, element.getid())
text += element_unlock
text += "/* OnPlcOutEvent update GUI with provided IEC __Q* PLC output variables */\n"
text += """void Program::OnPlcOutEvent(wxEvent& event)
{
SVGUIElement* element;
refreshing = true;
"""
for element in self.Elements:
element_type = GetElementType(element)
texts = {"location" : current_location, "id" : element.getid()}
text += """ if (COMPARE_AND_SWAP_VAL(&out_state_%(id)d, CHANGED, GUI_BUSY) == CHANGED)
{
element = (SVGUIElement*)GetElementById(wxT("%(id)d"));
if (_copy__QX%(location)s_%(id)d_1 != element->IsVisible()) {
if (_copy__QX%(location)s_%(id)d_1)
element->Show();
else
element->Hide();
}
if (_copy__QX%(location)s_%(id)d_2 != element->IsEnabled()) {
if (_copy__QX%(location)s_%(id)d_2)
element->Enable();
else
element->Disable();
}
"""%texts
if element_type == ITEM_BUTTON:
text += """ if (_copy__QX%(location)s_%(id)d_3 != ((SVGUIButton*)element)->GetToggle())
((SVGUIButton*)element)->SetToggle(_copy__QX%(location)s_%(id)d_3);
"""%texts
elif element_type == ITEM_TEXT:
text += """ if (((SVGUITextCtrl*)element)->GetValue().compare(_copy__QX%(location)s_%(id)d_3))
{
wxString str = wxString::FromAscii(_copy__QB%(location)s_%(id)d_3);
((SVGUITextCtrl*)element)->SetText(str);
}
"""%texts
elif element_type == ITEM_SCROLLBAR:
text += """ if (_copy__QW%(location)s_%(id)d_3 != ((SVGUIScrollBar*)element)->GetThumbPosition() ||
_copy__QW%(location)s_%(id)d_4 != ((SVGUIScrollBar*)element)->GetThumbSize() ||
_copy__QW%(location)s_%(id)d_5 != ((SVGUIScrollBar*)element)->GetRange())
((SVGUIScrollBar*)element)->Init_ScrollBar(_copy__QW%(location)s_%(id)d_3, _copy__QW%(location)s_%(id)d_4, _copy__QW%(location)s_%(id)d_5);
"""%texts
elif element_type == ITEM_ROTATING:
text += """ if (_copy__QD%(location)s_%(id)d_3 != ((SVGUIRotatingCtrl*)element)->GetAngle())
((SVGUIRotatingCtrl*)element)->SetAngle(_copy__QD%(location)s_%(id)d_3);
"""%texts
elif element_type == ITEM_NOTEBOOK:
text += """ if (_copy__QB%(location)s_%(id)d_3 != ((SVGUINoteBook*)element)->GetCurrentPage())
((SVGUINoteBook*)element)->SetCurrentPage(_copy__QB%(location)s_%(id)d_3);
"""%texts
elif element_type == ITEM_TRANSFORM:
text += """ if (_copy__QD%(location)s_%(id)d_3 != ((SVGUITransform*)element)->GetX() ||
_copy__QD%(location)s_%(id)d_4 != ((SVGUITransform*)element)->GetY())
((SVGUITransform*)element)->Move(_copy__QD%(location)s_%(id)d_3, _copy__QD%(location)s_%(id)d_4);
if (_copy__QD%(location)s_%(id)d_5 != ((SVGUITransform*)element)->GetXScale() ||
_copy__QD%(location)s_%(id)d_6 != ((SVGUITransform*)element)->GetYScale())
((SVGUITransform*)element)->Scale(_copy__QD%(location)s_%(id)d_5, _copy__QD%(location)s_%(id)d_6);
if (_copy__QD%(location)s_%(id)d_7 != ((SVGUITransform*)element)->GetAngle())
((SVGUITransform*)element)->Rotate(_copy__QD%(location)s_%(id)d_7);
"""%texts
text += " COMPARE_AND_SWAP_VAL(&out_state_%(id)d, GUI_BUSY, UNCHANGED);\n }\n"%texts
text += """
refreshing = false;
event.Skip();
}
"""
return text
def GenerateProgramPrivateFunctions(self):
current_location = "_".join(map(str, self.CurrentLocation))
text = "void Program::Retrieve()\n{\n"
for element in self.Elements:
element_type = GetElementType(element)
texts = {"location" : current_location, "id" : element.getid()}
block_infos = self.Controler.GetSVGUIBlockType(SVGUIFB_Types[GetElementType(element)])
if len(block_infos["outputs"]) > 0:
text += """ if (COMPARE_AND_SWAP_VAL(&in_state_%(id)d, CHANGED, PLC_BUSY) == CHANGED) {
"""%texts
for i, output in enumerate(block_infos["outputs"]):
texts["type"] = TYPECONVERSION[output[1]]
texts["pin"] = i + 1
variable = "__I%(type)s%(location)s_%(id)d_%(pin)d"%texts
text +=" beremiz%s = _copy%s;\n"%(variable, variable)
text += """ COMPARE_AND_SWAP_VAL(&in_state_%(id)d, PLC_BUSY, UNCHANGED);
}
"""%texts
text += "}\n\n"
text += "void Program::Publish()\n{\n STATE_TYPE new_state;\n\n"
for element in self.Elements:
element_type = GetElementType(element)
texts = {"location" : current_location, "id" : element.getid()}
block_infos = self.Controler.GetSVGUIBlockType(SVGUIFB_Types[GetElementType(element)])
text += """ if ((new_state = COMPARE_AND_SWAP_VAL(&out_state_%(id)d, UNCHANGED, PLC_BUSY)) == UNCHANGED ||
(new_state = COMPARE_AND_SWAP_VAL(&out_state_%(id)d, CHANGED, PLC_BUSY)) == CHANGED) {
"""%texts
for i, input in enumerate(block_infos["inputs"]):
texts["type"] = TYPECONVERSION[input[1]]
texts["pin"] = i + 1
variable = "__Q%(type)s%(location)s_%(id)d_%(pin)d"%texts
text += " if (_copy%s != beremiz%s) {\n"%(variable, variable)
text += " _copy%s = beremiz%s;\n"%(variable, variable)
text += " new_state = CHANGED;\n }\n"%texts
text += """ COMPARE_AND_SWAP_VAL(&out_state_%(id)d, PLC_BUSY, new_state);
refresh |= new_state == CHANGED;
}
"""%texts
text += """ /* Replace this with determinist signal if called from RT */
if (refresh && !refreshing) {
wxCommandEvent event( EVT_PLC );
AddPendingEvent(event);
refresh = false;
}
};
"""
text += """void Program::Initialize()
{
SVGUIElement* element;
"""
for element in self.Elements:
element_type = GetElementType(element)
texts = {"location" : current_location, "id" : element.getid()}
text += """
element = (SVGUIElement*)GetElementById(wxT("%(id)d"));
beremiz__QX%(location)s_%(id)d_1 = _copy__QX%(location)s_%(id)d_1 = element->IsVisible();
beremiz__QX%(location)s_%(id)d_2 = _copy__QX%(location)s_%(id)d_2 = element->IsEnabled();
"""%texts
if element_type == ITEM_BUTTON:
text += " beremiz__QX%(location)s_%(id)d_3 = _copy__QX%(location)s_%(id)d_3 = ((SVGUIButton*)element)->GetToggle();\n"%texts
text += " beremiz__IX%(location)s_%(id)d_1 = _copy__IX%(location)s_%(id)d_1 = ((SVGUIButton*)element)->GetToggle();\n"%texts
elif element_type == ITEM_TEXT:
text += " beremiz__QB%(location)s_%(id)d_3 = _copy__QB%(location)s_%(id)d_3 = ((SVGUITextCtrl*)element)->GetValue();\n"%texts
text += " beremiz__IB%(location)s_%(id)d_1 = _copy__IB%(location)s_%(id)d_1 = ((SVGUITextCtrl*)element)->GetValue();\n"%texts
elif element_type == ITEM_SCROLLBAR:
text += " beremiz__QW%(location)s_%(id)d_3 = _copy__QW%(location)s_%(id)d_3 = ((SVGUIScrollBar*)element)->GetThumbSize();\n"%texts
text += " beremiz__QW%(location)s_%(id)d_4 = _copy__QW%(location)s_%(id)d_4 = ((SVGUIScrollBar*)element)->GetRange();\n"%texts
text += " beremiz__QW%(location)s_%(id)d_5 = _copy__QW%(location)s_%(id)d_5 = ((SVGUIScrollBar*)element)->GetThumbPosition();\n"%texts
text += " beremiz__IW%(location)s_%(id)d_1 = _copy__IW%(location)s_%(id)d_1 = ((SVGUIScrollBar*)element)->GetThumbPosition();\n"%texts
elif element_type == ITEM_ROTATING:
text += " beremiz__QD%(location)s_%(id)d_3 = _copy__QD%(location)s_%(id)d_3 = ((SVGUIRotatingCtrl*)element)->GetAngle();\n"%texts
text += " beremiz__ID%(location)s_%(id)d_1 = _copy__ID%(location)s_%(id)d_1 = ((SVGUIRotatingCtrl*)element)->GetAngle();\n"%texts
elif element_type == ITEM_NOTEBOOK:
text += " beremiz__QB%(location)s_%(id)d_3 = _copy__QB%(location)s_%(id)d_3 = ((SVGUINoteBook*)element)->GetCurrentPage();\n"%texts
text += " beremiz__IB%(location)s_%(id)d_1 = _copy__IB%(location)s_%(id)d_1 = ((SVGUINoteBook*)element)->GetCurrentPage();\n"%texts
elif element_type == ITEM_TRANSFORM:
text += " beremiz__QD%(location)s_%(id)d_3 = _copy__QD%(location)s_%(id)d_3 = ((SVGUITransform*)element)->GetX();\n"%texts
text += " beremiz__QD%(location)s_%(id)d_4 = _copy__QD%(location)s_%(id)d_4 = ((SVGUITransform*)element)->GetY();\n"%texts
text += " beremiz__QD%(location)s_%(id)d_5 = _copy__QD%(location)s_%(id)d_5 = ((SVGUITransform*)element)->GetXScale();\n"%texts
text += " beremiz__QD%(location)s_%(id)d_6 = _copy__QD%(location)s_%(id)d_6 = ((SVGUITransform*)element)->GetYScale();\n"%texts
text += " beremiz__QD%(location)s_%(id)d_7 = _copy__QD%(location)s_%(id)d_7 = ((SVGUITransform*)element)->GetAngle();\n"%texts
text += " beremiz__ID%(location)s_%(id)d_1 = _copy__ID%(location)s_%(id)d_1 = ((SVGUITransform*)element)->GetX();\n"%texts
text += " beremiz__ID%(location)s_%(id)d_2 = _copy__ID%(location)s_%(id)d_2 = ((SVGUITransform*)element)->GetY();\n"%texts
text += "\n MyInitSem.Post();\n}\n\n"
return text