plugins/svgui/svgui.py
changeset 147 ccc5e683583d
parent 142 371284c1ad94
child 158 771578d7580e
equal deleted inserted replaced
146:ad2d8431104e 147:ccc5e683583d
     3 sys.path.append(os.path.join(base_folder, "wxsvg", "SVGUIEditor"))
     3 sys.path.append(os.path.join(base_folder, "wxsvg", "SVGUIEditor"))
     4 sys.path.append(os.path.join(base_folder, "plcopeneditor", "graphics"))
     4 sys.path.append(os.path.join(base_folder, "plcopeneditor", "graphics"))
     5 
     5 
     6 import wx
     6 import wx
     7 
     7 
       
     8 from SVGUIGenerator import *
     8 from SVGUIControler import *
     9 from SVGUIControler import *
     9 from SVGUIEditor import *
    10 from SVGUIEditor import *
    10 from FBD_Objects import *
    11 from FBD_Objects import *
    11 
    12 
    12 from wxPopen import ProcessLogger
    13 from wxPopen import ProcessLogger
   171     
   172     
   172     def OnPlugSave(self):
   173     def OnPlugSave(self):
   173         self.SaveXMLFile()
   174         self.SaveXMLFile()
   174         return True
   175         return True
   175     
   176     
   176     def GenerateProgramHeadersPublicVars(self, elements):
       
   177         text = """    void OnPlcOutEvent(wxEvent& event);
       
   178 
       
   179     void Retrieve();
       
   180     void Publish();
       
   181     void Initialize();
       
   182 """
       
   183 #        text += "    void Print();\n"
       
   184         return text
       
   185     
       
   186     def GenerateIECVars(self, elements):
       
   187         text = ""
       
   188         for element in elements:
       
   189             text += "volatile int out_state_%d;\n"%element.getid()
       
   190             text += "volatile int in_state_%d;\n"%element.getid()
       
   191         text +="\n"
       
   192         current_location = "_".join(map(str, self.GetCurrentLocation()))
       
   193         #Declaration des variables
       
   194         for element in elements:
       
   195             block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)])
       
   196             block_id = element.getid()
       
   197             for i, input in enumerate(block_infos["inputs"]):
       
   198                 element_c_type = CTYPECONVERSION[input[1]]
       
   199                 variable = "__Q%s%s_%d_%d"%(TYPECONVERSION[input[1]], current_location, block_id, i + 1)
       
   200                 text += "%s %s;\n"%(element_c_type, variable)
       
   201                 text += "%s _copy%s;\n"%(element_c_type, variable)
       
   202             for i, output in enumerate(block_infos["outputs"]):
       
   203                 element_c_type = CTYPECONVERSION[output[1]]
       
   204                 variable = "__I%s%s_%d_%d"%(TYPECONVERSION[output[1]], current_location, block_id, i + 1)
       
   205                 text += "%s %s;\n"%(element_c_type, variable)
       
   206                 text += "%s _copy%s;\n"%(element_c_type, variable)
       
   207             text +="\n"
       
   208         return text
       
   209     
       
   210     def GenerateGlobalVarsAndFuncs(self, elements, size):
       
   211         text = "#include \"iec_types.h\"\n\n"
       
   212         
       
   213         text += self.GenerateIECVars(elements)
       
   214         
       
   215         text += """IMPLEMENT_APP_NO_MAIN(SVGViewApp);
       
   216 IMPLEMENT_WX_THEME_SUPPORT;
       
   217 SVGViewApp *myapp = NULL;
       
   218 pthread_t wxMainLoop;
       
   219 """
       
   220 #        text += "pthread_t wxMainLoop,automate;\n"
       
   221         text += """int myargc = 0;
       
   222 char** myargv = NULL;
       
   223         
       
   224 #define UNCHANGED 1
       
   225 #define PLC_BUSY 2
       
   226 #define CHANGED 3
       
   227 #define GUI_BUSY 4
       
   228 
       
   229 bool refreshing = false;
       
   230 
       
   231 void* InitWxEntry(void* args)
       
   232 {
       
   233   wxEntry(myargc,myargv);
       
   234   return args;
       
   235 }
       
   236 
       
   237 """
       
   238 #        text += """void* SimulAutomate(void* args)
       
   239 #{
       
   240 #  while(1){
       
   241 #    myapp->frame->m_svgCtrl->IN_"+self.BusNumber+"();
       
   242 #    //printf(\"AUTOMATE\\n\");
       
   243 #    myapp->frame->m_svgCtrl->OUT_"+self.BusNumber+"();
       
   244 #    sleep(1);
       
   245 #  }
       
   246 #  return args;
       
   247 #}
       
   248 #
       
   249 #"""
       
   250       
       
   251         text += """bool SVGViewApp::OnInit()
       
   252 {
       
   253   #ifndef __WXMSW__
       
   254     setlocale(LC_NUMERIC, "C");
       
   255   #endif
       
   256 """
       
   257         #text += "  frame = new MainFrame(NULL, wxT(\"Program\"),wxDefaultPosition, wxSize(%d, %d));\n"%size
       
   258         text += """  frame = new MainFrame(NULL, wxT("Program"),wxDefaultPosition, wxDefaultSize);
       
   259   myapp = this;
       
   260 """
       
   261 #        text += "  pthread_create(&automate, NULL, SimulAutomate, NULL);\n"
       
   262         text += """  return true;
       
   263 }
       
   264 
       
   265 extern "C" {
       
   266 
       
   267 int __init_%(location)s(int argc, char** argv)
       
   268 {
       
   269   myargc = argc;
       
   270   myargv = argv;
       
   271   pthread_create(&wxMainLoop, NULL, InitWxEntry, NULL);
       
   272 }
       
   273 
       
   274 void __cleanup_%(location)s()
       
   275 {
       
   276 }
       
   277 
       
   278 void __retrieve_%(location)s()
       
   279 {
       
   280   if(myapp){
       
   281     myapp->frame->m_svgCtrl->Retrieve();
       
   282   }        
       
   283 }
       
   284 
       
   285 void __publish_%(location)s()
       
   286 {
       
   287   if(myapp){
       
   288     myapp->frame->m_svgCtrl->Publish();
       
   289   }
       
   290 }
       
   291 
       
   292 }
       
   293 
       
   294 IEC_STRING wxStringToIEC_STRING(wxString s)
       
   295 {
       
   296   IEC_STRING res = {0,""};
       
   297   int i;
       
   298   for(i = 0; i<s.Length() && i<STR_MAX_LEN; i++)
       
   299     res.body[i] = s.GetChar(i);
       
   300   res.len = i;
       
   301   return res;
       
   302 }
       
   303 
       
   304 """%{"location" : "_".join(map(str, self.GetCurrentLocation()))}
       
   305         
       
   306         return text
       
   307     
       
   308     def GenerateProgramEventTable(self, elements):
       
   309         text = ""        
       
   310         #text += "wxEVT_PLCOUT = wxNewEventType();\n\n";
       
   311         
       
   312         text += """BEGIN_DECLARE_EVENT_TYPES()
       
   313 DECLARE_LOCAL_EVENT_TYPE( EVT_PLC, wxNewEventType() )
       
   314 END_DECLARE_EVENT_TYPES()
       
   315          
       
   316 DEFINE_LOCAL_EVENT_TYPE( EVT_PLC )
       
   317 
       
   318 """     
       
   319         #Event Table Declaration
       
   320         text += "BEGIN_EVENT_TABLE(Program, SVGUIWindow)\n"
       
   321         for element in elements:
       
   322             element_type = GetElementType(element)
       
   323             element_name = element.getname()
       
   324             if element_type == ITEM_BUTTON:
       
   325                 text += "  EVT_BUTTON (SVGUIID(\"%s\"), Program::On%sClick)\n"%(element_name, element_name)
       
   326             elif element_type in [ITEM_SCROLLBAR, ITEM_ROTATING, ITEM_TRANSFORM]:
       
   327                 text += "  EVT_COMMAND_SCROLL_THUMBTRACK (SVGUIID(\"%s\"), Program::On%sChanging)\n"%(element_name, element_name)
       
   328             elif element_type == ITEM_NOTEBOOK:
       
   329                 text += "  EVT_NOTEBOOK_PAGE_CHANGED (SVGUIID(\"%s\"), Program::On%sTabChanged)\n"%(element_name, element_name)
       
   330         text += "  EVT_CUSTOM(EVT_PLC, wxID_ANY, Program::OnPlcOutEvent)\n"
       
   331         text += "END_EVENT_TABLE()\n\n"
       
   332         return text
       
   333     
       
   334     def GenerateProgramInitFrame(self, elements):
       
   335         text = """MainFrame::MainFrame(wxWindow *parent, const wxString& title, const wxPoint& pos,const wxSize& size, long style): wxFrame(parent, wxID_ANY, title, pos, size, style)
       
   336 {
       
   337   m_svgCtrl = new Program(this);
       
   338   if (m_svgCtrl->LoadFiles(wxT("%s"), wxT("%s")))
       
   339   {
       
   340     Show(true);
       
   341     m_svgCtrl->SetFocus();
       
   342     m_svgCtrl->SetFitToFrame(true);
       
   343     m_svgCtrl->RefreshScale();
       
   344     m_svgCtrl->InitScrollBars();
       
   345     m_svgCtrl->Initialize();
       
   346     m_svgCtrl->Update();
       
   347   }
       
   348   else
       
   349   {
       
   350     printf("Error while opening files\\n");
       
   351     exit(0);
       
   352   }
       
   353 }
       
   354 
       
   355 
       
   356 """%(self.GetSVGFilePath(), self.GetFilePath())
       
   357 
       
   358         return text
       
   359     
       
   360     def GenerateProgramInitProgram(self, elements):
       
   361         text = "Program::Program(wxWindow* parent):SVGUIWindow(parent)\n{\n"
       
   362         for element in elements:
       
   363             text += "    out_state_%d = UNCHANGED;\n"%element.getid()
       
   364             text += "    in_state_%d = UNCHANGED;\n"%element.getid()
       
   365         text += "}\n\n"
       
   366         return text
       
   367     
       
   368     def GenerateProgramEventFunctions(self, elements):
       
   369         text = ""
       
   370         current_location = "_".join(map(str, self.GetCurrentLocation()))
       
   371         for element in elements:
       
   372             element_type = GetElementType(element)
       
   373             element_state = "  in_state_%d = %s;\n"%(element.getid(), "%s")
       
   374             element_name = element.getname()
       
   375                 
       
   376             if element_type == ITEM_BUTTON:
       
   377                 text += """void Program::On%sClick(wxCommandEvent& event)
       
   378 {
       
   379   SVGUIButton* button = (SVGUIButton*)GetElementByName(wxT("%s"));\n"""%(element_name, element_name)
       
   380                 text += element_state%"GUI_BUSY"
       
   381                 text += "  _copy__IX%s_%d_1 = button->GetToggle();\n"%(current_location, element.getid())
       
   382                 text += element_state%"CHANGED"
       
   383                 text += "  event.Skip();\n}\n\n"
       
   384             elif element_type == ITEM_ROTATING:
       
   385                 text += """void Program::On%sChanging(wxScrollEvent& event)
       
   386 {
       
   387   SVGUIRotatingCtrl* rotating = (SVGUIRotatingCtrl*)GetElementByName(wxT("%s"));
       
   388 """%(element_name, element_name)
       
   389                 text += element_state%"GUI_BUSY"
       
   390                 text += "  _copy__ID%s_%d_1 = rotating->GetAngle();\n"%(current_location, element.getid())
       
   391                 text += element_state%"CHANGED"
       
   392                 text += "  event.Skip();\n}\n\n"
       
   393             elif element_type == ITEM_NOTEBOOK:
       
   394                 text += """void Program::On%sTabChanged(wxNotebookEvent& event)
       
   395 {
       
   396   SVGUINoteBook* notebook = (SVGUINoteBook*)GetElementByName(wxT("%s"));
       
   397 """%(element_name, element_name)
       
   398                 text += element_state%"GUI_BUSY"
       
   399                 text += "  _copy__IB%s_%d_1 = notebook->GetCurrentPage();\n"%(current_location, element.getid())
       
   400                 text += element_state%"CHANGED"
       
   401                 text += "  event.Skip();\n}\n\n"
       
   402             elif element_type == ITEM_TRANSFORM:
       
   403                 text += """void Program::On%sChanging(wxScrollEvent& event)
       
   404 {
       
   405   SVGUITransform* transform = (SVGUITransform*)GetElementByName(wxT("%s"));
       
   406 """%(element_name, element_name)
       
   407                 text += element_state%"GUI_BUSY"
       
   408                 text += "  _copy__ID%s_%d_1 = transform->GetX();\n"%(current_location, element.getid())
       
   409                 text += "  _copy__ID%s_%d_2 = transform->GetY();\n"%(current_location, element.getid())
       
   410                 text += element_state%"CHANGED"
       
   411                 text += "  event.Skip();\n}\n\n"
       
   412         
       
   413         text += "/* OnPlcOutEvent update GUI with provided IEC __Q* PLC output variables */\n"
       
   414         text += """void Program::OnPlcOutEvent(wxEvent& event)
       
   415 {
       
   416   SVGUIElement* element;
       
   417   
       
   418   refreshing = true;
       
   419 
       
   420   wxMutexGuiEnter();
       
   421 """
       
   422         for element in elements:
       
   423             element_type = GetElementType(element)
       
   424             texts = {"location" : current_location, "id" : element.getid()}
       
   425             
       
   426             text += """  if (__sync_bool_compare_and_swap (&out_state_%(id)d, CHANGED, GUI_BUSY))
       
   427   {
       
   428     element = (SVGUIElement*)GetElementById(wxT("%(id)d"));
       
   429             
       
   430     if (_copy__QX%(location)s_%(id)d_1 != element->IsVisible()) {
       
   431       if (_copy__QX%(location)s_%(id)d_1)
       
   432         element->Show();
       
   433       else
       
   434         element->Hide();
       
   435     }
       
   436     if (_copy__QX%(location)s_%(id)d_2 != element->IsEnabled()) {
       
   437       if (_copy__QX%(location)s_%(id)d_2)
       
   438         element->Enable();
       
   439       else
       
   440         element->Disable();
       
   441     }
       
   442 """%texts
       
   443             if element_type == ITEM_BUTTON:
       
   444                 text += """    if (_copy__QX%(location)s_%(id)d_3 != ((SVGUIButton*)element)->GetToggle())
       
   445       ((SVGUIButton*)element)->SetToggle(_copy__QX%(location)s_%(id)d_3);
       
   446 """%texts
       
   447             elif element_type == ITEM_TEXT:
       
   448                 text += """    if (((SVGUITextCtrl*)element)->GetValue().compare(_copy__QX%(location)s_%(id)d_3))
       
   449     {
       
   450       wxString str = wxString::FromAscii(_copy__QB%(location)s_%(id)d_3);
       
   451       ((SVGUITextCtrl*)element)->SetText(str);
       
   452     }
       
   453 """%texts
       
   454             elif  element_type == ITEM_SCROLLBAR:
       
   455                 text += """    if (_copy__QW%(location)s_%(id)d_3 != ((SVGUIScrollBar*)element)->GetThumbPosition() ||
       
   456         _copy__QW%(location)s_%(id)d_4 != ((SVGUIScrollBar*)element)->GetThumbSize() ||
       
   457         _copy__QW%(location)s_%(id)d_5 != ((SVGUIScrollBar*)element)->GetRange())
       
   458       ((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);
       
   459 """%texts
       
   460             elif element_type == ITEM_ROTATING:
       
   461                 text += """    if (_copy__QD%(location)s_%(id)d_3 != ((SVGUIRotatingCtrl*)element)->GetAngle())
       
   462       ((SVGUIRotatingCtrl*)element)->SetAngle(_copy__QD%(location)s_%(id)d_3);
       
   463 """%texts
       
   464             elif element_type == ITEM_NOTEBOOK:
       
   465                 text += """    if (_copy__QB%(location)s_%(id)d_3 != ((SVGUINoteBook*)element)->GetCurrentPage())
       
   466       ((SVGUINoteBook*)element)->SetCurrentPage(_copy__QB%(location)s_%(id)d_3);
       
   467 """%texts
       
   468             elif element_type == ITEM_TRANSFORM:
       
   469                 text += """    if (_copy__QD%(location)s_%(id)d_3 != ((SVGUITransform*)element)->GetX() ||
       
   470         copy__QD%(location)s_%(id)d_4 != ((SVGUITransform*)element)->GetY())
       
   471       transform->Move(_copy__QD%(location)s_%(id)d_3, _copy__QD%(location)s_%(id)d_4);
       
   472     if (_copy__QD%(location)s_%(id)d_5 != ((SVGUITransform*)element)->GetXScale() ||
       
   473         copy__QD%(location)s_%(id)d_6 != ((SVGUITransform*)element)->GetYScale())
       
   474       transform->Scale(_copy__QD%(location)s_%(id)d_5, _copy__QD%(location)s_%(id)d_6);
       
   475     if (_copy__QD%(location)s_%(id)d_7 != ((SVGUITransform*)element)->GetAngle())
       
   476       transform->Rotate(_copy__QD%(location)s_%(id)d_7);
       
   477 """%texts
       
   478             text += "    __sync_bool_compare_and_swap (&out_state_%(id)d, GUI_BUSY, UNCHANGED);\n  }\n"%texts
       
   479             
       
   480         text += """  wxMutexGuiLeave();
       
   481 
       
   482   refreshing = false;
       
   483 
       
   484   event.Skip();
       
   485 }
       
   486 
       
   487 """
       
   488         return text
       
   489     
       
   490     def GenerateProgramPrivateFunctions(self, elements):
       
   491         current_location = "_".join(map(str, self.GetCurrentLocation()))
       
   492         
       
   493         text = "void Program::Retrieve()\n{\n"
       
   494         for element in elements:
       
   495             element_type = GetElementType(element)
       
   496             texts = {"location" : current_location, "id" : element.getid()}
       
   497             block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)])
       
   498             
       
   499             text += """  do{
       
   500     if ( __sync_val_compare_and_swap (&in_state_%(id)d, CHANGED, PLC_BUSY) == CHANGED){
       
   501 """%texts
       
   502             for i, output in enumerate(block_infos["outputs"]):
       
   503                 texts["type"] = TYPECONVERSION[output[1]]
       
   504                 texts["pin"] = i + 1
       
   505                 
       
   506                 variable = "__I%(type)s%(location)s_%(id)d_%(pin)d"%texts
       
   507                 text +="      %s = _copy%s;\n"%(variable, variable)
       
   508             
       
   509             text += """    }
       
   510     else {
       
   511       break;
       
   512     }
       
   513 """
       
   514             #If GUI did change data while publishing, do it again (in real-time this should be avoided with priority stuff)
       
   515             text += "  }while(__sync_val_compare_and_swap (&in_state_%(id)s, PLC_BUSY, UNCHANGED) != PLC_BUSY);\n"%texts
       
   516         text += "}\n\n" 
       
   517 
       
   518         text += """void Program::Publish()
       
   519 {
       
   520   bool refresh = false;
       
   521 """
       
   522         for element in elements:
       
   523             element_type = GetElementType(element)
       
   524             texts = {"location" : current_location, "id" : element.getid()}
       
   525             block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)])
       
   526             
       
   527             text += """  if ( __sync_bool_compare_and_swap (&out_state_%(id)d, UNCHANGED, PLC_BUSY) ||
       
   528        __sync_bool_compare_and_swap (&out_state_%(id)d, CHANGED, PLC_BUSY)) {
       
   529 """%texts
       
   530             for i, input in enumerate(block_infos["inputs"]):
       
   531                 texts["type"] = TYPECONVERSION[input[1]]
       
   532                 texts["pin"] = i + 1
       
   533                 variable = "__Q%(type)s%(location)s_%(id)d_%(pin)d"%texts
       
   534                 text += "    if (_copy%s != %s) {\n"%(variable, variable)
       
   535                 text += "      _copy%s = %s;\n"%(variable, variable)
       
   536                 text += "      out_state_%(id)d = CHANGED;\n    }\n"%texts
       
   537             text += """    if (out_state_%(id)d == CHANGED) {
       
   538       refresh = true;
       
   539     }
       
   540     else {
       
   541       out_state_%(id)d = UNCHANGED;
       
   542     }
       
   543   }
       
   544 """%texts
       
   545         
       
   546         text += """  /*Replace this with determinist signal if called from RT*/;
       
   547   if (refresh && !refreshing) {
       
   548     wxCommandEvent event( EVT_PLC );
       
   549     ProcessEvent(event);
       
   550   }
       
   551 };
       
   552 
       
   553 """
       
   554 
       
   555         text += """void Program::Initialize()
       
   556 {
       
   557   SVGUIElement* element;
       
   558 """
       
   559         for element in elements:
       
   560             element_type = GetElementType(element)
       
   561             texts = {"location" : current_location, "id" : element.getid()}
       
   562             
       
   563             text += """
       
   564   element = (SVGUIElement*)GetElementById(wxT("%(id)d"));
       
   565   __QX%(location)s_%(id)d_1 = 1;
       
   566   _copy__QX%(location)s_%(id)d_1 = 1;
       
   567   __QX%(location)s_%(id)d_2 = 1;
       
   568   _copy__QX%(location)s_%(id)d_2 = 1;
       
   569 """%texts
       
   570             if element_type == ITEM_BUTTON:
       
   571                 text += "  _copy__IX%(location)s_%(id)d_1 = ((SVGUIButton*)element)->GetToggle();\n"%texts
       
   572             elif element_type == ITEM_TEXT:
       
   573                 text += "  _copy__IB%(location)s_%(id)d_1 = ((SVGUITextCtrl*)element)->GetValue();\n"%texts
       
   574             elif element_type == ITEM_SCROLLBAR:
       
   575                 text += "  _copy__IW%(location)s_%(id)d_1 = ((SVGUIScrollBar*)element)->GetThumbPosition();\n"%texts
       
   576             elif element_type == ITEM_ROTATING:
       
   577                 text += "  _copy__ID%(location)s_%(id)d_1 = ((SVGUIRotatingCtrl*)element)->GetAngle();\n"%texts
       
   578             elif element_type == ITEM_NOTEBOOK:
       
   579                 text += "  _copy__IB%(location)s_%(id)d_1 = ((SVGUINoteBook*)element)->GetCurrentPage();\n"%texts
       
   580             elif element_type == ITEM_TRANSFORM:
       
   581                 text += "  _copy__ID%(location)s_%(id)d_1 = ((SVGUITransform*)element)->GetX();\n"%texts
       
   582                 text += "  _copy__ID%(location)s_%(id)d_2 = ((SVGUITransform*)element)->GetY();\n"%texts
       
   583         text += "}\n\n"
       
   584         
       
   585         #DEBUG Fonction d'affichage
       
   586 #        fct += "void Program::Print()\n{\n"
       
   587 #        for element in elementsTab:
       
   588 #            infos = element.getElementAttributes()
       
   589 #            for info in infos:
       
   590 #                if info["name"] == "id":
       
   591 #                    element_id = str(info["value"])
       
   592 #            type = element.GetElementInfos()["type"]
       
   593 #            FbdBlock = self.GetBlockType(type)
       
   594 #            element_num_patte = 1
       
   595 #            for input in FbdBlock["inputs"]:
       
   596 #                element_type = TYPECONVERSION[input[1]]
       
   597 #                c_type = CPRINTTYPECONVERSION[input[1]]
       
   598 #                var = "_copy__Q"+element_type+self.BusNumber+"_"+element_id+"_"+str(element_num_patte)
       
   599 #                fct +="  printf(\""+var+": %"+c_type+"\\n\","+var+");\n"
       
   600 #                element_num_patte +=1
       
   601 #            element_num_patte = 1
       
   602 #            for output in FbdBlock["outputs"]:
       
   603 #                element_type = TYPECONVERSION[output[1]]
       
   604 #                c_type = CPRINTTYPECONVERSION[output[1]]
       
   605 #                var = "_copy__I"+element_type+self.BusNumber+"_"+element_id+"_"+str(element_num_patte)
       
   606 #                fct +="  printf(\""+var+": %"+c_type+"\\n\","+var+");\n"
       
   607 #                element_num_patte +=1
       
   608         #fct +="    wxPostEvent(Program,wxEVT_PLCOUT);\n"
       
   609 #        fct +="};\n\n"    
       
   610         return text
       
   611     
       
   612     def PlugGenerate_C(self, buildpath, locations, logger):
   177     def PlugGenerate_C(self, buildpath, locations, logger):
   613         progname = "SVGUI_%s"%"_".join(map(str, self.GetCurrentLocation()))
   178         progname = "SVGUI_%s"%"_".join(map(str, self.GetCurrentLocation()))
   614         self.GenerateProgram((0, 0), buildpath, progname)
   179         
       
   180         generator = _SVGUICGenerator(self.GetElementsByType(), self.GetSVGFilePath(), self.GetFilePath(), self.GetCurrentLocation())
       
   181         generator.GenerateProgram((0, 0), buildpath, progname)
   615         Gen_C_file = os.path.join(buildpath, progname+".cpp" )
   182         Gen_C_file = os.path.join(buildpath, progname+".cpp" )
   616         
   183         
   617         status, result, err_result = ProcessLogger(logger, "wx-config --cxxflags", no_stdout=True).spin()
   184         if wx.Platform == '__WXMSW__':
   618         if status:
   185             cxx_flags = "-I..\\..\\wxPython-src-2.8.7.1\\bld\\lib\\wx\\include\\msw-unicode-release-2.8 -I..\\..\\wxPython-src-2.8.7.1\\include -I..\\..\\wxPython-src-2.8.7.1\\contrib\\include -I..\\..\\matiec\\lib -DWXUSINGDLL -D__WXMSW__ -mthreads"
   619             logger.write_error("Unable to get wx cxxflags\n")
   186             libs = "\"..\\lib\\libwxsvg.a\" \"..\\lib\\libwxsvg_agg.a\" \"..\\lib\\libagg.a\" \"..\\lib\\libaggplatformwin32.a\" \"..\\lib\\libaggfontwin32tt.a\" -L..\\..\\wxPython-src-2.8.7.1\\bld\\lib -mno-cygwin -mwindows -mthreads  -mno-cygwin -mwindows -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"
   620         cxx_flags = result.strip() + " -I../matiec/lib"
   187         else:
   621         
   188             status, result, err_result = ProcessLogger(logger, "wx-config --cxxflags", no_stdout=True).spin()
   622         status, result, err_result = ProcessLogger(logger, "wx-config --libs", no_stdout=True).spin()
   189             if status:
   623         if status:
   190                 logger.write_error("Unable to get wx cxxflags\n")
   624             logger.write_error("Unable to get wx libs\n")
   191             cxx_flags = result.strip() + " -I../matiec/lib"
   625         libs = result.strip() + " -lwxsvg"
   192             
       
   193             status, result, err_result = ProcessLogger(logger, "wx-config --libs", no_stdout=True).spin()
       
   194             if status:
       
   195                 logger.write_error("Unable to get wx libs\n")
       
   196             libs = result.strip() + " -lwxsvg"
   626         
   197         
   627         return [(Gen_C_file, cxx_flags)],libs,True
   198         return [(Gen_C_file, cxx_flags)],libs,True
   628     
   199     
   629     def BlockTypesFactory(self):
   200     def BlockTypesFactory(self):
   630         def generate_svgui_block(generator, block, body, link, order=False):
   201         def generate_svgui_block(generator, block, body, link, order=False):
   634                 raise ValueError, "No corresponding block found"
   205                 raise ValueError, "No corresponding block found"
   635             type = block.gettypeName()
   206             type = block.gettypeName()
   636             block_infos = GetBlockType(type)
   207             block_infos = GetBlockType(type)
   637             current_location = ".".join(map(str, self.GetCurrentLocation()))
   208             current_location = ".".join(map(str, self.GetCurrentLocation()))
   638             if not generator.ComputedBlocks.get(name, False) and not order:
   209             if not generator.ComputedBlocks.get(name, False) and not order:
       
   210                 generator.ComputedBlocks[block] = True
   639                 for num, variable in enumerate(block.inputVariables.getvariable()):
   211                 for num, variable in enumerate(block.inputVariables.getvariable()):
   640                     connections = variable.connectionPointIn.getconnections()
   212                     connections = variable.connectionPointIn.getconnections()
   641                     if connections and len(connections) == 1:
   213                     if connections and len(connections) == 1:
   642                         parameter = "%sQ%s%s.%d.%d"%("%", TYPECONVERSION[block_infos["inputs"][num][1]], current_location, block_id, num+1)
   214                         parameter = "%sQ%s%s.%d.%d"%("%", TYPECONVERSION[block_infos["inputs"][num][1]], current_location, block_id, num+1)
   643                         value = generator.ComputeFBDExpression(body, connections[0])
   215                         value = generator.ComputeFBDExpression(body, connections[0])
   644                         generator.Program += ("  %s := %s;\n"%(parameter, generator.ExtractModifier(variable, value)))
   216                         generator.Program += ("  %s := %s;\n"%(parameter, generator.ExtractModifier(variable, value)))
   645                 generator.ComputedBlocks[block] = True
       
   646             if link:
   217             if link:
   647                 connectionPoint = link.getposition()[-1]
   218                 connectionPoint = link.getposition()[-1]
   648                 for num, variable in enumerate(block.outputVariables.getvariable()):
   219                 for num, variable in enumerate(block.outputVariables.getvariable()):
   649                     blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY()
   220                     blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY()
   650                     if block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety():
   221                     if block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety():
   712                     "comment" : "SVGUI Transform",
   283                     "comment" : "SVGUI Transform",
   713                     "generate" : generate_svgui_block, "initialise" : initialise_block},
   284                     "generate" : generate_svgui_block, "initialise" : initialise_block},
   714                ]}
   285                ]}
   715         ]
   286         ]
   716 
   287 
       
   288 
       
   289 
       
   290 class _SVGUICGenerator(SVGUICGenerator):
       
   291 
       
   292     def __init__(self, elements, svgfile, xmlfile, current_location):
       
   293         SVGUICGenerator.__init__(self, elements, svgfile, xmlfile)
       
   294         
       
   295         self.CurrentLocation = current_location
       
   296 
       
   297     def GenerateProgramHeadersPublicVars(self):
       
   298         text = """    void OnPlcOutEvent(wxEvent& event);
       
   299 
       
   300     void Retrieve();
       
   301     void Publish();
       
   302     void Initialize();
       
   303 """
       
   304 #        text += "    void Print();\n"
       
   305         return text
       
   306     
       
   307     def GenerateIECVars(self):
       
   308         text = ""
       
   309         for element in self.Elements:
       
   310             text += "STATE_TYPE out_state_%d;\n"%element.getid()
       
   311             text += "STATE_TYPE in_state_%d;\n"%element.getid()
       
   312         text +="\n"
       
   313         current_location = "_".join(map(str, self.CurrentLocation))
       
   314         #Declaration des variables
       
   315         for element in self.Elements:
       
   316             block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)])
       
   317             block_id = element.getid()
       
   318             for i, input in enumerate(block_infos["inputs"]):
       
   319                 element_c_type = CTYPECONVERSION[input[1]]
       
   320                 variable = "__Q%s%s_%d_%d"%(TYPECONVERSION[input[1]], current_location, block_id, i + 1)
       
   321                 text += "%s %s;\n"%(element_c_type, variable)
       
   322                 text += "%s _copy%s;\n"%(element_c_type, variable)
       
   323             for i, output in enumerate(block_infos["outputs"]):
       
   324                 element_c_type = CTYPECONVERSION[output[1]]
       
   325                 variable = "__I%s%s_%d_%d"%(TYPECONVERSION[output[1]], current_location, block_id, i + 1)
       
   326                 text += "%s %s;\n"%(element_c_type, variable)
       
   327                 text += "%s _copy%s;\n"%(element_c_type, variable)
       
   328             text +="\n"
       
   329         return text
       
   330     
       
   331     def GenerateGlobalVarsAndFuncs(self, size):
       
   332         text = """#include \"iec_types.h\"
       
   333 
       
   334 #ifdef __WXMSW__
       
   335 #define COMPARE_AND_SWAP_VAL(Destination, comparand, exchange) InterlockedCompareExchange(Destination, exchange, comparand)
       
   336 #define THREAD_RETURN_TYPE DWORD WINAPI
       
   337 #define STATE_TYPE long int
       
   338 #else
       
   339 #define COMPARE_AND_SWAP_VAL(Destination, comparand, exchange) __sync_val_compare_and_swap(Destination, comparand, exchange)
       
   340 #define THREAD_RETURN_TYPE void*
       
   341 #define STATE_TYPE volatile int
       
   342 #endif
       
   343 
       
   344 """
       
   345         
       
   346         text += self.GenerateIECVars()
       
   347         
       
   348         text += """IMPLEMENT_APP_NO_MAIN(SVGViewApp);
       
   349 IMPLEMENT_WX_THEME_SUPPORT;
       
   350 SVGViewApp *myapp = NULL;
       
   351 
       
   352 #ifdef __WXMSW__
       
   353 HANDLE wxMainLoop;
       
   354 DWORD wxMainLoopId;
       
   355 #else
       
   356 pthread_t wxMainLoop;
       
   357 #endif
       
   358 
       
   359 """
       
   360 
       
   361 #        text += "pthread_t wxMainLoop,automate;\n"
       
   362         text += """int myargc = 0;
       
   363 char** myargv = NULL;
       
   364         
       
   365 #define UNCHANGED 1
       
   366 #define PLC_BUSY 2
       
   367 #define CHANGED 3
       
   368 #define GUI_BUSY 4
       
   369 #ifdef __WXMSW__
       
   370 #else
       
   371 #endif
       
   372 
       
   373 bool refresh = false;
       
   374 bool refreshing = false;
       
   375 
       
   376 THREAD_RETURN_TYPE InitWxEntry(void* args)
       
   377 {
       
   378   wxEntry(myargc,myargv);
       
   379   return 0;
       
   380 }
       
   381 
       
   382 """
       
   383 #        text += """void* SimulAutomate(void* args)
       
   384 #{
       
   385 #  while(1){
       
   386 #    myapp->frame->m_svgCtrl->IN_"+self.BusNumber+"();
       
   387 #    //printf(\"AUTOMATE\\n\");
       
   388 #    myapp->frame->m_svgCtrl->OUT_"+self.BusNumber+"();
       
   389 #    sleep(1);
       
   390 #  }
       
   391 #  return args;
       
   392 #}
       
   393 #
       
   394 #"""
       
   395       
       
   396         text += """bool SVGViewApp::OnInit()
       
   397 {
       
   398   #ifndef __WXMSW__
       
   399     setlocale(LC_NUMERIC, "C");
       
   400   #endif
       
   401 """
       
   402         #text += "  frame = new MainFrame(NULL, wxT(\"Program\"),wxDefaultPosition, wxSize(%d, %d));\n"%size
       
   403         text += """  frame = new MainFrame(NULL, wxT("Program"),wxDefaultPosition, wxDefaultSize);
       
   404   frame->Show();
       
   405   myapp = this;
       
   406 """
       
   407 #        text += "  pthread_create(&automate, NULL, SimulAutomate, NULL);\n"
       
   408         text += """  return true;
       
   409 }
       
   410 
       
   411 extern "C" {
       
   412 
       
   413 int __init_%(location)s(int argc, char** argv)
       
   414 {
       
   415   myargc = argc;
       
   416   myargv = argv;
       
   417 #ifdef __WXMSW__
       
   418   wxMainLoop = CreateThread(NULL, 0, InitWxEntry, 0, 0, &wxMainLoopId);
       
   419 #else
       
   420   pthread_create(&wxMainLoop, NULL, InitWxEntry, NULL);
       
   421 #endif
       
   422   return 0;
       
   423 }
       
   424 
       
   425 void __cleanup_%(location)s()
       
   426 {
       
   427 }
       
   428 
       
   429 void __retrieve_%(location)s()
       
   430 {
       
   431   if(myapp){
       
   432     myapp->frame->m_svgCtrl->Retrieve();
       
   433   }        
       
   434 }
       
   435 
       
   436 void __publish_%(location)s()
       
   437 {
       
   438   if(myapp){
       
   439     myapp->frame->m_svgCtrl->Publish();
       
   440   }
       
   441 }
       
   442 
       
   443 }
       
   444 
       
   445 IEC_STRING wxStringToIEC_STRING(wxString s)
       
   446 {
       
   447   IEC_STRING res = {0,""};
       
   448   int i;
       
   449   for(i = 0; i<s.Length() && i<STR_MAX_LEN; i++)
       
   450     res.body[i] = s.GetChar(i);
       
   451   res.len = i;
       
   452   return res;
       
   453 }
       
   454 
       
   455 """%{"location" : "_".join(map(str, self.CurrentLocation))}
       
   456         
       
   457         return text
       
   458     
       
   459     def GenerateProgramEventTable(self):
       
   460         text = """BEGIN_DECLARE_EVENT_TYPES()
       
   461 DECLARE_LOCAL_EVENT_TYPE( EVT_PLC, wxNewEventType() )
       
   462 END_DECLARE_EVENT_TYPES()
       
   463          
       
   464 DEFINE_LOCAL_EVENT_TYPE( EVT_PLC )
       
   465 
       
   466 """     
       
   467         #Event Table Declaration
       
   468         text += "BEGIN_EVENT_TABLE(Program, SVGUIWindow)\n"
       
   469         for element in self.Elements:
       
   470             element_type = GetElementType(element)
       
   471             element_name = element.getname()
       
   472             if element_type == ITEM_BUTTON:
       
   473                 text += "  EVT_BUTTON (SVGUIID(\"%s\"), Program::On%sClick)\n"%(element_name, element_name)
       
   474             elif element_type in [ITEM_SCROLLBAR, ITEM_ROTATING, ITEM_TRANSFORM]:
       
   475                 text += "  EVT_COMMAND_SCROLL_THUMBTRACK (SVGUIID(\"%s\"), Program::On%sChanging)\n"%(element_name, element_name)
       
   476             elif element_type == ITEM_NOTEBOOK:
       
   477                 text += "  EVT_NOTEBOOK_PAGE_CHANGED (SVGUIID(\"%s\"), Program::On%sTabChanged)\n"%(element_name, element_name)
       
   478         text += "  EVT_CUSTOM(EVT_PLC, wxID_ANY, Program::OnPlcOutEvent)\n"
       
   479         text += "END_EVENT_TABLE()\n\n"
       
   480         return text
       
   481     
       
   482     def GenerateProgramInitFrame(self):
       
   483         text = """MainFrame::MainFrame(wxWindow *parent, const wxString& title, const wxPoint& pos,const wxSize& size, long style): wxFrame(parent, wxID_ANY, title, pos, size, style)
       
   484 {
       
   485   m_svgCtrl = new Program(this);
       
   486   if (m_svgCtrl->LoadFiles(wxT("%s"), wxT("%s")))
       
   487   {
       
   488     Show(true);
       
   489     m_svgCtrl->SetFocus();
       
   490     m_svgCtrl->SetFitToFrame(true);
       
   491     m_svgCtrl->RefreshScale();
       
   492     m_svgCtrl->InitScrollBars();
       
   493     m_svgCtrl->Initialize();
       
   494     m_svgCtrl->Update();
       
   495   }
       
   496   else
       
   497   {
       
   498     printf("Error while opening files\\n");
       
   499     exit(0);
       
   500   }
       
   501 }
       
   502 
       
   503 
       
   504 """%(self.SVGFilePath, self.XMLFilePath)
       
   505 
       
   506         return text
       
   507     
       
   508     def GenerateProgramInitProgram(self):
       
   509         text = "Program::Program(wxWindow* parent):SVGUIWindow(parent)\n{\n"
       
   510         for element in self.Elements:
       
   511             text += "    out_state_%d = UNCHANGED;\n"%element.getid()
       
   512             text += "    in_state_%d = UNCHANGED;\n"%element.getid()
       
   513         text += "}\n\n"
       
   514         return text
       
   515     
       
   516     def GenerateProgramEventFunctions(self):
       
   517         text = ""
       
   518         current_location = "_".join(map(str, self.CurrentLocation))
       
   519         for element in self.Elements:
       
   520             element_type = GetElementType(element)
       
   521             element_lock = """  if (COMPARE_AND_SWAP_VAL(&in_state_%d, CHANGED, GUI_BUSY) == CHANGED ||
       
   522       COMPARE_AND_SWAP_VAL(&in_state_%d, UNCHANGED, GUI_BUSY) == UNCHANGED) {
       
   523 """%(element.getid(), element.getid())
       
   524             element_unlock = """    COMPARE_AND_SWAP_VAL(&in_state_%d, GUI_BUSY, CHANGED);
       
   525   }
       
   526   else
       
   527       ProcessEvent(event);
       
   528 """%element.getid()
       
   529             element_name = element.getname()
       
   530                 
       
   531             if element_type == ITEM_BUTTON:
       
   532                 text += """void Program::On%sClick(wxCommandEvent& event)
       
   533 {
       
   534   SVGUIButton* button = (SVGUIButton*)GetElementByName(wxT("%s"));\n"""%(element_name, element_name)
       
   535                 text += element_lock
       
   536                 text += "    _copy__IX%s_%d_1 = button->GetToggle();\n"%(current_location, element.getid())
       
   537                 text += element_unlock
       
   538                 text += "  event.Skip();\n}\n\n"
       
   539             elif element_type == ITEM_ROTATING:
       
   540                 text += """void Program::On%sChanging(wxScrollEvent& event)
       
   541 {
       
   542   SVGUIRotatingCtrl* rotating = (SVGUIRotatingCtrl*)GetElementByName(wxT("%s"));
       
   543 """%(element_name, element_name)
       
   544                 text += element_lock
       
   545                 text += "    _copy__ID%s_%d_1 = rotating->GetAngle();\n"%(current_location, element.getid())
       
   546                 text += element_unlock
       
   547                 text += "  event.Skip();\n}\n\n"
       
   548             elif element_type == ITEM_NOTEBOOK:
       
   549                 text += """void Program::On%sTabChanged(wxNotebookEvent& event)
       
   550 {
       
   551   SVGUINoteBook* notebook = (SVGUINoteBook*)GetElementByName(wxT("%s"));
       
   552 """%(element_name, element_name)
       
   553                 text += element_lock
       
   554                 text += "    _copy__IB%s_%d_1 = notebook->GetCurrentPage();\n"%(current_location, element.getid())
       
   555                 text += element_unlock
       
   556                 text += "  event.Skip();\n}\n\n"
       
   557             elif element_type == ITEM_TRANSFORM:
       
   558                 text += """void Program::On%sChanging(wxScrollEvent& event)
       
   559 {
       
   560   SVGUITransform* transform = (SVGUITransform*)GetElementByName(wxT("%s"));
       
   561 """%(element_name, element_name)
       
   562                 text += element_lock
       
   563                 text += "    _copy__ID%s_%d_1 = transform->GetX();\n"%(current_location, element.getid())
       
   564                 text += "    _copy__ID%s_%d_2 = transform->GetY();\n"%(current_location, element.getid())
       
   565                 text += element_unlock
       
   566                 text += "  event.Skip();\n}\n\n"
       
   567         
       
   568         text += "/* OnPlcOutEvent update GUI with provided IEC __Q* PLC output variables */\n"
       
   569         text += """void Program::OnPlcOutEvent(wxEvent& event)
       
   570 {
       
   571   SVGUIElement* element;
       
   572   
       
   573   refreshing = true;
       
   574 
       
   575   wxMutexGuiEnter();
       
   576 """
       
   577         for element in self.Elements:
       
   578             element_type = GetElementType(element)
       
   579             texts = {"location" : current_location, "id" : element.getid()}
       
   580             
       
   581             text += """  if (COMPARE_AND_SWAP_VAL(&out_state_%(id)d, CHANGED, GUI_BUSY) == CHANGED)
       
   582   {
       
   583     element = (SVGUIElement*)GetElementById(wxT("%(id)d"));
       
   584             
       
   585     if (_copy__QX%(location)s_%(id)d_1 != element->IsVisible()) {
       
   586       if (_copy__QX%(location)s_%(id)d_1)
       
   587         element->Show();
       
   588       else
       
   589         element->Hide();
       
   590     }
       
   591     if (_copy__QX%(location)s_%(id)d_2 != element->IsEnabled()) {
       
   592       if (_copy__QX%(location)s_%(id)d_2)
       
   593         element->Enable();
       
   594       else
       
   595         element->Disable();
       
   596     }
       
   597 """%texts
       
   598             if element_type == ITEM_BUTTON:
       
   599                 text += """    if (_copy__QX%(location)s_%(id)d_3 != ((SVGUIButton*)element)->GetToggle())
       
   600       ((SVGUIButton*)element)->SetToggle(_copy__QX%(location)s_%(id)d_3);
       
   601 """%texts
       
   602             elif element_type == ITEM_TEXT:
       
   603                 text += """    if (((SVGUITextCtrl*)element)->GetValue().compare(_copy__QX%(location)s_%(id)d_3))
       
   604     {
       
   605       wxString str = wxString::FromAscii(_copy__QB%(location)s_%(id)d_3);
       
   606       ((SVGUITextCtrl*)element)->SetText(str);
       
   607     }
       
   608 """%texts
       
   609             elif  element_type == ITEM_SCROLLBAR:
       
   610                 text += """    if (_copy__QW%(location)s_%(id)d_3 != ((SVGUIScrollBar*)element)->GetThumbPosition() ||
       
   611         _copy__QW%(location)s_%(id)d_4 != ((SVGUIScrollBar*)element)->GetThumbSize() ||
       
   612         _copy__QW%(location)s_%(id)d_5 != ((SVGUIScrollBar*)element)->GetRange())
       
   613       ((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);
       
   614 """%texts
       
   615             elif element_type == ITEM_ROTATING:
       
   616                 text += """    if (_copy__QD%(location)s_%(id)d_3 != ((SVGUIRotatingCtrl*)element)->GetAngle())
       
   617       ((SVGUIRotatingCtrl*)element)->SetAngle(_copy__QD%(location)s_%(id)d_3);
       
   618 """%texts
       
   619             elif element_type == ITEM_NOTEBOOK:
       
   620                 text += """    if (_copy__QB%(location)s_%(id)d_3 != ((SVGUINoteBook*)element)->GetCurrentPage())
       
   621       ((SVGUINoteBook*)element)->SetCurrentPage(_copy__QB%(location)s_%(id)d_3);
       
   622 """%texts
       
   623             elif element_type == ITEM_TRANSFORM:
       
   624                 text += """    if (_copy__QD%(location)s_%(id)d_3 != ((SVGUITransform*)element)->GetX() ||
       
   625         copy__QD%(location)s_%(id)d_4 != ((SVGUITransform*)element)->GetY())
       
   626       transform->Move(_copy__QD%(location)s_%(id)d_3, _copy__QD%(location)s_%(id)d_4);
       
   627     if (_copy__QD%(location)s_%(id)d_5 != ((SVGUITransform*)element)->GetXScale() ||
       
   628         copy__QD%(location)s_%(id)d_6 != ((SVGUITransform*)element)->GetYScale())
       
   629       transform->Scale(_copy__QD%(location)s_%(id)d_5, _copy__QD%(location)s_%(id)d_6);
       
   630     if (_copy__QD%(location)s_%(id)d_7 != ((SVGUITransform*)element)->GetAngle())
       
   631       transform->Rotate(_copy__QD%(location)s_%(id)d_7);
       
   632 """%texts
       
   633             text += "    COMPARE_AND_SWAP_VAL(&out_state_%(id)d, GUI_BUSY, UNCHANGED);\n  }\n"%texts
       
   634             
       
   635         text += """  wxMutexGuiLeave();
       
   636 
       
   637   refreshing = false;
       
   638 
       
   639   event.Skip();
       
   640 }
       
   641 
       
   642 """
       
   643         return text
       
   644     
       
   645     def GenerateProgramPrivateFunctions(self):
       
   646         current_location = "_".join(map(str, self.CurrentLocation))
       
   647         
       
   648         text = "void Program::Retrieve()\n{\n"
       
   649         for element in self.Elements:
       
   650             element_type = GetElementType(element)
       
   651             texts = {"location" : current_location, "id" : element.getid()}
       
   652             block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)])
       
   653             if len(block_infos["outputs"]) > 0:
       
   654                 text += """  if (COMPARE_AND_SWAP_VAL(&in_state_%(id)d, CHANGED, PLC_BUSY) == CHANGED) {
       
   655 """%texts
       
   656                 for i, output in enumerate(block_infos["outputs"]):
       
   657                     texts["type"] = TYPECONVERSION[output[1]]
       
   658                     texts["pin"] = i + 1
       
   659                     
       
   660                     variable = "__I%(type)s%(location)s_%(id)d_%(pin)d"%texts
       
   661                     text +="    %s = _copy%s;\n"%(variable, variable)
       
   662                 
       
   663                 text += """    COMPARE_AND_SWAP_VAL(&in_state_%(id)d, PLC_BUSY, UNCHANGED);
       
   664   }
       
   665 """%texts
       
   666         text += "}\n\n" 
       
   667 
       
   668         text += "void Program::Publish()\n{\n  STATE_TYPE new_state;\n\n"
       
   669         for element in self.Elements:
       
   670             element_type = GetElementType(element)
       
   671             texts = {"location" : current_location, "id" : element.getid()}
       
   672             block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)])
       
   673             
       
   674             text += """  if ((new_state = COMPARE_AND_SWAP_VAL(&out_state_%(id)d, UNCHANGED, PLC_BUSY)) == UNCHANGED ||
       
   675        (new_state = COMPARE_AND_SWAP_VAL(&out_state_%(id)d, CHANGED, PLC_BUSY)) == CHANGED) {
       
   676 """%texts
       
   677             for i, input in enumerate(block_infos["inputs"]):
       
   678                 texts["type"] = TYPECONVERSION[input[1]]
       
   679                 texts["pin"] = i + 1
       
   680                 variable = "__Q%(type)s%(location)s_%(id)d_%(pin)d"%texts
       
   681                 text += "    if (_copy%s != %s) {\n"%(variable, variable)
       
   682                 text += "      _copy%s = %s;\n"%(variable, variable)
       
   683                 text += "      new_state = CHANGED;\n    }\n"%texts
       
   684             text += """    COMPARE_AND_SWAP_VAL(&out_state_%(id)d, PLC_BUSY, new_state);
       
   685     refresh |= new_state == CHANGED;
       
   686   }
       
   687 """%texts
       
   688         
       
   689         text += """  /* Replace this with determinist signal if called from RT */
       
   690   if (refresh && !refreshing) {
       
   691     wxCommandEvent event( EVT_PLC );
       
   692     ProcessEvent(event);
       
   693     refresh = false;
       
   694   }
       
   695 };
       
   696 
       
   697 """
       
   698 
       
   699         text += """void Program::Initialize()
       
   700 {
       
   701   SVGUIElement* element;
       
   702 """
       
   703         for element in self.Elements:
       
   704             element_type = GetElementType(element)
       
   705             texts = {"location" : current_location, "id" : element.getid()}
       
   706             
       
   707             text += """
       
   708   element = (SVGUIElement*)GetElementById(wxT("%(id)d"));
       
   709   __QX%(location)s_%(id)d_1 = 1;
       
   710   _copy__QX%(location)s_%(id)d_1 = 1;
       
   711   __QX%(location)s_%(id)d_2 = 1;
       
   712   _copy__QX%(location)s_%(id)d_2 = 1;
       
   713 """%texts
       
   714             if element_type == ITEM_BUTTON:
       
   715                 text += "  _copy__IX%(location)s_%(id)d_1 = ((SVGUIButton*)element)->GetToggle();\n"%texts
       
   716             elif element_type == ITEM_TEXT:
       
   717                 text += "  _copy__IB%(location)s_%(id)d_1 = ((SVGUITextCtrl*)element)->GetValue();\n"%texts
       
   718             elif element_type == ITEM_SCROLLBAR:
       
   719                 text += "  _copy__IW%(location)s_%(id)d_1 = ((SVGUIScrollBar*)element)->GetThumbPosition();\n"%texts
       
   720             elif element_type == ITEM_ROTATING:
       
   721                 text += "  _copy__ID%(location)s_%(id)d_1 = ((SVGUIRotatingCtrl*)element)->GetAngle();\n"%texts
       
   722             elif element_type == ITEM_NOTEBOOK:
       
   723                 text += "  _copy__IB%(location)s_%(id)d_1 = ((SVGUINoteBook*)element)->GetCurrentPage();\n"%texts
       
   724             elif element_type == ITEM_TRANSFORM:
       
   725                 text += "  _copy__ID%(location)s_%(id)d_1 = ((SVGUITransform*)element)->GetX();\n"%texts
       
   726                 text += "  _copy__ID%(location)s_%(id)d_2 = ((SVGUITransform*)element)->GetY();\n"%texts
       
   727         text += "}\n\n"
       
   728         
       
   729         return text