source: osgVisual/trunk/src/extLink/dataIO_extLinkVCL.cpp @ 394

Last change on this file since 394 was 240, checked in by Torben Dannhauer, 14 years ago
File size: 8.3 KB
Line 
1/* -*-c++-*- osgVisual - Copyright (C) 2009-2011 Torben Dannhauer
2 *
3 * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
9 * You have to aquire licenses for all used proprietary modules.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * OpenSceneGraph Public License for more details.
15*/
16
17#include <dataIO_extLinkVCL.h>
18
19#include <visual_dataIO.h>      // include in.cpp to avoid circular inclusion (visual_dataIO <-> extLinkVCL)
20
21using namespace osgVisual;
22
23dataIO_extLinkVCL::dataIO_extLinkVCL(std::vector<dataIO_slot *>& dataSlots_) : dataIO_extLink(dataSlots_)
24{
25        OSG_NOTIFY( osg::ALWAYS ) << "extLinkVCL constructed" << std::endl;
26}
27
28dataIO_extLinkVCL::~dataIO_extLinkVCL(void)
29{
30        OSG_NOTIFY( osg::ALWAYS ) << "extLinkVCL destroyed" << std::endl;
31}
32
33bool dataIO_extLinkVCL::init(xmlNode* configurationNode)
34{
35        if (!configurationNode || !processXMLConfiguration(configurationNode))
36                return false;
37
38        OSG_NOTIFY( osg::ALWAYS ) << "extLinkVCL init()" << std::endl;
39
40        if ( osgDB::fileExists( VCLConfigFilename ) )
41        {
42                CVCLIO::GetInstance().LoadProject(VCLConfigFilename.c_str());
43
44                parseVCLConfig();
45               
46                initialized = true;
47        }
48        else
49        {
50                OSG_NOTIFY( osg::FATAL ) << "ERROR: Could not find VCL Configuration file '" << VCLConfigFilename << "', falling back to extLinkDummy" << std::endl;
51                return false;
52        }
53        return true;
54}
55
56bool dataIO_extLinkVCL::processXMLConfiguration(xmlNode* extLinkConfig_)
57{
58        // Extract VCL config file
59        xmlAttr  *attr = extLinkConfig_->properties;
60        while ( attr ) 
61        { 
62                std::string attr_name=reinterpret_cast<const char*>(attr->name);
63                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
64                if( attr_name == "implementation" )
65                {
66                        if(attr_value != "vcl")
67                        {
68                                OSG_NOTIFY( osg::ALWAYS ) << "WARNING: extLink configuration does not match the currently used 'vcl' implementation, falling back to extLinkDummy" << std::endl;
69                                return false;
70                        }
71                }
72                if( attr_name == "filename" )
73                {
74                        VCLConfigFilename = attr_value;
75                }
76                attr = attr->next; 
77        }       // WHILE attrib END
78
79        return true;
80}
81
82void dataIO_extLinkVCL::shutdown()
83{
84        OSG_NOTIFY( osg::ALWAYS ) << "extLinkVCL shutdown()" << std::endl;
85}
86
87bool dataIO_extLinkVCL::readTO_OBJvalues()
88{
89        OSG_NOTIFY( osg::INFO ) << "extLinkVCL readTO_OBJvalues()" << std::endl;
90
91        // perform external data exchange
92        CVCLIO::GetInstance().DoDataExchange();
93
94        // read TO_OBJ values from VCL
95        for(unsigned int i=0;i<extLinkChannels.size();i++)
96        {
97                if(extLinkSlots[i]->getdataDirection() == osgVisual::dataIO_slot::TO_OBJ)
98                {
99                        //Copy data from VCL to slot. IMPORTANT: Due to VCL's string incapability only double slots are filled.
100                        osgVisual::visual_dataIO::getInstance()->setSlotData( extLinkSlots[i]->getVariableName(), osgVisual::dataIO_slot::TO_OBJ, extLinkChannels[i]->GetValue() );
101                }       // IF (TO_OBJ) END
102        }
103
104        return true;
105}
106
107bool dataIO_extLinkVCL::writebackFROM_OBJvalues()
108{
109        OSG_NOTIFY( osg::INFO ) << "extLinkVCL writebackFROM_OBJvalues()" << std::endl;
110
111        // write FROM_OBJ values into VCL
112        for(unsigned int i=0;i<extLinkChannels.size();i++)
113        {
114                if(extLinkSlots[i]->getdataDirection() == osgVisual::dataIO_slot::FROM_OBJ && extLinkSlots[i]->getvarType() == osgVisual::dataIO_slot::DOUBLE)
115                {
116                        //Copy data from slot to VCL. IMPORTANT: Due to VCL's string incapability only double slots are filled.
117                        extLinkChannels[i]->SetValue( osgVisual::visual_dataIO::getInstance()->getSlotDataAsDouble( extLinkSlots[i]->getVariableName(), osgVisual::dataIO_slot::FROM_OBJ ) );
118                }       // IF (FROM_OBJ) END
119        }
120
121        /* In VCL no VCL dataexchange is performed,
122        it is postponed until the next frame beginning,
123        where TO_OBJ exchange calls CVCLIO::GetInstance().DoDataExchange();.
124        */
125        return true;
126}
127
128bool dataIO_extLinkVCL::parseVCLConfig()
129{
130        configFileValid = false;
131        xmlDoc *doc = NULL;
132    xmlNode *root_element = NULL;
133       
134        doc = xmlReadFile(VCLConfigFilename.c_str(), NULL, 0);
135        if (doc == NULL)
136        {
137                configFileValid = false;
138                std::cout << "error: could not parse file" << VCLConfigFilename;
139        }
140        else
141        {
142                //  Get the root element node
143                root_element = xmlDocGetRootElement(doc);
144
145                // Parse the XML document.
146                checkXMLNode(root_element);
147
148                // free the document
149                xmlFreeDoc(doc);;
150        }
151        // Free the global variables that may have been allocated by the parser.
152        xmlCleanupParser();
153
154        if(!configFileValid)
155                OSG_ALWAYS << "ERROR: XML file seems not to be a valid VCL configuration file!" << std::endl;
156
157        return true;
158}
159
160void dataIO_extLinkVCL::checkXMLNode(xmlNode * a_node)
161{
162    for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
163        {
164                std::string node_name=reinterpret_cast<const char*>(cur_node->name);
165                if(cur_node->type == XML_ELEMENT_NODE && node_name == "CONFIGURATION")
166                {
167                        //OSG_DEBUG << "XML node CONFIGURATION found" << std::endl;
168                        configFileValid = true;
169                }
170
171        if (cur_node->type == XML_ELEMENT_NODE && node_name == "CHANNEL")
172                {
173                        //OSG_DEBUG << "XML node CHANNEL found" << std::endl;
174
175                        // Extract channel infos like name, direction and extract channels
176                        std::string name;
177                        dataIO_slot::dataDirection direction;
178                        xmlAttr  *attr = cur_node->properties;
179                        while ( attr ) 
180                        { 
181                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
182                                if( attr_name == "name" )
183                                        name = reinterpret_cast<const char*>(attr->children->content);
184                                if( attr_name == "multicast_in_group" )
185                                        direction = dataIO_slot::TO_OBJ;
186                                if( attr_name == "multicast_out_group" )
187                                        direction = dataIO_slot::FROM_OBJ;
188                                //std::cout << "Attribute name: " << attr->name << " value: " << attr->children->content << std::endl;
189                                attr = attr->next; 
190                        } 
191                        addChannels(cur_node->children, name, direction );
192       
193            //OSG_DEBUG << "node type=Element, name:" << cur_node->name << std::endl;
194                        //OSG_DEBUG << "Processing children at " << cur_node->children << std::endl;
195        }       // IF(CHANNEL) END
196
197                // Iterate to the next nodes to find channels.
198        checkXMLNode(cur_node->children);               
199    }   // FOR END
200}
201
202void dataIO_extLinkVCL::addChannels(xmlNode * a_node, std::string channelName_, dataIO_slot::dataDirection direction_ )
203{
204        if(!a_node)
205                return;
206
207        OSG_ALWAYS << "dataIO_extL) : Processing entries for channel " << channelName_ << " with the direction " << direction_ << std::endl;
208
209        for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
210        {
211                if (cur_node->type != XML_ELEMENT_NODE) // only emelent nodes are relevant entries. otherwise skip this iteration. VCL files only contain text nodes in comments or as untrimmed element nodes.
212                        continue;               
213
214                // Extract ENTRY - name (from the Channel <ENTRY> in the XML file
215                std::string entryName;
216                xmlAttr  *attr = cur_node->properties;
217                while ( attr ) 
218                { 
219                        std::string attr_name=reinterpret_cast<const char*>(attr->name);
220                        if( attr_name == "name" )
221                                entryName = reinterpret_cast<const char*>(attr->children->content);
222                        //OSG_ALWAYS << "Attribute name: " << attr->name << " value: " << attr->children->content << std::endl;
223                        attr = attr->next; 
224                } 
225
226                // Store VCL variable
227                CVCLVariable<double>* tmp = new CVCLVariable<double>;
228                extLinkChannels.push_back(tmp);
229
230                // Attach VCL variable to channel:
231                //OSG_DEBUG << "attaching.... name: " << channelName_ << ", entryName: " << entryName << std::endl;
232                if( !tmp->Attach(channelName_.c_str(), entryName.c_str() ) )
233                        OSG_ALWAYS << "ERROR - dataIO_extLinkVCL::addChannels(): unable to attach VCL variable entryName: " << entryName << " to channel: " << channelName_ << std::endl;
234
235                // Set SLOT data and store SLOT pointer
236                osgVisual::dataIO_slot* tmpSlot = osgVisual::visual_dataIO::getInstance()->setSlotData( entryName, direction_, 0 );
237                extLinkSlots.push_back( tmpSlot );
238
239        }       // FOR each ENTRY END
240}
Note: See TracBrowser for help on using the repository browser.