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

Revision 4314, 22.1 KB (checked in by DrewCormier, 6 years ago)

only need to add to the properties list once

  • 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    simpleCount = 0
225    simplesequenceCount = 0
226
227    # check to make sure there are properties
228    # TODO: use a more efficient method
229    props_present = False
230    for p in comp.properties:
231        props_present = True
232
233    # if there are properties present, open up a for loop to cycle through them
234    if props_present:
235        ts = " "*8 + "for property in props:\n"
236        output.write(ts)
237
238    for p in comp.properties:
239        ts = " "*12 + "if property not in self.propertySet:\n"; output.write(ts)
240        ts = " "*16 + "self.propertySet.append(property)\n"; output.write(ts)
241
242        if p.elementType == "Simple":
243            ts = " "*12 + "if property.id == '" +  p.id + "':\n"; output.write(ts)
244            # TODO: find out if int() type casting is needed
245            ts = " "*16 + "simpleProperty" + str(simpleCount) + " = int(property.value.value())\n"; output.write(ts)
246            simpleCount = simpleCount + 1
247
248        elif p.elementType == "SimpleSequence":
249            ts = " "*12 + "if property.id == '" +  p.id + "':\n"; output.write(ts)
250            ts = " "*16 + "simpleSequenceProperty" + str(simplesequenceCount) + " = []\n"; output.write(ts)
251            # TODO: find out if int() type casting is needed
252            ts = " "*16 + "simpleSequenceProperty" + str(simplesequenceCount) + ".extend(int([val for val in property.values.value()))\n"; output.write(ts)
253            simplesequenceCount = simplesequenceCount + 1
254
255        else:
256            print "Element types other than simple and simple sequence not supported in writeReadProps in generate/templates/py_comp/genStructure.py"
257            return
258
259
260
261  #-------------------------------------------------------------------------------------
262
263
264  #-------------------------------------------------------------------------------------
265  def writeReleaseMainProcessThreads(self,output,comp):
266    #TODO: comment this method
267    #TODO: test this method
268    outCount = 0
269    for p in comp.ports:
270        if p.type == "Uses":
271            ts = " "*8 + "self.outPort" + str(outCount) + "_servant.releasePort()\n"
272            output.write(ts)
273            outCount += 1
274  #-------------------------------------------------------------------------------------
275
276
277  #------------------------------------------------------------------------------------
278  def writeDeactivatePorts(self,output,comp):
279    #TODO: comment this method
280    #TODO: test this method
281    inCount = 0
282    for p in comp.ports:
283        if p.type == "Provides":
284            ts = " "*8 + "iid" + str(inCount) + " = self.poa.reference_to_id(self.inPort" + str(inCount) + "_var)\n"
285            output.write(ts)
286            inCount += 1
287   
288    outCount = 0
289    for p in comp.ports:
290        if p.type == "Uses":
291            ts = " "*8 + "oid" + str(outCount) + " = self.poa.reference_to_id(self.outPort" + str(outCount) + "_var)\n"
292            output.write(ts)
293            inCount += 1
294
295    ts = "\n"; output.write(ts)
296
297    inCount = 0
298    for p in comp.ports:
299        if p.type == "Provides":
300            ts = " "*8 + "self.poa.deactivate_object(iid" + str(inCount) + ")\n"
301            output.write(ts)
302            inCount += 1
303
304    outCount = 0
305    for p in comp.ports:
306        if p.type == "Uses":
307            ts = " "*8 + "self.poa.deactivate_object(oid" + str(outCount) + ")\n"
308            output.write(ts)
309            outCount += 1
310  #------------------------------------------------------------------------------------
311
312
313  #------------------------------------------------------------------------------------
314  def writeDataInClassDefs(self,output,comp):
315    '''Generates the code for the in port class definitions'''
316
317    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
318
319    for p in comp.ports:
320        if p.type == "Provides" and def_types_written.find(p.interface.name) == -1:
321            ts = "#------------------------------------------------------------------\n"
322            ts = ts + "# dataIn_" + p.interface.name + "_i class definition\n"
323            ts = ts + "#------------------------------------------------------------------\n"     
324            ts = ts + "class dataIn_" + p.interface.name + "_i(" + p.interface.nameSpace + "__POA." + p.interface.name + "):\n"
325            ts = ts + " "*4 + "def __init__(self, parent, name):\n"
326            ts = ts + " "*8 + "self.parent = parent\n"
327            ts = ts + " "*8 + "self.name = name\n\n"
328            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"
329            ts = ts + " "*4 + "def pushPacket(self, I, Q):\n"
330            ts = ts + " "*8 + "self.parent.work_mod.AddData(I, Q)\n"
331            ts = ts + "\n"
332            output.write(ts)
333
334            def_types_written = def_types_written + p.interface.name       
335  #------------------------------------------------------------------------------------
336
337
338  #------------------------------------------------------------------------------------
339  def writeDataOutClassDefs(self,output,comp):
340    '''generates the code for the out port class definitions'''
341    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
342    out_port_count = -1
343
344    for p in comp.ports:
345        if p.type == "Uses" and def_types_written.find(p.interface.name) == -1:
346            out_port_count = out_port_count + 1
347
348            ts = "#------------------------------------------------------------------\n"
349            ts = ts + "# dataOut_complexShort_i class definition\n"
350            ts = ts + "#------------------------------------------------------------------\n"
351            ts = ts + "class dataOut_" + p.interface.name + "_i(CF__POA.Port):\n"
352            output.write(ts)
353 
354            #create the __init__ method
355            ts = " "*4 + "def __init__(self, parent, name):\n\
356        self.parent = parent\n\
357        self.outPorts = {}\n\
358        self.name = name\n\
359        \n\
360        self.data_buffer = []\n\
361        self.data_event = threading.Event()\n\
362        self.data_buffer_lock = threading.Lock()\n\
363        \n\
364        self.is_running = True\n\
365        self.process_thread = threading.Thread(target = self.Process)\n\
366        self.process_thread.start()\n\n"
367            output.write(ts)
368
369            #create connectPort method
370            ts = " "*4 + "def connectPort(self, connection, connectionId):\n"
371            ts = ts + " "*8 + "port = connection._narrow(" + p.interface.nameSpace + "__POA." + p.interface.name + ")\n"
372            ts = ts + " "*8 + "self.outPorts[str(connectionId)] = port\n"
373            ts = ts + " "*8 + "self.parent.outPort" + str(out_port_count) + "_active = True\n\n"
374            output.write(ts)
375       
376            #create disconnectPort method
377            ts = " "*4 + "def disconnectPort(self, connectionId):\n\
378        self.outPorts.pop(str(connectionId))\n\
379        if len(self.outPorts)==0:\n\
380            self.parent.outPort0_active = False\n\n"
381            output.write(ts)
382
383            #create releasePort method
384            ts = " "*4 + "def releasePort(self):\n\
385        # shut down the Process thread\n\
386        self.is_running = False\n\
387        self.data_event.set()\n\n"
388            output.write(ts)
389       
390            #create send_data method
391            ts = " "*4 + "# WARNING:  I and Q may have to be changed depending on what data you are receiving (e.g., bytesIn for realChar)\n\
392    def send_data(self, I, Q):\n\
393        self.data_buffer_lock.acquire()\n\
394        self.data_buffer.insert(0, (I,Q))\n\
395        self.data_buffer_lock.release()\n\
396        self.data_event.set()\n\n"
397            output.write(ts)
398       
399            #create Process method
400            ts = " "*4 + "def Process(self):\n\
401        while self.is_running:\n\
402            self.data_event.wait()\n\
403            while len(self.data_buffer) > 0:\n\
404                self.data_buffer_lock.acquire()\n\
405                new_data = self.data_buffer.pop()\n\
406                self.data_buffer_lock.release()\n\
407                \n\
408                for port in self.outPorts.values():\n\
409                    port.pushPacket(new_data[0], new_data[1])\n\
410                \n\
411                self.data_event.clear()\n\n"
412            output.write(ts)
413
414                   
415            def_types_written = def_types_written + p.interface.name     
416  #------------------------------------------------------------------------------------
417
418
419         
420  def writePortInst(self,output,c):
421    """ This function writes the port instantiations to the component cpp file"""
422    inCount = 0; outCount=0;
423    for x in c.ports:
424        if x.type == "Provides":
425            ts = " "*4 + "inPort" + str(inCount) + "_servant" + " = new " + x.cname + "(this);\n"
426            output.write(ts)
427            ts = " "*4 + "inPort" + str(inCount) + "_var = inPort" + str(inCount)+ "_servant->_this();\n"
428            output.write(ts)
429            inCount += 1
430    ts = "\n"; output.write(ts)
431    for x in c.ports:
432        if x.type == "Uses":
433            ts = " "*4 + "outPort" + str(outCount) + "_servant" + " = new " + x.cname + "(this);\n"
434            output.write(ts)
435            ts = " "*4 + "outPort" + str(outCount) + "_var = outPort" + str(outCount)+ "_servant->_this();\n"
436            ts += " "*4 + "outPort" + str(outCount) + "_active = false;\n"
437            ts += " "*4 + "outPort" + str(outCount) + "_queue_size = DEFAULT_QUEUE_BLOCK_SIZE;\n"
438            output.write(ts)
439            outCount += 1
440    ts = "\n"; output.write(ts)
441    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)
442
443   
444  def writeDelPort(self,output,c):
445    """ This function writes the destructor functionality (for ports) to the component cpp file"""
446    inCount = 0; outCount=0;
447    flag = True
448    for x in c.ports:
449        if x.type == "Provides":
450            ts = " "*4 + "delete inPort" + str(inCount) + "_servant;\n"
451            output.write(ts)
452            inCount += 1
453    ts = "\n"; output.write(ts)
454    for x in c.ports:
455        if x.type == "Uses":
456            ts = " "*4 + "delete outPort" + str(outCount) + "_servant;\n"
457            output.write(ts)
458            outCount += 1
459    ts = "\n"; output.write(ts)
460       
461
462
463  #------------------------------------------------------------------------------------
464  def writeTimingMessageDef(self, output,c):
465    if c.timing == True:
466        ts = "\n#------------------------------------------------------------------\n"
467        ts = ts + "# dataOut_timingStatus_i class definition\n"
468        ts = ts + "#------------------------------------------------------------------\n"
469        output.write(ts)
470        ts = "\n\
471class dataOut_timingStatus_i(CF__POA.Port):\n\
472    def __init__(self, parent, name):\n\
473        self.parent = parent\n\
474        self.outPorts = {}\n\
475        self.name = name\n\
476        \n\
477        self.message_buffer = []\n\
478        self.timing_event = threading.Event()\n\
479        self.message_buffer_lock = threading.Lock()\n\
480        \n\
481        self.is_running = True\n\
482        self.process_thread = threading.Thread(target = self.Process)\n\
483        self.process_thread.start()\n\
484        \n\
485    def connectPort(self, connection, connectionId):\n\
486        port = connection._narrow(customInterfaces__POA.timingStatus)\n\
487        self.outPorts[str(connectionId)] = port\n\
488        self.parent.outPort1_active = True\n\
489    \n\
490    def disconnectPort(self, connectionId):\n\
491        self.outPorts.pop(str(connectionId))\n\
492        if len(self.outPorts) == 0:\n\
493            self.parent.outPort1_active = False\n\
494    \n\
495    def releasePort(self):\n\
496        # shut down the Process thread\n\
497        self.is_running = False\n\
498        self.timing_event.set()\n\
499        \n\
500    def send_timing_message(self, component_name, port_name, function_name, description, number_samples):\n\
501        tv = time.time()\n\
502        tv_sec = int(tv)\n\
503        tv_usec = int((tv-tv_sec)*1000000)\n\
504        \n\
505        tmpmsg = (str(component_name), str(port_name), str(function_name), str(description), tv_sec, tv_usec, number_samples)\n\
506        \n\
507        self.message_buffer_lock.acquire()\n\
508        self.message_buffer.insert(0, tmpmsg)\n\
509        self.message_buffer_lock.release()\n\
510        \n\
511        self.timing_event.set()\n\
512    \n\
513    def Process(self):\n\
514        while self.is_running:\n\
515            self.timing_event.wait()\n\
516            while len(self.message_buffer) > 0:\n\
517                self.message_buffer_lock.acquire()\n\
518                newmsg = self.message_buffer.pop()\n\
519                self.message_buffer_lock.release()\n\
520                \n\
521                for port in self.outPorts.values():\n\
522                    port.send_timing_event(newmsg[0], newmsg[1], newmsg[2], newmsg[3], newmsg[4], newmsg[5], newmsg[6])\n\
523            \n\
524            else:\n\
525                self.timing_event.clear()\n\n"
526        output.write(ts)
527  #------------------------------------------------------------------------------------
528
529
530
531     
532  def addGPL(self,outFile,name):
533      '''Creates a GPL for the component.  The new GPL will have the component
534name.  The new GPL is written to the beginning of the outFile'''
535
536      inFile = open('generate/gpl_preamble','r')
537      outFile.write('#! /usr/bin/env python\n\n')
538      outFile.write("'''\n")
539      for line in inFile.readlines():
540          l_out = line.replace("__COMP_NAME__",name)
541          outFile.write(l_out)
542      outFile.write("'''\n\n") 
543      inFile.close()
544         
545       
546       
Note: See TracBrowser for help on using the browser.