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

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

should write nothing and replace TIMING_MESSAGE_DEF tag if timing is not selected

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