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

Revision 4973, 22.8 KB (checked in by DrewCormier, 6 years ago)

generated work module now outputs data to all of the existing ports

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