root/WaveDev/trunk/WaveDev/wavedev/generate/templates/py_comp/genStructure.py @ 4315

Revision 4315, 21.9 KB (checked in by DrewCormier, 7 years ago)

name the property variable after the name given in the PropertiesDialog?

  • Property svn:executable set to *
Line 
1#! /usr/bin/env python
2
3## Copyright 2005, 2006 Virginia Polytechnic Institute and State University
4##
5## This file is part of the OSSIE Waveform Developer.
6##
7## OSSIE Waveform Developer is free software; you can redistribute it and/or modify
8## it under the terms of the GNU General Public License as published by
9## the Free Software Foundation; either version 2 of the License, or
10## (at your option) any later version.
11##
12## OSSIE Waveform Developer is distributed in the hope that it will be useful,
13## but WITHOUT ANY WARRANTY; without even the implied warranty of
14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15## GNU General Public License for more details.
16##
17## You should have received a copy of the GNU General Public License
18## along with OSSIE Waveform Developer; if not, write to the Free Software
19## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21import os, shutil
22from errorMsg import *
23
24class genAll:
25  def __init__(self,path,active_wave):
26    if path[len(path)-1] != '/':
27        path = path + '/'
28    self.path = path
29    self.active_wave = active_wave
30
31
32             
33  def writeCompMakefile(self,comp,compPath):
34    '''
35    ##############################################################################
36    ## writeCompMakefile - generates the make file for an indivdual component
37    ##############################################################################
38    '''
39
40    #copy over the readme file
41    shutil.copy('generate/templates/py_comp/README', compPath)
42
43    if compPath[len(compPath)-1] != '/':
44        compPath = compPath + '/'
45           
46    output = open(compPath + 'setup.py','w')
47    ts = "\
48#! /usr/bin/env python\n\
49\n\
50from distutils.core import setup\n\
51import sys\n\
52\n\
53install_location = '/sdr/'\n\
54\n\
55if len(sys.argv) != 2:\n\
56        sys.exit(1)\n\
57\n\
58sys.argv.append('--install-lib='+install_location)\n\n"
59    output.writelines(ts)
60   
61    ts = "\
62setup(name='" + comp.name + "', description='" + comp.name + "',data_files=[(install_location+'bin/" + comp.name + "',['" + comp.name + ".py', 'WorkModule.py']),\n\
63"     
64    output.writelines(ts)
65
66    ts = ' '*8 + "(install_location+'xml/" + comp.name + "',['" + comp.name + ".prf.xml',\n"
67    ts = ts +  " "*8 + "'" + comp.name + ".scd.xml', '" + comp.name + ".spd.xml'])])\n"
68    output.writelines(ts)
69
70    output.close()   #done creating the file
71
72
73
74 
75         
76  def writeConfAC(self, genPath, name, aceFlag, wavFlag, installPath):
77    '''
78    ##############################################################################
79    ## writeConfAC - gets called by ComponentFrame.  python component installation
80    ## does not need configure.ac files, so it does not really do anything.  still
81    ## needs to exist so that an error does not get thrown in ComponetFrame.py.
82    ##############################################################################
83    '''
84    pass         
85
86
87
88
89  #----------------------------------------------------------------------------- 
90  def genCompFiles(self,comp):
91      '''
92      ##############################################################################     
93      ## This function generates the cpp and h files for each component:
94      ## component.h, component.cpp, main.cpp, port_impl.h, and port_impl.cpp
95      ##############################################################################   
96      '''
97
98      #-------------------------------------------------------------------------
99      '''
100      ##########################################################################
101      ## generate component .py file
102      ##########################################################################
103      '''
104      #TODO: write more of the code for generting .py file based on component class instance
105      input_tmpl = open('generate/templates/py_comp/_sampleComp.py', 'r')
106
107      #create the main .py file for the component
108      output = open(self.path + comp.name + '/' + comp.name + '.py', 'w')
109 
110      #add the generic public license to the beginning of the component main .py file
111      self.addGPL(output, comp.name)   
112
113      for line in input_tmpl.readlines():
114          l_out = line.replace('__CLASS_NAME__',comp.name)
115          if l_out.find("__PORT_DECL__") != -1:
116              self.writePortDecl(output,comp)
117              continue
118          if l_out.find("__GET_PORT__") != -1:
119              self.writeGetPort(output,comp)
120              continue
121          if l_out.find("__READ_PROPS__") != -1:
122              self.writeReadProps(output,comp)
123              continue
124          if l_out.find("__REL_MAIN_PROCESS_THREADS__") != -1:
125              self.writeReleaseMainProcessThreads(output,comp)
126              continue
127          if l_out.find("__DEACTIVATE_PORTS__") != -1:
128              self.writeDeactivatePorts(output,comp)
129              continue
130          if l_out.find("__DATA_IN_CLASS_DEFS__") != -1:
131              self.writeDataInClassDefs(output,comp)
132              continue
133          if l_out.find("__DATA_OUT_CLASS_DEFS__") != -1:
134              self.writeDataOutClassDefs(output,comp)
135              continue
136          if l_out.find("__TIMING_MESSAGE_DEF__") != -1:
137              self.writeTimingMessageDef(output,comp)
138              continue
139
140          output.write(l_out)  #if none of the continue statements have been executed
141
142      input_tmpl.close()
143      output.close()
144     
145      # TODO: figure out this command
146      #os.chmod(self.path + comp.name + '/' + comp.name + '.py', os.X_OK | os.R_OK | os.W_OK)
147      #-------------------------------------------------------------------------
148
149
150      #-------------------------------------------------------------------------
151      '''
152      ##########################################################################
153      ## generate WorkModule.py file
154      ##########################################################################
155      '''
156      #TODO: write all the code for the WorkModule based on component class instance
157      input_wm = open('generate/templates/py_comp/WorkModule.py', 'r')
158
159      #create the WorkModule.py file for the component
160      output_wm = open(self.path + comp.name + '/' + 'WorkModule.py', 'w')
161 
162      #add the generic public license to the beginning of the generated WorkModule file
163      self.addGPL(output_wm, comp.name)   
164
165      for line in input_wm.readlines():
166         l_out = line.replace('__CLASS_NAME__',comp.name)
167         output_wm.write(l_out)
168
169      input_wm.close()
170      output_wm.close()
171      #-----------------------------------------------------------------------------
172  #----------------------------------------------------------------------------------
173     
174
175
176
177
178  #-----------------------------------------------------------------------------------
179  def writePortDecl(self,output,comp):
180    """ This function writes the corba declarations of the ports to the init method"""
181
182    inCount = 0
183    for p in comp.ports:
184        if p.type == "Provides":
185            ts = " "*8 + "self.inPort" + str(inCount) + '_servant = dataIn_complexShort_i(self, "' + p.name + '")\n'
186            ts = ts + " "*8 + 'self.inPort' + str(inCount) + '_var = self.inPort' + str(inCount) + '_servant._this()\n\n' 
187            output.write(ts)
188            inCount += 1
189
190    outCount = 0
191    for p in comp.ports:
192        if p.type == "Uses":
193            ts = " "*8 + 'self.outPort' + str(outCount) + '_servant = dataOut_' + p.interface.name + '_i(self, "' + p.name + '")\n'
194            ts = ts + " "*8 + 'self.outPort' + str(outCount) + '_var = self.outPort' + str(outCount) + '_servant._this()\n'
195            ts = ts + " "*8 + 'self.outPort' + str(outCount) + '_active = False\n\n'
196            output.write(ts)
197            outCount += 1
198  #-------------------------------------------------------------------------------------   
199
200  #-------------------------------------------------------------------------------------
201  def writeGetPort(self,output,comp):
202    inCount = 0
203    for p in comp.ports:
204        if p.type == "Provides":
205            ts = " "*8 + 'if str(id) == "' + p.name + '":\n'
206            ts = ts + " "*12 + 'return ' + 'self.inPort' + str(inCount) + '_var\n'
207            output.write(ts)
208            inCount += 1
209
210    outCount = 0
211    for p in comp.ports:
212        if p.type == "Uses":
213            ts = " "*8 + 'if str(id) == "' + p.name + '":\n'
214            ts = ts + " "*12 + 'return ' + 'self.outPort' + str(outCount) + '_var\n'
215            output.write(ts)
216            inCount += 1
217  #-------------------------------------------------------------------------------------
218
219
220  #-------------------------------------------------------------------------------------
221  def writeReadProps(self,output,comp):
222    '''write teh code that will read propeties from the prf file'''
223    # TODO: test this method
224
225    # check to make sure there are properties
226    # TODO: use a more efficient method
227    props_present = False
228    for p in comp.properties:
229        props_present = True
230
231    # if there are properties present, open up a for loop to cycle through them
232    if props_present:
233        ts = " "*8 + "for property in props:\n"
234        output.write(ts)
235
236    for p in comp.properties:
237        ts = " "*12 + "if property not in self.propertySet:\n"; output.write(ts)
238        ts = " "*16 + "self.propertySet.append(property)\n"; output.write(ts)
239
240        if p.elementType == "Simple":
241            ts = " "*12 + "if property.id == '" +  p.id + "':\n"; output.write(ts)
242            # TODO: find out if int() type casting is needed
243            ts = " "*16 + p.name " = int(property.value.value())\n"; output.write(ts)
244
245        elif p.elementType == "SimpleSequence":
246            ts = " "*12 + "if property.id == '" +  p.id + "':\n"; output.write(ts)
247            ts = " "*16 + str(p.name) + " = []\n"; output.write(ts)
248            # TODO: find out if int() type casting is needed
249            ts = " "*16 + str(p.name) + ".extend(int([val for val in property.values.value()))\n"; output.write(ts)
250
251        else:
252            print "Element types other than simple and simple sequence not supported in writeReadProps in generate/templates/py_comp/genStructure.py"
253            return
254
255
256
257  #-------------------------------------------------------------------------------------
258
259
260  #-------------------------------------------------------------------------------------
261  def writeReleaseMainProcessThreads(self,output,comp):
262    #TODO: comment this method
263    #TODO: test this method
264    outCount = 0
265    for p in comp.ports:
266        if p.type == "Uses":
267            ts = " "*8 + "self.outPort" + str(outCount) + "_servant.releasePort()\n"
268            output.write(ts)
269            outCount += 1
270  #-------------------------------------------------------------------------------------
271
272
273  #------------------------------------------------------------------------------------
274  def writeDeactivatePorts(self,output,comp):
275    #TODO: comment this method
276    #TODO: test this method
277    inCount = 0
278    for p in comp.ports:
279        if p.type == "Provides":
280            ts = " "*8 + "iid" + str(inCount) + " = self.poa.reference_to_id(self.inPort" + str(inCount) + "_var)\n"
281            output.write(ts)
282            inCount += 1
283   
284    outCount = 0
285    for p in comp.ports:
286        if p.type == "Uses":
287            ts = " "*8 + "oid" + str(outCount) + " = self.poa.reference_to_id(self.outPort" + str(outCount) + "_var)\n"
288            output.write(ts)
289            inCount += 1
290
291    ts = "\n"; output.write(ts)
292
293    inCount = 0
294    for p in comp.ports:
295        if p.type == "Provides":
296            ts = " "*8 + "self.poa.deactivate_object(iid" + str(inCount) + ")\n"
297            output.write(ts)
298            inCount += 1
299
300    outCount = 0
301    for p in comp.ports:
302        if p.type == "Uses":
303            ts = " "*8 + "self.poa.deactivate_object(oid" + str(outCount) + ")\n"
304            output.write(ts)
305            outCount += 1
306  #------------------------------------------------------------------------------------
307
308
309  #------------------------------------------------------------------------------------
310  def writeDataInClassDefs(self,output,comp):
311    '''Generates the code for the in port class definitions'''
312
313    def_types_written = " "   #keeps track of the interface names that have been written already so that a certain interface (e.g., complexShort) does not get defined more than once
314
315    for p in comp.ports:
316        if p.type == "Provides" and def_types_written.find(p.interface.name) == -1:
317            ts = "#------------------------------------------------------------------\n"
318            ts = ts + "# dataIn_" + p.interface.name + "_i class definition\n"
319            ts = ts + "#------------------------------------------------------------------\n"     
320            ts = ts + "class dataIn_" + p.interface.name + "_i(" + p.interface.nameSpace + "__POA." + p.interface.name + "):\n"
321            ts = ts + " "*4 + "def __init__(self, parent, name):\n"
322            ts = ts + " "*8 + "self.parent = parent\n"
323            ts = ts + " "*8 + "self.name = name\n\n"
324            ts = ts + " "*4 + "# WARNING:  I and Q may have to be changed depending on what data you are receiving (e.g., bytesIn for realChar)\n"
325            ts = ts + " "*4 + "def pushPacket(self, I, Q):\n"
326            ts = ts + " "*8 + "self.parent.work_mod.AddData(I, Q)\n"
327            ts = ts + "\n"
328            output.write(ts)
329
330            def_types_written = def_types_written + p.interface.name       
331  #------------------------------------------------------------------------------------
332
333
334  #------------------------------------------------------------------------------------
335  def writeDataOutClassDefs(self,output,comp):
336    '''generates the code for the out port class definitions'''
337    def_types_written = " "    #keeps track of the interface names that have been written already so that a certain interface (e.g., complexShort) does not get defined more than once
338    out_port_count = -1
339
340    for p in comp.ports:
341        if p.type == "Uses" and def_types_written.find(p.interface.name) == -1:
342            out_port_count = out_port_count + 1
343
344            ts = "#------------------------------------------------------------------\n"
345            ts = ts + "# dataOut_complexShort_i class definition\n"
346            ts = ts + "#------------------------------------------------------------------\n"
347            ts = ts + "class dataOut_" + p.interface.name + "_i(CF__POA.Port):\n"
348            output.write(ts)
349 
350            #create the __init__ method
351            ts = " "*4 + "def __init__(self, parent, name):\n\
352        self.parent = parent\n\
353        self.outPorts = {}\n\
354        self.name = name\n\
355        \n\
356        self.data_buffer = []\n\
357        self.data_event = threading.Event()\n\
358        self.data_buffer_lock = threading.Lock()\n\
359        \n\
360        self.is_running = True\n\
361        self.process_thread = threading.Thread(target = self.Process)\n\
362        self.process_thread.start()\n\n"
363            output.write(ts)
364
365            #create connectPort method
366            ts = " "*4 + "def connectPort(self, connection, connectionId):\n"
367            ts = ts + " "*8 + "port = connection._narrow(" + p.interface.nameSpace + "__POA." + p.interface.name + ")\n"
368            ts = ts + " "*8 + "self.outPorts[str(connectionId)] = port\n"
369            ts = ts + " "*8 + "self.parent.outPort" + str(out_port_count) + "_active = True\n\n"
370            output.write(ts)
371       
372            #create disconnectPort method
373            ts = " "*4 + "def disconnectPort(self, connectionId):\n\
374        self.outPorts.pop(str(connectionId))\n\
375        if len(self.outPorts)==0:\n\
376            self.parent.outPort0_active = False\n\n"
377            output.write(ts)
378
379            #create releasePort method
380            ts = " "*4 + "def releasePort(self):\n\
381        # shut down the Process thread\n\
382        self.is_running = False\n\
383        self.data_event.set()\n\n"
384            output.write(ts)
385       
386            #create send_data method
387            ts = " "*4 + "# WARNING:  I and Q may have to be changed depending on what data you are receiving (e.g., bytesIn for realChar)\n\
388    def send_data(self, I, Q):\n\
389        self.data_buffer_lock.acquire()\n\
390        self.data_buffer.insert(0, (I,Q))\n\
391        self.data_buffer_lock.release()\n\
392        self.data_event.set()\n\n"
393            output.write(ts)
394       
395            #create Process method
396            ts = " "*4 + "def Process(self):\n\
397        while self.is_running:\n\
398            self.data_event.wait()\n\
399            while len(self.data_buffer) > 0:\n\
400                self.data_buffer_lock.acquire()\n\
401                new_data = self.data_buffer.pop()\n\
402                self.data_buffer_lock.release()\n\
403                \n\
404                for port in self.outPorts.values():\n\
405                    port.pushPacket(new_data[0], new_data[1])\n\
406                \n\
407                self.data_event.clear()\n\n"
408            output.write(ts)
409
410                   
411            def_types_written = def_types_written + p.interface.name     
412  #------------------------------------------------------------------------------------
413
414
415         
416  def writePortInst(self,output,c):
417    """ This function writes the port instantiations to the component cpp file"""
418    inCount = 0; outCount=0;
419    for x in c.ports:
420        if x.type == "Provides":
421            ts = " "*4 + "inPort" + str(inCount) + "_servant" + " = new " + x.cname + "(this);\n"
422            output.write(ts)
423            ts = " "*4 + "inPort" + str(inCount) + "_var = inPort" + str(inCount)+ "_servant->_this();\n"
424            output.write(ts)
425            inCount += 1
426    ts = "\n"; output.write(ts)
427    for x in c.ports:
428        if x.type == "Uses":
429            ts = " "*4 + "outPort" + str(outCount) + "_servant" + " = new " + x.cname + "(this);\n"
430            output.write(ts)
431            ts = " "*4 + "outPort" + str(outCount) + "_var = outPort" + str(outCount)+ "_servant->_this();\n"
432            ts += " "*4 + "outPort" + str(outCount) + "_active = false;\n"
433            ts += " "*4 + "outPort" + str(outCount) + "_queue_size = DEFAULT_QUEUE_BLOCK_SIZE;\n"
434            output.write(ts)
435            outCount += 1
436    ts = "\n"; output.write(ts)
437    ts = " "*4 + "queue_size = DEFAULT_QUEUE_BLOCK_SIZE;\n\n" + " "*4 + "component_alive = true;\n\n" + " "*4 + "naming_service_name = label;\n"; output.write(ts)
438
439   
440  def writeDelPort(self,output,c):
441    """ This function writes the destructor functionality (for ports) to the component cpp file"""
442    inCount = 0; outCount=0;
443    flag = True
444    for x in c.ports:
445        if x.type == "Provides":
446            ts = " "*4 + "delete inPort" + str(inCount) + "_servant;\n"
447            output.write(ts)
448            inCount += 1
449    ts = "\n"; output.write(ts)
450    for x in c.ports:
451        if x.type == "Uses":
452            ts = " "*4 + "delete outPort" + str(outCount) + "_servant;\n"
453            output.write(ts)
454            outCount += 1
455    ts = "\n"; output.write(ts)
456       
457
458
459  #------------------------------------------------------------------------------------
460  def writeTimingMessageDef(self, output,c):
461    if c.timing == True:
462        ts = "\n#------------------------------------------------------------------\n"
463        ts = ts + "# dataOut_timingStatus_i class definition\n"
464        ts = ts + "#------------------------------------------------------------------\n"
465        output.write(ts)
466        ts = "\n\
467class dataOut_timingStatus_i(CF__POA.Port):\n\
468    def __init__(self, parent, name):\n\
469        self.parent = parent\n\
470        self.outPorts = {}\n\
471        self.name = name\n\
472        \n\
473        self.message_buffer = []\n\
474        self.timing_event = threading.Event()\n\
475        self.message_buffer_lock = threading.Lock()\n\
476        \n\
477        self.is_running = True\n\
478        self.process_thread = threading.Thread(target = self.Process)\n\
479        self.process_thread.start()\n\
480        \n\
481    def connectPort(self, connection, connectionId):\n\
482        port = connection._narrow(customInterfaces__POA.timingStatus)\n\
483        self.outPorts[str(connectionId)] = port\n\
484        self.parent.outPort1_active = True\n\
485    \n\
486    def disconnectPort(self, connectionId):\n\
487        self.outPorts.pop(str(connectionId))\n\
488        if len(self.outPorts) == 0:\n\
489            self.parent.outPort1_active = False\n\
490    \n\
491    def releasePort(self):\n\
492        # shut down the Process thread\n\
493        self.is_running = False\n\
494        self.timing_event.set()\n\
495        \n\
496    def send_timing_message(self, component_name, port_name, function_name, description, number_samples):\n\
497        tv = time.time()\n\
498        tv_sec = int(tv)\n\
499        tv_usec = int((tv-tv_sec)*1000000)\n\
500        \n\
501        tmpmsg = (str(component_name), str(port_name), str(function_name), str(description), tv_sec, tv_usec, number_samples)\n\
502        \n\
503        self.message_buffer_lock.acquire()\n\
504        self.message_buffer.insert(0, tmpmsg)\n\
505        self.message_buffer_lock.release()\n\
506        \n\
507        self.timing_event.set()\n\
508    \n\
509    def Process(self):\n\
510        while self.is_running:\n\
511            self.timing_event.wait()\n\
512            while len(self.message_buffer) > 0:\n\
513                self.message_buffer_lock.acquire()\n\
514                newmsg = self.message_buffer.pop()\n\
515                self.message_buffer_lock.release()\n\
516                \n\
517                for port in self.outPorts.values():\n\
518                    port.send_timing_event(newmsg[0], newmsg[1], newmsg[2], newmsg[3], newmsg[4], newmsg[5], newmsg[6])\n\
519            \n\
520            else:\n\
521                self.timing_event.clear()\n\n"
522        output.write(ts)
523  #------------------------------------------------------------------------------------
524
525
526
527     
528  def addGPL(self,outFile,name):
529      '''Creates a GPL for the component.  The new GPL will have the component
530name.  The new GPL is written to the beginning of the outFile'''
531
532      inFile = open('generate/gpl_preamble','r')
533      outFile.write('#! /usr/bin/env python\n\n')
534      outFile.write("'''\n")
535      for line in inFile.readlines():
536          l_out = line.replace("__COMP_NAME__",name)
537          outFile.write(l_out)
538      outFile.write("'''\n\n") 
539      inFile.close()
540         
541       
542       
Note: See TracBrowser for help on using the browser.