Compare commits

...

321 Commits

Author SHA1 Message Date
Torsten Dreyer
69cbc2feb5 Bump to version 2.5.0 2011-07-17 11:06:45 +02:00
Torsten Dreyer
feb0b83365 Bump version to 2.4.0 2011-07-17 10:46:56 +02:00
ThorstenB
d4f5a35e87 Alert message formatting.
Avoid log output cluttering due to "missing animation objects".
2011-07-03 13:04:00 +02:00
Torsten Dreyer
da707f3e40 terrasync: some code cleanup - don't use snprintf 2011-06-28 13:16:08 +02:00
ThorstenB
59a6fd1ed8 #348: (continued) Missing sound files not reported properly
Avoid useless "File '' not found." messages for missing sound files.
2011-06-26 01:06:07 +02:00
ThorstenB
8c8d9e5cc4 #348: Missing model/texture files not reported properly
Whenever resolving a (relative) path to an absolute path with
'findDataFile', check if the result is empty and report original
(relative) path as missing. Otherwise no or a meaningless message is
issued ("File '' not found.").
2011-06-26 00:36:19 +02:00
Torsten Dreyer
d36170879c Terrasync: make whitespace in pathnames work under windows 2011-06-25 00:04:44 +02:00
ThorstenB
204e483c08 Disable support of white-space path for Windows
Apparently enclosing white-space paths using '"' doesn't work on Windows.
2011-06-23 17:20:06 +02:00
ThorstenB
f582eb5310 Improve upate interval after failed updates. 2011-06-23 17:20:06 +02:00
Torsten Dreyer
6f9a14d6c4 Fix bug #346: httpd broken
Fix bug introduced by myself in
commit b06e38699a
2011-06-22 22:40:23 +02:00
ThorstenB
76fcad0a0b Bad boundary check. Add missing parentheses. 2011-06-22 09:16:27 +02:00
ThorstenB
cc06799838 fix #353: svn doesn't like stray path separators 2011-06-20 22:46:46 +02:00
ThorstenB
8a26c382a2 Improve error handling and avoid refresh nuisances.
Ignore errors due to missing (ocean-)scenery data on SVN server.
For now, only refresh scenery tiles when ocean is replaced by actual
scenery data after download.
2011-06-20 22:10:07 +02:00
ThorstenB
22198d8bd2 Improve external SVN support.
Support white-space paths when calling external SVN utility.
Support optional configuration of absolute path to SVN utility.
2011-06-20 22:05:37 +02:00
Frederic Bouvier
d534dcadfb Compile built-in svn in MSVC if 32-bit target is selected 2011-06-15 08:13:37 +02:00
ThorstenB
708ae35068 Melchior FRANZ: fix SGPropertyNode::LAST_USED_ATTRIBUTE
fixes commit c782a32076,
(also see 38494a48d8 :) )
2011-06-14 21:49:42 +02:00
ThorstenB
50cea4f64e Csaba Halasz: fix SGTimerQueue so tasks can remove themselves properly
fixes commit c033979130
2011-06-13 14:13:48 +02:00
ThorstenB
c782a32076 Introduce "PRESERVE" flag to protect properties on sim reset.
Some specific properties need protection and shouldn't be restored to their
original values on sim-reset.
2011-06-12 20:32:13 +02:00
ThorstenB
edc877442f Add optional attribute condition to "copyProperties".
Option to only copy properties with specific attribute values.
Default is copy all (as before).
2011-06-12 13:41:38 +02:00
ThorstenB
a1fe0f6305 Make some properties read-only to avoid sim-reset issues.
Do not loose internal statistics/state on sim-reset
2011-06-12 13:31:23 +02:00
ThorstenB
cb5aee9fa4 Add missing CMake module for built-in svn-client support.
Thanks to Martin for spotting this.
2011-06-12 10:08:16 +02:00
ThorstenB
9b18b14f11 Added missing terrsync make+header files... 2011-06-11 23:58:00 +02:00
ThorstenB
0fd7bb8d3f Convert terrasync into a subsystem.
Fixed scenery tile refresh method.
Simgear automake makefiles with libsvn detection.
Simgear CMake support for libsvn (may not work :) )
2011-06-11 23:22:26 +02:00
ThorstenB
c836018ac7 Copied original terrasync sources 2011-06-11 22:55:57 +02:00
ThorstenB
ba678eabdc Add method to reload specific scenery tiles. 2011-06-09 22:24:08 +02:00
ThorstenB
9442d3d0f3 Added guarded blocking deque class.
So, what are we going to do with it... ;-)
2011-06-08 23:39:24 +02:00
Mathias Froehlich
9f0313dd0b Do not crash on exporting some EffectGeodes. 2011-06-08 13:42:30 +02:00
ThorstenB
3d109f9c4c fix #314: Nasal not working on i386/32bit systems with gcc>=4.5.x
Change magic Nasal reftag to encode a quiet NaN (qNaN) instead of a
signaling NaN (sNaN), since sNaNs cannot pass cleanly through an FPU
(an sNaN is always converted to a qNaN, even by simple FPU load/store
instructions). gcc 4.5.x uses float load/store operations more
aggressively to move our 64bit Nasal variables (naRef) around.

Signed-off-by: Andy Ross
2011-06-02 10:05:10 +02:00
Torsten Dreyer
f8a337fb9f gcc warning fix: remove unused variable 2011-05-31 15:53:25 +02:00
ThorstenB
3c0966279c fixed #260: Scale animation also scales color
Added missing normalization. Thanks to Lauri for analysing this.
2011-05-29 18:40:19 +02:00
ThorstenB
c033979130 screen shot fixes (issue #127 related)
Provide proper return status when screen grabbing.
Allow tasks to remove themselves (return task entries to the queue _before_
executig them)
2011-05-28 23:09:06 +02:00
Torsten Dreyer
c828961327 Merge branch 'next' of gitorious.org:fg/simgear into next 2011-05-28 10:20:03 +02:00
Torsten Dreyer
83a95a0488 (Re)fix bug #285, textranslate broken
Due to fingertrouble, I removed the check for _step == 0 which
this patch re-adds.

Also, make this function look more like a template by not using
0.0 - constants.
2011-05-28 10:17:19 +02:00
ThorstenB
f3c131ffaf Minor compiler version detection issue.
Well, almost prepared for gcc 5.0 now ;-).
2011-05-27 22:30:43 +02:00
Torsten Dreyer
b06e38699a Make multicast sockets work under windows
msdn article 737550 states that "the preferred method is to call the
bind function to associate a socket with a local IP address and then
join the multicast group. Although this order of operations is not
mandatory, it is strongly recommended".
Since binding to the multicast address seems to fail, let's try binding
to INADDR_ANY and joint thereafter.
2011-05-27 21:06:06 +02:00
Torsten Dreyer
3a07e2fe21 ignore cmake generated files 2011-05-25 19:21:08 +02:00
Torsten Dreyer
ca668f8a37 Fix bug #285 textranslate and scroll animation with negative numbers
rewrite SGStepExpression::apply_mods so it creates the same step
for negative numbers as it does for positive numbers.
2011-05-25 19:14:09 +02:00
James Turner
5181aecc7b Port version-defined-in-a-file logic over from fg. 2011-05-21 14:56:10 +01:00
James Turner
0e92cfbd0d Bump Simgear version to 2.3.0 - should have been done after 2.2.0 was branched, oops. Will refactor this lot to use a single 'version' file like FG, soon. 2011-05-21 14:12:31 +01:00
Stuart Buchanan
60c7507a33 Fix 3D cloud elevation 2011-05-14 21:13:05 +01:00
ThorstenB
c7c3fae5c2 Also remove visual_enviro.cxx from the VC90 build. 2011-05-07 19:40:01 +02:00
Mathias Froehlich
4acbb2a312 Also remove visual_enviro.cxx from the cmake build system. 2011-05-07 18:32:44 +02:00
Torsten Dreyer
4e6159aa07 Remove unused class SGEnviro
This class and their source files visual_enviro.[h|c]xx were
unused since OSG transition. It's only functionality was to
keep a variable for the enable-state of rendering of precipitation.
This has now been moved to SGPrecipitation.
2011-05-06 14:10:04 +02:00
Torsten Dreyer
6a1d05646c fix typo 2011-05-06 13:07:21 +02:00
Curtis L. Olson
2e05043f43 Fix a crash on exit. The SGEnviro destructor was attempting to delete an
object that had already been deleted by the sound manager.  Since SGEnviro
doesn't own this object, I removed the delete from it's destructor.
2011-05-03 13:24:57 -05:00
Frederic Bouvier
1b8216e911 Consistency fix - remove a warning under MSVC 2011-04-26 20:42:42 +02:00
Frederic Bouvier
a2121b86df Compile under MSVC 2011-04-26 19:45:40 +02:00
Torsten Dreyer
1cd17e9edd Improvements to the global 3D clouds system
Stuart Buchanan:
Improvements to the global 3D clouds system
- clouds now move with the wind
- bug causing cloud coverage to be less than it should have been fixed
- support for adding 3D clouds with an fg_command.

(https://gitorious.org/fg/flightgear/merge_requests/1554)
2011-04-23 20:56:28 +02:00
Erik Hofman
5229f5a13c Lauri Peltonen's patch to increase the number of rings and bands of the sky dome 2011-04-16 11:32:34 +02:00
Torsten Dreyer
4ff014d275 Add multicast support for sockets 2011-04-13 18:43:28 +02:00
ThorstenB
83243f471a Enable OSG cache (default) and option to disable.
(also requires flightgear update)
2011-04-03 18:56:09 +02:00
ThorstenB
3c0c51a946 Minor event manager clean-up/simplification.
(Mainly disliked the "delete this;" concept :) ).
2011-04-03 18:22:39 +02:00
ThorstenB
08ad449774 Improve subsystem manager's timing statistics
Option to print statistics at run-time.
Convenient filter parameters to show subsystems with jitter or excessive
execution time only.
2011-03-23 23:12:13 +01:00
ThorstenB
eae1b99036 Keep PropertyList outside global namespace
Avoids conflict with FG's GUI widget "PropertyList"...
(don't use "using..." in header files since namespaces become useless then)
2011-03-23 22:30:42 +01:00
ThorstenB
44f27b23d0 Avoid some memory leaks in derived classes due to non-virtual destructors. 2011-03-19 14:50:18 +01:00
ThorstenB
92c83bc280 Avoid nuisance sounds in initial update loop.
Stop all "in-transit" sounds effects from triggering in the first update
loop when their initial property value is "1".
2011-03-19 14:48:58 +01:00
ThorstenB
10bbd435b7 Catch dangling property ties.
It's bad when tied properties are not untied before removing the tied property list.
We could try to "untie" the properties in the destructor - but that usually
caused weird mem access errors, since the tied properties will access
a no longer existing object (the very object whose destruction called the
TiedPropertyList destructor...). => so just add a warning and a nagging trap :)
2011-03-07 19:32:20 +01:00
ThorstenB
2ef8672a6b Change cloudfield::addCloud interface,
so it's more obvious that "addCloud" won't keep a reference to SGNewCloud.
2011-03-07 19:26:37 +01:00
ThorstenB
a22dd264cd Replace occurrences of osgDB::findDataFile with SGModelLib wrapper
which considers separate aircraft dirs (--fg-aircraft).
2011-03-06 22:38:44 +01:00
ThorstenB
baf5116841 Merge remote branch 'origin/releases/2.2.0' into next 2011-03-04 22:52:21 +01:00
ThorstenB
e55017bbfc Fix TextureBuilder to work with --fg-aircraft dirs.
Avoid direct use of osgDB to search for files. Using SGModelLib
instead to also search fg-aircraft dirs.
2011-03-04 22:50:32 +01:00
Csaba Halasz
19636bda4e Add missing META_Object to SGReaderWriterXMLOptions (needed for proper cloning) 2011-03-01 20:57:09 +01:00
Torsten Dreyer
83124e0c05 Don't depend on props.hxx
There is no reference to anything defined in props.hxx, so remove
the dependency here.
2011-02-27 20:35:44 +01:00
Torsten Dreyer
a079870bca Add strutils::starts_with and strutils::ends_with 2011-02-20 15:29:06 +01:00
ThorstenB
ce71b8c1cf Merge remote branch 'origin/releases/2.2.0' into next 2011-02-19 11:59:10 +01:00
ThorstenB
7b0c25f91e #83: John Denker: Set correct file modes
Sources shouldn't be executable.
2011-02-19 11:54:10 +01:00
Tim Moore
feab25d0be Merge branch 'releases/2.2.0' into next 2011-02-17 11:40:47 +01:00
Tim Moore
956b4406d0 fix SGPagedLOD change for 2.8.3
One more try...
2011-02-17 11:39:52 +01:00
Tim Moore
3a0fbae4d9 Merge branch 'releases/2.2.0' into next 2011-02-16 16:54:35 +01:00
Tim Moore
f106dc2a29 don't assume that OSG 2.8.3 has PagedLOD options
I was confused by my git svn import of the OSG tree.
2011-02-16 16:47:33 +01:00
Tim Moore
252a539e69 Merge branch 'releases/2.2.0' into next
Conflicts:
	simgear/scene/model/SGPagedLOD.cxx
2011-02-15 12:52:03 +01:00
Tim Moore
df6badfdd5 accomodate changes to osgDB::DatabasePager interface
The change was introduced in OSG SVN revision 12080. Note: that
revision has a bug that causes fgfs to crash. The bug is fixed in
revision 12170.
2011-02-15 12:41:23 +01:00
Torsten Dreyer
7479ae521c Provide easy Tie() for indexed properties 2011-02-14 20:24:41 +01:00
ThorstenB
416fb94ae8 Clear tile cache on (re-)init.
Clearing the cache was disabled to avoid scenery reloading on sim resets,
which is now avoided elsewhere (in FG).
Cache cleaning is now needed to support new option for complete scenery
reloading.
2011-02-13 19:23:21 +01:00
Torsten Dreyer
3a620fe55d Fix initial value for tied read-only properties 2011-02-12 14:46:58 +01:00
ThorstenB
5208750cdb Ivan Ngeow: Fixed compile for FreeBSD platforms. 2011-02-11 18:50:20 +01:00
ThorstenB
c684f8f043 Ivan Ngeow: Fixed compile for FreeBSD platforms. 2011-02-11 18:49:01 +01:00
ThorstenB
73084863b7 Temporary warning when compiling against OSG 2.9.11.
Current OSG development isn't supported by FG yet, so add a
warning for now...
2011-02-06 20:34:52 +01:00
Torsten Dreyer
503310cdb8 Darn! Typo in vc90 project file 2011-02-06 16:37:48 +01:00
Torsten Dreyer
bda8d34c2b Use tiedpropertylist.hxx in cmake and vc90 2011-02-06 16:35:15 +01:00
Torsten Dreyer
2ee87483f9 Move TiedPropertyList from flightgear to simgear 2011-02-06 15:05:50 +01:00
ThorstenB
9e04bf1ece Temporary warning when compiling against OSG 2.9.11.
Current OSG development isn't supported by FG yet, so add a
warning for now...
2011-02-06 10:04:55 +01:00
Frederic Bouvier
29c8c9f989 Fix cppcheck performance warning : Prefer prefix ++/-- operators for non-primitive types. 2011-01-30 21:22:06 +01:00
Frederic Bouvier
1035e714ff Deprecate VS2010 handmade project files now that we have Cmake 2011-01-28 19:03:38 +01:00
Frederic Bouvier
57fa022c9f Cmake: fix non MSVC build 2011-01-28 14:51:15 +01:00
Frederic Bouvier
76c3f7bc8f Cmake: support VS2010 and MSVC 64 bit 2011-01-28 14:46:05 +01:00
Torsten Dreyer
6d2646239e Fix wrong difference calculation in SGExpression 2011-01-25 23:01:14 +01:00
Torsten Dreyer
c955e61ba7 Fix wrong difference calculation in SGExpression 2011-01-25 22:58:50 +01:00
Frederic Bouvier
c31a5279af Cmake: restore its original name to the ephemeris library 2011-01-23 21:05:37 +01:00
ThorstenB
840780dc4a Another place to catch SG exceptions.
SGBinding::fire needs to catch, otherwise exceptions in the event handler
context cause an FG exit (fixes a crash with the route manager dialog).
2011-01-20 19:39:33 +01:00
ThorstenB
02b3c37b9f Another place to catch SG exceptions.
SGBinding::fire needs to catch, otherwise exceptions in the event handler
context cause an FG exit (fixes a crash with the route manager dialog).
2011-01-20 01:06:46 +01:00
Mathias Froehlich
d14fe813a9 Add the hla directory to the cmake build system. 2011-01-17 21:34:00 +01:00
Mathias Froehlich
44ff23b227 Add an initial implementation of a rti/hla dispatcher. 2011-01-17 21:33:45 +01:00
Mathias Froehlich
257459abc6 Add the new hla directory to the build system. 2011-01-17 21:33:33 +01:00
Torsten Dreyer
e988dc0e42 Fix bug in SGMisc<T>:: normalizePeriodic()
SGMisc<T>::normalizePeriodic(min,max,value) returned zero for
all values less than min.
Example:
A call of normalizePeriodic(0,twopi(),-pi()) returned zero
where the correct value would be 3*pi().
2011-01-17 19:51:29 +01:00
James Turner
7d544dee47 Olaf Flebbe: Decrease required OSG version. 2011-01-13 22:14:37 +00:00
Frederic Bouvier
1670f88e54 MSVC fix: deambiguiate function calls 2011-01-08 14:55:22 +01:00
Torsten Dreyer
58c7edfed6 SGExpression bugfix: allow <sin> within <product> 2011-01-08 13:06:25 +01:00
Torsten Dreyer
122d7f681f Add <expression> to animations
Allow complex animation expressions

Example: translate along the y-axis following a sin
function.
<animation>
  <type>translate</type>
  <axis>
    <y>1</y>
  </axis>
  <expression>
    <sin>
      <product>
        <property>/some/position-norm</property>
        <value>6.28</value>
      </product>
    </sin>
  </expression>
</animation>
2011-01-07 22:43:46 +01:00
Frederic Bouvier
acec1ba4bf Remove the dependency to boost serialization 2011-01-05 09:54:50 +01:00
Curtis L. Olson
0040757cd3 Merge branch 'next' of gitorious.org:fg/simgear into next 2011-01-03 07:55:45 -06:00
Curtis L. Olson
49d554e9d8 Update simgear version number to keep pace with FlightGear. 2011-01-03 07:54:31 -06:00
James Turner
fa3389ed23 Better MSVC Boost serialization fix from Olaf 2011-01-03 09:48:31 +00:00
Frederic Bouvier
188a84a893 Cmake: use build postfix 2011-01-02 19:44:04 +01:00
Frederic Bouvier
ceff1622c1 Cmake: Right way to search for include files 2011-01-02 18:45:14 +01:00
Frederic Bouvier
8d15cacf92 Cmake: MSVC_3RDPARTY_DIR is a path, not an option 2011-01-02 18:01:57 +01:00
James Turner
80161bfa96 Cmake: 3RDPARTY_DIR fixes from Olaf Flebbe 2011-01-01 21:06:43 +00:00
Torsten Dreyer
c32ab1b84f handle NCD (nil clouds detected) in METAR 2010-12-31 13:31:09 +01:00
Tim Moore
73c0ce628b Merge remote branch 'gitorious/next' into next 2010-12-29 18:12:56 +01:00
Tim Moore
dc68397e48 cmake improvements for shared library build 2010-12-29 18:12:44 +01:00
Tim Moore
c934b47f2e Issue 110: fix pick animation interaction with effects
Set OVERRIDE and PROTECTED attributes on pick animation state
attributes. Set up attributes and add a colorMode uniform so that the
default shader will take color and alpha values from the
material. Also, add a DotOsg writer method for ConditionNode.
2010-12-29 18:09:23 +01:00
James Turner
07d3d6508a Uninstall support, pinched from OSG. 2010-12-28 13:38:05 +00:00
James Turner
e4a8896fdc MSVC improvements from Olaf Flebbe. 2010-12-28 13:32:54 +00:00
Tim Moore
33e1a9457a set data variance to DYNAMIC for animated effect attributes 2010-12-26 18:34:00 +01:00
James Turner
b6a20fd6e4 64-bit compatability tweak from papillion 2010-12-20 14:46:53 +00:00
James Turner
ae9757bf43 Create version.h during SimGear CMake build 2010-12-19 19:08:14 +00:00
James Turner
b9a34b1b05 Initial work on CMake support for SimGear. 2010-12-19 14:16:39 +00:00
Erik Hofman
c33f66b691 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-12-13 18:40:39 +01:00
Erik Hofman
cf8d6c2621 Remove unused files 2010-12-13 18:40:08 +01:00
Torsten Dreyer
6c789f7165 metar: add string constants for cloud coverages 2010-12-12 22:18:10 +01:00
Erik Hofman
7d77eff4f4 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-12-12 20:23:08 +01:00
Erik Hofman
f83278bd61 Update the bad-doppler test and simplify it to only test for bad platforms. 2010-12-12 14:07:44 +01:00
Csaba Halasz
9a96018cc2 Compilation fix: add missing #include to SGPagedLod.cxx, needed by OSG 2.9.11 2010-12-12 00:23:06 +01:00
Torsten Dreyer
ab3612517f Make the max. opacity of a 2d cloud settable 2010-12-09 09:06:40 +01:00
Torsten Dreyer
0909722bb5 Metar: symbolic cloudnames and phenomena exposure
- use symbolic names for scattered, broken, overcast, etc. cloud
coverages.
- better approach to expose weather phenomena to the interface
2010-12-04 12:02:38 +01:00
Torsten Dreyer
1cb8f9237c Expose weather phenomena to the SGMetar interface 2010-11-27 21:04:04 +01:00
Anders Gidenstam
4cac366468 simgear/scene/sky/sky.cxx: Include sg_inlines.h with simgear/ prefix as all other simgear includes. 2010-11-26 21:49:30 +01:00
Torsten Dreyer
a6138b3445 Make visibility within cloudlayers settable 2010-11-26 19:24:44 +01:00
Frederic Bouvier
093e4614d3 Update VS2010 projects 2010-11-20 21:42:10 +01:00
Frederic Bouvier
82efb8a784 Update VS2010 projects 2010-11-20 14:23:20 +01:00
Frederic Bouvier
be720709fe Compile PropertyObject under Windows 2010-11-20 14:20:35 +01:00
James Turner
325b13b101 Build propertyObject on MSVC2008 2010-11-20 13:08:01 +00:00
James Turner
203d1c2b45 PropertyObject ::create tests. 2010-11-20 04:25:11 -08:00
James Turner
c3c97f2956 Shrink PropertyObjectBase by a pointer, don't pull exception header into the header. 2010-11-20 03:31:42 -08:00
James Turner
ac535de2fa PropertyObject enhancements, unit-test for make check 2010-11-20 02:49:04 -08:00
Torsten Dreyer
9d4f0f5824 A sum without diff is like foo without bar
Add a <difference> aka <diff> to SGExpression to compute
differences
2010-11-20 11:05:45 +01:00
ThorstenB
b4f5eaa541 Current timestamps for forced scenery loading.
Priorities during forced model loads won't work unless using current framestamps...
2010-11-19 13:39:20 +01:00
ThorstenB
66cdbf6215 Fixed invalid character in source file.
Removed illegal character (0xc). How did this happen???
2010-11-19 13:36:50 +01:00
ThorstenB
c9e0bfb7fe Improved tile cache priority scheme.
Use priorities for loading/unloading.
Maintain an expiry time for each tile.
Replaced "cache lock" by "current view" flag.
2010-11-19 13:33:12 +01:00
James Turner
6da8ef83af Merge branch 'topics/propobj' into next 2010-11-18 20:23:40 +00:00
James Turner
f53559b8d0 Initial propertyObject work. 2010-11-18 20:21:37 +00:00
Torsten Dreyer
49f038b9d1 Purge some gcc and MSVC warnings 2010-11-18 12:08:16 +01:00
Tim Moore
ce67657e0a eliminate property node path cache
The property path cache was making very little difference in practice
and made the eventual goal of having the property tree be thread safe
for readers more difficult to attain.
2010-11-17 11:25:07 +01:00
James Turner
56c520f455 Tighten up name filters on Unix. Fixes bug 168. 2010-11-15 23:23:40 +00:00
ThorstenB
9f88b077ee remove old .cvsignore files
Hello GIT!
2010-11-14 15:09:36 +01:00
Curtis L. Olson
50315a7346 Fix setsockopt() to match previous precident of setsockopt() usage (as seen
later in the setBroadcast() function.)
2010-11-12 15:52:33 -06:00
Frederic Bouvier
6b58afe823 Fix setsockopt call 2010-11-12 22:03:11 +01:00
Curtis L. Olson
167cba9e93 Patch to avoid the problem of the socket resource not yet being available
if the program is restarted quickly after being killed.

Reference: http://www.unixguide.net/network/socketfaq/4.5.shtml
2010-11-12 13:19:57 -06:00
Frederic Bouvier
ce89a410d2 Update VS2010 projects : use Boost 1.44.0 2010-11-07 20:01:18 +01:00
Frederic Bouvier
98d0f33f8f Don't crash on exit 2010-11-07 10:31:13 +01:00
Frederic Bouvier
c305341ef4 Update VS2008 projects : use Boost 1.44.0 available in last 3rd Party archive 2010-11-06 17:02:16 +01:00
ThorstenB
0607a67a92 Fixed METAR. Make loader fully HTTP compliant.
HTTP protocol requires a "Host:" line.
The old noaa server didn't mind. Now it does...
2010-11-05 20:07:50 +01:00
James Turner
5f2f95676c Formal shutdown interface on SGSubsystem. 2010-11-05 09:19:22 +00:00
Frederic Bouvier
4bf16243fc Update Vs2010 projects 2010-11-04 22:20:08 +01:00
James Turner
607738f22e Fix ConditionNode Win32 compilation. 2010-11-04 18:54:18 +00:00
James Turner
200df49d6e Make subsystem group destruction explicit, so get_subsystem calls during destruction are safe. 2010-11-04 18:49:24 +00:00
Tim Moore
580a1b7fc2 Add ConditionNode files to VC90 project 2010-11-04 15:04:03 +01:00
Tim Moore
3372f9fc0d add SGMath.hxx header file to ConditionNode.cxx
Apparently necessary for MSVC 2008.
2010-11-04 11:04:13 +01:00
Tim Moore
4787ac64ff issue 165: fix material animation condition problem
The evaluation of the condition is moved to a ConditionNode and
separated from the animation of values via properties. Previously the
conditional application of static values was broken.
2010-11-04 10:06:13 +01:00
Tim Moore
fef625ce27 add ConditionNode scenegraph node
This class directs its scenegraph traversal by evaluating a condition
and doesn't rely on an update callback.
2010-11-04 07:01:38 +01:00
ThorstenB
0b53dd8fa7 Show compiler warnings by default. 2010-10-30 20:53:19 +02:00
James Turner
fe628e44e1 Add platform defines to SimGear, and a replacement for ulSleep functions. 2010-10-30 19:18:57 +01:00
Frederic Bouvier
d314b6a552 Fix line endings 2010-10-29 19:47:44 +02:00
Frederic Bouvier
02462d1752 Quick hack to remote trailing / on Windows. Feel free to replace by something more elegant 2010-10-29 09:30:59 +02:00
ThorstenB
5b734d8c52 Merge branch 'integration' into next 2010-10-28 19:39:55 +02:00
James Turner
81d640ed7c Fix build when OSG implict-ref-ptr conversion is disabled. 2010-10-26 10:09:55 +01:00
Frederic Bouvier
7e2ad05fae Add mipmap.* to the unix build system 2010-10-25 21:59:55 +02:00
Frederic Bouvier
bda5890f17 Add a function to debug mipmaps 2010-10-25 21:51:27 +02:00
Frederic Bouvier
c7dd293e01 Update Vs2010 projects 2010-10-24 09:30:16 +02:00
Frederic Bouvier
fbf0a20f38 Unix line endings 2010-10-24 09:25:42 +02:00
Frederic Bouvier
87ccfbab02 Restore commit 48c6d3d89a by Torsten Dreyer: Provide a little more descriptive error message if TextureBuilder fails 2010-10-24 09:25:41 +02:00
Frederic Bouvier
97f39282ef Don't compute mipmap for inexistant image color components 2010-10-24 09:25:40 +02:00
Frederic Bouvier
4fd3d49fc1 Add mipmap control in the effect file 2010-10-24 09:25:40 +02:00
Frederic Bouvier
a70c8a9cae Untabify 2010-10-24 09:25:39 +02:00
Frederic Bouvier
c0926633e8 Update Vs2010 projects 2010-10-24 09:24:13 +02:00
James Turner
1ae91097ba Build fixes for net classes in Simgear. 2010-10-24 01:22:59 +01:00
James Turner
bfd76880a9 Migrate relevant PLIB netXXX classes into SimGear. 2010-10-24 01:12:42 +01:00
ThorstenB
662578dbe7 Buffer size safety.
Do not look for '\n' beyond valid data area.
Obey buffer length (in case a METAR contained a line > 512byte).
2010-10-23 14:47:24 +02:00
Torsten Dreyer
48c6d3d89a Provide a little more descriptive error message if TextureBuilder fails 2010-10-12 16:21:38 +02:00
Frederic Bouvier
7bdb530440 Add project.* to MSVC project files 2010-10-09 08:45:52 +02:00
Tim Moore
bfe953c18d replace glu functions with equivalents from OSG 2010-10-08 23:44:38 +02:00
Torsten Dreyer
136676012f Merge branch 'next' of gitorious.org:fg/simgear into next 2010-10-07 17:43:35 +02:00
Torsten Dreyer
0994ffc195 Don't crash in strutils::trim() with empty strings 2010-10-05 22:39:41 +02:00
Frederic Bouvier
df19feac34 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-10-05 08:32:00 +02:00
Frederic Bouvier
961fa89b7a Use same transformation for generated ocean tiles than for regular tiles. Fix the normal orientation that broke the new water shader 2010-10-05 08:30:52 +02:00
James Turner
ddf9e08069 Make get_subsystem safe during destruction of the manager. 2010-10-03 16:08:34 +01:00
Tim Moore
b5f3978b8a Thorsten Renk's fix for tile manager problems
Locking tiles in cache keeps tiles from mysteriously disappearing.
2010-10-02 23:05:52 +02:00
James Turner
82dc6c32ec Don't crash when a submodel fails to load. 2010-10-02 21:01:29 +01:00
James Turner
889e2d6f06 Add another overload for sg_io_exception ctor. 2010-10-01 12:27:08 +01:00
Torsten Dreyer
9a28642a4e tolerate NDV (no directional validation) in METAR 2010-09-27 19:38:15 +02:00
Torsten Dreyer
0b953462f7 Ivan Ngeow: Fix build on FreeBSD
FreeBSD 8.0-RELEASE, only a very small patch needed
to be applied to simgear/simgear/compiler.h, to add

so that __FreeBSD_version is defined.
2010-09-23 10:27:06 +02:00
Torsten Dreyer
061eb686c6 Fix wrong movement of 2d cloud layers on N/S courses 2010-09-19 10:53:25 +02:00
Frederic Bouvier
937297561f Fix MSVC 100 project files updated by hand 2010-09-12 12:06:57 +02:00
Erik Hofman
bf70d6f087 Set the listener position to it's default value, just like the samples position 2010-09-10 15:02:37 +02:00
Frederic Bouvier
26fdfc42f4 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-09-09 20:06:27 +02:00
Frederic Bouvier
abab8c6ec8 MSVC 10 project update 2010-09-09 20:06:15 +02:00
James Turner
a7697f6095 Second attempt to fixed OpenAL tests. 2010-09-06 14:27:58 +01:00
James Turner
49270e99e5 Fix up tests for revised SGSoundSample ctor. 2010-09-06 12:30:13 +01:00
James Turner
d75ce1e12e Pass current-dir down through XMLSound
(should allow relative paths in sound XML files)
2010-09-06 09:26:46 +01:00
James Turner
289e768ca5 Add ResourceManager, and use to find sound and model paths. 2010-09-06 09:09:58 +01:00
James Turner
44c587400d Validate sound file paths in an XML file. 2010-09-05 14:15:18 +01:00
Torsten Dreyer
df467b9dba Let SGCloudLayer handle coverage strings
This is currently handled in various places in FlightGear.
2010-08-27 18:20:09 +02:00
Frederic Bouvier
510543e14b Add a convenience constructeur to SGPath 2010-08-22 09:33:56 +02:00
Frederic Bouvier
c3133f020d std::string::c_str() is const 2010-08-21 09:02:12 +02:00
James Turner
a7439aa056 Standardise path-handling in XML mode files
aircraft-dir/fg-data paths always work, and
paths relative to the location of the current XML
file always work.
2010-08-17 11:05:55 +01:00
James Turner
d7bea0c4c6 Add isAbsolute/isRelative predicates to SGPath. 2010-08-14 22:51:01 +01:00
James Turner
764a3c29e9 Allow loading of 2.5D panels to be controlled again. 2010-08-14 19:48:52 +01:00
James Turner
3c57572b89 Ralf Gerlich: fix bucket numbering at extreme latitudes
Also document existing algorithms
2010-08-14 10:18:35 +01:00
Tim Moore
fe7c6554f7 support for integer uniforms
Also, share common Uniform objects
2010-08-13 12:54:02 +02:00
Tim Moore
19bb7f5a83 force static models to have effects too 2010-08-13 12:54:02 +02:00
Torsten Dreyer
c0e20ad56b add padding function lpad and rpad to strutils 2010-08-12 13:02:16 +02:00
Torsten Dreyer
49887ff06e Fix the fix that turned a warning into a bug :-( 2010-08-12 12:16:48 +02:00
Torsten Dreyer
1f6555c9ad two warning fixes 2010-08-12 11:42:04 +02:00
Torsten Dreyer
7f8efa7cef use correct parameter types for SGText::UpdateCallback 2010-08-12 11:35:09 +02:00
James Turner
8106956be2 Merge branch 'topics/cmdcatch' into next 2010-08-11 00:20:02 +01:00
James Turner
cc435ba817 Fix Win32 build of SGPath. 2010-08-09 09:13:28 +01:00
James Turner
0c55a4d7bb Catch exceptions raised executing a command. 2010-08-09 09:12:26 +01:00
James Turner
c4b4c0ce59 Make SGPath cache stat() information, cheers Fred
* cache exists/isDir/isFile in SGPath, to avoid
  repeated calls.
2010-08-09 08:19:14 +01:00
James Turner
d31c1df639 More ignore files, for 'make check' binaries 2010-08-08 09:55:31 +01:00
James Turner
780286ea81 Ding, dong, the witch is dead. PLIB is no more, in SimGear. 2010-08-07 18:03:37 +01:00
James Turner
20a75b9c9e Change how certain constants are (re-)defined, to avoid warning when PLIB sg.h is included. 2010-08-07 16:28:39 +01:00
James Turner
2a2e2716bd Removal of PLIB/SG from SimGear 2010-08-07 13:55:33 +01:00
James Turner
6a07c22826 Catch subsystem update() exceptions in the manager, and permit a maximum number of exceptions before suspending the subsystem. 2010-08-07 10:25:20 +01:00
James Turner
7c294915c8 Ensure 'make dist' works. 2010-08-07 09:09:58 +01:00
James Turner
7788cb288e Fixes for automake correctness. 2010-08-06 21:18:04 +01:00
James Turner
c1762c709e Ralf Gerlich: add headless mode to SimGear (merging simgear-cs) 2010-08-06 19:17:14 +01:00
James Turner
8690528080 Fix compilation if OSG ref_ptr implicit conversion is not enabled. 2010-08-06 18:42:56 +01:00
Frederic Bouvier
5376294389 Merge commit 'refs/merge-requests/1' of git://gitorious.org/fg/simgear into vivian/cube 2010-08-03 08:41:27 +02:00
Frederic Bouvier
fa1b703bf8 Update MSVC10 project files 2010-08-03 08:40:10 +02:00
Vivian Meazza
72d2c7f078 Remove debugging messages
Signed-off-by: Vivian Meazza <vivian.meazza@lineone.net>
2010-08-02 20:27:49 +01:00
Vivian Meazza
09ecc66e53 Add support for Cube Crosses. Based on Zan's work, with some bugs removed.
Signed-off-by: Vivian Meazza <vivian.meazza@lineone.net>
2010-08-02 20:22:33 +01:00
Erik Hofman
879dc295a8 Actually enable looping for a sample queue 2010-08-02 11:43:53 +02:00
Erik Hofman
8a5a1d3301 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-08-02 10:11:41 +02:00
Erik Hofman
67c8067aed Initial commit for a sample queue extension. 2010-08-02 10:10:58 +02:00
Frederic Bouvier
123e32e345 MSVC 10 build 2010-08-01 18:00:39 +02:00
Frederic Bouvier
3a09d67f59 MSVC 10 build: Resolve an ambiguity between boost::bind and std::tr1::bind 2010-08-01 18:00:37 +02:00
Frederic Bouvier
ec3ed8fbcd Project file to build and install SimGear alone 2010-08-01 18:00:32 +02:00
Frederic Bouvier
18370ebd08 Update project to use VC100 OSG and Boost 1.42.0 2010-08-01 18:00:30 +02:00
Frederic Bouvier
acbc09b232 MSVC10 build fix 2010-08-01 18:00:27 +02:00
Frederic Bouvier
9d1cf253b4 Compile with MSVC10 2010-08-01 18:00:25 +02:00
Frederic Bouvier
e46304d1ce Add VS2010 project files 2010-08-01 18:00:23 +02:00
James Turner
668c62b1f4 Missed removing a build rule. 2010-07-31 15:33:25 +01:00
James Turner
49f418f146 Remove legacy direct-OpenGL code in simgear/screen (predating switch to OSG). 2010-07-31 15:17:09 +01:00
Erik Hofman
c46c735f2f fix a typo 2010-07-30 10:44:50 +02:00
Erik Hofman
82aa7fcbad use std::string 2010-07-30 10:42:44 +02:00
James Turner
2cfeeb4b13 Merge branch 'topics/remove_point3d' of git@gitorious.org:~zakalawe/fg/james-simgear into topics/remove_point3d 2010-07-30 09:00:35 +01:00
James Turner
aa859c488f Remove deprecated vector classes - finally! 2010-07-30 00:46:30 +01:00
James Turner
1b2915aa2a WIP - removing remaining users of Point3D. 2010-07-29 17:49:37 +01:00
James Turner
e99c3d4705 Collapse SGGeoCoord into SGTimeZone, and switch timezone search to cartesian math. 2010-07-29 10:12:00 +01:00
James Turner
d23491646a Use a custom 'findDataFile' method in key places, and hook this into a callback set on SGModelLib. 2010-07-29 01:05:24 +01:00
Erik Hofman
1d740a63bd C++ify some code 2010-07-27 15:57:36 +02:00
Erik Hofman
d1897fabf0 Small bugfix, the previous test always sets _property (these days) 2010-07-27 14:51:44 +02:00
Erik Hofman
d4178d6440 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-07-27 10:15:28 +02:00
James Turner
f4d42289d4 More ignore rules for Git. 2010-07-27 00:21:44 +01:00
Erik Hofman
d0def466da Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-07-25 10:29:25 +02:00
James Turner
959f44502b Fix simgear::Dir::children on Linux where dirent->d_type might be 0; always use stat() to determine file type. Thanks to Alex Romonsan for helping debugging this! 2010-07-24 10:27:50 +01:00
Erik Hofman
1840541f6d Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-07-23 20:05:40 +02:00
Cutis L. Olson
c5ec6927b3 Add a method to set particle wind using from heading (deg) and speed (kt) 2010-07-23 09:01:49 -05:00
James Turner
7beaf3705e Add closest-point calculation to SGRay, to replace a vector.h helper. 2010-07-23 13:04:09 +01:00
Erik Hofman
792ffa2d26 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-07-23 13:57:53 +02:00
James Turner
bbd61977f1 Change SGPath::exists to use stat(), fix '.' and '..' handling on Windows, add simgear::Dir version of exists(). 2010-07-23 07:54:10 +01:00
James Turner
e3d1fa2686 Merge branch 'next' of git@gitorious.org:fg/simgear into next 2010-07-23 06:30:37 +01:00
James Turner
293d3b4fb3 Fix Win32 compilation of raw_socket. 2010-07-23 06:30:02 +01:00
James Turner
e1d8155565 Linux build fixes, now netSocket.h is no longer included. 2010-07-22 22:06:02 +01:00
James Turner
c37b27a926 I greatly dislike GNU automake. 2010-07-22 21:27:11 +01:00
James Turner
6b3a05e23f Move PLIB netSocket into SimGear, as simgear::Socket, and update the wrapper classes. 2010-07-22 20:02:37 +01:00
Erik Hofman
0e92bb58b0 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-07-22 08:57:04 +02:00
James Turner
63cbd4deb0 On Unix, check for symlinks from readdir(), and look through them (using stat()) to discern target type. 2010-07-21 22:08:06 +01:00
Frederic Bouvier
17bcd4e2ab Add a new function alias for MSVC: strcasecmp -> stricmp 2010-07-19 22:36:01 +02:00
Frederic Bouvier
72f301c655 Merge branch 'next' of git://gitorious.org/fg/simgear into fredb/winbuild 2010-07-19 20:02:41 +02:00
Erik Hofman
a62a8518b9 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-07-16 20:20:28 +02:00
Torsten Dreyer
fa169d6aa2 Merge branch 'next' of gitorious.org:fg/simgear into next 2010-07-16 18:35:55 +02:00
Torsten Dreyer
d2bcb86e1e Warning fix: compare signed/unsigned 2010-07-16 18:34:39 +02:00
Torsten Dreyer
ed7361622b Warning fix: unused variable in TextureBuilder.cxx 2010-07-16 18:19:56 +02:00
James Turner
3117ec5a7d Fix simgear::Dir compilation on some Unix setups, thanks Anders. 2010-07-16 08:40:07 +01:00
James Turner
cb4716f403 Initial work on simgear::Dir, replacement for PLIB ulDir functions. 2010-07-15 09:40:46 +01:00
Erik Hofman
b48c0e968f Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-07-14 12:19:08 +02:00
James Turner
aa2ed5fb0c Allow tasks to be removed from the EventManager by name. 2010-07-13 13:07:35 +01:00
Erik Hofman
8b7a279c61 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2010-07-09 08:53:56 +02:00
James Turner
b286e9d337 Add two more subsystem groups, to aid in fixing bug 141. 2010-07-08 23:21:25 +01:00
Erik Hofman
d671c3d9fa At some points Flightgear stops and restarts the entire sample group containing the looping background/engine noise. But it does not restart the individual (looping) samples in the group. So now the background noise dies when resetting the sim or changing aircraft location. 2010-06-29 08:28:38 +02:00
Erik Hofman
7086f2dc89 brehmt:
When a sample's state constantly is "changed" (because sth. keeps updating the
sample in each update loop), then SGSampleGroup::update never ever checked if
the sample had already stopped playing by itself.
The attached patch reorders the last two conditions. It now first checks if a
sample has already stopped playing, before checking if there's sth to update.
2010-06-28 08:12:23 +02:00
Frederic Bouvier
7e8bb9ea00 Merge branch 'next' of git://gitorious.org/fg/simgear into fredb/winbuild 2010-06-19 08:14:26 +02:00
Frederic Bouvier
4e46bb6671 Merge branch 'master' of git://gitorious.org/fg/simgear into fredb/winbuild 2010-06-19 08:14:02 +02:00
Tim Moore
de35658096 Merge remote branch 'gitorious/next' into next 2010-06-17 23:46:52 +02:00
Tim Moore
034f5db3bd use an additional shader program map keyed using the resolved shader filenames 2010-06-17 23:45:27 +02:00
James Turner
57375bfd73 Merge commit 'b846e33' into next 2010-06-17 21:40:09 +01:00
James Turner
b846e33ee3 Extend Magvar interface to use SGGeod. 2010-06-17 21:39:10 +01:00
James Turner
cc9b817f0e Extend SGSubsystemGroup, to allow running a fixed dt time, internally 2010-06-16 18:02:41 +01:00
Tim Moore
0d419aba8a Add bool and int uniform types for shaders, and vertex-program-two-sided
vertex-program-two-sided is an extra parameter written by the code
that creates effects from state sets generated by the ac3d loader. The
objective of this work is to support a workaround for broken
gl_FrontFacing on some Macintosh machines.
2010-06-15 19:05:18 +02:00
James Turner
ae22321d9c Automake changes to Hudson 'make check' runs.
Includes moving the OpenAL test programs to 'noinst' so they don't run as part of make check
2010-06-14 12:38:41 +01:00
James Turner
87169febf8 Const-ify some ephemeris accessors, so they can be tied. 2010-06-14 10:23:06 +01:00
James Turner
dd044844e5 Add radial intersection code to SGGeodesy, and test coverage for geocentric helpers. 2010-06-14 10:15:44 +01:00
James Turner
0c8c596ee5 Fix longitude sign convention of geocentric routines
(derived from the Williams aviation formulary, with W longitude +ve)
2010-06-11 18:38:43 +02:00
James Turner
b9496fef1d Merge branch 'topics/condexp' into next 2010-05-27 15:19:38 +01:00
James Turner
b4b9d3a4b7 Support constant true and false values in conditions. 2010-05-27 15:19:04 +01:00
James Turner
0128c89f8d Merge branch 'topics/condexp' into next 2010-05-26 19:29:28 +01:00
James Turner
9e77d06c72 Support <table>s in expression XML. 2010-05-26 19:28:42 +01:00
Torsten Dreyer
25bb1cc957 Cleanup some nonprinting characters make this file work 2010-05-23 21:02:19 +02:00
Torsten Dreyer
2c6f8299f0 typo in gitignore filename 2010-05-23 19:09:00 +02:00
Torsten Dreyer
6a2773c3ac ignore generated files 2010-05-23 10:54:23 +02:00
Torsten Dreyer
1eea917121 ignore generated files 2010-05-23 10:45:01 +02:00
Torsten Dreyer
ea1bbbabfa ignore generated test apps 2010-05-23 10:44:29 +02:00
Torsten Dreyer
399d2bc73c Fix a gcc warning 2010-05-22 23:40:07 +02:00
Torsten Dreyer
0759dbcdc9 Merge branch 'next' of gitorious.org:fg/simgear into next 2010-05-22 23:36:39 +02:00
Torsten Dreyer
1ae0f9c19d New pick animation capability from Alex Perry
Alex Perry: Adds a new pick animation capability which parallels the existing
"action" for a named object.  Specifying "vncaction" and a transform
from model space will enable all mouse clicks on that object to be
delivered directly to the OSG image.  Currently, the readers for VNC
and PDF files yield interactive images; more are likely to be added
over time.
2010-05-22 23:35:01 +02:00
James Turner
e8364a03bc Merge branch 'topics/condexp' into next 2010-05-20 23:57:54 +01:00
James Turner
046d88ab2d Support <expression> children in comparison conditions. Also makes ordering of child nodes match XML consistently. 2010-05-20 23:56:04 +01:00
Mathias Froehlich
f161f78a33 Add a tight and cheap method to represent a rotation.
Adapt tests for that new method.
2010-05-17 23:13:59 +02:00
Erik Hofman
1912444886 revert previous commit, this was a mistake 2010-05-11 11:32:58 +02:00
Erik Hofman
b6ef5a0a3d Before 2010-05-08 11:19:01 +02:00
Frederic Bouvier
401c88adbb Test git commit with a simple change 2010-05-08 00:19:43 +02:00
James Turner
42984d1bfb Make ALUT 1.0 builds again, hopefully in the short term - MinGW needs this. 2010-05-07 00:12:21 +01:00
James Turner
6997082b03 Add .gitignore files, ignore automake/configure artefacts. 2010-05-06 11:25:53 +01:00
James Turner
139217dc79 Configure.as updates for ALUT changes, make --with-alut-framework= work. 2010-05-06 10:27:38 +01:00
Tim Moore
2cc2a857a2 Merge branch 'jmt/ref_ptr-conv' 2010-05-06 10:43:53 +02:00
Tim Moore
7dfb463ba9 Merge branch 'ehofman/framebuffer' 2010-05-06 10:43:45 +02:00
Tim Moore
da07871bc6 Merge branch 'mathias/intersect' 2010-05-06 10:43:27 +02:00
Tim Moore
530d2309e7 Merge branch 'ehofman/sound' 2010-05-06 10:43:12 +02:00
Tim Moore
7e7a5d38f8 Merge branch 'fredb/msvc-cleanup' 2010-05-06 10:42:59 +02:00
Tim Moore
ecf949dee0 Merge branch 'ehofman/model' 2010-05-06 10:42:44 +02:00
334 changed files with 24104 additions and 12613 deletions

View File

@@ -1,19 +1,25 @@
Makefile
Makefile.in
SimGear.spec
aclocal.m4
.deps
autom4te.cache
config.cache
config.guess
config.log
config.status
configure
do-config.sh
.cdtproject
.project
config.guess
config.sub
configure
depcomp
INSTALL
install-sh
missing
mkinstalldirs
aclocal.m4
INSTALL
SimGear.spec
*.o
lib*.a
cmake_install.cmake
CMakeFiles
CMakeCache.txt
CPackConfig.cmake
CPackSourceConfig.cmake
cmake_uninstall.cmake
install_manifest.txt

158
CMakeLists.txt Normal file
View File

@@ -0,0 +1,158 @@
cmake_minimum_required (VERSION 2.6)
include (CheckFunctionExists)
include (CheckIncludeFile)
include (CheckCXXSourceCompiles)
include (CPack)
project(SimGear)
# read 'version' file into a variable (stripping any newlines or spaces)
file(READ version versionFile)
string(STRIP ${versionFile} SIMGEAR_VERSION)
#packaging
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README")
# We have some custom .cmake scripts not in the official distribution.
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}")
option(SIMGEAR_SHARED "Set to ON to build SimGear as a shared library/framework" OFF)
option(SIMGEAR_HEADLESS "Set to ON to build SimGear with GUI/graphics support" OFF)
option(JPEG_FACTORY "Enable JPEG-factory support" OFF)
option(ENABLE_LIBSVN "Set to ON to build SimGear with libsvnclient support" OFF)
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
if (MSVC AND MSVC_3RDPARTY_ROOT)
message(STATUS "3rdparty files located in ${MSVC_3RDPARTY_ROOT}")
set( OSG_MSVC "msvc" )
if (${MSVC_VERSION} EQUAL 1600)
set( OSG_MSVC ${OSG_MSVC}100 )
else (${MSVC_VERSION} EQUAL 1600)
set( OSG_MSVC ${OSG_MSVC}90 )
endif (${MSVC_VERSION} EQUAL 1600)
if (CMAKE_CL_64)
set( OSG_MSVC ${OSG_MSVC}-64 )
set( MSVC_3RDPARTY_DIR 3rdParty.x64 )
else (CMAKE_CL_64)
set( MSVC_3RDPARTY_DIR 3rdParty )
endif (CMAKE_CL_64)
set (CMAKE_LIBRARY_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/lib )
set (CMAKE_INCLUDE_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/include)
set (BOOST_ROOT ${MSVC_3RDPARTY_ROOT}/boost_1_44_0)
set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
set (ALUT_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib)
endif (MSVC AND MSVC_3RDPARTY_ROOT)
find_package(Boost REQUIRED)
set (BOOST_CXX_FLAGS "-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DBOOST_BIMAP_DISABLE_SERIALIZATION")
find_package(ZLIB REQUIRED)
find_package(Threads REQUIRED)
if (${SIMGEAR_HEADLESS})
message(STATUS "headlesss mode")
set(NO_OPENSCENEGRAPH_INTERFACE 1)
else()
find_package(OpenGL REQUIRED)
find_package(OpenAL REQUIRED)
find_package(ALUT REQUIRED)
find_package(OpenSceneGraph 2.8.1 REQUIRED osgText osgSim osgDB osgParticle osgUtil)
endif()
if(JPEG_FACTORY)
message(STATUS "JPEG-factory enabled")
find_package(JPEG REQUIRED)
include_directories(${JPEG_INCLUDE_DIR})
endif()
if(ENABLE_LIBSVN)
find_package(SvnClient)
if(LIBSVN_FOUND)
message(STATUS "libsvn found, enabling in SimGear")
set(HAVE_SVN_CLIENT_H 1)
set(HAVE_LIBSVN_CLIENT_1 1)
endif(LIBSVN_FOUND)
endif(ENABLE_LIBSVN)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(sys/timeb.h HAVE_SYS_TIMEB_H)
check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(windows.h HAVE_WINDOWS_H)
# See if we have any rti library variant installed
find_package(RTI)
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
check_function_exists(ftime HAVE_FTIME)
check_function_exists(timegm HAVE_TIMEGM)
check_function_exists(rint HAVE_RINT)
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually d on windows")
SET(CMAKE_RELEASE_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
SET(CMAKE_RELWITHDEBINFO_POSTFIX "rd" CACHE STRING "add a postfix, usually empty on windows")
SET(CMAKE_MINSIZEREL_POSTFIX "s" CACHE STRING "add a postfix, usually empty on windows")
# isnan might not be real symbol, so can't check using function_exists
check_cxx_source_compiles(
"#include <cmath>
void f() { isnan(0.0);} "
HAVE_ISNAN)
if(CMAKE_COMPILER_IS_GNUCXX)
set(WARNING_FLAGS -Wall)
endif(CMAKE_COMPILER_IS_GNUCXX)
if(WIN32)
if(MSVC)
# turn off various warnings
# foreach(warning 4244 4251 4267 4275 4290 4786 4305 4996)
# SET(WARNING_FLAGS "${WARNING_FLAGS} /wd${warning}")
# endforeach(warning)
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS")
endif(MSVC)
# assumed on Windows
set(HAVE_GETLOCALTIME 1)
endif(WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} ${MSVC_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}")
include_directories(${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_BINARY_DIR}/simgear)
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR}
${ALUT_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR} )
add_definitions(-DHAVE_CONFIG_H)
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/simgear/simgear_config_cmake.h.in"
"${PROJECT_BINARY_DIR}/simgear/simgear_config.h"
)
install (FILES ${PROJECT_BINARY_DIR}/simgear/simgear_config.h DESTINATION include/simgear/)
add_subdirectory(simgear)
#-----------------------------------------------------------------------------
### uninstall target
#-----------------------------------------------------------------------------
CONFIGURE_FILE(
"${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
ADD_CUSTOM_TARGET(uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")

View File

@@ -0,0 +1,67 @@
# Locate ALUT
# This module defines
# ALUT_LIBRARY
# ALUT_FOUND, if false, do not try to link to ALUT
# ALUT_INCLUDE_DIR, where to find the headers
#
# $ALUTDIR is an environment variable that would
# correspond to the ./configure --prefix=$ALUTDIR
# used in building ALUT.
#
# Created by James Turner. This was influenced by the FindOpenAL.cmake module.
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distributed this file outside of CMake, substitute the full
# License text for the above reference.)
# Per my request, CMake should search for frameworks first in
# the following order:
# ~/Library/Frameworks/OpenAL.framework/Headers
# /Library/Frameworks/OpenAL.framework/Headers
# /System/Library/Frameworks/OpenAL.framework/Headers
#
# On OS X, this will prefer the Framework version (if found) over others.
# People will have to manually change the cache values of
# OPENAL_LIBRARY to override this selection or set the CMake environment
# CMAKE_INCLUDE_PATH to modify the search paths.
FIND_PATH(ALUT_INCLUDE_DIR alut.h
HINTS
$ENV{ALUTDIR}
PATH_SUFFIXES include/AL include/ALUT include
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
FIND_LIBRARY(ALUT_LIBRARY
NAMES ALUT alut
HINTS
$ENV{ALUTDIR}
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
SET(ALUT_FOUND "NO")
IF(ALUT_LIBRARY AND ALUT_INCLUDE_DIR)
SET(ALUT_FOUND "YES")
ENDIF(ALUT_LIBRARY AND ALUT_INCLUDE_DIR)

View File

@@ -0,0 +1,48 @@
# Find Subversion client libraries, and dependencies
# including APR (Apache Portable Runtime)
include (CheckFunctionExists)
include (CheckIncludeFile)
find_program(HAVE_APR_CONFIG apr-1-config)
if(HAVE_APR_CONFIG)
execute_process(COMMAND apr-1-config --cppflags --includes
OUTPUT_VARIABLE APR_CFLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND apr-1-config --link-ld
OUTPUT_VARIABLE RAW_APR_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE)
# clean up some vars, or other CMake pieces complain
string(STRIP ${RAW_APR_LIBS} APR_LIBS)
else(HAVE_APR_CONFIG)
message(STATUS "apr-1-config not found, implement manual search for APR")
endif(HAVE_APR_CONFIG)
find_path(LIBSVN_INCLUDE_DIR svn_client.h
HINTS
$ENV{LIBSVN_DIR}
PATH_SUFFIXES include/subversion-1
PATHS
/usr/local
/usr
/opt
)
check_library_exists(svn_client-1 svn_client_checkout "" HAVE_LIB_SVNCLIENT)
check_library_exists(svn_subr-1 svn_cmdline_init "" HAVE_LIB_SVNSUBR)
check_library_exists(svn_ra-1 svn_ra_initialize "" HAVE_LIB_SVNRA)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG
HAVE_LIB_SVNSUBR
HAVE_LIB_SVNCLIENT
HAVE_LIB_SVNRA
LIBSVN_INCLUDE_DIR)
if(LIBSVN_FOUND)
set(LIBSVN_LIBRARIES "svn_client-1" "svn_subr-1" "svn_ra-1" ${APR_LIBS})
endif(LIBSVN_FOUND)

View File

@@ -0,0 +1,23 @@
macro(simgear_component name includePath sources headers)
if (SIMGEAR_SHARED)
foreach(s ${sources})
set_property(GLOBAL
APPEND PROPERTY ALL_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${s}")
endforeach()
foreach(h ${headers})
set_property(GLOBAL
APPEND PROPERTY PUBLIC_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${h}")
endforeach()
else()
set(libName "sg${name}")
add_library(${libName} STATIC ${sources} )
install (TARGETS ${libName} ARCHIVE DESTINATION lib${LIB_SUFFIX})
install (FILES ${headers} DESTINATION include/simgear/${includePath})
endif()
endmacro()

View File

@@ -0,0 +1,22 @@
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
ENDIF()
FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
STRING(REGEX REPLACE "\n" ";" files "${files}")
FOREACH(file ${files})
MESSAGE(STATUS "Uninstalling \"${file}\"")
IF(EXISTS "${file}")
EXEC_PROGRAM(
"@CMAKE_COMMAND@" ARGS "-E remove \"${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
IF(NOT "${rm_retval}" STREQUAL 0)
MESSAGE(FATAL_ERROR "Problem when removing \"${file}\"")
ENDIF()
ELSE()
MESSAGE(STATUS "File \"${file}\" does not exist.")
ENDIF()
ENDFOREACH()

View File

@@ -22,7 +22,7 @@ PROJECT_NAME = SimGear
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 1.9.0
PROJECT_NUMBER = 2.2.0
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.

View File

@@ -10,10 +10,6 @@ EXTRA_DIST = \
SUBDIRS = simgear
dist-hook:
(cd $(top_srcdir); $(HOME)/Projects/FlightGear/admin/am2dsp.pl)
rm -rf `find $(distdir)/projects -name CVS`
#
# Rule to build RPM distribution package
#

View File

@@ -1,15 +1,17 @@
dnl Process this file with autoget.sh to produce a working configure
dnl Process this file with autogen.sh to produce a working configure
dnl script.
AC_INIT
AC_INIT(SimGear, m4_esyscmd([cat ./version | tr -d '\n']), [http://www.flightgear.org])
dnl Ensure touching the version causes autoconf to re-run
AC_SUBST([CONFIGURE_DEPENDENCIES], ['$(top_srcdir)/version'])
AC_CONFIG_SRCDIR([simgear/bucket/newbucket.cxx])
dnl Require at least automake 2.52
AC_PREREQ(2.52)
dnl Initialize the automake stuff
AM_INIT_AUTOMAKE(SimGear, 2.0.0)
dnl Specify KAI C++ compiler and flags.
dnl Borrowed with slight modification from blitz distribution.
AC_ARG_WITH(cxx,
@@ -23,6 +25,17 @@ AC_ARG_WITH(cxx,
;;
esac
])
dnl set the $host variable based on local machine/os
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([dist-bzip2])
AC_ARG_ENABLE(headless,
AS_HELP_STRING([--enable-headless],[Enable only packages for headless build]))
AC_MSG_CHECKING([for headless mode])
AC_MSG_RESULT([$enable_headless])
AM_CONDITIONAL(WANT_HEADLESS,[test "x$enable_headless" = "xyes"])
AC_MSG_CHECKING([CXX])
AC_MSG_RESULT([$CXX])
@@ -84,13 +97,17 @@ AC_SUBST(AR)
AC_SUBST(ARFLAGS)
AC_SUBST(compatibility_DIR)
# Show all compiler warnings by default
CXXFLAGS="$CXXFLAGS -Wall"
CFLAGS="$CFLAGS -Wall"
if echo $includedir | egrep "simgear$" > /dev/null; then
echo "includedir is" $includedir "libdir is" $libdir
else
includedir="${includedir}/simgear"
echo "includedir changed to" $includedir "libdir is" $libdir
fi
dnl set logging; default value of with_logging=yes
AC_ARG_WITH(logging, [ --with-logging Include logging output (default)])
if test "x$with_logging" = "xno" ; then
@@ -119,20 +136,6 @@ else
fi
AM_CONDITIONAL(ENABLE_JPEG_SERVER, test "x$with_jpeg_factory" = "xyes")
# specify the plib location
AC_ARG_WITH(plib, [ --with-plib=PREFIX Specify the prefix path to plib])
if test "x$with_plib" != "x" ; then
echo "plib prefix is $with_plib"
EXTRA_DIRS="${EXTRA_DIRS} $with_plib"
fi
AC_ARG_WITH(plib_framework, [ --with-plib-framework=PREFIX Specify the prefix path to PLIB.framework ])
if test "x$with_plib_framework" != "x"; then
echo "plib framework prefix is $with_plib_framework"
fi
# specify the osg location
AC_ARG_WITH(osg, [ --with-osg=PREFIX Specify the prefix path to osg])
@@ -141,7 +144,7 @@ if test "x$with_osg" != "x" ; then
EXTRA_DIRS="${EXTRA_DIRS} $with_osg"
fi
AC_ARG_WITH(osg_framework, [ --with-osg-framework=PREFIX Specify the prefix path to OSG.framework ])
AC_ARG_WITH(osg_framework, [ --with-osg-framework=PREFIX Specify the prefix path to OSG.framework ])
if test "x$with_osg_framework" != "x"; then
echo "osg framework prefix is $with_osg_framework"
@@ -149,11 +152,27 @@ if test "x$with_osg_framework" != "x"; then
export DYLD_FRAMEWORK_PATH="$DYLD_FRAMEWORK_PATH:$with_osg_framework"
fi
dnl specifying OpenAL.framework (for user provided OpenAL.framework / ALUT)
AC_ARG_WITH(openal_framework, [ --with-openal-framework=PREFIX Speicfy the prefix path to OpenAL.framework ])
dnl specifying ALUT.framework (for user provided ALUT.framework)
AC_ARG_WITH(alut_framework, [ --with-alut-framework=PREFIX Specify the prefix path to ALUT.framework ])
if test "x$with_openal_framework" != "x"; then
echo "OpenAL framework prefix is $with_openal_framework"
if test "x$with_alut_framework" != "x"; then
echo "ALUT framework prefix is $with_alut_framework"
fi
# specify the rti13 location
AC_ARG_WITH(rti13, [ --with-rti13=PREFIX Specify the prefix path to a HLA13 rti])
if test "x$with_rti13" != "x" ; then
echo "rti13 prefix is $with_rti13"
EXTRA_DIRS="${EXTRA_DIRS} $with_rti13"
fi
# specify the rti13 location
AC_ARG_WITH(rti1516, [ --with-rti1516=PREFIX Specify the prefix path to a HLA1516 rti])
if test "x$with_rti1516" != "x" ; then
echo "rti1516 prefix is $with_rti1516"
EXTRA_DIRS="${EXTRA_DIRS} $with_rti1516"
fi
dnl Determine an extra directories to add to include/lib search paths
@@ -176,7 +195,7 @@ esac
wi_EXTRA_DIRS(no, ${EXTRA_DIRS})
dnl Using AM_CONDITIONAL is a step out of the protected little
dnl Using AM_CONDITIONAL is a step out of the protected little
dnl automake fold so it is potentially dangerous. But, we are
dnl beginning to run into cases where the standard checks are not
dnl enough. AM_CONDITIONALS are then referenced to conditionally
@@ -267,7 +286,7 @@ case "${host}" in
AC_SEARCH_LIBS(SmcOpenConnection, SM)
AC_SEARCH_LIBS(XtMalloc, Xt)
AC_SEARCH_LIBS(XmuLookupStandardColormap, Xmu)
AC_SEARCH_LIBS(glNewList, [ GL GLcore MesaGL ])
if test "x$ac_cv_search_glNewList" = "x-lGLcore"; then
dnl if GLcore found, then also check for GL
@@ -288,9 +307,6 @@ case "${host}" in
esac
AC_SEARCH_LIBS(glutGetModifiers, [ glut glut32 freeglut ], have_glut=yes, have_glut=no)
AM_CONDITIONAL(HAVE_GLUT, test "x$have_glut" = "xyes")
opengl_LIBS="$LIBS"
LIBS="$base_LIBS"
@@ -313,24 +329,21 @@ case "${host}" in
*-apple-darwin*)
dnl Mac OS X
LIBS="$LIBS -framework IOKit -framework OpenAL"
LIBS="$LIBS -framework IOKit -framework OpenAL -framework ALUT"
openal_LIBS="$LIBS"
OPENAL_OK="yes"
ALUT_OK="no"
if test "x$with_openal_lib" != "x"; then
echo "libopenal is not supported on Mac OS platform."
openal_LIBS=""
fi
OPENAL_OK="yes"
# Looking for alut.h, if found assume that it is a part of
# the OpenAL package.
AC_CHECK_HEADERS([OpenAL/alut.h],[ALUT_OK="yes"])
AC_CHECK_HEADERS([OpenAL/al.h],[OPENAL_OK="yes"])
# Looking for alut.h
AC_CHECK_HEADERS([ALUT/alut.h],[ALUT_OK="yes"])
dnl Thank you Christian Bauer from SheepSaver
dnl Modified by Tatsuhiro Nishioka for accepting a given framework path
dnl AC_CHECK_FRAMEWORK($1=NAME, $2=INCLUDES, $3=FRAMEWORK_PATH) ; $3 is optional
dnl AC_CHECK_FRAMEWORK($1=NAME, $2=INCLUDES, $3=FRAMEWORK_PATH, $4=ACTION_IF_TRUE) ; $3 is optional
AC_DEFUN([AC_CHECK_FRAMEWORK], [
AS_VAR_PUSHDEF([ac_Framework], [ac_cv_framework_$1])dnl
AC_CACHE_CHECK([whether compiler supports framework $1],
@@ -342,6 +355,7 @@ case "${host}" in
elif test "`echo $FRAMEWORKS | grep -- -F$3`" = ""; then
FRAMEWORKS="$FRAMEWORKS -F$3"
CXXFLAGS="$CXXFLAGS -F$3"
CPPFLAGS="$CPPFLAGS -F$3"
CCFLAGS="$CCFLAGS -F$3"
dnl This is needed for AC_TRY_LINK when a framework path is specified
export DYLD_FRAMEWORK_PATH="${DYLD_FRAMEWORK_PATH}:$3"
@@ -354,13 +368,14 @@ case "${host}" in
AS_IF([test AS_VAR_GET(ac_Framework) = yes],
[AC_DEFINE(AS_TR_CPP(HAVE_FRAMEWORK_$1), 1, [Define if framework $1 is available.])]
)
AS_IF([test AS_VAR_GET(ac_Framework) = yes], $4)
AS_VAR_POPDEF([ac_Framework])dnl
])
dnl Check for OpenAL.framework when --with-openal-framework is specified
dnl Of cource OpenAL.framework needs to have alut.h
if test "x$with_openal_framework" != "x"; then
AC_CHECK_FRAMEWORK(OpenAL, [#include <OpenAL/alut.h>], $with_openal_framework)
dnl Check for ALUT.framework when --with-alut-framework is specified
if test "x$with_alut_framework" != "x"; then
AC_CHECK_FRAMEWORK(ALUT, [#include <ALUT/alut.h>], $with_alut_framework, [ALUT_OK="yes"])
fi
;;
@@ -380,7 +395,7 @@ case "${host}" in
esac
if test "$OPENAL_OK" == "no"; then
if test "$OPENAL_OK" == "no" -a "x$enable_headless" != "xyes"; then
echo
echo "You *must* have the openal library installed on your system to build"
echo "SimGear!"
@@ -391,7 +406,7 @@ if test "$OPENAL_OK" == "no"; then
exit
fi
if test "$ALUT_OK" == "no"; then
if test "$ALUT_OK" == "no" -a "x$enable_headless" != "xyes"; then
echo
echo "You *must* have the alut library installed on your system to build"
echo "SimGear!"
@@ -422,62 +437,6 @@ AM_CONDITIONAL(EXTGL_NEEDED, test "x$ac_cv_header_windows_h" = "xyes")
CXXCPP="g++ -E"
AC_LANG_PUSH(C++)
dnl Check for "plib" without which we cannot go on
case ${host} in
*-apple-darwin*)
# Check PLIB framework availability when with-plib-framework is specified
if test "x$with_plib_framework" != "x"; then
AC_CHECK_FRAMEWORK(PLIB, [#include <plib/ul.h>], $with_plib_framework)
plib_FRAMEWORK="$FRAMEWORKS"
FRAMEWORKS=""
AC_SUBST(plib_FRAMEWORK)
fi
;;
esac
AM_CONDITIONAL(HAVE_FRAMEWORK_PLIB, test "x$ac_cv_framework_PLIB" != "x")
AC_CHECK_HEADER(plib/ul.h)
AC_CHECK_LIB(plibul,ulInit)
if test "x$ac_cv_header_plib_ul_h" != "xyes" \
-o "x$ac_cv_lib_plibul_ulInit" != "xyes" ; then
echo
echo "You *must* have the plib library installed on your system to build"
echo "SimGear!"
echo
echo " LIBS: '$LIBS'"
echo " LDFLAGS: '$LDFLAGS'"
echo " CPPFLAGS: '$CPPFLAGS'"
echo
echo "Please see README.plib for more details."
echo
echo "configure aborted."
exit
fi
AC_MSG_CHECKING([for plib 1.8.5 or newer])
AC_TRY_RUN([
#include <plib/ul.h>
#define MIN_PLIB_VERSION 185
int main() {
if ( PLIB_VERSION < MIN_PLIB_VERSION ) {
return -1;
}
return 0;
}
],
AC_MSG_RESULT(yes),
[AC_MSG_RESULT(wrong version);
AC_MSG_ERROR([Install plib 1.8.5 or later first...])],
AC_MSG_RESULT(yes)
)
LIBS="$saved_LIBS"
# OpenSceneGraph
case "${host}" in
*-apple-darwin*)
@@ -490,7 +449,7 @@ case "${host}" in
# AC_CHECK_FRAMEWORK(osgDB, [#include <osgDB/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgSim, [#include <osgSim/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgParticle, [#include <osgParticle/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osg, [#include <osg/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osg, [#include <osg/Version>], $with_osg_framework)
# osg_FRAMEWORKS="$FRAMEWORKS"
# FRAMEWORKS=""
# AC_SUBST(osg_FRAMEWORKS)
@@ -500,7 +459,7 @@ case "${host}" in
AC_SUBST(openthreads_FRAMEWORK)
else
dnl
dnl This is needed when osg dynamic libs are specified
dnl This is needed when osg dynamic libs are specified
dnl instead of OSG frameworks on Mac OS X
dnl
AC_CHECK_LIB(OpenThreads,OpenThreadsGetVersion)
@@ -552,6 +511,17 @@ if test "x$ac_cv_header_boost_version_hpp" != "xyes"; then
exit
fi
dnl Check for a HLA13 rti.
dnl This is really tricky because of the ancient iostream stuff in RTI13
saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -DRTI_USES_STD_FSTREAM"
AC_CHECK_HEADER(RTI.hh)
CPPFLAGS="${saved_CPPFLAGS}"
dnl Up to now only RTI13
AM_CONDITIONAL(ENABLE_HLA, test "x$ac_cv_header_RTI_hh" = "xyes")
AM_CONDITIONAL(ENABLE_HLA13, test "x$ac_cv_header_RTI_hh" = "xyes")
AC_LANG_POP
dnl Check for system installed zlib
@@ -570,6 +540,39 @@ if test "x$ac_cv_header_zlib_h" != "xyes"; then
echo
fi
dnl Check for Subversion library support
# libsvn support defaults to yes
save_LIBS=$LIBS
save_CPPFLAGS=$CPPFLAGS
AC_ARG_WITH(libsvn, [ --without-libsvn Do not use built-in subversion (libsvn) for simgear [default=no]], [], [with_libsvn=yes])
if test "x$with_libsvn" = "xyes"; then
LIBS="`apr-1-config --link-ld`"
CPPFLAGS="-I/usr/include/subversion-1 `apr-1-config --includes --cppflags`"
AC_CHECK_HEADERS([svn_client.h])
if test "x$ac_cv_header_svn_client_h" = "xyes"; then
echo "Using built-in subversion (libsvn) for scenery downloads."
AC_SEARCH_LIBS(svn_client_checkout, svn_client-1,
[AC_DEFINE([HAVE_LIBSVN_CLIENT_1], [1], [Define to 1 if you have libsvn_client-1])],
[AC_MSG_ERROR(svn_client-1 library not found.)],)
AC_SEARCH_LIBS(svn_cmdline_init, svn_subr-1, , [AC_MSG_ERROR(svn_subr-1 library not found.)],)
AC_SEARCH_LIBS(svn_ra_initialize, svn_ra-1, , [AC_MSG_ERROR(svn_ra-1 library not found.)],)
svn_LIBS=$LIBS
svn_CPPFLAGS=$CPPFLAGS
AC_SUBST(svn_LIBS)
AC_SUBST(svn_CPPFLAGS)
else
echo "Libsvn not found. Will use command line subversion for scenery downloads."
svn_LIBS=""
svn_CPPFLAGS=""
fi
else
echo "Libsvn explicitly disabled. Will use command line subversion for scenery downloads."
svn_LIBS=""
svn_CPPFLAGS=""
fi
LIBS=$save_LIBS
CPPFLAGS=$save_CPPFLAGS
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS( \
@@ -610,6 +613,7 @@ AC_CONFIG_FILES([ \
simgear/bucket/Makefile \
simgear/debug/Makefile \
simgear/ephemeris/Makefile \
simgear/hla/Makefile \
simgear/io/Makefile \
simgear/magvar/Makefile \
simgear/math/Makefile \
@@ -625,6 +629,7 @@ AC_CONFIG_FILES([ \
simgear/scene/sky/Makefile \
simgear/scene/tgdb/Makefile \
simgear/scene/util/Makefile \
simgear/scene/tsync/Makefile \
simgear/screen/Makefile \
simgear/serial/Makefile \
simgear/sound/Makefile \

2
projects/VC100/README Normal file
View File

@@ -0,0 +1,2 @@
The handmade VS2010 project files have been replaced by the Cmake build system.
Please use Cmake to build FlightGear with Visual Studio 2010.

View File

@@ -1,5 +0,0 @@
SimGear.ncb
SimGear.suo
*.user
Win32
x64

3
projects/VC90/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*.user
Win32
x64

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +0,0 @@
Makefile
Makefile.in
simgear_config.h
simgear_config.h.in
stamp-h
stamp-h.in
stamp-h1
version.h

4
simgear/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
simgear_config.h
simgear_config.h.*
stamp-h1
version.h

58
simgear/CMakeLists.txt Normal file
View File

@@ -0,0 +1,58 @@
file(WRITE ${PROJECT_BINARY_DIR}/simgear/version.h "#define SIMGEAR_VERSION ${SIMGEAR_VERSION}")
foreach( mylibfolder
bucket
debug
ephemeris
hla
io
magvar
math
misc
nasal
props
route
serial
structure
threads
timing
xml
)
add_subdirectory(${mylibfolder})
endforeach( mylibfolder )
if (NOT SIMGEAR_HEADLESS)
add_subdirectory(environment)
add_subdirectory(screen)
add_subdirectory(scene)
add_subdirectory(sound)
endif()
set(HEADERS compiler.h constants.h sg_inlines.h ${PROJECT_BINARY_DIR}/simgear/version.h)
install (FILES ${HEADERS} DESTINATION include/simgear/)
if(SIMGEAR_SHARED)
message(STATUS "building shared library")
get_property(allSources GLOBAL PROPERTY ALL_SOURCES)
get_property(publicHeaders GLOBAL PROPERTY PUBLIC_HEADERS)
add_library(SimGear SHARED ${allSources})
set_property(TARGET SimGear PROPERTY FRAMEWORK 1)
message(STATUS "public header: ${publicHeaders}")
set_property(TARGET SimGear PROPERTY PUBLIC_HEADER "${publicHeaders}")
set_property(TARGET SimGear PROPERTY LINKER_LANGUAGE CXX)
target_link_libraries(SimGear ${ZLIB_LIBRARY}
${OPENSCENEGRAPH_LIBRARIES}
${OPENAL_LIBRARY} ${ALUT_LIBRARY}
${OPENGL_LIBRARY})
install(TARGETS SimGear LIBRARY DESTINATION lib${LIB_SUFFIX}
PUBLIC_HEADER DESTINATION include/simgear)
endif(SIMGEAR_SHARED)

View File

@@ -1,31 +1,50 @@
# METAR_DIRS =
METAR_DIRS = environment
if ENABLE_HLA
HLA_DIR = hla
else
HLA_DIR =
endif
EXTRA_DIST = simgear_config.h.vc5 simgear_config.h-msvc71 version.h.in
include_HEADERS = \
compiler.h constants.h sg_inlines.h version.h
SUBDIRS = \
$(compatibility_DIR) \
if WANT_HEADLESS
SG_EXTRA_DIRS =
METAR_DIRS =
else
SG_EXTRA_DIRS = scene sound screen
METAR_DIRS = environment
endif
if HAVE_THREADS
SGTHREAD_DIR = threads
else
SGTHREAD_DIR =
endif
SUBDIRS_ALWAYS = \
xml \
debug \
misc \
structure \
bucket \
ephemeris \
$(HLA_DIR) \
io \
magvar \
math \
$(METAR_DIRS) \
nasal \
props \
route \
scene \
screen \
serial \
sound \
threads \
timing
DIST_SUBDIRS = $(SUBDIRS) compatibility
SUBDIRS = $(SUBDIRS_ALWAYS) \
$(compatibility_DIR) \
$(METAR_DIRS) \
$(SG_EXTRA_DIRS) \
$(SGTHREAD_DIR)
DIST_SUBDIRS = $(SUBDIRS_ALWAYS) compatibility scene sound screen environment threads

View File

@@ -1,3 +0,0 @@
.deps
Makefile
Makefile.in

View File

@@ -0,0 +1,7 @@
include (SimGearComponent)
set(HEADERS newbucket.hxx)
set(SOURCES newbucket.cxx)
simgear_component(bucket bucket "${SOURCES}" "${HEADERS}")

View File

@@ -92,6 +92,11 @@ void SGBucket::set_bucket( double dlon, double dlat ) {
// cout << "diff = " << diff << " span = " << span << endl;
/* Calculate the greatest integral longitude less than
* or equal to the given longitude (floor(dlon)),
* but attribute coordinates near the east border
* to the next tile.
*/
if ( (dlon >= 0) || (fabs(diff) < SG_EPSILON) ) {
lon = (int)dlon;
} else {
@@ -100,22 +105,48 @@ void SGBucket::set_bucket( double dlon, double dlat ) {
// find subdivision or super lon if needed
if ( span < SG_EPSILON ) {
/* sg_bucket_span() never returns 0.0
* or anything near it, so this really
* should not occur at any time.
*/
// polar cap
lon = 0;
x = 0;
} else if ( span <= 1.0 ) {
/* We have more than one tile per degree of
* longitude, so we need an x offset.
*/
x = (int)((dlon - lon) / span);
} else {
if ( dlon >= 0 ) {
lon = (int)( (int)(lon / span) * span);
} else {
// cout << " lon = " << lon
// << " tmp = " << (int)((lon-1) / span) << endl;
lon = (int)( (int)((lon + 1) / span) * span - span);
if ( lon < -180 ) {
lon = -180;
}
}
/* We have one or more degrees per tile,
* so we need to find the base longitude
* of that tile.
*
* First we calculate the integral base longitude
* (e.g. -85.5 => -86) and then find the greatest
* multiple of span that is less than or equal to
* that longitude.
*
* That way, the Greenwich Meridian is always
* a tile border.
*
* This gets us into trouble with the polar caps,
* which have width 360 and thus either span
* the range from 0 to 360 or from -360 to 0
* degrees, depending on whether lon is positive
* or negative!
*
* We also get into trouble with the 8 degree tiles
* north of 88N and south of 88S, because the west-
* and east-most tiles in that range will cover 184W
* to 176W and 176E to 184E respectively, with their
* center at 180E/W!
*/
lon=(int)floor(floor((lon+SG_EPSILON)/span)*span);
/* Correct the polar cap issue */
if ( lon < -180 ) {
lon = -180;
}
x = 0;
}
@@ -124,11 +155,15 @@ void SGBucket::set_bucket( double dlon, double dlat ) {
//
diff = dlat - (double)(int)dlat;
/* Again, a modified floor() function (see longitude) */
if ( (dlat >= 0) || (fabs(diff) < SG_EPSILON) ) {
lat = (int)dlat;
} else {
lat = (int)dlat - 1;
}
/* Latitude base and offset are easier, as
* tiles always are 1/8 degree of latitude wide.
*/
y = (int)((dlat - lat) * 8);
}
@@ -139,7 +174,7 @@ void SGBucket::set_bucket(const SGGeod& geod)
}
// Build the path name for this bucket
string SGBucket::gen_base_path() const {
std::string SGBucket::gen_base_path() const {
// long int index;
int top_lon, top_lat, main_lon, main_lat;
char hem, pole;
@@ -189,6 +224,17 @@ string SGBucket::gen_base_path() const {
// return width of the tile in degrees
double SGBucket::get_width() const {
if (lon==-180 && (lat==-89 || lat==88) ) {
/* Normally the tile at 180W in 88N and 89S
* would cover 184W to 176W and the next
* on the east side starts at 176W.
* To correct, make this a special tile
* from 180W to 176W with 4 degrees width
* instead of the normal 8 degrees at
* that latitude.
*/
return 4.0;
}
return sg_bucket_span( get_center_lat() );
}
@@ -213,7 +259,7 @@ double SGBucket::get_width_m() const {
double local_perimeter = local_radius * SGD_2PI;
double degree_width = local_perimeter / 360.0;
return sg_bucket_span( get_center_lat() ) * degree_width;
return get_width() * degree_width;
}

View File

@@ -24,6 +24,11 @@
/** \file newbucket.hxx
* A class and associated utiltity functions to manage world scenery tiling.
*
* Tile borders are aligned along circles of latitude and longitude.
* All tiles are 1/8 degree of latitude high and their width in degrees
* longitude depends on their latitude, adjusted in such a way that
* all tiles cover about the same amount of area of the earth surface.
*/
#ifndef _NEWBUCKET_HXX
@@ -211,9 +216,9 @@ public:
double span = sg_bucket_span( lat + y / 8.0 + SG_HALF_BUCKET_SPAN );
if ( span >= 1.0 ) {
return lon + span / 2.0;
return lon + get_width() / 2.0;
} else {
return lon + x * span + span / 2.0;
return lon + x * span + get_width() / 2.0;
}
}
@@ -329,7 +334,7 @@ void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy );
inline std::ostream&
operator<< ( std::ostream& out, const SGBucket& b )
{
return out << b.lon << ":" << b.x << ", " << b.lat << ":" << b.y;
return out << b.lon << ":" << (int)b.x << ", " << b.lat << ":" << (int)b.y;
}

View File

@@ -1,2 +0,0 @@
Makefile
Makefile.in

View File

@@ -1,2 +0,0 @@
Makefile
Makefile.in

View File

@@ -1,2 +0,0 @@
Makefile
Makefile.in

View File

@@ -67,6 +67,10 @@
# define vsnprintf _vsnprintf
# endif
# define copysign _copysign
# define strcasecmp stricmp
# undef min
# undef max
# pragma warning(disable: 4786) // identifier was truncated to '255' characters
# pragma warning(disable: 4244) // conversion from double to float
@@ -105,6 +109,7 @@
#if defined (__sun)
# define SG_UNIX
# include <strings.h>
# include <memory.h>
# if defined ( __cplusplus )
@@ -134,6 +139,8 @@
//
#ifdef __APPLE__
# define SG_MAC
# define SG_UNIX
# ifdef __GNUC__
# if ( __GNUC__ > 3 ) || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 3 )
inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
@@ -150,6 +157,8 @@ inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
#endif
#if defined (__FreeBSD__)
# define SG_UNIX
#include <sys/param.h>
# if __FreeBSD_version < 500000
extern "C" {
inline int isnan(double r) { return !(r <= 0 || r >= 0); }
@@ -158,9 +167,19 @@ inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
#endif
#if defined (__CYGWIN__)
# define SG_WINDOWS
# define SG_UNIX
# include <ieeefp.h> // isnan
#endif
// includes both MSVC and mingw compilers
#if defined(_WIN32) || defined(__WIN32__)
# define SG_WINDOWS
#endif
#if defined(__linux__) || defined(_AIX) || defined ( sgi )
# define SG_UNIX
#endif
//
// No user modifiable definitions beyond here.

View File

@@ -34,15 +34,22 @@
#include <cmath>
#include <plib/sg.h>
// Make sure PI is defined in its various forms
// SG_PI and SGD_PI (float and double) come from plib/sg.h
#ifndef SGD_PI // remove me once FlightGear no longer uses PLIB
#ifdef M_PI
const double SGD_PI = M_PI;
const float SG_PI = M_PI;
#else
const float SG_PI = 3.1415926535f;
const double SGD_PI = 3.1415926535;
#endif
#endif // of PLIB-SG guard
/** 2 * PI */
#define SGD_2PI 6.28318530717958647692
const double SGD_2PI = SGD_PI * 2.0;
/** PI / 2 */
#ifdef M_PI_2
@@ -52,7 +59,17 @@
#endif
/** PI / 4 */
#define SGD_PI_4 0.78539816339744830961
const double SGD_PI_4 = 0.78539816339744830961;
#ifndef SGD_DEGREES_TO_RADIANS // // remove me once FlightGear no longer uses PLIB
const double SGD_DEGREES_TO_RADIANS = SGD_PI / 180.0;
const double SGD_RADIANS_TO_DEGREES = 180.0 / SGD_PI;
const float SG_DEGREES_TO_RADIANS = SG_PI / 180.0f;
const float SG_RADIANS_TO_DEGREES = 180.0f / SG_PI;
#endif // of PLIB-SG guard
/** \def SG_E "e" */
#ifdef M_E

View File

@@ -1,3 +0,0 @@
.deps
Makefile
Makefile.in

View File

@@ -0,0 +1,7 @@
include (SimGearComponent)
set(HEADERS debug_types.h logstream.hxx)
set(SOURCES logstream.cxx)
simgear_component(debug debug "${SOURCES}" "${HEADERS}")

View File

@@ -1,4 +0,0 @@
.deps
Makefile
Makefile.in
metar

View File

@@ -0,0 +1,7 @@
include (SimGearComponent)
set(HEADERS metar.hxx precipitation.hxx)
set(SOURCES metar.cxx precipitation.cxx)
simgear_component(environment environment "${SOURCES}" "${HEADERS}")

View File

@@ -2,8 +2,8 @@ includedir = @includedir@/environment
lib_LIBRARIES = libsgenvironment.a
include_HEADERS = metar.hxx visual_enviro.hxx precipitation.hxx
include_HEADERS = metar.hxx precipitation.hxx
libsgenvironment_a_SOURCES = metar.cxx visual_enviro.cxx precipitation.cxx
libsgenvironment_a_SOURCES = metar.cxx precipitation.cxx
INCLUDES = -I$(top_srcdir)

View File

@@ -30,6 +30,7 @@
#include <string>
#include <time.h>
#include <cstring>
#include <simgear/io/sg_socket.hxx>
#include <simgear/debug/logstream.hxx>
@@ -189,11 +190,12 @@ char *SGMetar::loadData(const char *id, const string& proxy, const string& port,
const int buflen = 512;
char buf[2 * buflen];
string host = proxy.empty() ? "weather.noaa.gov" : proxy;
string metar_server = "weather.noaa.gov";
string host = proxy.empty() ? metar_server : proxy;
string path = "/pub/data/observations/metar/stations/";
path += string(id) + ".TXT";
_url = "http://weather.noaa.gov" + path;
_url = "http://" + metar_server + path;
SGSocket *sock = new SGSocket(host, port.empty() ? "80" : port, "tcp");
sock->set_timeout(10000);
@@ -204,10 +206,11 @@ char *SGMetar::loadData(const char *id, const string& proxy, const string& port,
string get = "GET ";
if (!proxy.empty())
get += "http://weather.noaa.gov";
get += "http://" + metar_server;
sprintf(buf, "%ld", time);
get += path + " HTTP/1.0\015\012X-Time: " + buf + "\015\012";
get += "Host: " + metar_server + "\015\012";
if (!auth.empty())
get += "Proxy-Authorization: " + auth + "\015\012";
@@ -465,11 +468,13 @@ bool SGMetar::scanVisibility()
int modifier = SGMetarVisibility::EQUALS;
// \d{4}(N|NE|E|SE|S|SW|W|NW)?
if (scanNumber(&m, &i, 4)) {
if (*m == 'E')
if( strncmp( m, "NDV",3 ) == 0 ) {
m+=3; // tolerate NDV (no directional validation)
} else if (*m == 'E') {
m++, dir = 90;
else if (*m == 'W')
} else if (*m == 'W') {
m++, dir = 270;
else if (*m == 'N') {
} else if (*m == 'N') {
m++;
if (*m == 'E')
m++, dir = 45;
@@ -485,7 +490,7 @@ bool SGMetar::scanVisibility()
m++, dir = 225;
else
dir = 180;
}
}
if (i == 0)
i = 50, modifier = SGMetarVisibility::LESS_THAN;
else if (i == 9999)
@@ -591,7 +596,7 @@ bool SGMetar::scanRwyVisRange()
r._max_visibility._distance = to;
if (*m == '/') // this is not in the spec!
*m++;
m++;
if (*m == 'D')
m++, r._min_visibility._tendency = SGMetarVisibility::DECREASING;
else if (*m == 'N')
@@ -612,8 +617,8 @@ bool SGMetar::scanRwyVisRange()
static const struct Token special[] = {
{ "NSW", "no significant weather" },
{ "VCSH", "showers in the vicinity" },
{ "VCTS", "thunderstorm in the vicinity" },
/* { "VCSH", "showers in the vicinity" },
{ "VCTS", "thunderstorm in the vicinity" }, */
{ 0, 0 }
};
@@ -666,6 +671,7 @@ bool SGMetar::scanWeather()
char *m = _m;
string weather;
const struct Token *a;
if ((a = scanToken(&m, special))) {
if (!scanBoundary(&m))
return false;
@@ -675,32 +681,35 @@ bool SGMetar::scanWeather()
}
string pre, post;
int intensity = 0;
struct Weather w;
if (*m == '-')
m++, pre = "light ", intensity = 1;
m++, pre = "light ", w.intensity = LIGHT;
else if (*m == '+')
m++, pre = "heavy ", intensity = 3;
m++, pre = "heavy ", w.intensity = HEAVY;
else if (!strncmp(m, "VC", 2))
m += 2, post = "in the vicinity ";
m += 2, post = "in the vicinity ", w.vincinity=true;
else
pre = "moderate ", intensity = 2;
pre = "moderate ", w.intensity = MODERATE;
int i;
for (i = 0; i < 3; i++) {
if (!(a = scanToken(&m, description)))
break;
w.descriptions.push_back(a->id);
weather += string(a->text) + " ";
}
for (i = 0; i < 3; i++) {
if (!(a = scanToken(&m, phenomenon)))
break;
w.phenomena.push_back(a->id);
weather += string(a->text) + " ";
if (!strcmp(a->id, "RA"))
_rain = intensity;
_rain = w.intensity;
else if (!strcmp(a->id, "HA"))
_hail = intensity;
_hail = w.intensity;
else if (!strcmp(a->id, "SN"))
_snow = intensity;
_snow = w.intensity;
}
if (!weather.length())
return false;
@@ -710,6 +719,8 @@ bool SGMetar::scanWeather()
weather = pre + weather + post;
weather.erase(weather.length() - 1);
_weather.push_back(weather);
if( w.phenomena.size() > 0 )
_weather2.push_back( w );
_grpcount++;
return true;
}
@@ -738,7 +749,7 @@ static const struct Token cloud_types[] = {
{ 0, 0 }
};
#include <iostream>
// (FEW|SCT|BKN|OVC|SKC|CLR|CAVOK|VV)([0-9]{3}|///)?[:cloud_type:]?
bool SGMetar::scanSkyCondition()
{
@@ -756,6 +767,7 @@ bool SGMetar::scanSkyCondition()
if (!strncmp(m, "CLR", i = 3) // clear
|| !strncmp(m, "SKC", i = 3) // sky clear
|| !strncmp(m, "NCD", i = 3) // nil cloud detected
|| !strncmp(m, "NSC", i = 3) // no significant clouds
|| !strncmp(m, "CAVOK", i = 5)) { // ceiling and visibility OK (implies 9999)
m += i;
@@ -763,7 +775,7 @@ bool SGMetar::scanSkyCondition()
return false;
if (i == 3) {
cl._coverage = 0;
cl._coverage = SGMetarCloud::COVERAGE_CLEAR;
_clouds.push_back(cl);
} else {
_cavok = true;
@@ -775,13 +787,13 @@ bool SGMetar::scanSkyCondition()
if (!strncmp(m, "VV", i = 2)) // vertical visibility
;
else if (!strncmp(m, "FEW", i = 3))
cl._coverage = 1;
cl._coverage = SGMetarCloud::COVERAGE_FEW;
else if (!strncmp(m, "SCT", i = 3))
cl._coverage = 2;
cl._coverage = SGMetarCloud::COVERAGE_SCATTERED;
else if (!strncmp(m, "BKN", i = 3))
cl._coverage = 3;
cl._coverage = SGMetarCloud::COVERAGE_BROKEN;
else if (!strncmp(m, "OVC", i = 3))
cl._coverage = 4;
cl._coverage = SGMetarCloud::COVERAGE_OVERCAST;
else
return false;
m += i;
@@ -794,7 +806,7 @@ bool SGMetar::scanSkyCondition()
} else if (!scanNumber(&m, &i, 3))
i = -1;
if (cl._coverage == -1) {
if (cl._coverage == SGMetarCloud::COVERAGE_NIL) {
if (!scanBoundary(&m))
return false;
if (i == -1) // 'VV///'
@@ -1194,13 +1206,29 @@ const struct Token *SGMetar::scanToken(char **str, const struct Token *list)
}
void SGMetarCloud::set(double alt, int cov)
void SGMetarCloud::set(double alt, Coverage cov)
{
_altitude = alt;
if (cov != -1)
_coverage = cov;
}
SGMetarCloud::Coverage SGMetarCloud::getCoverage( const std::string & coverage )
{
if( coverage == "clear" ) return COVERAGE_CLEAR;
if( coverage == "few" ) return COVERAGE_FEW;
if( coverage == "scattered" ) return COVERAGE_SCATTERED;
if( coverage == "broken" ) return COVERAGE_BROKEN;
if( coverage == "overcast" ) return COVERAGE_OVERCAST;
return COVERAGE_NIL;
}
const char * SGMetarCloud::COVERAGE_NIL_STRING = "nil";
const char * SGMetarCloud::COVERAGE_CLEAR_STRING = "clear";
const char * SGMetarCloud::COVERAGE_FEW_STRING = "few";
const char * SGMetarCloud::COVERAGE_SCATTERED_STRING = "scattered";
const char * SGMetarCloud::COVERAGE_BROKEN_STRING = "broken";
const char * SGMetarCloud::COVERAGE_OVERCAST_STRING = "overcast";
void SGMetarVisibility::set(double dist, int dir, int mod, int tend)
{

View File

@@ -130,18 +130,35 @@ protected:
class SGMetarCloud {
friend class SGMetar;
public:
SGMetarCloud() : _coverage(-1), _altitude(NaN), _type(0), _type_long(0) {}
enum Coverage {
COVERAGE_NIL = -1,
COVERAGE_CLEAR = 0,
COVERAGE_FEW = 1,
COVERAGE_SCATTERED = 2,
COVERAGE_BROKEN = 3,
COVERAGE_OVERCAST = 4
};
void set(double alt, int cov = -1);
static const char * COVERAGE_NIL_STRING;
static const char * COVERAGE_CLEAR_STRING;
static const char * COVERAGE_FEW_STRING;
static const char * COVERAGE_SCATTERED_STRING;
static const char * COVERAGE_BROKEN_STRING;
static const char * COVERAGE_OVERCAST_STRING;
inline int getCoverage() const { return _coverage; }
SGMetarCloud() : _coverage(COVERAGE_NIL), _altitude(NaN), _type(0), _type_long(0) {}
void set(double alt, Coverage cov = COVERAGE_NIL );
inline Coverage getCoverage() const { return _coverage; }
static Coverage getCoverage( const std::string & coverage );
inline double getAltitude_m() const { return _altitude; }
inline double getAltitude_ft() const { return _altitude == NaN ? NaN : _altitude * SG_METER_TO_FEET; }
inline const char *getTypeString() const { return _type; }
inline const char *getTypeLongString() const { return _type_long; }
protected:
int _coverage; // quarters: 0 -> clear ... 4 -> overcast
Coverage _coverage; // quarters: 0 -> clear ... 4 -> overcast
double _altitude; // 1000 m
const char *_type; // CU
const char *_type_long; // cumulus
@@ -161,6 +178,21 @@ public:
RTD
};
enum Intensity {
NIL = 0,
LIGHT = 1,
MODERATE = 2,
HEAVY = 3
};
struct Weather {
Weather() { intensity = NIL; vincinity = false; }
Intensity intensity;
bool vincinity;
vector<string> descriptions;
vector<string> phenomena;
};
inline const char *getData() const { return _data; }
inline const char *getUnusedData() const { return _m; }
inline const bool getProxy() const { return _x_proxy; }
@@ -208,6 +240,7 @@ public:
inline const vector<SGMetarCloud>& getClouds() const { return _clouds; }
inline const map<string, SGMetarRunway>& getRunways() const { return _runways; }
inline const vector<string>& getWeather() const { return _weather; }
inline const vector<struct Weather> getWeather2() const { return _weather2; }
protected:
string _url;
@@ -234,6 +267,7 @@ protected:
int _hail;
int _snow;
bool _cavok;
vector<struct Weather> _weather2;
SGMetarVisibility _min_visibility;
SGMetarVisibility _max_visibility;

View File

@@ -25,7 +25,7 @@
*/
#include "precipitation.hxx"
#include "visual_enviro.hxx"
//#include "visual_enviro.hxx"
#include <simgear/constants.h>
#include <osg/ClipNode>
@@ -36,11 +36,20 @@
* Build a new OSG object from osgParticle.
*/
SGPrecipitation::SGPrecipitation() :
_freeze(false), _snow_intensity(0.0), _rain_intensity(0.0), _clip_distance(5.0)
_freeze(false), _enabled(true), _snow_intensity(0.0), _rain_intensity(0.0), _clip_distance(5.0)
{
_precipitationEffect = new osgParticle::PrecipitationEffect;
}
void SGPrecipitation::setEnabled( bool value )
{
_enabled = value;
}
bool SGPrecipitation::getEnabled() const
{
return _enabled;
}
/**
* @brief Build and add the object "precipitationEffect"
@@ -161,8 +170,7 @@ bool SGPrecipitation::update(void)
this->_snow_intensity = this->_rain_intensity;
}
bool enabled = sgEnviro.get_precipitation_enable_state();
if (enabled && this->_snow_intensity > 0) {
if (_enabled && this->_snow_intensity > 0) {
_precipitationEffect->setWind(_wind_vec);
_precipitationEffect->setParticleSpeed( -0.75f - 0.25f*_snow_intensity);
@@ -174,7 +182,7 @@ bool SGPrecipitation::update(void)
_precipitationEffect->setFarTransition(100.0f - 60.0f*sqrtf(_snow_intensity));
_precipitationEffect->setParticleColor(osg::Vec4(0.85, 0.85, 0.85, 1.0) - osg::Vec4(0.1, 0.1, 0.1, 1.0) * _snow_intensity);
} else if (enabled && this->_rain_intensity > 0) {
} else if (_enabled && this->_rain_intensity > 0) {
_precipitationEffect->setWind(_wind_vec);
_precipitationEffect->setParticleSpeed( -2.0f + -5.0f*_rain_intensity);

View File

@@ -36,6 +36,7 @@ class SGPrecipitation : public osg::Referenced
{
private:
bool _freeze;
bool _enabled;
float _snow_intensity;
float _rain_intensity;
@@ -56,6 +57,9 @@ public:
void setFreezing(bool);
void setRainIntensity(float);
void setSnowIntensity(float);
void setEnabled( bool );
bool getEnabled() const;
};
#endif

View File

@@ -28,8 +28,6 @@
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/math/sg_random.h>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/math/point3d.hxx>
#include <simgear/math/polar3d.hxx>
#include <simgear/sound/sample_group.hxx>
#include <simgear/scene/sky/cloudfield.hxx>
#include <simgear/scene/sky/newcloud.hxx>
@@ -42,7 +40,7 @@ using std::vector;
typedef struct {
Point3D pt;
SGVec3d pt;
int depth;
int prev;
} lt_tree_seg;
@@ -52,23 +50,23 @@ static float rainpos[MAX_RAIN_SLICE];
#define MAX_LT_TREE_SEG 400
#define DFL_MIN_LIGHT 0.35
sgVec3 SGEnviro::min_light = {DFL_MIN_LIGHT, DFL_MIN_LIGHT, DFL_MIN_LIGHT};
SGVec3f SGEnviro::min_light(DFL_MIN_LIGHT, DFL_MIN_LIGHT, DFL_MIN_LIGHT);
#define DFL_STREAK_BRIGHT_NEARMOST_LAYER 0.9
SGfloat SGEnviro::streak_bright_nearmost_layer = DFL_STREAK_BRIGHT_NEARMOST_LAYER;
float SGEnviro::streak_bright_nearmost_layer = DFL_STREAK_BRIGHT_NEARMOST_LAYER;
#define DFL_STREAK_BRIGHT_FARMOST_LAYER 0.5
SGfloat SGEnviro::streak_bright_farmost_layer = DFL_STREAK_BRIGHT_FARMOST_LAYER;
float SGEnviro::streak_bright_farmost_layer = DFL_STREAK_BRIGHT_FARMOST_LAYER;
#define DFL_STREAK_PERIOD_MAX 2.5
SGfloat SGEnviro::streak_period_max = DFL_STREAK_PERIOD_MAX;
float SGEnviro::streak_period_max = DFL_STREAK_PERIOD_MAX;
#define DFL_STREAK_PERIOD_CHANGE_PER_KT 0.005
SGfloat SGEnviro::streak_period_change_per_kt = DFL_STREAK_PERIOD_CHANGE_PER_KT;
float SGEnviro::streak_period_change_per_kt = DFL_STREAK_PERIOD_CHANGE_PER_KT;
#define DFL_STREAK_PERIOD_MIN 1.0
SGfloat SGEnviro::streak_period_min = DFL_STREAK_PERIOD_MIN;
float SGEnviro::streak_period_min = DFL_STREAK_PERIOD_MIN;
#define DFL_STREAK_LENGTH_MIN 0.03
SGfloat SGEnviro::streak_length_min = DFL_STREAK_LENGTH_MIN;
float SGEnviro::streak_length_min = DFL_STREAK_LENGTH_MIN;
#define DFL_STREAK_LENGTH_CHANGE_PER_KT 0.0005
SGfloat SGEnviro::streak_length_change_per_kt = DFL_STREAK_LENGTH_CHANGE_PER_KT;
float SGEnviro::streak_length_change_per_kt = DFL_STREAK_LENGTH_CHANGE_PER_KT;
#define DFL_STREAK_LENGTH_MAX 0.1
SGfloat SGEnviro::streak_length_max = DFL_STREAK_LENGTH_MAX;
float SGEnviro::streak_length_max = DFL_STREAK_LENGTH_MAX;
#define DFL_STREAK_COUNT_MIN 40
int SGEnviro::streak_count_min = DFL_STREAK_COUNT_MIN;
#define DFL_STREAK_COUNT_MAX 190
@@ -77,9 +75,9 @@ int SGEnviro::streak_count_min = DFL_STREAK_COUNT_MIN;
#endif
int SGEnviro::streak_count_max = DFL_STREAK_COUNT_MAX;
#define DFL_CONE_BASE_RADIUS 15.0
SGfloat SGEnviro::cone_base_radius = DFL_CONE_BASE_RADIUS;
float SGEnviro::cone_base_radius = DFL_CONE_BASE_RADIUS;
#define DFL_CONE_HEIGHT 30.0
SGfloat SGEnviro::cone_height = DFL_CONE_HEIGHT;
float SGEnviro::cone_height = DFL_CONE_HEIGHT;
void SGEnviro::config(const SGPropertyNode* n)
@@ -88,7 +86,7 @@ void SGEnviro::config(const SGPropertyNode* n)
return;
const float ml = n->getFloatValue("min-light", DFL_MIN_LIGHT);
sgSetVec3(min_light, ml, ml, ml);
min_light = SGVec3f(ml, ml, ml);
streak_bright_nearmost_layer = n->getFloatValue(
"streak-brightness-nearmost-layer",
@@ -146,7 +144,7 @@ public:
~SGLightning();
void lt_Render(void);
void lt_build(void);
void lt_build_tree_branch(int tree_nr, Point3D &start, float energy, int nbseg, float segsize);
void lt_build_tree_branch(int tree_nr, SGVec3d &start, float energy, int nbseg, float segsize);
// contains all the segments of the lightning
lt_tree_seg lt_tree[MAX_LT_TREE_SEG];
@@ -189,18 +187,18 @@ SGEnviro::SGEnviro() :
}
SGEnviro::~SGEnviro(void) {
if (sampleGroup) delete sampleGroup;
// if (sampleGroup) delete sampleGroup;
// OSGFIXME
return;
list_of_lightning::iterator iLightning;
for( iLightning = lightnings.begin() ; iLightning != lightnings.end() ; iLightning++ ) {
for( iLightning = lightnings.begin() ; iLightning != lightnings.end() ; ++iLightning ) {
delete (*iLightning);
}
lightnings.clear();
}
void SGEnviro::startOfFrame( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double delta_time) {
void SGEnviro::startOfFrame( SGVec3f p, SGVec3f up, double lon, double lat, double alt, double delta_time) {
// OSGFIXME
return;
view_in_cloud = false;
@@ -210,7 +208,7 @@ void SGEnviro::startOfFrame( sgVec3 p, sgVec3 up, double lon, double lat, double
elapsed_time += delta_time;
min_time_before_lt -= delta_time;
dt = delta_time;
#if 0
sgMat4 T1, LON, LAT;
sgVec3 axis;
@@ -232,6 +230,7 @@ void SGEnviro::startOfFrame( sgVec3 p, sgVec3 up, double lon, double lat, double
sgSetCoord( &pos, TRANSFORM );
sgMakeCoordMat4( transform, &pos );
#endif
last_lon = lon;
last_lat = lat;
last_alt = alt;
@@ -289,10 +288,10 @@ void SGEnviro::set_lightning_enable_state(bool enable) {
}
}
void SGEnviro::setLight(sgVec4 adj_fog_color) {
void SGEnviro::setLight(SGVec4f adj_fog_color) {
// OSGFIXME
return;
sgCopyVec4( fog_color, adj_fog_color );
fog_color = adj_fog_color;
if( false ) {
// ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
}
@@ -381,7 +380,7 @@ void SGEnviro::callback_cloud(float heading, float alt, float radius, int family
if(lightning_enable_state && min_time_before_lt <= 0.0 && (family == SGNewCloud::CLFamilly_cb) &&
dist < 15000.0 * 15000.0 && sg_random() > 0.9f) {
double lat, lon;
Point3D orig, dest;
SGVec3d orig, dest;
orig.setlat(last_lat * SG_DEGREES_TO_RADIANS );
orig.setlon(last_lon * SG_DEGREES_TO_RADIANS );
orig.setelev(0.0);
@@ -418,118 +417,11 @@ list_of_SGWxRadarEcho *SGEnviro::get_radar_echo(void) {
void SGEnviro::DrawCone2(float baseRadius, float height, int slices, bool down, double rain_norm, double speed) {
// OSGFIXME
return;
sgVec3 light;
sgAddVec3( light, fog_color, min_light );
float da = SG_PI * 2.0f / (float) slices;
// low number = faster
float speedf = streak_period_max - speed * streak_period_change_per_kt;
if( speedf < streak_period_min )
speedf = streak_period_min;
float lenf = streak_length_min + speed * streak_length_change_per_kt;
if( lenf > streak_length_max )
lenf = streak_length_max;
float t = fmod((float) elapsed_time, speedf) / speedf;
// t = 0.1f;
if( !down )
t = 1.0f - t;
float angle = 0.0f;
//glColor4f(1.0f, 0.7f, 0.7f, 0.9f); // XXX unneeded? overriden below
glBegin(GL_LINES);
if (slices > MAX_RAIN_SLICE)
slices = MAX_RAIN_SLICE; // should never happen
for( int i = 0 ; i < slices ; i++ ) {
float x = cos(angle) * baseRadius;
float y = sin(angle) * baseRadius;
angle += da;
sgVec3 dir = {x, -height, y};
// rain drops at 2 different speed to simulate depth
float t1 = (i & 1 ? t : t + t) + rainpos[i];
if(t1 > 1.0f) t1 -= 1.0f;
if(t1 > 1.0f) t1 -= 1.0f;
// distant raindrops are more transparent
float c = t1 * (i & 1 ?
streak_bright_farmost_layer
: streak_bright_nearmost_layer);
glColor4f(c * light[0], c * light[1], c * light[2], c);
sgVec3 p1, p2;
sgScaleVec3(p1, dir, t1);
// distant raindrops are shorter
float t2 = t1 + (i & 1 ? lenf : lenf+lenf);
sgScaleVec3(p2, dir, t2);
glVertex3f(p1[0], p1[1] + height, p1[2]);
glVertex3f(p2[0], p2[1] + height, p2[2]);
}
glEnd();
}
void SGEnviro::drawRain(double pitch, double roll, double heading, double hspeed, double rain_norm) {
// OSGFIXME
return;
#if 0
static int debug_period = 0;
if (debug_period++ == 50) {
debug_period = 0;
cout << "drawRain("
<< pitch << ", "
<< roll << ", "
<< heading << ", "
<< hspeed << ", "
<< rain_norm << ");"
//" angle = " << angle
//<< " raindrop(KTS) = " << raindrop_speed_kts
<< endl;
}
#endif
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
glDisable( GL_FOG );
glDisable(GL_LIGHTING);
int slice_count = static_cast<int>(
(streak_count_min + rain_norm*(streak_count_max-streak_count_min))
* precipitation_density / 100.0);
// www.wonderquest.com/falling-raindrops.htm says that
// Raindrop terminal velocity is 5 to 20mph
// Rather than model it accurately (temp, pressure, diameter), and make it
// smaller than terminal when closer to the precipitation cloud base,
// we interpolate in the 5-20mph range according to rain_norm.
double raindrop_speed_kts
= (5.0 + rain_norm*15.0) * SG_MPH_TO_MPS * SG_MPS_TO_KT;
float angle = atanf(hspeed / raindrop_speed_kts) * SG_RADIANS_TO_DEGREES;
glPushMatrix();
// the cone rotate with hspeed
angle = -pitch - angle;
glRotatef(roll, 0.0, 0.0, 1.0);
glRotatef(heading, 0.0, 1.0, 0.0);
glRotatef(angle, 1.0, 0.0, 0.0);
// up cone
DrawCone2(cone_base_radius, cone_height,
slice_count, true, rain_norm, hspeed);
// down cone (usually not visible)
if(angle > 0.0 || heading != 0.0)
DrawCone2(cone_base_radius, -cone_height,
slice_count, false, rain_norm, hspeed);
glPopMatrix();
glEnable(GL_LIGHTING);
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
glEnable( GL_FOG );
glEnable(GL_DEPTH_TEST);
}
void SGEnviro::set_sampleGroup(SGSampleGroup *sgr) {
@@ -560,169 +452,20 @@ SGLightning::~SGLightning() {
}
// lightning rendering code
void SGLightning::lt_build_tree_branch(int tree_nr, Point3D &start, float energy, int nbseg, float segsize) {
void SGLightning::lt_build_tree_branch(int tree_nr, SGVec3d &start, float energy, int nbseg, float segsize) {
// OSGFIXME
return;
sgVec3 dir, newdir;
int nseg = 0;
Point3D pt = start;
if( nbseg == 50 )
sgSetVec3( dir, 0.0, -1.0, 0.0 );
else {
sgSetVec3( dir, sg_random() - 0.5f, sg_random() - 0.5f, sg_random() - 0.5f);
sgNormaliseVec3(dir);
}
if( nb_tree >= MAX_LT_TREE_SEG )
return;
lt_tree[nb_tree].depth = tree_nr;
nseg = 0;
lt_tree[nb_tree].pt = pt;
lt_tree[nb_tree].prev = -1;
nb_tree ++;
// TODO:check agl
while(nseg < nbseg && pt.y() > 0.0) {
int prev = nb_tree - 1;
nseg++;
// add a branch
if( energy * sg_random() > 0.8f )
lt_build_tree_branch(tree_nr + 1, pt, energy * 0.9f, nbseg == 50 ? 10 : static_cast<int>(nbseg * 0.4f), segsize * 0.7f);
if( nb_tree >= MAX_LT_TREE_SEG )
return;
sgSetVec3(newdir, (sg_random() - 0.5f), (sg_random() - 0.5f) - (nbseg == 50 ? 0.5f : 0.0), (sg_random() - 0.5f));
sgNormaliseVec3(newdir);
sgAddVec3( dir, newdir);
sgNormaliseVec3(dir);
sgVec3 scaleDir;
sgScaleVec3( scaleDir, dir, segsize * energy * 0.5f );
pt[PX] += scaleDir[0];
pt[PY] += scaleDir[1];
pt[PZ] += scaleDir[2];
lt_tree[nb_tree].depth = tree_nr;
lt_tree[nb_tree].pt = pt;
lt_tree[nb_tree].prev = prev;
nb_tree ++;
}
}
void SGLightning::lt_build(void) {
// OSGFIXME
return;
Point3D top;
nb_tree = 0;
top[PX] = 0 ;
top[PY] = alt;
top[PZ] = 0;
lt_build_tree_branch(0, top, 1.0, 50, top[PY] / 8.0);
if( ! sgEnviro.sampleGroup )
return;
Point3D start( sgEnviro.last_lon*SG_DEGREES_TO_RADIANS, sgEnviro.last_lat*SG_DEGREES_TO_RADIANS, 0.0 );
Point3D dest( lon*SG_DEGREES_TO_RADIANS, lat*SG_DEGREES_TO_RADIANS, 0.0 );
double course = 0.0, dist = 0.0;
calc_gc_course_dist( dest, start, &course, &dist );
if( dist < 10000.0 && ! sgEnviro.snd_playing && (dist < sgEnviro.snd_dist || ! sgEnviro.snd_active) ) {
sgEnviro.snd_timer = 0.0;
sgEnviro.snd_wait = dist / 340;
sgEnviro.snd_dist = dist;
sgEnviro.snd_pos_lat = lat;
sgEnviro.snd_pos_lon = lon;
sgEnviro.snd_active = true;
sgEnviro.snd_playing = false;
}
}
void SGLightning::lt_Render(void) {
// OSGFIXME
return;
float flash = 0.5;
if( fmod(sgEnviro.elapsed_time*100.0, 100.0) > 50.0 )
flash = sg_random() * 0.75f + 0.25f;
float h = lt_tree[0].pt[PY];
sgVec4 col={0.62f, 0.83f, 1.0f, 1.0f};
sgVec4 c;
#define DRAW_SEG() \
{glColorMaterial(GL_FRONT, GL_EMISSION); \
glDisable(GL_LINE_SMOOTH); glBegin(GL_LINES); \
glColor4fv(c); \
glVertex3f(lt_tree[n].pt[PX], lt_tree[n].pt[PZ], lt_tree[n].pt[PY]); \
glVertex3f(lt_tree[lt_tree[n].prev].pt[PX], lt_tree[lt_tree[n].prev].pt[PZ], lt_tree[lt_tree[n].prev].pt[PY]); \
glEnd(); glEnable(GL_LINE_SMOOTH);}
glDepthMask( GL_FALSE );
glEnable(GL_BLEND);
glBlendFunc( GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_LIGHTING);
glDisable( GL_FOG );
glPushMatrix();
sgMat4 modelview, tmp;
// OSGFIXME
// ssgGetModelviewMatrix( modelview );
sgCopyMat4( tmp, sgEnviro.transform );
sgPostMultMat4( tmp, modelview );
// OSGFIXME
// ssgLoadModelviewMatrix( tmp );
Point3D start( sgEnviro.last_lon*SG_DEGREES_TO_RADIANS, sgEnviro.last_lat*SG_DEGREES_TO_RADIANS, 0.0 );
Point3D dest( lon*SG_DEGREES_TO_RADIANS, lat*SG_DEGREES_TO_RADIANS, 0.0 );
double course = 0.0, dist = 0.0;
calc_gc_course_dist( dest, start, &course, &dist );
double ax = 0.0, ay = 0.0;
ax = cos(course) * dist;
ay = sin(course) * dist;
glTranslatef( ax, ay, -sgEnviro.last_alt );
sgEnviro.radarEcho.push_back( SGWxRadarEcho ( course, 0.0, 0.0, dist, age, true, 0 ) );
for( int n = 0 ; n < nb_tree ; n++ ) {
if( lt_tree[n].prev < 0 )
continue;
float t1 = sgLerp(0.5, 1.0, lt_tree[n].pt[PY] / h);
t1 *= flash;
if( lt_tree[n].depth >= 2 ) {
glLineWidth(3);
sgScaleVec4(c, col, t1 * 0.6f);
DRAW_SEG();
} else {
if( lt_tree[n].depth == 0 ) {
glLineWidth(12);
sgScaleVec4(c, col, t1 * 0.5f);
DRAW_SEG();
glLineWidth(6);
sgScaleVec4(c, col, t1);
DRAW_SEG();
} else {
glLineWidth(6);
sgScaleVec4(c, col, t1 * 0.7f);
DRAW_SEG();
}
if( lt_tree[n].depth == 0 )
glLineWidth(3);
else
glLineWidth(2);
sgSetVec4(c, t1, t1, t1, t1);
DRAW_SEG();
}
}
glLineWidth(1);
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
glPopMatrix();
glDepthMask( GL_TRUE );
glEnable( GL_FOG );
glEnable(GL_LIGHTING);
}
void SGEnviro::addLightning(double lon, double lat, double alt) {
@@ -737,53 +480,6 @@ void SGEnviro::addLightning(double lon, double lat, double alt) {
void SGEnviro::drawLightning(void) {
// OSGFIXME
return;
list_of_lightning::iterator iLightning;
// play 'thunder' for lightning
if( snd_active ) {
if( !snd_playing ) {
// wait until sound has reached us
snd_timer += dt;
if( snd_timer >= snd_wait ) {
snd_playing = true;
// compute relative position of lightning
Point3D start( sgEnviro.last_lon*SG_DEGREES_TO_RADIANS, sgEnviro.last_lat*SG_DEGREES_TO_RADIANS, 0.0 );
Point3D dest( snd_pos_lon*SG_DEGREES_TO_RADIANS, snd_pos_lat*SG_DEGREES_TO_RADIANS, 0.0 );
double course = 0.0, dist = 0.0;
calc_gc_course_dist( dest, start, &course, &dist );
double ax = 0.0, ay = 0.0;
ax = cos(course) * dist;
ay = sin(course) * dist;
SGSharedPtr<SGSoundSample> snd = sampleGroup->find("thunder");
if( snd ) {
SGVec3d pos = SGVec3d(ax, ay, -sgEnviro.last_alt);
snd->set_position(pos);
snd->play_once();
}
}
} else {
if( !sampleGroup->is_playing("thunder") ) {
snd_active = false;
snd_playing = false;
}
}
}
if( ! lightning_enable_state )
return;
for( iLightning = lightnings.begin() ; iLightning != lightnings.end() ; iLightning++ ) {
if( dt )
if( sg_random() > 0.95f )
(*iLightning)->lt_build();
(*iLightning)->lt_Render();
(*iLightning)->age -= dt;
if( (*iLightning)->age < 0.0 ) {
delete (*iLightning);
lightnings.erase( iLightning );
break;
}
}
}

View File

@@ -22,14 +22,11 @@
#ifndef _VISUAL_ENVIRO_HXX
#define _VISUAL_ENVIRO_HXX
#include <plib/sg.h>
#include <simgear/compiler.h>
#include <string>
#include <vector>
using std::vector;
using std::string;
#include <simgear/math/SGMath.hxx>
class SGLightning;
class SGSampleGroup;
@@ -62,7 +59,7 @@ public:
int cloudId;
};
typedef vector<SGWxRadarEcho> list_of_SGWxRadarEcho;
typedef std::vector<SGWxRadarEcho> list_of_SGWxRadarEcho;
/**
* Visual environment helper class.
@@ -81,8 +78,8 @@ private:
double last_cloud_turbulence, cloud_turbulence;
bool lightning_enable_state;
double elapsed_time, dt;
sgVec4 fog_color;
sgMat4 transform;
SGVec4f fog_color;
SGMatrixf transform;
double last_lon, last_lat, last_alt;
SGSampleGroup *sampleGroup;
bool snd_active, snd_playing;
@@ -93,8 +90,8 @@ private:
/** a list of all the radar echo. */
list_of_SGWxRadarEcho radarEcho;
static sgVec3 min_light;
static SGfloat streak_bright_nearmost_layer,
static SGVec3f min_light;
static float streak_bright_nearmost_layer,
streak_bright_farmost_layer,
streak_period_max,
streak_period_change_per_kt,
@@ -103,7 +100,7 @@ private:
streak_length_change_per_kt,
streak_length_max;
static int streak_count_min, streak_count_max;
static SGfloat cone_base_radius,
static float cone_base_radius,
cone_height;
public:
@@ -121,7 +118,7 @@ public:
/**
* Forward a few states used for renderings.
*/
void startOfFrame( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double delta_time);
void startOfFrame( SGVec3f p, SGVec3f up, double lon, double lat, double alt, double delta_time);
void endOfFrame(void);
@@ -158,7 +155,7 @@ public:
* Forward the fog color used by the rain rendering.
* @param adj_fog_color color of the fog
*/
void setLight(sgVec4 adj_fog_color);
void setLight(SGVec4f adj_fog_color);
// this can be queried to add some turbulence for example
bool is_view_in_cloud(void) const;
@@ -250,7 +247,7 @@ public:
list_of_SGWxRadarEcho *get_radar_echo(void);
sgMat4 *get_transform(void) { return &transform; }
SGMatrixf *get_transform(void) { return &transform; }
};
extern SGEnviro sgEnviro;

View File

@@ -1,3 +0,0 @@
.deps
Makefile
Makefile.in

View File

@@ -0,0 +1,35 @@
include (SimGearComponent)
set(HEADERS
celestialBody.hxx
ephemeris.hxx
jupiter.hxx
mars.hxx
mercury.hxx
moonpos.hxx
neptune.hxx
pluto.hxx
saturn.hxx
star.hxx
stardata.hxx
uranus.hxx
venus.hxx
)
set(SOURCES
celestialBody.cxx
ephemeris.cxx
jupiter.cxx
mars.cxx
mercury.cxx
moonpos.cxx
neptune.cxx
saturn.cxx
star.cxx
stardata.cxx
uranus.cxx
venus.cxx
)
simgear_component(ephem ephemeris "${SOURCES}" "${HEADERS}")

View File

@@ -81,8 +81,8 @@ public:
double getRightAscension();
double getDeclination();
double getMagnitude();
double getLon();
double getLat();
double getLon() const;
double getLat() const;
void updatePosition(double mjd, Star *ourSun);
};
@@ -90,12 +90,12 @@ inline double CelestialBody::getRightAscension() { return rightAscension; }
inline double CelestialBody::getDeclination() { return declination; }
inline double CelestialBody::getMagnitude() { return magnitude; }
inline double CelestialBody::getLon()
inline double CelestialBody::getLon() const
{
return lonEcl;
}
inline double CelestialBody::getLat()
inline double CelestialBody::getLat() const
{
return latEcl;
}

View File

@@ -43,47 +43,47 @@ public:
Star ();
~Star();
void updatePosition(double mjd);
double getM();
double getw();
double getxs();
double getys();
double getye();
double getze();
double getDistance();
double getM() const;
double getw() const;
double getxs() const;
double getys() const;
double getye() const;
double getze() const;
double getDistance() const;
};
inline double Star::getM()
inline double Star::getM() const
{
return M;
}
inline double Star::getw()
inline double Star::getw() const
{
return w;
}
inline double Star::getxs()
inline double Star::getxs() const
{
return xs;
}
inline double Star::getys()
inline double Star::getys() const
{
return ys;
}
inline double Star::getye()
inline double Star::getye() const
{
return ye;
}
inline double Star::getze()
inline double Star::getze() const
{
return ze;
}
inline double Star::getDistance()
inline double Star::getDistance() const
{
return distance;
}

View File

@@ -34,6 +34,8 @@
using std::getline;
#endif
using std::string;
// Constructor
SGStarData::SGStarData( const SGPath& path )
{

View File

@@ -0,0 +1,65 @@
include (SimGearComponent)
set(HLA_HEADERS
RTIData.hxx
HLAArrayDataElement.hxx
HLAArrayDataType.hxx
HLABasicDataElement.hxx
HLABasicDataType.hxx
HLADataElement.hxx
HLADataType.hxx
HLADataTypeVisitor.hxx
HLAEnumeratedDataElement.hxx
HLAEnumeratedDataType.hxx
HLAFixedRecordDataElement.hxx
HLAFixedRecordDataType.hxx
HLAFederate.hxx
HLAInteractionClass.hxx
HLALocation.hxx
HLAObjectClass.hxx
HLAObjectInstance.hxx
HLAOMTXmlVisitor.hxx
HLAPropertyDataElement.hxx
HLARawDataElement.hxx
HLAVariantDataElement.hxx
HLAVariantDataType.hxx
)
set(HLA_SOURCES
RTIObjectClass.cxx
RTIObjectInstance.cxx
RTIFederate.cxx
HLAArrayDataElement.cxx
HLAArrayDataType.cxx
HLABasicDataElement.cxx
HLABasicDataType.cxx
HLADataElement.cxx
HLADataType.cxx
HLAEnumeratedDataElement.cxx
HLAEnumeratedDataType.cxx
HLAFederate.cxx
HLAFixedRecordDataElement.cxx
HLAFixedRecordDataType.cxx
HLAObjectClass.cxx
HLAObjectInstance.cxx
HLAOMTXmlVisitor.cxx
HLAPropertyDataElement.cxx
HLARawDataElement.cxx
HLAVariantDataElement.cxx
HLAVariantDataType.cxx
)
simgear_component(hla hla "${HLA_SOURCES}" "${HLA_HEADERS}")
if(RTI_FOUND)
set(HLA13_HEADERS
HLA13Federate.hxx
)
set(HLA13_SOURCES
RTI13ObjectClass.cxx
RTI13ObjectInstance.cxx
RTI13Federate.cxx
HLA13Federate.cxx
)
simgear_component(hla13 hla "${HLA13_SOURCES}" "${HLA13_HEADERS}")
set_property(TARGET sghla13 APPEND PROPERTY COMPILE_FLAGS "-I${RTI_INCLUDE_DIR}")
endif()

View File

@@ -0,0 +1,33 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLA13Federate.hxx"
#include "RTI13Federate.hxx"
namespace simgear {
HLA13Federate::HLA13Federate() :
HLAFederate(new RTI13Federate)
{
}
HLA13Federate::~HLA13Federate()
{
}
} // namespace simgear

View File

@@ -0,0 +1,33 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLA13Federate_hxx
#define HLA13Federate_hxx
#include "HLAFederate.hxx"
namespace simgear {
class HLA13Federate : public HLAFederate {
public:
HLA13Federate();
virtual ~HLA13Federate();
};
} // namespace simgear
#endif

View File

@@ -0,0 +1,313 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAArrayDataElement.hxx"
#include <simgear/debug/logstream.hxx>
namespace simgear {
HLAAbstractArrayDataElement::HLAAbstractArrayDataElement(const HLAArrayDataType* dataType) :
_dataType(dataType)
{
}
HLAAbstractArrayDataElement::~HLAAbstractArrayDataElement()
{
}
bool
HLAAbstractArrayDataElement::decode(HLADecodeStream& stream)
{
if (!_dataType.valid())
return false;
return _dataType->decode(stream, *this);
}
bool
HLAAbstractArrayDataElement::encode(HLAEncodeStream& stream) const
{
if (!_dataType.valid())
return false;
return _dataType->encode(stream, *this);
}
const HLAArrayDataType*
HLAAbstractArrayDataElement::getDataType() const
{
return _dataType.get();
}
bool
HLAAbstractArrayDataElement::setDataType(const HLADataType* dataType)
{
const HLAArrayDataType* arrayDataType = dynamic_cast<const HLAArrayDataType*>(dataType);
if (!arrayDataType) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAArrayDataType: unable to set data type!");
return false;
}
_dataType = arrayDataType;
return true;
}
const HLADataType*
HLAAbstractArrayDataElement::getElementDataType() const
{
if (!_dataType.valid())
return 0;
return _dataType->getElementDataType();
}
////////////////////////////////////////////////////////////////////////
HLAArrayDataElement::DataElementFactory::~DataElementFactory()
{
}
HLAArrayDataElement::HLAArrayDataElement(const HLAArrayDataType* dataType) :
HLAAbstractArrayDataElement(dataType)
{
}
HLAArrayDataElement::~HLAArrayDataElement()
{
}
bool
HLAArrayDataElement::setNumElements(unsigned size)
{
unsigned oldSize = _elementVector.size();
if (size == oldSize)
return true;
_elementVector.resize(size);
for (unsigned i = oldSize; i < size; ++i)
_elementVector[i] = newElement(i);
return true;
}
bool
HLAArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
{
HLADataElement* dataElement = getElement(i);
if (!dataElement)
return false;
return dataElement->decode(stream);
}
unsigned
HLAArrayDataElement::getNumElements() const
{
return _elementVector.size();
}
bool
HLAArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
{
const HLADataElement* dataElement = getElement(i);
if (!dataElement)
return false;
return dataElement->encode(stream);
}
const HLADataElement*
HLAArrayDataElement::getElement(unsigned index) const
{
if (_elementVector.size() <= index)
return 0;
return _elementVector[index].get();
}
HLADataElement*
HLAArrayDataElement::getElement(unsigned index)
{
if (_elementVector.size() <= index)
return 0;
return _elementVector[index].get();
}
HLADataElement*
HLAArrayDataElement::getOrCreateElement(unsigned index)
{
if (_elementVector.size() <= index)
if (!setNumElements(index + 1))
return 0;
return _elementVector[index].get();
}
void
HLAArrayDataElement::setElement(unsigned index, HLADataElement* value)
{
unsigned oldSize = _elementVector.size();
if (oldSize <= index) {
_elementVector.resize(index + 1);
for (unsigned j = oldSize; j < index; ++j)
_elementVector[j] = newElement(j);
}
_elementVector[index] = value;
}
void
HLAArrayDataElement::setDataElementFactory(HLAArrayDataElement::DataElementFactory* dataElementFactory)
{
_dataElementFactory = dataElementFactory;
}
HLAArrayDataElement::DataElementFactory*
HLAArrayDataElement::getDataElementFactory()
{
return _dataElementFactory.get();
}
HLADataElement*
HLAArrayDataElement::newElement(unsigned index)
{
if (!_dataElementFactory.valid())
return 0;
return _dataElementFactory->createElement(*this, index);
}
////////////////////////////////////////////////////////////////////////
HLAVariantArrayDataElement::HLAVariantArrayDataElement() :
HLAAbstractArrayDataElement(0)
{
}
HLAVariantArrayDataElement::~HLAVariantArrayDataElement()
{
}
bool
HLAVariantArrayDataElement::setDataType(const HLADataType* dataType)
{
const HLAArrayDataType* arrayDataType = dataType->toArrayDataType();
if (!arrayDataType) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantArrayDataType: unable to set data type, dataType is not an array data type!");
return false;
}
const HLAVariantDataType* variantDataType = arrayDataType->getElementDataType()->toVariantDataType();
if (!variantDataType) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantArrayDataType: unable to set data type: arrayDataTypes element data type is no a variant data type!");
return false;
}
_dataType = arrayDataType;
return true;
}
bool
HLAVariantArrayDataElement::setNumElements(unsigned size)
{
unsigned oldSize = _elementVector.size();
if (size == oldSize)
return true;
_elementVector.resize(size);
for (unsigned i = oldSize; i < size; ++i)
_elementVector[i] = newElement();
return true;
}
bool
HLAVariantArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
{
HLAVariantDataElement* dataElement = getElement(i);
if (!dataElement)
return false;
return dataElement->decode(stream);
}
unsigned
HLAVariantArrayDataElement::getNumElements() const
{
return _elementVector.size();
}
bool
HLAVariantArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
{
const HLADataElement* dataElement = getElement(i);
if (!dataElement)
return false;
return dataElement->encode(stream);
}
const HLAVariantDataElement*
HLAVariantArrayDataElement::getElement(unsigned index) const
{
if (_elementVector.size() <= index)
return 0;
return _elementVector[index].get();
}
HLAVariantDataElement*
HLAVariantArrayDataElement::getElement(unsigned index)
{
if (_elementVector.size() <= index)
return 0;
return _elementVector[index].get();
}
HLAVariantDataElement*
HLAVariantArrayDataElement::getOrCreateElement(unsigned index)
{
if (_elementVector.size() <= index)
if (!setNumElements(index + 1))
return 0;
return _elementVector[index].get();
}
void
HLAVariantArrayDataElement::setElement(unsigned index, HLAVariantDataElement* value)
{
unsigned oldSize = _elementVector.size();
if (oldSize <= index) {
_elementVector.resize(index + 1);
for (unsigned j = oldSize; j < index; ++j)
_elementVector[j] = newElement();
}
_elementVector[index] = value;
}
void
HLAVariantArrayDataElement::setAlternativeDataElementFactory(HLAVariantArrayDataElement::AlternativeDataElementFactory* alternativeDataElementFactory)
{
_alternativeDataElementFactory = alternativeDataElementFactory;
}
HLAVariantArrayDataElement::AlternativeDataElementFactory*
HLAVariantArrayDataElement::getAlternativeDataElementFactory()
{
return _alternativeDataElementFactory.get();
}
HLAVariantDataElement*
HLAVariantArrayDataElement::newElement()
{
const HLAArrayDataType* arrayDataType = getDataType();
if (!arrayDataType)
return 0;
const HLADataType* elementDataType = arrayDataType->getElementDataType();
if (!elementDataType)
return 0;
const HLAVariantDataType* variantDataType = elementDataType->toVariantDataType();
if (!variantDataType)
return 0;
HLAVariantDataElement* variantDataElement = new HLAVariantDataElement(variantDataType);
variantDataElement->setDataElementFactory(_alternativeDataElementFactory.get());
return variantDataElement;
}
}

View File

@@ -0,0 +1,418 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAArrayDataElement_hxx
#define HLAArrayDataElement_hxx
#include <string>
#include <vector>
#include <simgear/math/SGMath.hxx>
#include "HLAArrayDataType.hxx"
#include "HLADataElement.hxx"
#include "HLAVariantDataElement.hxx"
#include "HLADataTypeVisitor.hxx"
namespace simgear {
class HLAAbstractArrayDataElement : public HLADataElement {
public:
HLAAbstractArrayDataElement(const HLAArrayDataType* dataType);
virtual ~HLAAbstractArrayDataElement();
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;
virtual const HLAArrayDataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType);
const HLADataType* getElementDataType() const;
virtual bool setNumElements(unsigned count) = 0;
virtual bool decodeElement(HLADecodeStream& stream, unsigned i) = 0;
virtual unsigned getNumElements() const = 0;
virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const = 0;
protected:
SGSharedPtr<const HLAArrayDataType> _dataType;
};
class HLAArrayDataElement : public HLAAbstractArrayDataElement {
public:
HLAArrayDataElement(const HLAArrayDataType* dataType = 0);
virtual ~HLAArrayDataElement();
virtual bool setNumElements(unsigned size);
virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
virtual unsigned getNumElements() const;
virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
const HLADataElement* getElement(unsigned index) const;
HLADataElement* getElement(unsigned index);
HLADataElement* getOrCreateElement(unsigned index);
void setElement(unsigned i, HLADataElement* value);
class DataElementFactory : public SGReferenced {
public:
virtual ~DataElementFactory();
virtual HLADataElement* createElement(const HLAArrayDataElement&, unsigned) = 0;
};
void setDataElementFactory(DataElementFactory* dataElementFactory);
DataElementFactory* getDataElementFactory();
private:
HLADataElement* newElement(unsigned index);
typedef std::vector<SGSharedPtr<HLADataElement> > ElementVector;
ElementVector _elementVector;
SGSharedPtr<DataElementFactory> _dataElementFactory;
};
// Holds an array of variants.
// Factors out common code for that use case.
class HLAVariantArrayDataElement : public HLAAbstractArrayDataElement {
public:
HLAVariantArrayDataElement();
virtual ~HLAVariantArrayDataElement();
// Overwrite this from the abstract class, need some more checks here
virtual bool setDataType(const HLADataType* dataType);
virtual bool setNumElements(unsigned size);
virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
virtual unsigned getNumElements() const;
virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
const HLAVariantDataElement* getElement(unsigned index) const;
HLAVariantDataElement* getElement(unsigned index);
HLAVariantDataElement* getOrCreateElement(unsigned index);
void setElement(unsigned index, HLAVariantDataElement* value);
typedef HLAVariantDataElement::DataElementFactory AlternativeDataElementFactory;
void setAlternativeDataElementFactory(AlternativeDataElementFactory* alternativeDataElementFactory);
AlternativeDataElementFactory* getAlternativeDataElementFactory();
private:
HLAVariantDataElement* newElement();
typedef std::vector<SGSharedPtr<HLAVariantDataElement> > ElementVector;
ElementVector _elementVector;
SGSharedPtr<AlternativeDataElementFactory> _alternativeDataElementFactory;
};
class HLAStringDataElement : public HLAAbstractArrayDataElement {
public:
HLAStringDataElement(const HLAArrayDataType* dataType = 0) :
HLAAbstractArrayDataElement(dataType)
{}
HLAStringDataElement(const HLAArrayDataType* dataType, const std::string& value) :
HLAAbstractArrayDataElement(dataType),
_value(value)
{}
const std::string& getValue() const
{ return _value; }
void setValue(const std::string& value)
{ _value = value; }
virtual bool setNumElements(unsigned count)
{
_value.resize(count);
return true;
}
virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
{
HLATemplateDecodeVisitor<std::string::value_type> visitor(stream);
getElementDataType()->accept(visitor);
_value[i] = visitor.getValue();
return true;
}
virtual unsigned getNumElements() const
{
return _value.size();
}
virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
{
HLATemplateEncodeVisitor<std::string::value_type> visitor(stream, _value[i]);
getElementDataType()->accept(visitor);
return true;
}
private:
std::string _value;
};
class HLAStringData {
public:
HLAStringData() :
_value(new HLAStringDataElement(0))
{ }
HLAStringData(const std::string& value) :
_value(new HLAStringDataElement(0))
{ _value->setValue(value); }
operator const std::string&() const
{ return _value->getValue(); }
HLAStringData& operator=(const std::string& value)
{ _value->setValue(value); return *this; }
const std::string& getValue() const
{ return _value->getValue(); }
void setValue(const std::string& value)
{ _value->setValue(value); }
const HLAStringDataElement* getDataElement() const
{ return _value.get(); }
HLAStringDataElement* getDataElement()
{ return _value.get(); }
const HLAArrayDataType* getDataType() const
{ return _value->getDataType(); }
void setDataType(const HLAArrayDataType* dataType)
{ _value->setDataType(dataType); }
private:
SGSharedPtr<HLAStringDataElement> _value;
};
template<typename T>
class HLAVec2DataElement : public HLAAbstractArrayDataElement {
public:
HLAVec2DataElement(const HLAArrayDataType* dataType = 0) :
HLAAbstractArrayDataElement(dataType),
_value(SGVec2<T>::zeros())
{}
HLAVec2DataElement(const HLAArrayDataType* dataType, const SGVec2<T>& value) :
HLAAbstractArrayDataElement(dataType),
_value(value)
{}
const SGVec2<T>& getValue() const
{ return _value; }
void setValue(const SGVec2<T>& value)
{ _value = value; }
virtual bool setNumElements(unsigned count)
{
for (unsigned i = 2; i < count; ++i)
_value[i] = 0;
return true;
}
virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
{
if (i < 2) {
HLATemplateDecodeVisitor<typename SGVec2<T>::value_type> visitor(stream);
getElementDataType()->accept(visitor);
_value[i] = visitor.getValue();
} else {
HLADataTypeDecodeVisitor visitor(stream);
getElementDataType()->accept(visitor);
}
return true;
}
virtual unsigned getNumElements() const
{
return 2;
}
virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
{
if (i < 2) {
HLATemplateEncodeVisitor<typename SGVec2<T>::value_type> visitor(stream, _value[i]);
getElementDataType()->accept(visitor);
} else {
HLADataTypeEncodeVisitor visitor(stream);
getElementDataType()->accept(visitor);
}
return true;
}
private:
SGVec2<T> _value;
};
template<typename T>
class HLAVec3DataElement : public HLAAbstractArrayDataElement {
public:
HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
HLAAbstractArrayDataElement(dataType),
_value(SGVec3<T>::zeros())
{}
HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
HLAAbstractArrayDataElement(dataType),
_value(value)
{}
const SGVec3<T>& getValue() const
{ return _value; }
void setValue(const SGVec3<T>& value)
{ _value = value; }
virtual bool setNumElements(unsigned count)
{
for (unsigned i = 3; i < count; ++i)
_value[i] = 0;
return true;
}
virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
{
if (i < 3) {
HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
getElementDataType()->accept(visitor);
_value[i] = visitor.getValue();
} else {
HLADataTypeDecodeVisitor visitor(stream);
getElementDataType()->accept(visitor);
}
return true;
}
virtual unsigned getNumElements() const
{
return 3;
}
virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
{
if (i < 3) {
HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
getElementDataType()->accept(visitor);
} else {
HLADataTypeEncodeVisitor visitor(stream);
getElementDataType()->accept(visitor);
}
return true;
}
private:
SGVec3<T> _value;
};
template<typename T>
class HLAVec4DataElement : public HLAAbstractArrayDataElement {
public:
HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
HLAAbstractArrayDataElement(dataType),
_value(SGVec4<T>::zeros())
{}
HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
HLAAbstractArrayDataElement(dataType),
_value(value)
{}
const SGVec4<T>& getValue() const
{ return _value; }
void setValue(const SGVec4<T>& value)
{ _value = value; }
virtual bool setNumElements(unsigned count)
{
for (unsigned i = 4; i < count; ++i)
_value[i] = 0;
return true;
}
virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
{
if (i < 4) {
HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
getElementDataType()->accept(visitor);
_value[i] = visitor.getValue();
} else {
HLADataTypeDecodeVisitor visitor(stream);
getElementDataType()->accept(visitor);
}
return true;
}
virtual unsigned getNumElements() const
{
return 4;
}
virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
{
if (i < 4) {
HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
getElementDataType()->accept(visitor);
} else {
HLADataTypeEncodeVisitor visitor(stream);
getElementDataType()->accept(visitor);
}
return true;
}
private:
SGVec4<T> _value;
};
template<typename T>
class HLAQuatDataElement : public HLAAbstractArrayDataElement {
public:
HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
HLAAbstractArrayDataElement(dataType),
_value(SGQuat<T>::zeros())
{}
HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
HLAAbstractArrayDataElement(dataType),
_value(value)
{}
const SGQuat<T>& getValue() const
{ return _value; }
void setValue(const SGQuat<T>& value)
{ _value = value; }
virtual bool setNumElements(unsigned count)
{
for (unsigned i = 4; i < count; ++i)
_value[i] = 0;
return true;
}
virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
{
if (i < 4) {
HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
getElementDataType()->accept(visitor);
_value[i] = visitor.getValue();
} else {
HLADataTypeDecodeVisitor visitor(stream);
getElementDataType()->accept(visitor);
}
return true;
}
virtual unsigned getNumElements() const
{
return 4;
}
virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
{
if (i < 4) {
HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
getElementDataType()->accept(visitor);
} else {
HLADataTypeEncodeVisitor visitor(stream);
getElementDataType()->accept(visitor);
}
return true;
}
private:
SGQuat<T> _value;
};
}
#endif

View File

@@ -0,0 +1,158 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAArrayDataType.hxx"
#include "HLAArrayDataElement.hxx"
namespace simgear {
HLAArrayDataType::HLAArrayDataType(const std::string& name) :
HLADataType(name)
{
}
HLAArrayDataType::~HLAArrayDataType()
{
}
void
HLAArrayDataType::accept(HLADataTypeVisitor& visitor) const
{
visitor.apply(*this);
}
const HLAArrayDataType*
HLAArrayDataType::toArrayDataType() const
{
return this;
}
void
HLAArrayDataType::setElementDataType(const HLADataType* elementDataType)
{
// FIXME this only works if we do not reset the alignment to something smaller
if (getAlignment() < elementDataType->getAlignment())
setAlignment(elementDataType->getAlignment());
_elementDataType = elementDataType;
}
///////////////////////////////////////////////////////////////////////////////////
HLAFixedArrayDataType::HLAFixedArrayDataType(const std::string& name) :
HLAArrayDataType(name)
{
}
HLAFixedArrayDataType::~HLAFixedArrayDataType()
{
}
void
HLAFixedArrayDataType::accept(HLADataTypeVisitor& visitor) const
{
visitor.apply(*this);
}
bool
HLAFixedArrayDataType::decode(HLADecodeStream& stream, HLAAbstractArrayDataElement& value) const
{
stream.alignOffsetForSize(getAlignment());
unsigned numElements = getNumElements();
if (!value.setNumElements(numElements))
return false;
for (unsigned i = 0; i < numElements; ++i)
if (!value.decodeElement(stream, i))
return false;
return true;
}
bool
HLAFixedArrayDataType::encode(HLAEncodeStream& stream, const HLAAbstractArrayDataElement& value) const
{
stream.alignOffsetForSize(getAlignment());
unsigned numElementsType = getNumElements();
unsigned numElementsValue = value.getNumElements();
unsigned numElements = SGMisc<unsigned>::min(numElementsType, numElementsValue);
unsigned i = 0;
for (; i < numElements; ++i)
if (!value.encodeElement(stream, i))
return false;
for (; i < numElementsType; ++i) {
HLADataTypeEncodeVisitor visitor(stream);
getElementDataType()->accept(visitor);
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////
HLAVariableArrayDataType::HLAVariableArrayDataType(const std::string& name) :
HLAArrayDataType(name)
{
setSizeDataType(new HLAUInt32BEDataType);
}
HLAVariableArrayDataType::~HLAVariableArrayDataType()
{
}
void
HLAVariableArrayDataType::accept(HLADataTypeVisitor& visitor) const
{
visitor.apply(*this);
}
bool
HLAVariableArrayDataType::decode(HLADecodeStream& stream, HLAAbstractArrayDataElement& value) const
{
stream.alignOffsetForSize(getAlignment());
HLATemplateDecodeVisitor<unsigned> numElementsVisitor(stream);
getSizeDataType()->accept(numElementsVisitor);
unsigned numElements = numElementsVisitor.getValue();
if (!value.setNumElements(numElements))
return false;
for (unsigned i = 0; i < numElements; ++i)
if (!value.decodeElement(stream, i))
return false;
return true;
}
bool
HLAVariableArrayDataType::encode(HLAEncodeStream& stream, const HLAAbstractArrayDataElement& value) const
{
stream.alignOffsetForSize(getAlignment());
unsigned numElements = value.getNumElements();
HLATemplateEncodeVisitor<unsigned> numElementsVisitor(stream, numElements);
getSizeDataType()->accept(numElementsVisitor);
for (unsigned i = 0; i < numElements; ++i)
if (!value.encodeElement(stream, i))
return false;
return true;
}
void
HLAVariableArrayDataType::setSizeDataType(const HLADataType* sizeDataType)
{
// FIXME this only works if we do not reset the alignment to something smaller
if (getAlignment() < sizeDataType->getAlignment())
setAlignment(sizeDataType->getAlignment());
_sizeDataType = sizeDataType;
// setAlignment(SGMisc<unsigned>::max(_sizeDataType->getAlignment(), _elementDataType->getAlignment());
}
} // namespace simgear

View File

@@ -0,0 +1,88 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAArrayDataType_hxx
#define HLAArrayDataType_hxx
#include <string>
#include <simgear/structure/SGSharedPtr.hxx>
#include "HLADataType.hxx"
namespace simgear {
class HLAAbstractArrayDataElement;
class HLAArrayDataType : public HLADataType {
public:
HLAArrayDataType(const std::string& name = "HLAArrayDataType");
virtual ~HLAArrayDataType();
virtual void accept(HLADataTypeVisitor& visitor) const;
virtual const HLAArrayDataType* toArrayDataType() const;
virtual bool decode(HLADecodeStream& stream, HLAAbstractArrayDataElement& value) const = 0;
virtual bool encode(HLAEncodeStream& stream, const HLAAbstractArrayDataElement& value) const = 0;
void setElementDataType(const HLADataType* elementDataType);
const HLADataType* getElementDataType() const
{ return _elementDataType.get(); }
private:
SGSharedPtr<const HLADataType> _elementDataType;
};
class HLAFixedArrayDataType : public HLAArrayDataType {
public:
HLAFixedArrayDataType(const std::string& name = "HLAFixedArrayDataType");
virtual ~HLAFixedArrayDataType();
virtual void accept(HLADataTypeVisitor& visitor) const;
virtual bool decode(HLADecodeStream& stream, HLAAbstractArrayDataElement& value) const;
virtual bool encode(HLAEncodeStream& stream, const HLAAbstractArrayDataElement& value) const;
void setNumElements(unsigned numElements)
{ _numElements = numElements; }
unsigned getNumElements() const
{ return _numElements; }
private:
unsigned _numElements;
};
class HLAVariableArrayDataType : public HLAArrayDataType {
public:
HLAVariableArrayDataType(const std::string& name = "HLAVariableArrayDataType");
virtual ~HLAVariableArrayDataType();
virtual void accept(HLADataTypeVisitor& visitor) const;
virtual bool decode(HLADecodeStream& stream, HLAAbstractArrayDataElement& value) const;
virtual bool encode(HLAEncodeStream& stream, const HLAAbstractArrayDataElement& value) const;
void setSizeDataType(const HLADataType* sizeDataType);
const HLADataType* getSizeDataType() const
{ return _sizeDataType.get(); }
private:
SGSharedPtr<const HLADataType> _sizeDataType;
};
} // namespace simgear
#endif

View File

@@ -0,0 +1,132 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLABasicDataElement.hxx"
#include "HLADataTypeVisitor.hxx"
namespace simgear {
HLABasicDataElement::HLABasicDataElement(const HLABasicDataType* dataType) :
_dataType(dataType)
{
}
HLABasicDataElement::~HLABasicDataElement()
{
}
const HLABasicDataType*
HLABasicDataElement::getDataType() const
{
return _dataType.get();
}
bool
HLABasicDataElement::setDataType(const HLADataType* dataType)
{
const HLABasicDataType* scalarDataType = dynamic_cast<const HLABasicDataType*>(dataType);
if (!scalarDataType) {
SG_LOG(SG_NETWORK, SG_WARN, "HLABasicDataType: unable to set data type!");
return false;
}
setDataType(scalarDataType);
return true;
}
void
HLABasicDataElement::setDataType(const HLABasicDataType* dataType)
{
_dataType = dataType;
}
#define IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(type, ctype) \
HLAAbstract##type##DataElement::HLAAbstract##type##DataElement(const HLABasicDataType* dataType) :\
HLABasicDataElement(dataType) \
{ \
} \
\
HLAAbstract##type##DataElement::~HLAAbstract##type##DataElement() \
{ \
} \
\
bool \
HLAAbstract##type##DataElement::encode(HLAEncodeStream& stream) const \
{ \
if (!_dataType.valid()) \
return false; \
HLATemplateEncodeVisitor<ctype> visitor(stream, getValue()); \
_dataType->accept(visitor); \
return true; \
} \
\
bool \
HLAAbstract##type##DataElement::decode(HLADecodeStream& stream) \
{ \
if (!_dataType.valid()) \
return false; \
HLATemplateDecodeVisitor<ctype> visitor(stream); \
_dataType->accept(visitor); \
setValue(visitor.getValue()); \
return true; \
} \
\
HLA##type##DataElement::HLA##type##DataElement(const HLABasicDataType* dataType) : \
HLAAbstract##type##DataElement(dataType), \
_value(0) \
{ \
} \
\
HLA##type##DataElement::HLA##type##DataElement(const HLABasicDataType* dataType, \
const ctype& value) : \
HLAAbstract##type##DataElement(dataType), \
_value(value) \
{ \
} \
\
HLA##type##DataElement::~HLA##type##DataElement() \
{ \
} \
\
ctype \
HLA##type##DataElement::getValue() const \
{ \
return _value; \
} \
\
void \
HLA##type##DataElement::setValue(ctype value) \
{ \
_value = value; \
}
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Char, char);
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(WChar, wchar_t);
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(SChar, signed char);
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(UChar, unsigned char);
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Short, short);
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(UShort, unsigned short);
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Int, int);
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(UInt, unsigned int);
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Long, long);
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(ULong, unsigned long);
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Float, float);
IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT(Double, double);
#undef IMPLEMENT_TYPED_HLA_BASIC_DATA_ELEMENT
}

View File

@@ -0,0 +1,108 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLABasicDataElement_hxx
#define HLABasicDataElement_hxx
#include "HLABasicDataType.hxx"
#include "HLADataElement.hxx"
namespace simgear {
class HLABasicDataElement : public HLADataElement {
public:
HLABasicDataElement(const HLABasicDataType* dataType);
virtual ~HLABasicDataElement();
virtual const HLABasicDataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType);
void setDataType(const HLABasicDataType* dataType);
protected:
SGSharedPtr<const HLABasicDataType> _dataType;
};
#define TYPED_HLA_BASIC_DATA_ELEMENT(type, ctype) \
class HLAAbstract##type##DataElement : public HLABasicDataElement { \
public: \
HLAAbstract##type##DataElement(const HLABasicDataType* dataType = 0); \
virtual ~HLAAbstract##type##DataElement(); \
virtual bool encode(HLAEncodeStream& stream) const; \
virtual bool decode(HLADecodeStream& stream); \
\
virtual ctype getValue() const = 0; \
virtual void setValue(ctype) = 0; \
}; \
class HLA##type##DataElement : public HLAAbstract##type##DataElement { \
public: \
HLA##type##DataElement(const HLABasicDataType* dataType = 0); \
HLA##type##DataElement(const HLABasicDataType* dataType, \
const ctype& value); \
virtual ~HLA##type##DataElement(); \
virtual ctype getValue() const; \
virtual void setValue(ctype value); \
private: \
ctype _value; \
}; \
class HLA##type##Data { \
public: \
HLA##type##Data() : \
_value(new HLA##type##DataElement(0)) \
{ } \
HLA##type##Data(const ctype& value) : \
_value(new HLA##type##DataElement(0, value)) \
{ } \
operator ctype() const \
{ return _value->getValue(); } \
HLA##type##Data& operator=(const ctype& value) \
{ _value->setValue(value); return *this; } \
ctype getValue() const \
{ return _value->getValue(); } \
void setValue(const ctype& value) \
{ _value->setValue(value); } \
const HLA##type##DataElement* getDataElement() const \
{ return _value.get(); } \
HLA##type##DataElement* getDataElement() \
{ return _value.get(); } \
const HLABasicDataType* getDataType() const \
{ return _value->getDataType(); } \
void setDataType(const HLABasicDataType* dataType) \
{ _value->setDataType(dataType); } \
\
private: \
SGSharedPtr<HLA##type##DataElement> _value; \
};
TYPED_HLA_BASIC_DATA_ELEMENT(Char, char);
TYPED_HLA_BASIC_DATA_ELEMENT(WChar, wchar_t);
TYPED_HLA_BASIC_DATA_ELEMENT(SChar, signed char);
TYPED_HLA_BASIC_DATA_ELEMENT(UChar, unsigned char);
TYPED_HLA_BASIC_DATA_ELEMENT(Short, short);
TYPED_HLA_BASIC_DATA_ELEMENT(UShort, unsigned short);
TYPED_HLA_BASIC_DATA_ELEMENT(Int, int);
TYPED_HLA_BASIC_DATA_ELEMENT(UInt, unsigned int);
TYPED_HLA_BASIC_DATA_ELEMENT(Long, long);
TYPED_HLA_BASIC_DATA_ELEMENT(ULong, unsigned long);
TYPED_HLA_BASIC_DATA_ELEMENT(Float, float);
TYPED_HLA_BASIC_DATA_ELEMENT(Double, double);
#undef TYPED_HLA_BASIC_DATA_ELEMENT
}
#endif

View File

@@ -0,0 +1,170 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLABasicDataType.hxx"
#include "HLADataType.hxx"
#include "HLADataTypeVisitor.hxx"
namespace simgear {
HLABasicDataType::HLABasicDataType(const std::string& name) :
HLADataType(name)
{
}
HLABasicDataType::~HLABasicDataType()
{
}
void
HLABasicDataType::accept(HLADataTypeVisitor& visitor) const
{
visitor.apply(*this);
}
const HLABasicDataType*
HLABasicDataType::toBasicDataType() const
{
return this;
}
//////////////////////////////////////////////////////////////////////////////
HLAInt8DataType::HLAInt8DataType(const std::string& name) :
HLABasicDataType(name)
{
setAlignment(sizeof(int8_t));
}
HLAInt8DataType::~HLAInt8DataType()
{
}
void
HLAInt8DataType::accept(HLADataTypeVisitor& visitor) const
{
visitor.apply(*this);
}
//////////////////////////////////////////////////////////////////////////////
HLAUInt8DataType::HLAUInt8DataType(const std::string& name) :
HLABasicDataType(name)
{
setAlignment(sizeof(uint8_t));
}
HLAUInt8DataType::~HLAUInt8DataType()
{
}
void
HLAUInt8DataType::accept(HLADataTypeVisitor& visitor) const
{
visitor.apply(*this);
}
//////////////////////////////////////////////////////////////////////////////
#define BASIC_DATATYPE_IMPLEMENTATION(type, name) \
HLA##name##DataType::HLA##name##DataType(const std::string& name) : \
HLABasicDataType(name) \
{ \
setAlignment(sizeof(type)); \
} \
\
HLA##name##DataType::~HLA##name##DataType() \
{ \
} \
\
void \
HLA##name##DataType::accept(HLADataTypeVisitor& visitor) const \
{ \
visitor.apply(*this); \
} \
\
\
\
HLA##name##LEDataType::HLA##name##LEDataType(const std::string& name) : \
HLA##name##DataType(name) \
{ \
} \
\
HLA##name##LEDataType::~HLA##name##LEDataType() \
{ \
} \
\
bool \
HLA##name##LEDataType::decode(HLADecodeStream& stream, \
type& value) const \
{ \
if (!stream.alignOffsetForSize(getAlignment())) \
return false; \
return stream.decode##name##LE(value); \
} \
\
bool \
HLA##name##LEDataType::encode(HLAEncodeStream& stream, \
const type& value) const \
{ \
if (!stream.alignOffsetForSize(getAlignment())) \
return false; \
return stream.encode##name##LE(value); \
} \
\
\
\
HLA##name##BEDataType::HLA##name##BEDataType(const std::string& name) : \
HLA##name##DataType(name) \
{ \
} \
\
HLA##name##BEDataType::~HLA##name##BEDataType() \
{ \
} \
\
bool \
HLA##name##BEDataType::decode(HLADecodeStream& stream, \
type& value) const \
{ \
if (!stream.alignOffsetForSize(getAlignment())) \
return false; \
return stream.decode##name##BE(value); \
} \
\
bool \
HLA##name##BEDataType::encode(HLAEncodeStream& stream, \
const type& value) const \
{ \
if (!stream.alignOffsetForSize(getAlignment())) \
return false; \
return stream.encode##name##BE(value); \
}
BASIC_DATATYPE_IMPLEMENTATION(int16_t, Int16)
BASIC_DATATYPE_IMPLEMENTATION(uint16_t, UInt16)
BASIC_DATATYPE_IMPLEMENTATION(int32_t, Int32)
BASIC_DATATYPE_IMPLEMENTATION(uint32_t, UInt32)
BASIC_DATATYPE_IMPLEMENTATION(int64_t, Int64)
BASIC_DATATYPE_IMPLEMENTATION(uint64_t, UInt64)
BASIC_DATATYPE_IMPLEMENTATION(float, Float32)
BASIC_DATATYPE_IMPLEMENTATION(double, Float64)
#undef BASIC_DATATYPE_IMPLEMENTATION
} // namespace simgear

View File

@@ -0,0 +1,155 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLABasicDataType_hxx
#define HLABasicDataType_hxx
#include <string>
#include "HLADataType.hxx"
namespace simgear {
class HLABasicDataType : public HLADataType {
public:
virtual ~HLABasicDataType();
virtual void accept(HLADataTypeVisitor& visitor) const;
virtual const HLABasicDataType* toBasicDataType() const;
protected:
HLABasicDataType(const std::string& name);
};
class HLAInt8DataType : public HLABasicDataType {
public:
HLAInt8DataType(const std::string& name = "HLAInt8DataType");
virtual ~HLAInt8DataType();
virtual void accept(HLADataTypeVisitor& visitor) const;
bool skip(HLADecodeStream& stream) const
{
if (!stream.alignOffsetForSize(getAlignment()))
return false;
return stream.skip(1);
}
bool skip(HLAEncodeStream& stream) const
{
if (!stream.alignOffsetForSize(getAlignment()))
return false;
return stream.skip(1);
}
bool decode(HLADecodeStream& stream, int8_t& value) const
{
if (!stream.alignOffsetForSize(getAlignment()))
return false;
return stream.decodeInt8(value);
}
bool encode(HLAEncodeStream& stream, const int8_t& value) const
{
if (!stream.alignOffsetForSize(getAlignment()))
return false;
return stream.encodeInt8(value);
}
};
class HLAUInt8DataType : public HLABasicDataType {
public:
HLAUInt8DataType(const std::string& name = "HLAUInt8DataType");
virtual ~HLAUInt8DataType();
virtual void accept(HLADataTypeVisitor& visitor) const;
bool skip(HLADecodeStream& stream) const
{
if (!stream.alignOffsetForSize(getAlignment()))
return false;
return stream.skip(1);
}
bool skip(HLAEncodeStream& stream) const
{
if (!stream.alignOffsetForSize(getAlignment()))
return false;
return stream.skip(1);
}
bool decode(HLADecodeStream& stream, uint8_t& value) const
{
if (!stream.alignOffsetForSize(getAlignment()))
return false;
return stream.decodeUInt8(value);
}
bool encode(HLAEncodeStream& stream, const uint8_t& value) const
{
if (!stream.alignOffsetForSize(getAlignment()))
return false;
return stream.encodeUInt8(value);
}
};
#define BASIC_DATATYPE_IMPLEMENTATION(type, name) \
class HLA##name##DataType : public HLABasicDataType { \
public: \
virtual ~HLA##name##DataType(); \
\
virtual void accept(HLADataTypeVisitor& visitor) const; \
\
bool skip(HLADecodeStream& stream) const \
{ \
if (!stream.alignOffsetForSize(getAlignment())) \
return false; \
return stream.skip(sizeof(type)); \
} \
bool skip(HLAEncodeStream& stream) const \
{ \
if (!stream.alignOffsetForSize(getAlignment())) \
return false; \
return stream.skip(sizeof(type)); \
} \
virtual bool decode(HLADecodeStream& stream, type& value) const = 0; \
virtual bool encode(HLAEncodeStream& stream, const type& value) const = 0;\
protected: \
HLA##name##DataType(const std::string& name); \
}; \
class HLA##name##LEDataType : public HLA##name##DataType { \
public: \
HLA##name##LEDataType(const std::string& name = "HLA" #name "LEDataType");\
virtual ~HLA##name##LEDataType(); \
virtual bool decode(HLADecodeStream& stream, type& value) const; \
virtual bool encode(HLAEncodeStream& stream, const type& value) const; \
}; \
class HLA##name##BEDataType : public HLA##name##DataType { \
public: \
HLA##name##BEDataType(const std::string& name = "HLA" #name "BEDataType");\
virtual ~HLA##name##BEDataType(); \
virtual bool decode(HLADecodeStream& stream, type& value) const; \
virtual bool encode(HLAEncodeStream& stream, const type& value) const; \
};
BASIC_DATATYPE_IMPLEMENTATION(int16_t, Int16)
BASIC_DATATYPE_IMPLEMENTATION(uint16_t, UInt16)
BASIC_DATATYPE_IMPLEMENTATION(int32_t, Int32)
BASIC_DATATYPE_IMPLEMENTATION(uint32_t, UInt32)
BASIC_DATATYPE_IMPLEMENTATION(int64_t, Int64)
BASIC_DATATYPE_IMPLEMENTATION(uint64_t, UInt64)
BASIC_DATATYPE_IMPLEMENTATION(float, Float32)
BASIC_DATATYPE_IMPLEMENTATION(double, Float64)
#undef BASIC_DATATYPE_IMPLEMENTATION
} // namespace simgear
#endif

View File

@@ -0,0 +1,187 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLADataElement.hxx"
#include <simgear/debug/logstream.hxx>
namespace simgear {
HLADataElement::PathElement::Data::~Data()
{
}
const HLADataElement::PathElement::FieldData*
HLADataElement::PathElement::Data::toFieldData() const
{
return 0;
}
const HLADataElement::PathElement::IndexData*
HLADataElement::PathElement::Data::toIndexData() const
{
return 0;
}
HLADataElement::PathElement::FieldData::FieldData(const std::string& name) :
_name(name)
{
}
HLADataElement::PathElement::FieldData::~FieldData()
{
}
const HLADataElement::PathElement::FieldData*
HLADataElement::PathElement::FieldData::toFieldData() const
{
return this;
}
bool
HLADataElement::PathElement::FieldData::less(const Data* data) const
{
const FieldData* fieldData = data->toFieldData();
// IndexData is allways smaller than FieldData
if (!fieldData)
return false;
return _name < fieldData->_name;
}
bool
HLADataElement::PathElement::FieldData::equal(const Data* data) const
{
const FieldData* fieldData = data->toFieldData();
// IndexData is allways smaller than FieldData
if (!fieldData)
return false;
return _name == fieldData->_name;
}
void
HLADataElement::PathElement::FieldData::append(std::string& s) const
{
s.append(1, std::string::value_type('.'));
s.append(_name);
}
HLADataElement::PathElement::IndexData::IndexData(unsigned index) :
_index(index)
{
}
HLADataElement::PathElement::IndexData::~IndexData()
{
}
const HLADataElement::PathElement::IndexData*
HLADataElement::PathElement::IndexData::toIndexData() const
{
return this;
}
bool
HLADataElement::PathElement::IndexData::less(const Data* data) const
{
const IndexData* indexData = data->toIndexData();
// IndexData is allways smaller than FieldData
if (!indexData)
return true;
return _index < indexData->_index;
}
bool
HLADataElement::PathElement::IndexData::equal(const Data* data) const
{
const IndexData* indexData = data->toIndexData();
// IndexData is allways smaller than FieldData
if (!indexData)
return false;
return _index == indexData->_index;
}
void
HLADataElement::PathElement::IndexData::append(std::string& s) const
{
s.append(1, std::string::value_type('['));
unsigned value = _index;
do {
s.append(1, std::string::value_type('0' + value % 10));
} while (value /= 10);
s.append(1, std::string::value_type(']'));
}
HLADataElement::~HLADataElement()
{
}
std::string
HLADataElement::toString(const Path& path)
{
std::string s;
for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
i->append(s);
return s;
}
HLADataElement::AttributePathPair
HLADataElement::toAttributePathPair(const std::string& s)
{
Path path;
// Skip the initial attribute name if given
std::string::size_type i = s.find_first_of("[.");
std::string attribute = s.substr(0, i);
while (i < s.size()) {
if (s[i] == '[') {
++i;
unsigned index = 0;
while (i < s.size()) {
if (s[i] == ']')
break;
unsigned v = s[i] - '0';
// Error, no number
if (10 <= v) {
SG_LOG(SG_NETWORK, SG_WARN, "HLADataElement: invalid character in array subscript for \""
<< s << "\" at \"" << attribute << toString(path) << "\"!");
return AttributePathPair();
}
index *= 10;
index += v;
++i;
}
path.push_back(index);
++i;
continue;
}
if (s[i] == '.') {
// Error, . cannot be last
if (s.size() <= ++i) {
SG_LOG(SG_NETWORK, SG_WARN, "HLADataElement: invalid terminating '.' for \""
<< s << "\"!");
return AttributePathPair();
}
std::string::size_type e = s.find_first_of("[.", i);
path.push_back(s.substr(i, e - i));
i = e;
continue;
}
}
return AttributePathPair(attribute, path);
}
}

View File

@@ -0,0 +1,217 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLADataElement_hxx
#define HLADataElement_hxx
#include <list>
#include <map>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/timing/timestamp.hxx>
#include "RTIData.hxx"
#include "HLADataType.hxx"
class SGTimeStamp;
namespace simgear {
class HLADataElement : public SGReferenced {
public:
virtual ~HLADataElement();
virtual bool encode(HLAEncodeStream& stream) const = 0;
virtual bool decode(HLADecodeStream& stream) = 0;
virtual const HLADataType* getDataType() const = 0;
virtual bool setDataType(const HLADataType* dataType) = 0;
// Container for the timestamp the originating attribute was last updated for
// class TimeStamp : public SGReferenced {
// public:
// const SGTimeStamp& getTimeStamp() const
// { return _timeStamp; }
// void setTimeStamp(const SGTimeStamp& timeStamp)
// { _timeStamp = timeStamp; }
// private:
// SGTimeStamp _timeStamp;
// };
// const TimeStamp* getTimeStamp() const
// { return _timeStamp.get(); }
// void setTimeStamp(const TimeStamp* timeStamp)
// { _timeStamp = timeStamp; }
// struct ChangeCount : public SGReferenced {
// ChangeCount() : _value(0) {}
// unsigned _value;
// };
// SGSharedPtr<ChangeCount> _changeCount;
// unsigned getChangeCount() const
// {
// // If we don't have return allways the same
// if (!_changeCount.valid())
// return 0;
// return _changeCount->_value;
// }
/// HLADataElements could be identified by path
/// These paths are composed of structure field names and array indices in the
/// order they appear while walking to the data element.
/// So provide here some tool functions to access these elements
/// Note that these functions are relatively expensive in execution time.
/// So only use them once at object creation time and store direct references to the values
class PathElement {
public:
PathElement(unsigned index) : _data(new IndexData(index)) {}
PathElement(const std::string& name) : _data(new FieldData(name)) {}
bool isFieldValue() const
{ return _data->toFieldData(); }
bool isIndexValue() const
{ return _data->toIndexData(); }
unsigned getIndexValue() const
{
const IndexData* indexData = _data->toIndexData();
if (!indexData)
return ~unsigned(0);
return indexData->_index;
}
std::string getFieldValue() const
{
const FieldData* fieldData = _data->toFieldData();
if (!fieldData)
return std::string();
return fieldData->_name;
}
// Want to be able to use that in std::map and std::set
bool operator<(const PathElement& pathElement) const
{ return _data->less(pathElement._data.get()); }
bool operator==(const PathElement& pathElement) const
{ return _data->equal(pathElement._data.get()); }
void append(std::string& s) const
{ _data->append(s); }
private:
struct FieldData;
struct IndexData;
struct Data : public SGReferenced {
virtual ~Data();
virtual const FieldData* toFieldData() const;
virtual const IndexData* toIndexData() const;
virtual bool less(const Data*) const = 0;
virtual bool equal(const Data*) const = 0;
virtual void append(std::string&) const = 0;
};
struct FieldData : public Data {
FieldData(const std::string& name);
virtual ~FieldData();
virtual const FieldData* toFieldData() const;
virtual bool less(const Data* data) const;
virtual bool equal(const Data* data) const;
virtual void append(std::string& s) const;
std::string _name;
};
struct IndexData : public Data {
IndexData(unsigned index);
virtual ~IndexData();
virtual const IndexData* toIndexData() const;
virtual bool less(const Data* data) const;
virtual bool equal(const Data* data) const;
virtual void append(std::string& s) const;
unsigned _index;
};
SGSharedPtr<Data> _data;
};
typedef std::list<PathElement> Path;
typedef std::pair<std::string, Path> AttributePathPair;
typedef std::pair<unsigned, Path> IndexPathPair;
static std::string toString(const Path& path);
static std::string toString(const AttributePathPair& path)
{ return path.first + toString(path.second); }
static AttributePathPair toAttributePathPair(const std::string& s);
static Path toPath(const std::string& s)
{ return toAttributePathPair(s).second; }
private:
// SGSharedPtr<const TimeStamp> _timeStamp;
};
class HLADataElementProvider {
public:
class AbstractProvider : public SGReferenced {
public:
virtual ~AbstractProvider() { }
virtual HLADataElement* getDataElement(const HLADataElement::Path& path) = 0;
// virtual HLADataElement* getDataElement(const HLADataElement::Path& path, const HLADataType* dataType)
// {
// SGSharedPtr<HLADataElement> dataElement = getDataElement(path);
// if (!dataElement.valid())
// return 0;
// if (!dataElement->setDataType(dataType))
// return 0;
// return dataElement.release();
// }
};
HLADataElementProvider()
{ }
HLADataElementProvider(HLADataElement* dataElement) :
_provider(new ConcreteProvider(dataElement))
{ }
HLADataElementProvider(const SGSharedPtr<HLADataElement>& dataElement) :
_provider(new ConcreteProvider(dataElement))
{ }
HLADataElementProvider(AbstractProvider* provider) :
_provider(provider)
{ }
HLADataElement* getDataElement(const HLADataElement::Path& path) const
{
if (!_provider.valid())
return 0;
return _provider->getDataElement(path);
}
private:
class ConcreteProvider : public AbstractProvider {
public:
ConcreteProvider(const SGSharedPtr<HLADataElement>& dataElement) :
_dataElement(dataElement)
{ }
virtual HLADataElement* getDataElement(const HLADataElement::Path&)
{ return _dataElement.get(); }
private:
SGSharedPtr<HLADataElement> _dataElement;
};
SGSharedPtr<AbstractProvider> _provider;
};
typedef std::map<HLADataElement::Path, HLADataElementProvider> HLAPathElementMap;
typedef std::map<unsigned, HLAPathElementMap> HLAAttributePathElementMap;
}
#endif

104
simgear/hla/HLADataType.cxx Normal file
View File

@@ -0,0 +1,104 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLADataType.hxx"
#include "HLADataElement.hxx"
#include "HLADataTypeVisitor.hxx"
namespace simgear {
HLADataType::HLADataType(const std::string& name, unsigned alignment) :
_name(name),
_alignment(1)
{
setAlignment(alignment);
}
HLADataType::~HLADataType()
{
}
void
HLADataType::accept(HLADataTypeVisitor& visitor) const
{
visitor.apply(*this);
}
const HLADataTypeReference*
HLADataType::toDataTypeReference() const
{
return 0;
}
const HLABasicDataType*
HLADataType::toBasicDataType() const
{
return 0;
}
const HLAArrayDataType*
HLADataType::toArrayDataType() const
{
return 0;
}
const HLAEnumeratedDataType*
HLADataType::toEnumeratedDataType() const
{
return 0;
}
const HLAFixedRecordDataType*
HLADataType::toFixedRecordDataType() const
{
return 0;
}
const HLAVariantDataType*
HLADataType::toVariantDataType() const
{
return 0;
}
void
HLADataType::setAlignment(unsigned alignment)
{
/// FIXME: more checks
if (alignment == 0)
_alignment = 1;
else
_alignment = alignment;
}
HLADataTypeReference::~HLADataTypeReference()
{
}
void
HLADataTypeReference::accept(HLADataTypeVisitor& visitor) const
{
visitor.apply(*this);
}
const HLADataTypeReference*
HLADataTypeReference::toDataTypeReference() const
{
return this;
}
}

View File

@@ -0,0 +1,99 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLADataType_hxx
#define HLADataType_hxx
#include <string>
#include <simgear/structure/SGWeakPtr.hxx>
#include <simgear/structure/SGWeakReferenced.hxx>
#include "RTIData.hxx"
namespace simgear {
class HLADataTypeVisitor;
class HLADataTypeReference;
class HLABasicDataType;
class HLAArrayDataType;
class HLAEnumeratedDataType;
class HLAFixedRecordDataType;
class HLAVariantDataType;
enum HLAUpdateType {
HLAStaticUpdate,
HLAPeriodicUpdate,
HLAConditionalUpdate,
HLAUndefinedUpdate
};
class HLADataType : public SGWeakReferenced {
public:
virtual ~HLADataType();
const std::string& getName() const
{ return _name; }
const std::string& getSemantics() const
{ return _semantics; }
void setSemantics(const std::string& semantics)
{ _semantics = semantics; }
unsigned getAlignment() const
{ return _alignment; }
virtual void accept(HLADataTypeVisitor& visitor) const;
virtual const HLADataTypeReference* toDataTypeReference() const;
virtual const HLABasicDataType* toBasicDataType() const;
virtual const HLAArrayDataType* toArrayDataType() const;
virtual const HLAEnumeratedDataType* toEnumeratedDataType() const;
virtual const HLAFixedRecordDataType* toFixedRecordDataType() const;
virtual const HLAVariantDataType* toVariantDataType() const;
protected:
HLADataType(const std::string& name, unsigned alignment = 1);
void setAlignment(unsigned alignment);
private:
std::string _name;
std::string _semantics;
unsigned _alignment;
};
// Weak reference to a data type. Used to implement self referencing data types
class HLADataTypeReference : public HLADataType {
public:
HLADataTypeReference(const SGSharedPtr<HLADataType>& dataType) :
HLADataType(dataType->getName(), dataType->getAlignment()),
_dataType(dataType)
{ }
virtual ~HLADataTypeReference();
SGSharedPtr<const HLADataType> getDataType() const
{ return _dataType.lock(); }
virtual void accept(HLADataTypeVisitor& visitor) const;
virtual const HLADataTypeReference* toDataTypeReference() const;
private:
SGWeakPtr<const HLADataType> _dataType;
};
} // namespace simgear
#endif

View File

@@ -0,0 +1,634 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLADataTypeVisitor_hxx
#define HLADataTypeVisitor_hxx
#include <cassert>
#include <string>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/SGMath.hxx>
#include "HLAArrayDataType.hxx"
#include "HLABasicDataType.hxx"
#include "HLADataTypeVisitor.hxx"
#include "HLAEnumeratedDataType.hxx"
#include "HLAFixedRecordDataType.hxx"
#include "HLAVariantDataType.hxx"
namespace simgear {
class HLADataTypeVisitor {
public:
virtual ~HLADataTypeVisitor() {}
virtual void apply(const HLADataType& dataType)
{ }
virtual void apply(const HLADataTypeReference& dataType)
{
SGSharedPtr<const HLADataType> dataTypeReference = dataType.getDataType();
if (!dataTypeReference.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLADataTypeReference weak reference vanished!");
return;
}
dataTypeReference->accept(*this);
}
virtual void apply(const HLABasicDataType& dataType)
{ apply(static_cast<const HLADataType&>(dataType)); }
virtual void apply(const HLAInt8DataType& dataType)
{ apply(static_cast<const HLABasicDataType&>(dataType)); }
virtual void apply(const HLAUInt8DataType& dataType)
{ apply(static_cast<const HLABasicDataType&>(dataType)); }
virtual void apply(const HLAInt16DataType& dataType)
{ apply(static_cast<const HLABasicDataType&>(dataType)); }
virtual void apply(const HLAUInt16DataType& dataType)
{ apply(static_cast<const HLABasicDataType&>(dataType)); }
virtual void apply(const HLAInt32DataType& dataType)
{ apply(static_cast<const HLABasicDataType&>(dataType)); }
virtual void apply(const HLAUInt32DataType& dataType)
{ apply(static_cast<const HLABasicDataType&>(dataType)); }
virtual void apply(const HLAInt64DataType& dataType)
{ apply(static_cast<const HLABasicDataType&>(dataType)); }
virtual void apply(const HLAUInt64DataType& dataType)
{ apply(static_cast<const HLABasicDataType&>(dataType)); }
virtual void apply(const HLAFloat32DataType& dataType)
{ apply(static_cast<const HLABasicDataType&>(dataType)); }
virtual void apply(const HLAFloat64DataType& dataType)
{ apply(static_cast<const HLABasicDataType&>(dataType)); }
virtual void apply(const HLAArrayDataType& dataType)
{ apply(static_cast<const HLADataType&>(dataType)); }
virtual void apply(const HLAFixedArrayDataType& dataType)
{ apply(static_cast<const HLAArrayDataType&>(dataType)); }
virtual void apply(const HLAVariableArrayDataType& dataType)
{ apply(static_cast<const HLAArrayDataType&>(dataType)); }
virtual void apply(const HLAEnumeratedDataType& dataType)
{ apply(static_cast<const HLADataType&>(dataType)); }
virtual void apply(const HLAFixedRecordDataType& dataType)
{ apply(static_cast<const HLADataType&>(dataType)); }
virtual void apply(const HLAVariantDataType& dataType)
{ apply(static_cast<const HLADataType&>(dataType)); }
};
/// Walks the datatype tree and checks if it is completely defined
class HLADataTypeCheckVisitor : public HLADataTypeVisitor {
public:
HLADataTypeCheckVisitor() : _valid(true) {}
bool valid() const { return _valid; }
virtual void apply(const HLAInt8DataType& dataType) { }
virtual void apply(const HLAUInt8DataType& dataType) { }
virtual void apply(const HLAInt16DataType& dataType) { }
virtual void apply(const HLAUInt16DataType& dataType) { }
virtual void apply(const HLAInt32DataType& dataType) { }
virtual void apply(const HLAUInt32DataType& dataType) { }
virtual void apply(const HLAInt64DataType& dataType) { }
virtual void apply(const HLAUInt64DataType& dataType) { }
virtual void apply(const HLAFloat32DataType& dataType) { }
virtual void apply(const HLAFloat64DataType& dataType) { }
virtual void apply(const HLAFixedArrayDataType& dataType)
{
if (!dataType.getElementDataType())
_valid = false;
else
dataType.getElementDataType()->accept(*this);
}
virtual void apply(const HLAVariableArrayDataType& dataType)
{
if (!dataType.getElementDataType())
_valid = false;
else
dataType.getElementDataType()->accept(*this);
if (!dataType.getSizeDataType())
_valid = false;
else
dataType.getSizeDataType()->accept(*this);
}
virtual void apply(const HLAEnumeratedDataType& dataType)
{
if (!dataType.getRepresentation())
_valid = false;
else
dataType.getRepresentation()->accept(*this);
}
virtual void apply(const HLAFixedRecordDataType& dataType)
{
unsigned numFields = dataType.getNumFields();
for (unsigned i = 0; i < numFields; ++i) {
if (!dataType.getFieldDataType(i))
_valid = false;
else
dataType.getFieldDataType(i)->accept(*this);
}
}
virtual void apply(const HLAVariantDataType& dataType)
{ assert(0); }
protected:
bool _valid;
};
class HLADataTypeDecodeVisitor : public HLADataTypeVisitor {
public:
HLADataTypeDecodeVisitor(HLADecodeStream& stream) : _stream(stream) {}
virtual ~HLADataTypeDecodeVisitor() {}
virtual void apply(const HLAInt8DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAUInt8DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAInt16DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAUInt16DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAInt32DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAUInt32DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAInt64DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAUInt64DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAFloat32DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAFloat64DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAFixedArrayDataType& dataType)
{
unsigned numElements = dataType.getNumElements();
for (unsigned i = 0; i < numElements; ++i)
dataType.getElementDataType()->accept(*this);
}
virtual void apply(const HLAVariableArrayDataType& dataType);
virtual void apply(const HLAEnumeratedDataType& dataType)
{
dataType.getRepresentation()->accept(*this);
}
virtual void apply(const HLAFixedRecordDataType& dataType)
{
unsigned numFields = dataType.getNumFields();
for (unsigned i = 0; i < numFields; ++i)
dataType.getFieldDataType(i)->accept(*this);
}
virtual void apply(const HLAVariantDataType& dataType) { assert(0); }
protected:
HLADecodeStream& _stream;
};
class HLADataTypeEncodeVisitor : public HLADataTypeVisitor {
public:
HLADataTypeEncodeVisitor(HLAEncodeStream& stream) : _stream(stream) {}
virtual ~HLADataTypeEncodeVisitor() {}
virtual void apply(const HLAInt8DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAUInt8DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAInt16DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAUInt16DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAInt32DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAUInt32DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAInt64DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAUInt64DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAFloat32DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAFloat64DataType& dataType) { dataType.skip(_stream); }
virtual void apply(const HLAFixedArrayDataType& dataType)
{
/// FIXME, might vanish in this sense ...
// dataType.encode(_stream, *this);
unsigned numElements = dataType.getNumElements();
for (unsigned i = 0; i < numElements; ++i)
dataType.getElementDataType()->accept(*this);
}
virtual void apply(const HLAVariableArrayDataType& dataType);
virtual void apply(const HLAEnumeratedDataType& dataType)
{
dataType.getRepresentation()->accept(*this);
}
virtual void apply(const HLAFixedRecordDataType& dataType)
{
unsigned numFields = dataType.getNumFields();
for (unsigned i = 0; i < numFields; ++i)
dataType.getFieldDataType(i)->accept(*this);
}
virtual void apply(const HLAVariantDataType& dataType) { assert(0); }
protected:
HLAEncodeStream& _stream;
};
/// Begin implementation of some get/set visitors
class HLAScalarDecodeVisitor : public HLADataTypeDecodeVisitor {
public:
HLAScalarDecodeVisitor(HLADecodeStream& stream) :
HLADataTypeDecodeVisitor(stream)
{}
virtual void apply(const HLAFixedArrayDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAVariableArrayDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAEnumeratedDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAFixedRecordDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAVariantDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
HLADataTypeDecodeVisitor::apply(dataType);
}
};
class HLAScalarEncodeVisitor : public HLADataTypeEncodeVisitor {
public:
HLAScalarEncodeVisitor(HLAEncodeStream& stream) :
HLADataTypeEncodeVisitor(stream)
{}
virtual void apply(const HLAFixedArrayDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAVariableArrayDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAEnumeratedDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAFixedRecordDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAVariantDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
HLADataTypeEncodeVisitor::apply(dataType);
}
};
class HLAFixedRecordDecodeVisitor : public HLADataTypeDecodeVisitor {
public:
HLAFixedRecordDecodeVisitor(HLADecodeStream& stream) :
HLADataTypeDecodeVisitor(stream)
{ }
virtual void apply(const HLAInt8DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAUInt8DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAInt16DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAUInt16DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAInt32DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAUInt32DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAInt64DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAUInt64DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAFloat32DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAFloat64DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAFixedArrayDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAVariableArrayDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAEnumeratedDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
virtual void apply(const HLAVariantDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
HLADataTypeDecodeVisitor::apply(dataType);
}
};
class HLAFixedRecordEncodeVisitor : public HLADataTypeEncodeVisitor {
public:
HLAFixedRecordEncodeVisitor(HLAEncodeStream& stream) :
HLADataTypeEncodeVisitor(stream)
{ }
virtual void apply(const HLAInt8DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAUInt8DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAInt16DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAUInt16DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAInt32DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAUInt32DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAInt64DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAUInt64DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAFloat32DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAFloat64DataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAFixedArrayDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAVariableArrayDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAEnumeratedDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
virtual void apply(const HLAVariantDataType& dataType)
{
SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
HLADataTypeEncodeVisitor::apply(dataType);
}
};
template<typename T>
class HLATemplateDecodeVisitor : public HLAScalarDecodeVisitor {
public:
typedef T value_type;
HLATemplateDecodeVisitor(HLADecodeStream& stream, const value_type& value = value_type()) :
HLAScalarDecodeVisitor(stream),
_value(value)
{}
void setValue(const value_type& value)
{ _value = value; }
const value_type& getValue() const
{ return _value; }
virtual void apply(const HLAInt8DataType& dataType)
{
int8_t value = 0;
dataType.decode(_stream, value);
_value = value_type(value);
}
virtual void apply(const HLAUInt8DataType& dataType)
{
uint8_t value = 0;
dataType.decode(_stream, value);
_value = value_type(value);
}
virtual void apply(const HLAInt16DataType& dataType)
{
int16_t value = 0;
dataType.decode(_stream, value);
_value = value_type(value);
}
virtual void apply(const HLAUInt16DataType& dataType)
{
uint16_t value = 0;
dataType.decode(_stream, value);
_value = value_type(value);
}
virtual void apply(const HLAInt32DataType& dataType)
{
int32_t value = 0;
dataType.decode(_stream, value);
_value = value_type(value);
}
virtual void apply(const HLAUInt32DataType& dataType)
{
uint32_t value = 0;
dataType.decode(_stream, value);
_value = value_type(value);
}
virtual void apply(const HLAInt64DataType& dataType)
{
int64_t value = 0;
dataType.decode(_stream, value);
_value = value_type(value);
}
virtual void apply(const HLAUInt64DataType& dataType)
{
uint64_t value = 0;
dataType.decode(_stream, value);
_value = value_type(value);
}
virtual void apply(const HLAFloat32DataType& dataType)
{
float value = 0;
dataType.decode(_stream, value);
_value = value_type(value);
}
virtual void apply(const HLAFloat64DataType& dataType)
{
double value = 0;
dataType.decode(_stream, value);
_value = value_type(value);
}
private:
value_type _value;
};
template<typename T>
class HLATemplateEncodeVisitor : public HLAScalarEncodeVisitor {
public:
typedef T value_type;
HLATemplateEncodeVisitor(HLAEncodeStream& stream, const value_type& value = value_type()) :
HLAScalarEncodeVisitor(stream),
_value(value)
{}
void setValue(const value_type& value)
{ _value = value; }
const value_type& getValue() const
{ return _value; }
virtual void apply(const HLAInt8DataType& dataType)
{
dataType.encode(_stream, _value);
}
virtual void apply(const HLAUInt8DataType& dataType)
{
dataType.encode(_stream, _value);
}
virtual void apply(const HLAInt16DataType& dataType)
{
dataType.encode(_stream, _value);
}
virtual void apply(const HLAUInt16DataType& dataType)
{
dataType.encode(_stream, _value);
}
virtual void apply(const HLAInt32DataType& dataType)
{
dataType.encode(_stream, _value);
}
virtual void apply(const HLAUInt32DataType& dataType)
{
dataType.encode(_stream, _value);
}
virtual void apply(const HLAInt64DataType& dataType)
{
dataType.encode(_stream, _value);
}
virtual void apply(const HLAUInt64DataType& dataType)
{
dataType.encode(_stream, _value);
}
virtual void apply(const HLAFloat32DataType& dataType)
{
dataType.encode(_stream, _value);
}
virtual void apply(const HLAFloat64DataType& dataType)
{
dataType.encode(_stream, _value);
}
private:
value_type _value;
};
inline void HLADataTypeDecodeVisitor::apply(const HLAVariableArrayDataType& dataType)
{
HLATemplateDecodeVisitor<unsigned> numElementsVisitor(_stream);
dataType.getSizeDataType()->accept(numElementsVisitor);
unsigned numElements = numElementsVisitor.getValue();
for (unsigned i = 0; i < numElements; ++i)
dataType.getElementDataType()->accept(*this);
}
inline void HLADataTypeEncodeVisitor::apply(const HLAVariableArrayDataType& dataType)
{
HLATemplateEncodeVisitor<unsigned> numElementsVisitor(_stream, 0);
dataType.getSizeDataType()->accept(numElementsVisitor);
}
} // namespace simgear
#endif

View File

@@ -0,0 +1,128 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAEnumeratedDataElement.hxx"
#include <simgear/debug/logstream.hxx>
namespace simgear {
HLAAbstractEnumeratedDataElement::HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType) :
_dataType(dataType)
{
}
HLAAbstractEnumeratedDataElement::~HLAAbstractEnumeratedDataElement()
{
}
bool
HLAAbstractEnumeratedDataElement::decode(HLADecodeStream& stream)
{
if (!_dataType.valid())
return false;
unsigned index;
if (!_dataType->decode(stream, index))
return false;
setEnumeratorIndex(index);
return true;
}
bool
HLAAbstractEnumeratedDataElement::encode(HLAEncodeStream& stream) const
{
if (!_dataType.valid())
return false;
return _dataType->encode(stream, getEnumeratorIndex());
}
const HLAEnumeratedDataType*
HLAAbstractEnumeratedDataElement::getDataType() const
{
return _dataType.get();
}
bool
HLAAbstractEnumeratedDataElement::setDataType(const HLADataType* dataType)
{
const HLAEnumeratedDataType* enumeratedDataType = dataType->toEnumeratedDataType();
if (!enumeratedDataType) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAEnumeratedDataType: unable to set data type!");
return false;
}
setDataType(enumeratedDataType);
return true;
}
void
HLAAbstractEnumeratedDataElement::setDataType(const HLAEnumeratedDataType* dataType)
{
_dataType = dataType;
}
const HLABasicDataType*
HLAAbstractEnumeratedDataElement::getRepresentationDataType() const
{
if (!_dataType.valid())
return 0;
return _dataType->getRepresentation();
}
std::string
HLAAbstractEnumeratedDataElement::getStringRepresentation() const
{
if (!_dataType.valid())
return std::string();
return _dataType->getString(getEnumeratorIndex());
}
bool
HLAAbstractEnumeratedDataElement::setStringRepresentation(const std::string& name)
{
if (!_dataType.valid())
return false;
unsigned index = _dataType->getIndex(name);
if (_dataType->getNumEnumerators() <= index)
return false;
setEnumeratorIndex(index);
return true;
}
HLAEnumeratedDataElement::HLAEnumeratedDataElement(const HLAEnumeratedDataType* dataType) :
HLAAbstractEnumeratedDataElement(dataType),
_enumeratorIndex(~unsigned(0))
{
}
HLAEnumeratedDataElement::~HLAEnumeratedDataElement()
{
}
unsigned
HLAEnumeratedDataElement::getEnumeratorIndex() const
{
return _enumeratorIndex;
}
void
HLAEnumeratedDataElement::setEnumeratorIndex(unsigned index)
{
_enumeratorIndex = index;
}
}

View File

@@ -0,0 +1,64 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAEnumeratedDataElement_hxx
#define HLAEnumeratedDataElement_hxx
#include "HLADataElement.hxx"
#include "HLAEnumeratedDataType.hxx"
namespace simgear {
class HLAAbstractEnumeratedDataElement : public HLADataElement {
public:
HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType);
virtual ~HLAAbstractEnumeratedDataElement();
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;
virtual const HLAEnumeratedDataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType);
void setDataType(const HLAEnumeratedDataType* dataType);
const HLABasicDataType* getRepresentationDataType() const;
std::string getStringRepresentation() const;
bool setStringRepresentation(const std::string& name);
virtual unsigned getEnumeratorIndex() const = 0;
virtual void setEnumeratorIndex(unsigned index) = 0;
private:
SGSharedPtr<const HLAEnumeratedDataType> _dataType;
};
class HLAEnumeratedDataElement : public HLAAbstractEnumeratedDataElement {
public:
HLAEnumeratedDataElement(const HLAEnumeratedDataType* dataType);
virtual ~HLAEnumeratedDataElement();
virtual unsigned getEnumeratorIndex() const;
virtual void setEnumeratorIndex(unsigned index);
private:
unsigned _enumeratorIndex;
};
}
#endif

View File

@@ -0,0 +1,180 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAEnumeratedDataType.hxx"
#include <map>
#include <sstream>
#include <vector>
#include "HLAEnumeratedDataType.hxx"
#include "HLADataTypeVisitor.hxx"
namespace simgear {
template<typename DataType, typename T>
class HLAEnumeratedDataType::Map : public HLAEnumeratedDataType::AbstractMap {
public:
typedef typename std::pair<std::string,T> RepresentationPair;
typedef typename std::map<T, unsigned> RepresentationIndexMap;
typedef typename std::vector<RepresentationPair> IndexRepresentationMap;
typedef typename std::map<std::string, unsigned> StringIndexMap;
Map(const DataType* dataType) :
_dataType(dataType)
{ }
virtual bool encode(HLAEncodeStream& stream, unsigned index) const
{
T value = _otherRepresentation;
if (index < _indexRepresentationMap.size())
value = _indexRepresentationMap[index].second;
if (!_dataType->encode(stream, value))
return false;
return true;
}
virtual bool decode(HLADecodeStream& stream, unsigned& index) const
{
T value;
if (!_dataType->decode(stream, value))
return false;
typename RepresentationIndexMap::const_iterator i;
i = _representationIndexMap.find(value);
if (i == _representationIndexMap.end())
index = _indexRepresentationMap.size();
else
index = i->second;
return true;
}
virtual const HLABasicDataType* getDataType() const
{ return _dataType.get(); }
virtual bool add(const std::string& name, const std::string& number)
{
std::stringstream ss(number);
T value;
ss >> value;
if (ss.fail())
return false;
if (_representationIndexMap.find(value) != _representationIndexMap.end())
return false;
if (_stringIndexMap.find(name) != _stringIndexMap.end())
return false;
_stringIndexMap[name] = _indexRepresentationMap.size();
_representationIndexMap[value] = _indexRepresentationMap.size();
_indexRepresentationMap.push_back(RepresentationPair(name, value));
return true;
}
virtual std::string getString(unsigned index) const
{
if (_indexRepresentationMap.size() <= index)
return std::string();
return _indexRepresentationMap[index].first;
}
virtual unsigned getIndex(const std::string& name) const
{
typename StringIndexMap::const_iterator i = _stringIndexMap.find(name);
if (i == _stringIndexMap.end())
return ~unsigned(0);
return i->second;
}
virtual unsigned getNumEnumerators() const
{ return _indexRepresentationMap.size(); }
private:
IndexRepresentationMap _indexRepresentationMap;
StringIndexMap _stringIndexMap;
RepresentationIndexMap _representationIndexMap;
T _otherRepresentation;
SGSharedPtr<const DataType> _dataType;
};
class HLAEnumeratedDataType::RepresentationVisitor : public HLADataTypeVisitor {
public:
virtual void apply(const HLAInt8DataType& dataType)
{ _map = new Map<HLAInt8DataType, int8_t>(&dataType); }
virtual void apply(const HLAUInt8DataType& dataType)
{ _map = new Map<HLAUInt8DataType, uint8_t>(&dataType); }
virtual void apply(const HLAInt16DataType& dataType)
{ _map = new Map<HLAInt16DataType, int16_t>(&dataType); }
virtual void apply(const HLAUInt16DataType& dataType)
{ _map = new Map<HLAUInt16DataType, uint16_t>(&dataType); }
virtual void apply(const HLAInt32DataType& dataType)
{ _map = new Map<HLAInt32DataType, int32_t>(&dataType); }
virtual void apply(const HLAUInt32DataType& dataType)
{ _map = new Map<HLAUInt32DataType, uint32_t>(&dataType); }
virtual void apply(const HLAInt64DataType& dataType)
{ _map = new Map<HLAInt64DataType, int64_t>(&dataType); }
virtual void apply(const HLAUInt64DataType& dataType)
{ _map = new Map<HLAUInt64DataType, uint64_t>(&dataType); }
SGSharedPtr<AbstractMap> _map;
};
HLAEnumeratedDataType::HLAEnumeratedDataType(const std::string& name) :
HLADataType(name)
{
}
HLAEnumeratedDataType::~HLAEnumeratedDataType()
{
}
void
HLAEnumeratedDataType::accept(HLADataTypeVisitor& visitor) const
{
visitor.apply(*this);
}
const HLAEnumeratedDataType*
HLAEnumeratedDataType::toEnumeratedDataType() const
{
return this;
}
bool
HLAEnumeratedDataType::decode(HLADecodeStream& stream, unsigned& index) const
{
if (!_map.valid())
return false;
if (!_map->decode(stream, index))
return false;
return true;
}
bool
HLAEnumeratedDataType::encode(HLAEncodeStream& stream, unsigned index) const
{
if (!_map.valid())
return false;
return _map->encode(stream, index);
}
void
HLAEnumeratedDataType::setRepresentation(HLABasicDataType* representation)
{
if (!representation)
return;
RepresentationVisitor representationVisitor;
representation->accept(representationVisitor);
_map.swap(representationVisitor._map);
}
} // namespace simgear

View File

@@ -0,0 +1,95 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAEnumeratedDataType_hxx
#define HLAEnumeratedDataType_hxx
#include <string>
#include <simgear/structure/SGSharedPtr.hxx>
#include "HLADataType.hxx"
namespace simgear {
class HLAEnumeratedDataType : public HLADataType {
public:
HLAEnumeratedDataType(const std::string& name = "HLAEnumeratedDataType");
virtual ~HLAEnumeratedDataType();
virtual void accept(HLADataTypeVisitor& visitor) const;
virtual const HLAEnumeratedDataType* toEnumeratedDataType() const;
virtual bool decode(HLADecodeStream& stream, unsigned& index) const;
virtual bool encode(HLAEncodeStream& stream, unsigned index) const;
std::string getString(unsigned index) const
{
if (!_map.valid())
return std::string();
return _map->getString(index);
}
unsigned getIndex(const std::string& name) const
{
if (!_map.valid())
return ~unsigned(0);
return _map->getIndex(name);
}
unsigned getNumEnumerators() const
{
if (!_map.valid())
return 0;
return _map->getNumEnumerators();
}
bool addEnumerator(const std::string& name, const std::string& number)
{
if (!_map.valid())
return false;
return _map->add(name, number);
}
void setRepresentation(HLABasicDataType* representation);
const HLABasicDataType* getRepresentation() const
{
if (!_map.valid())
return 0;
return _map->getDataType();
}
private:
class AbstractMap : public SGReferenced {
public:
virtual ~AbstractMap() {}
virtual bool encode(HLAEncodeStream& stream, unsigned index) const = 0;
virtual bool decode(HLADecodeStream& stream, unsigned& index) const = 0;
virtual const HLABasicDataType* getDataType() const = 0;
virtual bool add(const std::string& name, const std::string& number) = 0;
virtual std::string getString(unsigned index) const = 0;
virtual unsigned getIndex(const std::string& name) const = 0;
virtual unsigned getNumEnumerators() const = 0;
};
template<typename DataType, typename T>
class Map;
class RepresentationVisitor;
SGSharedPtr<AbstractMap> _map;
};
} // namespace simgear
#endif

246
simgear/hla/HLAFederate.cxx Normal file
View File

@@ -0,0 +1,246 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAFederate.hxx"
#include "RTIFederate.hxx"
#include "RTIInteractionClass.hxx"
#include "RTIObjectClass.hxx"
#include "HLADataElement.hxx"
#include "HLADataType.hxx"
#include "HLAOMTXmlVisitor.hxx"
namespace simgear {
HLAFederate::HLAFederate(const SGSharedPtr<RTIFederate>& rtiFederate) :
_rtiFederate(rtiFederate)
{
}
HLAFederate::~HLAFederate()
{
}
const std::string&
HLAFederate::getFederateType() const
{
return _rtiFederate->getFederateType();
}
const std::string&
HLAFederate::getFederationName() const
{
return _rtiFederate->getFederationName();
}
bool
HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
{
return _rtiFederate->createFederationExecution(federation, objectModel);
}
bool
HLAFederate::destroyFederationExecution(const std::string& federation)
{
return _rtiFederate->destroyFederationExecution(federation);
}
bool
HLAFederate::join(const std::string& federateType, const std::string& federation)
{
return _rtiFederate->join(federateType, federation);
}
bool
HLAFederate::resign()
{
return _rtiFederate->resign();
}
bool
HLAFederate::enableTimeConstrained()
{
return _rtiFederate->enableTimeConstrained();
}
bool
HLAFederate::disableTimeConstrained()
{
return _rtiFederate->disableTimeConstrained();
}
bool
HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
{
return _rtiFederate->enableTimeRegulation(lookahead);
}
bool
HLAFederate::disableTimeRegulation()
{
return _rtiFederate->disableTimeRegulation();
}
bool
HLAFederate::timeAdvanceRequestBy(const SGTimeStamp& dt)
{
return _rtiFederate->timeAdvanceRequestBy(dt);
}
bool
HLAFederate::timeAdvanceRequest(const SGTimeStamp& dt)
{
return _rtiFederate->timeAdvanceRequest(dt);
}
bool
HLAFederate::tick()
{
return _rtiFederate->tick();
}
bool
HLAFederate::tick(const double& minimum, const double& maximum)
{
return _rtiFederate->tick(minimum, maximum);
}
bool
HLAFederate::readObjectModelTemplate(const std::string& objectModel,
HLAFederate::ObjectModelFactory& objectModelFactory)
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not process HLA XML object model file: "
"No rti federate available!");
return false;
}
// The XML version of the federate object model.
// This one covers the generic attributes, parameters and data types.
HLAOMTXmlVisitor omtXmlVisitor;
try {
readXML(objectModel, omtXmlVisitor);
} catch (const sg_throwable& e) {
SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
<< e.getMessage());
return false;
} catch (...) {
SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
return false;
}
unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses();
for (unsigned i = 0; i < numObjectClasses; ++i) {
const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i);
std::string objectClassName = objectClass->getName();
SGSharedPtr<HLAObjectClass> hlaObjectClass = objectModelFactory.createObjectClass(objectClassName, *this);
if (!hlaObjectClass.valid()) {
SG_LOG(SG_IO, SG_INFO, "Ignoring object class \"" << objectClassName << "\".");
continue;
}
bool publish = objectModelFactory.publishObjectClass(objectClassName, objectClass->getSharing());
bool subscribe = objectModelFactory.subscribeObjectClass(objectClassName, objectClass->getSharing());
std::set<unsigned> subscriptions;
std::set<unsigned> publications;
// process the attributes
for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
const simgear::HLAOMTXmlVisitor::Attribute* attribute;
attribute = objectClass->getAttribute(j);
std::string attributeName = attribute->getName();
unsigned index = hlaObjectClass->getAttributeIndex(attributeName);
if (index == ~0u) {
SG_LOG(SG_IO, SG_WARN, "RTI does not know the \"" << attributeName << "\" attribute!");
continue;
}
SGSharedPtr<HLADataType> dataType;
dataType = omtXmlVisitor.getAttributeDataType(objectClassName, attributeName);
if (!dataType.valid()) {
SG_LOG(SG_IO, SG_WARN, "Could not find data type for attribute \""
<< attributeName << "\" in object class \"" << objectClassName << "\"!");
}
hlaObjectClass->setAttributeDataType(index, dataType);
HLAUpdateType updateType = HLAUndefinedUpdate;
if (attribute->_updateType == "Periodic")
updateType = HLAPeriodicUpdate;
else if (attribute->_updateType == "Static")
updateType = HLAStaticUpdate;
else if (attribute->_updateType == "Conditional")
updateType = HLAConditionalUpdate;
hlaObjectClass->setAttributeUpdateType(index, updateType);
if (subscribe && objectModelFactory.subscribeAttribute(objectClassName, attributeName, attribute->_sharing))
subscriptions.insert(index);
if (publish && objectModelFactory.publishAttribute(objectClassName, attributeName, attribute->_sharing))
publications.insert(index);
}
if (publish)
hlaObjectClass->publish(publications);
if (subscribe)
hlaObjectClass->subscribe(subscriptions, true);
_objectClassMap[objectClassName] = hlaObjectClass;
}
return true;
}
HLAObjectClass*
HLAFederate::getObjectClass(const std::string& name)
{
ObjectClassMap::const_iterator i = _objectClassMap.find(name);
if (i == _objectClassMap.end())
return 0;
return i->second.get();
}
const HLAObjectClass*
HLAFederate::getObjectClass(const std::string& name) const
{
ObjectClassMap::const_iterator i = _objectClassMap.find(name);
if (i == _objectClassMap.end())
return 0;
return i->second.get();
}
HLAInteractionClass*
HLAFederate::getInteractionClass(const std::string& name)
{
InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
if (i == _interactionClassMap.end())
return 0;
return i->second.get();
}
const HLAInteractionClass*
HLAFederate::getInteractionClass(const std::string& name) const
{
InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
if (i == _interactionClassMap.end())
return 0;
return i->second.get();
}
} // namespace simgear

111
simgear/hla/HLAFederate.hxx Normal file
View File

@@ -0,0 +1,111 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAFederate_hxx
#define HLAFederate_hxx
#include <map>
#include "HLAObjectInstance.hxx"
#include "HLAObjectClass.hxx"
#include "HLAInteractionClass.hxx"
class SGTimeStamp;
namespace simgear {
class RTIFederate;
class HLAFederate : public SGWeakReferenced {
public:
virtual ~HLAFederate();
/// Get the name of the joined federate/federation
const std::string& getFederateType() const;
const std::string& getFederationName() const;
/// Create a federation execution
/// Semantically this methods should be static,
/// but the nonstatic case could reuse the connection to the server
/// FIXME: cannot determine from the return value if we created the execution
bool createFederationExecution(const std::string& federation, const std::string& objectModel);
bool destroyFederationExecution(const std::string& federation);
/// Join with federateType the federation execution
bool join(const std::string& federateType, const std::string& federation);
bool resign();
bool enableTimeConstrained();
bool disableTimeConstrained();
bool enableTimeRegulation(const SGTimeStamp& lookahead);
bool disableTimeRegulation();
bool timeAdvanceRequestBy(const SGTimeStamp& dt);
bool timeAdvanceRequest(const SGTimeStamp& dt);
/// Process messages
bool tick();
bool tick(const double& minimum, const double& maximum);
class ObjectModelFactory {
public:
virtual ~ObjectModelFactory()
{ }
virtual HLAObjectClass* createObjectClass(const std::string& name, HLAFederate& federate)
{ return new HLAObjectClass(name, federate); }
virtual bool subscribeObjectClass(const std::string& objectClassName, const std::string& sharing)
{ return sharing.find("Subscribe") != std::string::npos; }
virtual bool publishObjectClass(const std::string& objectClassName, const std::string& sharing)
{ return sharing.find("Publish") != std::string::npos; }
virtual bool subscribeAttribute(const std::string& objectClassName, const std::string& attributeName, const std::string& sharing)
{ return sharing.find("Subscribe") != std::string::npos; }
virtual bool publishAttribute(const std::string& objectClassName, const std::string& attributeName, const std::string& sharing)
{ return sharing.find("Publish") != std::string::npos; }
};
/// Read an omt xml file
bool readObjectModelTemplate(const std::string& objectModel,
ObjectModelFactory& objectModelFactory);
HLAObjectClass* getObjectClass(const std::string& name);
const HLAObjectClass* getObjectClass(const std::string& name) const;
HLAInteractionClass* getInteractionClass(const std::string& name);
const HLAInteractionClass* getInteractionClass(const std::string& name) const;
protected:
HLAFederate(const SGSharedPtr<RTIFederate>& rtiFederate);
private:
SGSharedPtr<RTIFederate> _rtiFederate;
typedef std::map<std::string, SGSharedPtr<HLAObjectClass> > ObjectClassMap;
ObjectClassMap _objectClassMap;
typedef std::map<std::string, SGSharedPtr<HLAInteractionClass> > InteractionClassMap;
InteractionClassMap _interactionClassMap;
friend class HLAInteractionClass;
friend class HLAObjectClass;
};
} // namespace simgear
#endif

View File

@@ -0,0 +1,179 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAFixedRecordDataElement.hxx"
#include <string>
#include <vector>
#include <simgear/debug/logstream.hxx>
#include "HLADataTypeVisitor.hxx"
namespace simgear {
HLAAbstractFixedRecordDataElement::HLAAbstractFixedRecordDataElement(const HLAFixedRecordDataType* dataType) :
_dataType(dataType)
{
}
HLAAbstractFixedRecordDataElement::~HLAAbstractFixedRecordDataElement()
{
}
bool
HLAAbstractFixedRecordDataElement::decode(HLADecodeStream& stream)
{
if (!_dataType.valid())
return false;
return _dataType->decode(stream, *this);
}
bool
HLAAbstractFixedRecordDataElement::encode(HLAEncodeStream& stream) const
{
if (!_dataType.valid())
return false;
return _dataType->encode(stream, *this);
}
const HLAFixedRecordDataType*
HLAAbstractFixedRecordDataElement::getDataType() const
{
return _dataType.get();
}
bool
HLAAbstractFixedRecordDataElement::setDataType(const HLADataType* dataType)
{
const HLAFixedRecordDataType* fixedRecordDataType = dataType->toFixedRecordDataType();
if (!fixedRecordDataType) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAFixedRecordDataType: unable to set data type!");
return false;
}
setDataType(fixedRecordDataType);
return true;
}
void
HLAAbstractFixedRecordDataElement::setDataType(const HLAFixedRecordDataType* dataType)
{
_dataType = dataType;
}
unsigned
HLAAbstractFixedRecordDataElement::getNumFields() const
{
return _dataType->getNumFields();
}
unsigned
HLAAbstractFixedRecordDataElement::getFieldNumber(const std::string& name) const
{
return _dataType->getFieldNumber(name);
}
const HLADataType*
HLAAbstractFixedRecordDataElement::getFieldDataType(unsigned i) const
{
return _dataType->getFieldDataType(i);
}
const HLADataType*
HLAAbstractFixedRecordDataElement::getFieldDataType(const std::string& name) const
{
return getFieldDataType(getFieldNumber(name));
}
HLAFixedRecordDataElement::HLAFixedRecordDataElement(const HLAFixedRecordDataType* dataType) :
HLAAbstractFixedRecordDataElement(dataType)
{
_fieldVector.resize(getNumFields());
}
HLAFixedRecordDataElement::~HLAFixedRecordDataElement()
{
}
bool
HLAFixedRecordDataElement::decodeField(HLADecodeStream& stream, unsigned i)
{
HLADataElement* dataElement = getField(i);
if (dataElement) {
return dataElement->decode(stream);
} else {
HLADataTypeDecodeVisitor visitor(stream);
getDataType()->getFieldDataType(i)->accept(visitor);
return true;
}
}
bool
HLAFixedRecordDataElement::encodeField(HLAEncodeStream& stream, unsigned i) const
{
const HLADataElement* dataElement = getField(i);
if (dataElement) {
return dataElement->encode(stream);
} else {
HLADataTypeEncodeVisitor visitor(stream);
getDataType()->getFieldDataType(i)->accept(visitor);
return true;
}
}
HLADataElement*
HLAFixedRecordDataElement::getField(const std::string& name)
{
return getField(getFieldNumber(name));
}
const HLADataElement*
HLAFixedRecordDataElement::getField(const std::string& name) const
{
return getField(getFieldNumber(name));
}
HLADataElement*
HLAFixedRecordDataElement::getField(unsigned i)
{
if (_fieldVector.size() <= i)
return 0;
return _fieldVector[i].get();
}
const HLADataElement*
HLAFixedRecordDataElement::getField(unsigned i) const
{
if (_fieldVector.size() <= i)
return 0;
return _fieldVector[i].get();
}
void
HLAFixedRecordDataElement::setField(unsigned index, HLADataElement* value)
{
if (getNumFields() <= index)
return;
_fieldVector[index] = value;
}
void
HLAFixedRecordDataElement::setField(const std::string& name, HLADataElement* value)
{
setField(getFieldNumber(name), value);
}
}

View File

@@ -0,0 +1,77 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAFixedRecordDataElement_hxx
#define HLAFixedRecordDataElement_hxx
#include <string>
#include <vector>
#include "HLADataElement.hxx"
#include "HLAFixedRecordDataType.hxx"
namespace simgear {
class HLAAbstractFixedRecordDataElement : public HLADataElement {
public:
HLAAbstractFixedRecordDataElement(const HLAFixedRecordDataType* dataType);
virtual ~HLAAbstractFixedRecordDataElement();
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;
virtual const HLAFixedRecordDataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType);
void setDataType(const HLAFixedRecordDataType* dataType);
unsigned getNumFields() const;
unsigned getFieldNumber(const std::string& name) const;
const HLADataType* getFieldDataType(unsigned i) const;
const HLADataType* getFieldDataType(const std::string& name) const;
virtual bool decodeField(HLADecodeStream& stream, unsigned i) = 0;
virtual bool encodeField(HLAEncodeStream& stream, unsigned i) const = 0;
private:
SGSharedPtr<const HLAFixedRecordDataType> _dataType;
};
class HLAFixedRecordDataElement : public HLAAbstractFixedRecordDataElement {
public:
HLAFixedRecordDataElement(const HLAFixedRecordDataType* dataType);
virtual ~HLAFixedRecordDataElement();
virtual bool decodeField(HLADecodeStream& stream, unsigned i);
virtual bool encodeField(HLAEncodeStream& stream, unsigned i) const;
HLADataElement* getField(const std::string& name);
const HLADataElement* getField(const std::string& name) const;
HLADataElement* getField(unsigned i);
const HLADataElement* getField(unsigned i) const;
void setField(unsigned index, HLADataElement* value);
void setField(const std::string& name, HLADataElement* value);
private:
typedef std::vector<SGSharedPtr<HLADataElement> > FieldVector;
FieldVector _fieldVector;
};
}
#endif

View File

@@ -0,0 +1,77 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAFixedRecordDataType.hxx"
#include "HLADataTypeVisitor.hxx"
#include "HLAFixedRecordDataElement.hxx"
namespace simgear {
HLAFixedRecordDataType::HLAFixedRecordDataType(const std::string& name) :
HLADataType(name)
{
}
HLAFixedRecordDataType::~HLAFixedRecordDataType()
{
}
void
HLAFixedRecordDataType::accept(HLADataTypeVisitor& visitor) const
{
visitor.apply(*this);
}
const HLAFixedRecordDataType*
HLAFixedRecordDataType::toFixedRecordDataType() const
{
return this;
}
bool
HLAFixedRecordDataType::decode(HLADecodeStream& stream, HLAAbstractFixedRecordDataElement& value) const
{
stream.alignOffsetForSize(getAlignment());
unsigned numFields = getNumFields();
for (unsigned i = 0; i < numFields; ++i)
if (!value.decodeField(stream, i))
return false;
return true;
}
bool
HLAFixedRecordDataType::encode(HLAEncodeStream& stream, const HLAAbstractFixedRecordDataElement& value) const
{
stream.alignOffsetForSize(getAlignment());
unsigned numFields = getNumFields();
for (unsigned i = 0; i < numFields; ++i)
if (!value.encodeField(stream, i))
return false;
return true;
}
void
HLAFixedRecordDataType::addField(const std::string& name, const HLADataType* dataType)
{
// FIXME this only works if we do not reset the alignment to something smaller
if (getAlignment() < dataType->getAlignment())
setAlignment(dataType->getAlignment());
_fieldList.push_back(Field(name, dataType));
}
} // namespace simgear

View File

@@ -0,0 +1,91 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAFixedRecordDataType_hxx
#define HLAFixedRecordDataType_hxx
#include <string>
#include <vector>
#include <simgear/structure/SGSharedPtr.hxx>
#include "HLADataType.hxx"
namespace simgear {
class HLAAbstractFixedRecordDataElement;
class HLAFixedRecordDataType : public HLADataType {
public:
HLAFixedRecordDataType(const std::string& name = "HLAFixedRecordDataType");
virtual ~HLAFixedRecordDataType();
virtual void accept(HLADataTypeVisitor& visitor) const;
virtual const HLAFixedRecordDataType* toFixedRecordDataType() const;
virtual bool decode(HLADecodeStream& stream, HLAAbstractFixedRecordDataElement& value) const;
virtual bool encode(HLAEncodeStream& stream, const HLAAbstractFixedRecordDataElement& value) const;
unsigned getNumFields() const
{ return _fieldList.size(); }
std::string getFieldName(unsigned i) const
{
if (_fieldList.size() <= i)
return std::string();
return _fieldList[i].getName();
}
const HLADataType* getFieldDataType(unsigned i) const
{
if (_fieldList.size() <= i)
return 0;
return _fieldList[i].getDataType();
}
unsigned getFieldNumber(const std::string& name) const
{
for (unsigned i = 0; i < _fieldList.size(); ++i) {
if (_fieldList[i].getName() != name)
continue;
return i;
}
return ~0u;
}
void addField(const std::string& name, const HLADataType* dataType);
private:
struct Field {
Field(const std::string& name, const HLADataType* dataType) :
_name(name), _dataType(dataType) {}
const std::string& getName() const
{ return _name; }
const HLADataType* getDataType() const
{ return _dataType.get(); }
private:
std::string _name;
SGSharedPtr<const HLADataType> _dataType;
};
typedef std::vector<Field> FieldList;
FieldList _fieldList;
};
} // namespace simgear
#endif

View File

@@ -0,0 +1,32 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAInteractionClass_hxx
#define HLAInteractionClass_hxx
namespace simgear {
class RTIInteractionClass;
class HLAInteractionClass : public SGWeakReferenced {
public:
virtual ~HLAInteractionClass() {}
};
} // namespace simgear
#endif

549
simgear/hla/HLALocation.hxx Normal file
View File

@@ -0,0 +1,549 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLALocation_hxx
#define HLALocation_hxx
#include "HLABasicDataElement.hxx"
namespace simgear {
class HLAAbstractLocation : public SGReferenced {
public:
virtual ~HLAAbstractLocation() {}
virtual SGVec3d getCartPosition() const = 0;
virtual void setCartPosition(const SGVec3d&) = 0;
virtual SGQuatd getCartOrientation() const = 0;
virtual void setCartOrientation(const SGQuatd&) = 0;
virtual SGVec3d getAngularBodyVelocity() const = 0;
virtual void setAngularBodyVelocity(const SGVec3d& angular) = 0;
virtual SGVec3d getLinearBodyVelocity() const = 0;
virtual void setLinearBodyVelocity(const SGVec3d& linear) = 0;
};
class HLACartesianLocation : public HLAAbstractLocation {
public:
HLACartesianLocation() :
_position(SGVec3d::zeros()),
_imag(SGVec3d::zeros()),
_angularVelocity(SGVec3d::zeros()),
_linearVelocity(SGVec3d::zeros())
{ }
virtual SGVec3d getCartPosition() const
{ return _position; }
virtual void setCartPosition(const SGVec3d& position)
{ _position = position; }
virtual SGQuatd getCartOrientation() const
{ return SGQuatd::fromPositiveRealImag(_imag); }
virtual void setCartOrientation(const SGQuatd& orientation)
{ _imag = orientation.getPositiveRealImag(); }
virtual SGVec3d getAngularBodyVelocity() const
{ return _angularVelocity; }
virtual void setAngularBodyVelocity(const SGVec3d& angularVelocity)
{ _angularVelocity = angularVelocity; }
virtual SGVec3d getLinearBodyVelocity() const
{ return _linearVelocity; }
virtual void setLinearBodyVelocity(const SGVec3d& linearVelocity)
{ _linearVelocity = linearVelocity; }
HLADataElementProvider getPositionDataElement(unsigned i)
{
if (3 <= i)
return HLADataElementProvider();
return new PositionDataElement(this, i);
}
HLADataElementProvider getOrientationDataElement(unsigned i)
{
if (3 <= i)
return HLADataElementProvider();
return new OrientationDataElement(this, i);
}
HLADataElementProvider getAngularVelocityDataElement(unsigned i)
{
if (3 <= i)
return HLADataElementProvider();
return new AngularVelocityDataElement(this, i);
}
HLADataElementProvider getLinearVelocityDataElement(unsigned i)
{
if (3 <= i)
return HLADataElementProvider();
return new LinearVelocityDataElement(this, i);
}
private:
class PositionDataElement : public HLAAbstractDoubleDataElement {
public:
PositionDataElement(HLACartesianLocation* data, unsigned index) :
_data(data), _index(index)
{ }
virtual double getValue() const
{ return _data->_position[_index]; }
virtual void setValue(double value)
{ _data->_position[_index] = value; }
private:
SGSharedPtr<HLACartesianLocation> _data;
unsigned _index;
};
class OrientationDataElement : public HLAAbstractDoubleDataElement {
public:
OrientationDataElement(HLACartesianLocation* data, unsigned index) :
_data(data), _index(index)
{ }
virtual double getValue() const
{ return _data->_imag[_index]; }
virtual void setValue(double value)
{ _data->_imag[_index] = value; }
private:
SGSharedPtr<HLACartesianLocation> _data;
unsigned _index;
};
class AngularVelocityDataElement : public HLAAbstractDoubleDataElement {
public:
AngularVelocityDataElement(HLACartesianLocation* data, unsigned index) :
_data(data), _index(index)
{ }
virtual double getValue() const
{ return _data->_angularVelocity[_index]; }
virtual void setValue(double value)
{ _data->_angularVelocity[_index] = value; }
private:
SGSharedPtr<HLACartesianLocation> _data;
unsigned _index;
};
class LinearVelocityDataElement : public HLAAbstractDoubleDataElement {
public:
LinearVelocityDataElement(HLACartesianLocation* data, unsigned index) :
_data(data), _index(index)
{ }
virtual double getValue() const
{ return _data->_linearVelocity[_index]; }
virtual void setValue(double value)
{ _data->_linearVelocity[_index] = value; }
private:
SGSharedPtr<HLACartesianLocation> _data;
unsigned _index;
};
SGVec3d _position;
SGVec3d _imag;
SGVec3d _angularVelocity;
SGVec3d _linearVelocity;
};
class HLALocationFactory : public SGReferenced {
public:
virtual ~HLALocationFactory() {}
virtual HLAAbstractLocation* createLocation(HLAAttributePathElementMap&) const = 0;
};
class HLACartesianLocationFactory : public HLALocationFactory {
public:
virtual HLAAbstractLocation* createLocation(HLAAttributePathElementMap& attributePathElementMap) const
{
HLACartesianLocation* location = new HLACartesianLocation;
for (unsigned i = 0; i < 3; ++i) {
const HLADataElement::IndexPathPair& indexPathPair = _positonIndexPathPair[i];
attributePathElementMap[indexPathPair.first][indexPathPair.second] = location->getPositionDataElement(i);
}
for (unsigned i = 0; i < 3; ++i) {
const HLADataElement::IndexPathPair& indexPathPair = _orientationIndexPathPair[i];
attributePathElementMap[indexPathPair.first][indexPathPair.second] = location->getOrientationDataElement(i);
}
for (unsigned i = 0; i < 3; ++i) {
const HLADataElement::IndexPathPair& indexPathPair = _angularVelocityIndexPathPair[i];
attributePathElementMap[indexPathPair.first][indexPathPair.second] = location->getAngularVelocityDataElement(i);
}
for (unsigned i = 0; i < 3; ++i) {
const HLADataElement::IndexPathPair& indexPathPair = _linearVelocityIndexPathPair[i];
attributePathElementMap[indexPathPair.first][indexPathPair.second] = location->getLinearVelocityDataElement(i);
}
return location;
}
void setPositionIndexPathPair(unsigned index, const HLADataElement::IndexPathPair& indexPathPair)
{
if (3 <= index)
return;
_positonIndexPathPair[index] = indexPathPair;
}
void setOrientationIndexPathPair(unsigned index, const HLADataElement::IndexPathPair& indexPathPair)
{
if (3 <= index)
return;
_orientationIndexPathPair[index] = indexPathPair;
}
void setAngularVelocityIndexPathPair(unsigned index, const HLADataElement::IndexPathPair& indexPathPair)
{
if (3 <= index)
return;
_angularVelocityIndexPathPair[index] = indexPathPair;
}
void setLinearVelocityIndexPathPair(unsigned index, const HLADataElement::IndexPathPair& indexPathPair)
{
if (3 <= index)
return;
_linearVelocityIndexPathPair[index] = indexPathPair;
}
private:
HLADataElement::IndexPathPair _positonIndexPathPair[3];
HLADataElement::IndexPathPair _orientationIndexPathPair[3];
HLADataElement::IndexPathPair _angularVelocityIndexPathPair[3];
HLADataElement::IndexPathPair _linearVelocityIndexPathPair[3];
};
class HLAGeodeticLocation : public HLAAbstractLocation {
public:
HLAGeodeticLocation() :
_dirty(true),
_cartPosition(SGVec3d::zeros()),
_cartOrientation(SGQuatd::unit()),
_cartBodyVelocity(SGVec3d::zeros()),
_geodPosition(),
_geodEulerRad(SGVec3d::zeros()),
_groundTrackRad(0),
_groundSpeedMPerSec(0),
_verticalSpeedMPerSec(0)
{
updateCartesianFromGeodetic();
}
virtual SGVec3d getCartPosition() const
{ updateCartesianFromGeodetic(); return _cartPosition; }
virtual void setCartPosition(const SGVec3d& position)
{ _cartPosition = position; _dirty = true; }
virtual SGQuatd getCartOrientation() const
{ updateCartesianFromGeodetic(); return _cartOrientation; }
virtual void setCartOrientation(const SGQuatd& orientation)
{ _cartOrientation = orientation; _dirty = true; }
virtual SGVec3d getAngularBodyVelocity() const
{ return SGVec3d::zeros(); }
virtual void setAngularBodyVelocity(const SGVec3d& angular)
{ }
virtual SGVec3d getLinearBodyVelocity() const
{ updateCartesianFromGeodetic(); return _cartBodyVelocity; }
virtual void setLinearBodyVelocity(const SGVec3d& linear)
{ _cartBodyVelocity = linear; _dirty = true; }
void setLatitudeDeg(double value)
{ _geodPosition.setLatitudeDeg(value); _dirty = true; }
double getLatitudeDeg() const
{ updateGeodeticFromCartesian(); return _geodPosition.getLatitudeDeg(); }
void setLatitudeRad(double value)
{ _geodPosition.setLatitudeRad(value); _dirty = true; }
double getLatitudeRad() const
{ updateGeodeticFromCartesian(); return _geodPosition.getLatitudeRad(); }
void setLongitudeDeg(double value)
{ _geodPosition.setLongitudeDeg(value); _dirty = true; }
double getLongitudeDeg() const
{ updateGeodeticFromCartesian(); return _geodPosition.getLongitudeDeg(); }
void setLongitudeRad(double value)
{ _geodPosition.setLongitudeRad(value); _dirty = true; }
double getLongitudeRad() const
{ updateGeodeticFromCartesian(); return _geodPosition.getLongitudeRad(); }
void setElevationFt(double value)
{ _geodPosition.setElevationFt(value); _dirty = true; }
double getElevationFt() const
{ updateGeodeticFromCartesian(); return _geodPosition.getElevationFt(); }
void setElevationM(double value)
{ _geodPosition.setElevationM(value); _dirty = true; }
double getElevationM() const
{ updateGeodeticFromCartesian(); return _geodPosition.getElevationM(); }
void setHeadingRad(double value)
{ _geodEulerRad[2] = value; _dirty = true; }
double getHeadingRad() const
{ updateGeodeticFromCartesian(); return _geodEulerRad[2]; }
void setHeadingDeg(double value)
{ setHeadingRad(SGMiscd::deg2rad(value)); }
double getHeadingDeg() const
{ return SGMiscd::rad2deg(getHeadingRad()); }
void setPitchRad(double value)
{ _geodEulerRad[1] = value; _dirty = true; }
double getPitchRad() const
{ updateGeodeticFromCartesian(); return _geodEulerRad[1]; }
void setPitchDeg(double value)
{ setPitchRad(SGMiscd::deg2rad(value)); }
double getPitchDeg() const
{ return SGMiscd::rad2deg(getPitchRad()); }
void setRollRad(double value)
{ _geodEulerRad[0] = value; _dirty = true; }
double getRollRad() const
{ updateGeodeticFromCartesian(); return _geodEulerRad[0]; }
void setRollDeg(double value)
{ setRollRad(SGMiscd::deg2rad(value)); }
double getRollDeg() const
{ return SGMiscd::rad2deg(getRollRad()); }
void setGroundTrackRad(double value)
{ _groundTrackRad = value; _dirty = true; }
double getGroundTrackRad() const
{ updateGeodeticFromCartesian(); return _groundTrackRad; }
void setGroundTrackDeg(double value)
{ setGroundTrackRad(SGMiscd::deg2rad(value)); }
double getGroundTrackDeg() const
{ return SGMiscd::rad2deg(getGroundTrackRad()); }
void setGroundSpeedMPerSec(double value)
{ _groundSpeedMPerSec = value; _dirty = true; }
double getGroundSpeedMPerSec() const
{ updateGeodeticFromCartesian(); return _groundSpeedMPerSec; }
void setGroundSpeedFtPerSec(double value)
{ setGroundSpeedMPerSec(SG_FEET_TO_METER*value); }
double getGroundSpeedFtPerSec() const
{ return SG_METER_TO_FEET*getGroundSpeedMPerSec(); }
void setGroundSpeedKnots(double value)
{ setGroundSpeedMPerSec(SG_KT_TO_MPS*value); }
double getGroundSpeedKnots() const
{ return SG_MPS_TO_KT*getGroundSpeedMPerSec(); }
void setVerticalSpeedMPerSec(double value)
{ _verticalSpeedMPerSec = value; _dirty = true; }
double getVerticalSpeedMPerSec() const
{ updateGeodeticFromCartesian(); return _verticalSpeedMPerSec; }
void setVerticalSpeedFtPerSec(double value)
{ setVerticalSpeedMPerSec(SG_FEET_TO_METER*value); }
double getVerticalSpeedFtPerSec() const
{ return SG_METER_TO_FEET*getVerticalSpeedMPerSec(); }
void setVerticalSpeedFtPerMin(double value)
{ setVerticalSpeedFtPerSec(value/60); }
double getVerticalSpeedFtPerMin() const
{ return 60*getVerticalSpeedFtPerSec(); }
#define DATA_ELEMENT(name) \
HLADataElementProvider get## name ## DataElement() \
{ return new DataElement<&HLAGeodeticLocation::get## name, &HLAGeodeticLocation::set ## name>(this); }
DATA_ELEMENT(LatitudeDeg)
DATA_ELEMENT(LatitudeRad)
DATA_ELEMENT(LongitudeDeg)
DATA_ELEMENT(LongitudeRad)
DATA_ELEMENT(ElevationFt)
DATA_ELEMENT(ElevationM)
DATA_ELEMENT(HeadingDeg)
DATA_ELEMENT(HeadingRad)
DATA_ELEMENT(PitchDeg)
DATA_ELEMENT(PitchRad)
DATA_ELEMENT(RollDeg)
DATA_ELEMENT(RollRad)
DATA_ELEMENT(GroundTrackDeg)
DATA_ELEMENT(GroundTrackRad)
DATA_ELEMENT(GroundSpeedMPerSec)
DATA_ELEMENT(GroundSpeedFtPerSec)
DATA_ELEMENT(GroundSpeedKnots)
DATA_ELEMENT(VerticalSpeedMPerSec)
DATA_ELEMENT(VerticalSpeedFtPerSec)
DATA_ELEMENT(VerticalSpeedFtPerMin)
#undef DATA_ELEMENT
private:
template<double (HLAGeodeticLocation::*getter)() const,
void (HLAGeodeticLocation::*setter)(double)>
class DataElement : public HLAAbstractDoubleDataElement {
public:
DataElement(HLAGeodeticLocation* data) :
_data(data)
{ }
virtual double getValue() const
{ return (_data->*getter)(); }
virtual void setValue(double value)
{ (_data->*setter)(value); }
private:
SGSharedPtr<HLAGeodeticLocation> _data;
};
void updateGeodeticFromCartesian() const
{
if (!_dirty)
return;
_geodPosition = SGGeod::fromCart(_cartPosition);
SGQuatd geodOrientation = inverse(SGQuatd::fromLonLat(_geodPosition))*_cartOrientation;
geodOrientation.getEulerRad(_geodEulerRad[2], _geodEulerRad[1], _geodEulerRad[0]);
SGVec3d nedVel = geodOrientation.backTransform(_cartBodyVelocity);
if (SGLimitsd::min() < SGMiscd::max(fabs(nedVel[0]), fabs(nedVel[1])))
_groundTrackRad = atan2(nedVel[1], nedVel[0]);
else
_groundTrackRad = 0;
_groundSpeedMPerSec = sqrt(nedVel[0]*nedVel[0] + nedVel[1]*nedVel[1]);
_verticalSpeedMPerSec = -nedVel[2];
_dirty = false;
}
void updateCartesianFromGeodetic() const
{
if (!_dirty)
return;
_cartPosition = SGVec3d::fromGeod(_geodPosition);
SGQuatd geodOrientation = SGQuatd::fromEulerRad(_geodEulerRad[2], _geodEulerRad[1], _geodEulerRad[0]);
_cartOrientation = SGQuatd::fromLonLat(_geodPosition)*geodOrientation;
SGVec3d nedVel(cos(_groundTrackRad)*_groundSpeedMPerSec,
sin(_groundTrackRad)*_groundSpeedMPerSec,
-_verticalSpeedMPerSec);
_cartBodyVelocity = geodOrientation.transform(nedVel);
_dirty = false;
}
mutable bool _dirty;
// the cartesian values
mutable SGVec3d _cartPosition;
mutable SGQuatd _cartOrientation;
mutable SGVec3d _cartBodyVelocity;
// The geodetic values
mutable SGGeod _geodPosition;
mutable SGVec3d _geodEulerRad;
mutable double _groundTrackRad;
mutable double _groundSpeedMPerSec;
mutable double _verticalSpeedMPerSec;
};
class HLAGeodeticLocationFactory : public HLALocationFactory {
public:
enum Semantic {
LatitudeDeg,
LatitudeRad,
LongitudeDeg,
LongitudeRad,
ElevationM,
ElevationFt,
HeadingDeg,
HeadingRad,
PitchDeg,
PitchRad,
RollDeg,
RollRad,
GroundTrackDeg,
GroundTrackRad,
GroundSpeedKnots,
GroundSpeedFtPerSec,
GroundSpeedMPerSec,
VerticalSpeedFtPerSec,
VerticalSpeedFtPerMin,
VerticalSpeedMPerSec
};
virtual HLAGeodeticLocation* createLocation(HLAAttributePathElementMap& attributePathElementMap) const
{
HLAGeodeticLocation* location = new HLAGeodeticLocation;
for (IndexPathPairSemanticMap::const_iterator i = _indexPathPairSemanticMap.begin();
i != _indexPathPairSemanticMap.end(); ++i) {
switch (i->second) {
case LatitudeDeg:
attributePathElementMap[i->first.first][i->first.second] = location->getLatitudeDegDataElement();
break;
case LatitudeRad:
attributePathElementMap[i->first.first][i->first.second] = location->getLatitudeRadDataElement();
break;
case LongitudeDeg:
attributePathElementMap[i->first.first][i->first.second] = location->getLongitudeDegDataElement();
break;
case LongitudeRad:
attributePathElementMap[i->first.first][i->first.second] = location->getLongitudeRadDataElement();
break;
case ElevationM:
attributePathElementMap[i->first.first][i->first.second] = location->getElevationMDataElement();
break;
case ElevationFt:
attributePathElementMap[i->first.first][i->first.second] = location->getElevationFtDataElement();
break;
case HeadingDeg:
attributePathElementMap[i->first.first][i->first.second] = location->getHeadingDegDataElement();
break;
case HeadingRad:
attributePathElementMap[i->first.first][i->first.second] = location->getHeadingRadDataElement();
break;
case PitchDeg:
attributePathElementMap[i->first.first][i->first.second] = location->getPitchDegDataElement();
break;
case PitchRad:
attributePathElementMap[i->first.first][i->first.second] = location->getPitchRadDataElement();
break;
case RollDeg:
attributePathElementMap[i->first.first][i->first.second] = location->getRollDegDataElement();
break;
case RollRad:
attributePathElementMap[i->first.first][i->first.second] = location->getRollRadDataElement();
break;
case GroundTrackDeg:
attributePathElementMap[i->first.first][i->first.second] = location->getGroundTrackDegDataElement();
break;
case GroundTrackRad:
attributePathElementMap[i->first.first][i->first.second] = location->getGroundTrackRadDataElement();
break;
case GroundSpeedKnots:
attributePathElementMap[i->first.first][i->first.second] = location->getGroundSpeedKnotsDataElement();
break;
case GroundSpeedFtPerSec:
attributePathElementMap[i->first.first][i->first.second] = location->getGroundSpeedFtPerSecDataElement();
break;
case GroundSpeedMPerSec:
attributePathElementMap[i->first.first][i->first.second] = location->getGroundSpeedMPerSecDataElement();
break;
case VerticalSpeedFtPerSec:
attributePathElementMap[i->first.first][i->first.second] = location->getVerticalSpeedFtPerSecDataElement();
break;
case VerticalSpeedFtPerMin:
attributePathElementMap[i->first.first][i->first.second] = location->getVerticalSpeedFtPerMinDataElement();
break;
case VerticalSpeedMPerSec:
attributePathElementMap[i->first.first][i->first.second] = location->getVerticalSpeedMPerSecDataElement();
break;
}
}
return location;
}
void setIndexPathPair(Semantic semantic, const HLADataElement::IndexPathPair& indexPathPair)
{ _indexPathPairSemanticMap[indexPathPair] = semantic; }
private:
typedef std::map<HLADataElement::IndexPathPair, Semantic> IndexPathPairSemanticMap;
IndexPathPairSemanticMap _indexPathPairSemanticMap;
};
} // namespace simgear
#endif

View File

@@ -0,0 +1,865 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAOMTXmlVisitor.hxx"
#include <map>
#include <string>
#include <sstream>
#include <simgear/structure/exception.hxx>
#include <simgear/xml/easyxml.hxx>
#include "HLAArrayDataType.hxx"
#include "HLABasicDataType.hxx"
#include "HLADataTypeVisitor.hxx"
#include "HLAEnumeratedDataType.hxx"
#include "HLAFixedRecordDataType.hxx"
#include "HLAVariantDataType.hxx"
namespace simgear {
HLAOMTXmlVisitor::ObjectClass::ObjectClass(const std::string& name, const std::string& sharing) :
_name(name),
_sharing(sharing)
{
}
HLAOMTXmlVisitor::ObjectClass::~ObjectClass()
{
}
const std::string&
HLAOMTXmlVisitor::ObjectClass::getName() const
{
return _name;
}
const std::string&
HLAOMTXmlVisitor::ObjectClass::getSharing() const
{
return _sharing;
}
unsigned
HLAOMTXmlVisitor::ObjectClass::getNumAttributes() const
{
return _attributes.size();
}
const HLAOMTXmlVisitor::Attribute*
HLAOMTXmlVisitor::ObjectClass::getAttribute(unsigned index) const
{
if (_attributes.size() <= index)
return 0;
return _attributes[index];
}
const HLAOMTXmlVisitor::Attribute*
HLAOMTXmlVisitor::ObjectClass::getAttribute(const std::string& name) const
{
for (AttributeList::const_iterator i = _attributes.begin(); i != _attributes.end(); ++i) {
if ((*i)->_name != name)
continue;
return i->get();
}
SG_LOG(SG_IO, SG_ALERT, "Could not find class attribute \"" << name << "\".");
return 0;
}
const HLAOMTXmlVisitor::ObjectClass*
HLAOMTXmlVisitor::ObjectClass::getParentObjectClass() const
{
return _parentObjectClass.get();
}
HLAOMTXmlVisitor::InteractionClass::InteractionClass(const std::string& name) :
_name(name)
{
}
HLAOMTXmlVisitor::InteractionClass::~InteractionClass()
{
}
const std::string&
HLAOMTXmlVisitor::InteractionClass::getName() const
{
return _name;
}
const std::string&
HLAOMTXmlVisitor::InteractionClass::getDimensions() const
{
return _dimensions;
}
const std::string&
HLAOMTXmlVisitor::InteractionClass::getTransportation() const
{
return _transportation;
}
const std::string&
HLAOMTXmlVisitor::InteractionClass::getOrder() const
{
return _order;
}
unsigned
HLAOMTXmlVisitor::InteractionClass::getNumParameters() const
{
return _parameters.size();
}
const HLAOMTXmlVisitor::Parameter*
HLAOMTXmlVisitor::InteractionClass::getParameter(unsigned index) const
{
if (_parameters.size() <= index)
return 0;
return _parameters[index];
}
const HLAOMTXmlVisitor::Parameter*
HLAOMTXmlVisitor::InteractionClass::getParameter(const std::string& name) const
{
for (ParameterList::const_iterator i = _parameters.begin(); i != _parameters.end(); ++i) {
if ((*i)->_name != name)
continue;
return i->get();
}
SG_LOG(SG_IO, SG_ALERT, "Could not find parameter \"" << name << "\".");
return 0;
}
const HLAOMTXmlVisitor::InteractionClass*
HLAOMTXmlVisitor::InteractionClass::getParentInteractionClass() const
{
return _parentInteractionClass.get();
}
HLAOMTXmlVisitor::HLAOMTXmlVisitor()
{
}
HLAOMTXmlVisitor::~HLAOMTXmlVisitor()
{
}
unsigned
HLAOMTXmlVisitor::getNumObjectClasses() const
{
return _objectClassList.size();
}
const HLAOMTXmlVisitor::ObjectClass*
HLAOMTXmlVisitor::getObjectClass(unsigned i) const
{
if (_objectClassList.size() <= i)
return 0;
return _objectClassList[i];
}
const HLAOMTXmlVisitor::ObjectClass*
HLAOMTXmlVisitor::getObjectClass(const std::string& name) const
{
for (ObjectClassList::const_iterator i = _objectClassList.begin(); i != _objectClassList.end(); ++i) {
if ((*i)->_name != name)
continue;
return i->get();
}
SG_LOG(SG_IO, SG_ALERT, "Could not resolve ObjectClass \"" << name << "\".");
return 0;
}
const HLAOMTXmlVisitor::Attribute*
HLAOMTXmlVisitor::getAttribute(const std::string& objectClassName, const std::string& attributeName) const
{
const ObjectClass* objectClass = getObjectClass(objectClassName);
if (!objectClass)
return 0;
return objectClass->getAttribute(attributeName);
}
HLADataType*
HLAOMTXmlVisitor::getAttributeDataType(const std::string& objectClassName, const std::string& attributeName) const
{
const Attribute* attribute = getAttribute(objectClassName, attributeName);
if (!attribute)
return 0;
return getDataType(attribute->_dataType);
}
unsigned
HLAOMTXmlVisitor::getNumInteractionClasses() const
{
return _interactionClassList.size();
}
const HLAOMTXmlVisitor::InteractionClass*
HLAOMTXmlVisitor::getInteractionClass(unsigned i) const
{
if (_interactionClassList.size() <= i)
return 0;
return _interactionClassList[i];
}
const HLAOMTXmlVisitor::InteractionClass*
HLAOMTXmlVisitor::getInteractionClass(const std::string& name) const
{
for (InteractionClassList::const_iterator i = _interactionClassList.begin(); i != _interactionClassList.end(); ++i) {
if ((*i)->_name != name)
continue;
return i->get();
}
SG_LOG(SG_IO, SG_ALERT, "Could not resolve InteractionClass \"" << name << "\".");
return 0;
}
const HLAOMTXmlVisitor::Parameter*
HLAOMTXmlVisitor::getParameter(const std::string& interactionClassName, const std::string& parameterName) const
{
const InteractionClass* interactionClass = getInteractionClass(interactionClassName);
if (!interactionClass)
return 0;
return interactionClass->getParameter(parameterName);
}
HLADataType*
HLAOMTXmlVisitor::getParameterDataType(const std::string& interactionClassName, const std::string& parameterName) const
{
const Parameter* parameter = getParameter(interactionClassName, parameterName);
if (!parameter)
return 0;
return getDataType(parameter->_dataType);
}
HLADataType*
HLAOMTXmlVisitor::getDataType(const std::string& dataTypeName) const
{
SGSharedPtr<HLADataType> dataType;
{
// Playing dirty things with reference counts
StringDataTypeMap dataTypeMap;
dataType = getDataType(dataTypeName, dataTypeMap);
}
return dataType.release();
}
SGSharedPtr<HLADataType>
HLAOMTXmlVisitor::getDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
{
StringDataTypeMap::const_iterator i = dataTypeMap.find(dataTypeName);
if (i != dataTypeMap.end())
return new HLADataTypeReference(i->second);
SGSharedPtr<HLADataType> dataType;
dataType = getBasicDataType(dataTypeName);
if (dataType.valid())
return dataType;
dataType = getSimpleDataType(dataTypeName);
if (dataType.valid())
return dataType;
dataType = getEnumeratedDataType(dataTypeName);
if (dataType.valid())
return dataType;
dataType = getArrayDataType(dataTypeName, dataTypeMap);
if (dataType.valid())
return dataType;
dataType = getFixedRecordDataType(dataTypeName, dataTypeMap);
if (dataType.valid())
return dataType;
dataType = getVariantDataType(dataTypeName, dataTypeMap);
if (dataType.valid())
return dataType;
SG_LOG(SG_IO, SG_WARN, "Could not resolve dataType \"" << dataTypeName << "\".");
return 0;
}
SGSharedPtr<HLABasicDataType>
HLAOMTXmlVisitor::getBasicDataType(const std::string& dataTypeName) const
{
BasicDataMap::const_iterator i = _basicDataMap.find(dataTypeName);
if (i == _basicDataMap.end())
return 0;
if (i->second._size == "8") {
return new HLAUInt8DataType(dataTypeName);
} else if (i->second._size == "16") {
if (i->first.find("Unsigned") != std::string::npos) {
if (i->second._endian == "Little") {
return new HLAUInt16LEDataType(dataTypeName);
} else {
return new HLAUInt16BEDataType(dataTypeName);
}
} else if (i->first.find("octetPair") != std::string::npos) {
if (i->second._endian == "Little") {
return new HLAUInt16LEDataType(dataTypeName);
} else {
return new HLAUInt16BEDataType(dataTypeName);
}
} else {
if (i->second._endian == "Little") {
return new HLAInt16LEDataType(dataTypeName);
} else {
return new HLAInt16BEDataType(dataTypeName);
}
}
} else if (i->second._size == "32") {
if (i->first.find("Unsigned") != std::string::npos) {
if (i->second._endian == "Little") {
return new HLAUInt32LEDataType(dataTypeName);
} else {
return new HLAUInt32BEDataType(dataTypeName);
}
} else if (i->first.find("float") != std::string::npos) {
if (i->second._endian == "Little") {
return new HLAFloat32LEDataType(dataTypeName);
} else {
return new HLAFloat32BEDataType(dataTypeName);
}
} else {
if (i->second._endian == "Little") {
return new HLAInt32LEDataType(dataTypeName);
} else {
return new HLAInt32BEDataType(dataTypeName);
}
}
} else if (i->second._size == "64") {
if (i->first.find("Unsigned") != std::string::npos) {
if (i->second._endian == "Little") {
return new HLAUInt64LEDataType(dataTypeName);
} else {
return new HLAUInt64BEDataType(dataTypeName);
}
} else if (i->first.find("float") != std::string::npos) {
if (i->second._endian == "Little") {
return new HLAFloat64LEDataType(dataTypeName);
} else {
return new HLAFloat64BEDataType(dataTypeName);
}
} else {
if (i->second._endian == "Little") {
return new HLAInt64LEDataType(dataTypeName);
} else {
return new HLAInt64BEDataType(dataTypeName);
}
}
}
return 0;
}
SGSharedPtr<HLADataType>
HLAOMTXmlVisitor::getSimpleDataType(const std::string& dataTypeName) const
{
SimpleDataMap::const_iterator i = _simpleDataMap.find(dataTypeName);
if (i == _simpleDataMap.end())
return 0;
return getDataType(i->second._representation);
}
SGSharedPtr<HLAEnumeratedDataType>
HLAOMTXmlVisitor::getEnumeratedDataType(const std::string& dataTypeName) const
{
EnumeratedDataMap::const_iterator i = _enumeratedDataMap.find(dataTypeName);
if (i == _enumeratedDataMap.end())
return 0;
SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = new HLAEnumeratedDataType(dataTypeName);
enumeratedDataType->setRepresentation(getBasicDataType(i->second._representation));
for (EnumeratorList::const_iterator j = i->second._enumeratorList.begin();
j != i->second._enumeratorList.end(); ++j) {
if (!enumeratedDataType->addEnumerator(j->_name, j->_values)) {
SG_LOG(SG_IO, SG_ALERT, "Could not add enumerator \"" << j->_name
<< "\" to find enumerated data type \"" << dataTypeName << "\".");
return 0;
}
}
return enumeratedDataType;
}
SGSharedPtr<HLADataType>
HLAOMTXmlVisitor::getArrayDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
{
ArrayDataMap::const_iterator i = _arrayDataMap.find(dataTypeName);
if (i == _arrayDataMap.end())
return 0;
SGSharedPtr<HLAArrayDataType> arrayDataType;
if (i->second._encoding == "HLAvariableArray") {
arrayDataType = new HLAVariableArrayDataType(dataTypeName);
} else if (i->second._encoding == "HLAfixedArray") {
std::stringstream ss(i->second._cardinality);
unsigned cardinality;
ss >> cardinality;
if (ss.fail()) {
SG_LOG(SG_IO, SG_ALERT, "Could not interpret cardinality \""
<< i->second._cardinality << "\" for dataType \""
<< dataTypeName << "\".");
return 0;
}
SGSharedPtr<HLAFixedArrayDataType> dataType = new HLAFixedArrayDataType(dataTypeName);
dataType->setNumElements(cardinality);
arrayDataType = dataType;
} else {
SG_LOG(SG_IO, SG_ALERT, "Can not interpret encoding \""
<< i->second._encoding << "\" for dataType \""
<< dataTypeName << "\".");
return 0;
}
dataTypeMap[dataTypeName] = arrayDataType;
SGSharedPtr<HLADataType> elementDataType = getDataType(i->second._dataType, dataTypeMap);
if (!elementDataType.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not interpret dataType \""
<< i->second._dataType << "\" for array data type \""
<< dataTypeName << "\".");
dataTypeMap.erase(dataTypeName);
return 0;
}
arrayDataType->setElementDataType(elementDataType.get());
return arrayDataType;
}
SGSharedPtr<HLAFixedRecordDataType>
HLAOMTXmlVisitor::getFixedRecordDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
{
FixedRecordDataMap::const_iterator i = _fixedRecordDataMap.find(dataTypeName);
if (i == _fixedRecordDataMap.end())
return 0;
SGSharedPtr<HLAFixedRecordDataType> dataType = new HLAFixedRecordDataType(dataTypeName);
dataTypeMap[dataTypeName] = dataType;
for (FieldList::size_type j = 0; j < i->second._fieldList.size(); ++j) {
SGSharedPtr<HLADataType> fieldDataType = getDataType(i->second._fieldList[j]._dataType, dataTypeMap);
if (!fieldDataType.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not get data type \"" << i->second._fieldList[j]._dataType
<< "\" for field " << j << "of fixed record data type \"" << dataTypeName << "\".");
dataTypeMap.erase(dataTypeName);
return 0;
}
dataType->addField(i->second._fieldList[j]._name, fieldDataType.get());
}
return dataType;
}
SGSharedPtr<HLAVariantDataType>
HLAOMTXmlVisitor::getVariantDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
{
VariantRecordDataMap::const_iterator i = _variantRecordDataMap.find(dataTypeName);
if (i == _variantRecordDataMap.end())
return 0;
SGSharedPtr<HLAVariantDataType> dataType = new HLAVariantDataType(dataTypeName);
dataTypeMap[dataTypeName] = dataType;
SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = getEnumeratedDataType(i->second._dataType);
if (!enumeratedDataType.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not find enumerted data type \"" << i->second._dataType
<< "\" for variant data type \"" << dataTypeName << "\".");
return 0;
}
dataType->setEnumeratedDataType(enumeratedDataType);
for (AlternativeList::const_iterator j = i->second._alternativeList.begin();
j != i->second._alternativeList.end(); ++j) {
SGSharedPtr<HLADataType> alternativeDataType = getDataType(j->_dataType, dataTypeMap);
if (!alternativeDataType.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not resolve alternative dataType \"" << j->_dataType
<< "\" for alternative \"" << j->_name << "\".");
dataTypeMap.erase(dataTypeName);
return 0;
}
if (!dataType->addAlternative(j->_name, j->_enumerator, alternativeDataType.get(), j->_semantics)) {
SG_LOG(SG_IO, SG_ALERT, "Could not add alternative \"" << j->_name << "\".");
return 0;
}
}
return dataType;
}
HLAOMTXmlVisitor::Mode
HLAOMTXmlVisitor::getCurrentMode()
{
if (_modeStack.empty())
return UnknownMode;
return _modeStack.back();
}
void
HLAOMTXmlVisitor::pushMode(HLAOMTXmlVisitor::Mode mode)
{
_modeStack.push_back(mode);
}
void
HLAOMTXmlVisitor::popMode()
{
_modeStack.pop_back();
}
void
HLAOMTXmlVisitor::startXML()
{
_modeStack.clear();
}
void
HLAOMTXmlVisitor::endXML()
{
if (!_modeStack.empty())
throw sg_exception("Internal parse error!");
// propagate parent attributes to the derived classes
for (ObjectClassList::const_iterator i = _objectClassList.begin(); i != _objectClassList.end(); ++i) {
SGSharedPtr<const ObjectClass> objectClass = (*i)->_parentObjectClass;
while (objectClass) {
for (AttributeList::const_reverse_iterator j = objectClass->_attributes.rbegin();
j != objectClass->_attributes.rend(); ++j) {
(*i)->_attributes.insert((*i)->_attributes.begin(), *j);
}
objectClass = objectClass->_parentObjectClass;
}
}
// propagate parent parameter to the derived interactions
for (InteractionClassList::const_iterator i = _interactionClassList.begin(); i != _interactionClassList.end(); ++i) {
SGSharedPtr<const InteractionClass> interactionClass = (*i)->_parentInteractionClass;
while (interactionClass) {
for (ParameterList::const_reverse_iterator j = interactionClass->_parameters.rbegin();
j != interactionClass->_parameters.rend(); ++j) {
(*i)->_parameters.insert((*i)->_parameters.begin(), *j);
}
interactionClass = interactionClass->_parentInteractionClass;
}
}
}
void
HLAOMTXmlVisitor::startElement(const char* name, const XMLAttributes& atts)
{
if (strcmp(name, "attribute") == 0) {
if (getCurrentMode() != ObjectClassMode)
throw sg_exception("attribute tag outside objectClass!");
pushMode(AttributeMode);
if (_objectClassList.empty())
throw sg_exception("attribute tag outside of an objectClass");
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("attribute tag without name attribute");
SGSharedPtr<Attribute> attribute = new Attribute(name);
attribute->_dataType = getAttribute("dataType", atts);
attribute->_updateType = getAttribute("updateType", atts);
attribute->_updateCondition = getAttribute("updateCondition", atts);
attribute->_ownership = getAttribute("ownership", atts);
attribute->_sharing = getAttribute("sharing", atts);
attribute->_dimensions = getAttribute("dimensions", atts);
attribute->_transportation = getAttribute("transportation", atts);
attribute->_order = getAttribute("order", atts);
_objectClassStack.back()->_attributes.push_back(attribute);
} else if (strcmp(name, "objectClass") == 0) {
if (getCurrentMode() != ObjectsMode && getCurrentMode() != ObjectClassMode)
throw sg_exception("objectClass tag outside objectClass or objects!");
pushMode(ObjectClassMode);
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("objectClass tag without name attribute");
std::string sharing = getAttribute("sharing", atts);
// The new ObjectClass
ObjectClass* objectClass = new ObjectClass(name, sharing);
// Inherit all previous attributes
if (!_objectClassStack.empty())
objectClass->_parentObjectClass = _objectClassStack.back();
_objectClassStack.push_back(objectClass);
_objectClassList.push_back(objectClass);
} else if (strcmp(name, "objects") == 0) {
if (getCurrentMode() != ObjectModelMode)
throw sg_exception("objects tag outside objectModel!");
pushMode(ObjectsMode);
} else if (strcmp(name, "parameter") == 0) {
if (getCurrentMode() != InteractionClassMode)
throw sg_exception("parameter tag outside interactionClass!");
pushMode(ParameterMode);
if (_interactionClassList.empty())
throw sg_exception("parameter tag outside of an interactionClass");
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("parameter tag without name parameter");
SGSharedPtr<Parameter> parameter = new Parameter(name);
parameter->_dataType = getAttribute("dataType", atts);
_interactionClassStack.back()->_parameters.push_back(parameter);
} else if (strcmp(name, "interactionClass") == 0) {
if (getCurrentMode() != InteractionsMode && getCurrentMode() != InteractionClassMode)
throw sg_exception("interactionClass tag outside interactions or interactionClass!");
pushMode(InteractionClassMode);
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("interactionClass tag without name attribute");
// The new ObjectClass
InteractionClass* interactionClass = new InteractionClass(name);
interactionClass->_dimensions = getAttribute("dimensions", atts);
interactionClass->_transportation = getAttribute("transportation", atts);
interactionClass->_order = getAttribute("order", atts);
// Inherit all previous attributes
if (!_interactionClassStack.empty())
interactionClass->_parentInteractionClass = _interactionClassStack.back();
_interactionClassStack.push_back(interactionClass);
_interactionClassList.push_back(interactionClass);
} else if (strcmp(name, "interactions") == 0) {
if (getCurrentMode() != ObjectModelMode)
throw sg_exception("interactions tag outside objectModel!");
pushMode(InteractionsMode);
} else if (strcmp(name, "basicData") == 0) {
if (getCurrentMode() != BasicDataRepresentationsMode)
throw sg_exception("basicData tag outside basicDataRepresentations!");
pushMode(BasicDataMode);
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("basicData tag without name attribute");
_basicDataMap[name]._size = getAttribute("size", atts);
_basicDataMap[name]._endian = getAttribute("endian", atts);
} else if (strcmp(name, "basicDataRepresentations") == 0) {
if (getCurrentMode() != DataTypesMode)
throw sg_exception("basicDataRepresentations tag outside dataTypes!");
pushMode(BasicDataRepresentationsMode);
} else if (strcmp(name, "simpleData") == 0) {
if (getCurrentMode() != SimpleDataTypesMode)
throw sg_exception("simpleData tag outside simpleDataTypes!");
pushMode(SimpleDataMode);
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("simpleData tag without name attribute");
_simpleDataMap[name]._representation = getAttribute("representation", atts);
_simpleDataMap[name]._units = getAttribute("units", atts);
_simpleDataMap[name]._resolution = getAttribute("resolution", atts);
_simpleDataMap[name]._accuracy = getAttribute("accuracy", atts);
} else if (strcmp(name, "simpleDataTypes") == 0) {
if (getCurrentMode() != DataTypesMode)
throw sg_exception("simpleDataTypes tag outside dataTypes!");
pushMode(SimpleDataTypesMode);
} else if (strcmp(name, "enumerator") == 0) {
if (getCurrentMode() != EnumeratedDataMode)
throw sg_exception("enumerator tag outside enumeratedData!");
pushMode(EnumeratorMode);
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("enumerator tag without name attribute");
Enumerator enumerator;
enumerator._name = name;
enumerator._values = getAttribute("values", atts);
_enumeratedDataMap[_enumeratedDataName]._enumeratorList.push_back(enumerator);
} else if (strcmp(name, "enumeratedData") == 0) {
if (getCurrentMode() != EnumeratedDataTypesMode)
throw sg_exception("enumeratedData tag outside enumeratedDataTypes!");
pushMode(EnumeratedDataMode);
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("enumeratedData tag without name attribute");
_enumeratedDataName = name;
_enumeratedDataMap[_enumeratedDataName]._representation = getAttribute("representation", atts);
} else if (strcmp(name, "enumeratedDataTypes") == 0) {
if (getCurrentMode() != DataTypesMode)
throw sg_exception("enumeratedDataTypes tag outside dataTypes!");
pushMode(EnumeratedDataTypesMode);
Enumerator enumerator;
enumerator._name = getAttribute("name", atts);
enumerator._values = getAttribute("values", atts);
_enumeratedDataMap[_enumeratedDataName]._enumeratorList.push_back(enumerator);
} else if (strcmp(name, "arrayData") == 0) {
if (getCurrentMode() != ArrayDataTypesMode)
throw sg_exception("arrayData tag outside arrayDataTypes!");
pushMode(ArrayDataMode);
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("arrayData tag without name attribute");
_arrayDataMap[name]._dataType = getAttribute("dataType", atts);
_arrayDataMap[name]._cardinality = getAttribute("cardinality", atts);
_arrayDataMap[name]._encoding = getAttribute("encoding", atts);
} else if (strcmp(name, "arrayDataTypes") == 0) {
if (getCurrentMode() != DataTypesMode)
throw sg_exception("arrayDataTypes tag outside dataTypes!");
pushMode(ArrayDataTypesMode);
} else if (strcmp(name, "field") == 0) {
if (getCurrentMode() != FixedRecordDataMode)
throw sg_exception("field tag outside fixedRecordData!");
pushMode(FieldMode);
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("field tag without name attribute");
Field field;
field._name = name;
field._dataType = getAttribute("dataType", atts);
_fixedRecordDataMap[_fixedRecordDataName]._fieldList.push_back(field);
} else if (strcmp(name, "fixedRecordData") == 0) {
if (getCurrentMode() != FixedRecordDataTypesMode)
throw sg_exception("fixedRecordData tag outside fixedRecordDataTypes!");
pushMode(FixedRecordDataMode);
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("fixedRecordData tag without name attribute");
_fixedRecordDataName = name;
_fixedRecordDataMap[name]._encoding = getAttribute("encoding", atts);
} else if (strcmp(name, "fixedRecordDataTypes") == 0) {
if (getCurrentMode() != DataTypesMode)
throw sg_exception("fixedRecordDataTypes tag outside dataTypes!");
pushMode(FixedRecordDataTypesMode);
} else if (strcmp(name, "alternative") == 0) {
if (getCurrentMode() != VariantRecordDataMode)
throw sg_exception("alternative tag outside variantRecordData!");
pushMode(AlternativeDataMode);
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("alternative tag without name attribute");
Alternative alternative;
alternative._name = name;
alternative._dataType = getAttribute("dataType", atts);
alternative._semantics = getAttribute("semantics", atts);
alternative._enumerator = getAttribute("enumerator", atts);
_variantRecordDataMap[_variantRecordDataName]._alternativeList.push_back(alternative);
} else if (strcmp(name, "variantRecordData") == 0) {
if (getCurrentMode() != VariantRecordDataTypesMode)
throw sg_exception("variantRecordData tag outside variantRecordDataTypes!");
pushMode(VariantRecordDataMode);
std::string name = getAttribute("name", atts);
if (name.empty())
throw sg_exception("fixedRecordData tag without name attribute");
_variantRecordDataName = name;
_variantRecordDataMap[name]._encoding = getAttribute("encoding", atts);
_variantRecordDataMap[name]._dataType = getAttribute("dataType", atts);
_variantRecordDataMap[name]._semantics = getAttribute("semantics", atts);
_variantRecordDataMap[name]._discriminant = getAttribute("discriminant", atts);
} else if (strcmp(name, "variantRecordDataTypes") == 0) {
if (getCurrentMode() != DataTypesMode)
throw sg_exception("variantRecordDataTypes tag outside dataTypes!");
pushMode(VariantRecordDataTypesMode);
} else if (strcmp(name, "dataTypes") == 0) {
if (getCurrentMode() != ObjectModelMode)
throw sg_exception("dataTypes tag outside objectModel!");
pushMode(DataTypesMode);
} else if (strcmp(name, "objectModel") == 0) {
if (!_modeStack.empty())
throw sg_exception("objectModel tag not at top level!");
pushMode(ObjectModelMode);
} else {
_modeStack.push_back(UnknownMode);
}
}
void
HLAOMTXmlVisitor::endElement(const char* name)
{
if (strcmp(name, "objectClass") == 0) {
_objectClassStack.pop_back();
} else if (strcmp(name, "interactionClass") == 0) {
_interactionClassStack.pop_back();
} else if (strcmp(name, "enumeratedData") == 0) {
_enumeratedDataName.clear();
} else if (strcmp(name, "fixedRecordData") == 0) {
_fixedRecordDataName.clear();
} else if (strcmp(name, "variantRecordData") == 0) {
_variantRecordDataName.clear();
}
_modeStack.pop_back();
}
std::string
HLAOMTXmlVisitor::getAttribute(const char* name, const XMLAttributes& atts)
{
int index = atts.findAttribute(name);
if (index < 0 || atts.size() <= index)
return std::string();
return std::string(atts.getValue(index));
}
std::string
HLAOMTXmlVisitor::getAttribute(const std::string& name, const XMLAttributes& atts)
{
int index = atts.findAttribute(name.c_str());
if (index < 0 || atts.size() <= index)
return std::string();
return std::string(atts.getValue(index));
}
} // namespace simgear

View File

@@ -0,0 +1,293 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAOMTXmlVisitor_hxx
#define HLAOMTXmlVisitor_hxx
#include <map>
#include <string>
#include <simgear/structure/exception.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/xml/easyxml.hxx>
#include "HLADataType.hxx"
namespace simgear {
class HLAOMTXmlVisitor : public XMLVisitor {
public:
/// structures representing the federate object model data
struct Attribute : public SGReferenced {
Attribute(const std::string& name) :
_name(name)
{ }
const std::string& getName() const
{ return _name; }
const std::string& getDimensions() const
{ return _dimensions; }
const std::string& getTransportation() const
{ return _transportation; }
const std::string& getOrder() const
{ return _order; }
std::string _name;
std::string _dataType;
std::string _updateType;
std::string _updateCondition;
std::string _ownership;
std::string _sharing;
std::string _dimensions;
std::string _transportation;
std::string _order;
friend class HLAOMTXmlVisitor;
};
typedef std::vector<SGSharedPtr<Attribute> > AttributeList;
struct ObjectClass : public SGReferenced {
ObjectClass(const std::string& name, const std::string& sharing);
~ObjectClass();
const std::string& getName() const;
const std::string& getSharing() const;
unsigned getNumAttributes() const;
const Attribute* getAttribute(unsigned index) const;
const Attribute* getAttribute(const std::string& name) const;
const ObjectClass* getParentObjectClass() const;
private:
friend class HLAOMTXmlVisitor;
std::string _name;
std::string _sharing;
AttributeList _attributes;
SGSharedPtr<ObjectClass> _parentObjectClass;
};
typedef std::vector<SGSharedPtr<ObjectClass> > ObjectClassList;
struct Parameter : public SGReferenced {
Parameter(const std::string& name) :
_name(name)
{ }
const std::string& getName() const
{ return _name; }
const std::string& getDataType() const
{ return _dataType; }
private:
std::string _name;
std::string _dataType;
friend class HLAOMTXmlVisitor;
};
typedef std::vector<SGSharedPtr<Parameter> > ParameterList;
struct InteractionClass : public SGReferenced {
InteractionClass(const std::string& name);
~InteractionClass();
const std::string& getName() const;
const std::string& getDimensions() const;
const std::string& getTransportation() const;
const std::string& getOrder() const;
unsigned getNumParameters() const;
const Parameter* getParameter(unsigned index) const;
const Parameter* getParameter(const std::string& name) const;
const InteractionClass* getParentInteractionClass() const;
private:
friend class HLAOMTXmlVisitor;
std::string _name;
std::string _dimensions;
std::string _transportation;
std::string _order;
ParameterList _parameters;
SGSharedPtr<InteractionClass> _parentInteractionClass;
};
typedef std::vector<SGSharedPtr<InteractionClass> > InteractionClassList;
HLAOMTXmlVisitor();
~HLAOMTXmlVisitor();
unsigned getNumObjectClasses() const;
const ObjectClass* getObjectClass(unsigned i) const;
const ObjectClass* getObjectClass(const std::string& name) const;
/// Return the data type from the fom data
const Attribute* getAttribute(const std::string& objectClassName, const std::string& attributeName) const;
/// Return the data type from the fom data
HLADataType* getAttributeDataType(const std::string& objectClassName, const std::string& attributeName) const;
unsigned getNumInteractionClasses() const;
const InteractionClass* getInteractionClass(unsigned i) const;
const InteractionClass* getInteractionClass(const std::string& name) const;
/// Return the data type from the fom data
const Parameter* getParameter(const std::string& interactionClassName, const std::string& parameterName) const;
/// Return the data type from the fom data
HLADataType* getParameterDataType(const std::string& interactionClassName, const std::string& parameterName) const;
HLADataType* getDataType(const std::string& dataTypeName) const;
private:
typedef std::map<std::string, SGSharedPtr<HLADataType> > StringDataTypeMap;
SGSharedPtr<HLADataType> getDataType(const std::string& dataTypeName, StringDataTypeMap& dataTypeMap) const;
SGSharedPtr<HLABasicDataType> getBasicDataType(const std::string& dataTypeName) const;
SGSharedPtr<HLADataType> getSimpleDataType(const std::string& dataTypeName) const;
SGSharedPtr<HLAEnumeratedDataType> getEnumeratedDataType(const std::string& dataTypeName) const;
SGSharedPtr<HLADataType> getArrayDataType(const std::string& dataTypeName, StringDataTypeMap& dataTypeMap) const;
SGSharedPtr<HLAFixedRecordDataType> getFixedRecordDataType(const std::string& dataTypeName, StringDataTypeMap& dataTypeMap) const;
SGSharedPtr<HLAVariantDataType> getVariantDataType(const std::string& dataTypeName, StringDataTypeMap& dataTypeMap) const;
enum Mode {
UnknownMode,
ObjectModelMode,
ObjectsMode,
ObjectClassMode,
AttributeMode,
InteractionsMode,
InteractionClassMode,
ParameterMode,
DataTypesMode,
BasicDataRepresentationsMode,
BasicDataMode,
SimpleDataTypesMode,
SimpleDataMode,
EnumeratedDataTypesMode,
EnumeratedDataMode,
EnumeratorMode,
ArrayDataTypesMode,
ArrayDataMode,
FixedRecordDataTypesMode,
FixedRecordDataMode,
FieldMode,
VariantRecordDataTypesMode,
VariantRecordDataMode,
AlternativeDataMode
};
Mode getCurrentMode();
void pushMode(Mode mode);
void popMode();
virtual void startXML();
virtual void endXML ();
virtual void startElement(const char* name, const XMLAttributes& atts);
virtual void endElement(const char* name);
std::string getAttribute(const char* name, const XMLAttributes& atts);
std::string getAttribute(const std::string& name, const XMLAttributes& atts);
struct BasicData {
// std::string _name;
std::string _size;
std::string _endian;
};
typedef std::map<std::string, BasicData> BasicDataMap;
struct SimpleData {
// std::string _name;
std::string _representation;
std::string _units;
std::string _resolution;
std::string _accuracy;
};
typedef std::map<std::string, SimpleData> SimpleDataMap;
struct Enumerator {
std::string _name;
std::string _values;
};
typedef std::vector<Enumerator> EnumeratorList;
struct EnumeratedData {
// std::string _name;
std::string _representation;
EnumeratorList _enumeratorList;
};
typedef std::map<std::string, EnumeratedData> EnumeratedDataMap;
struct ArrayData {
// std::string _name;
std::string _dataType;
std::string _cardinality;
std::string _encoding;
};
typedef std::map<std::string, ArrayData> ArrayDataMap;
struct Field {
std::string _name;
std::string _dataType;
};
typedef std::vector<Field> FieldList;
struct FixedRecordData {
// std::string _name;
std::string _encoding;
FieldList _fieldList;
};
typedef std::map<std::string, FixedRecordData> FixedRecordDataMap;
struct Alternative {
std::string _name;
std::string _dataType;
std::string _semantics;
std::string _enumerator;
};
typedef std::vector<Alternative> AlternativeList;
struct VariantRecordData {
// std::string _name;
std::string _encoding;
std::string _dataType;
std::string _discriminant;
std::string _semantics;
AlternativeList _alternativeList;
};
typedef std::map<std::string, VariantRecordData> VariantRecordDataMap;
std::vector<Mode> _modeStack;
/// The total list of object classes
ObjectClassList _objectClassList;
ObjectClassList _objectClassStack;
/// The total list of interaction classes
InteractionClassList _interactionClassList;
InteractionClassList _interactionClassStack;
/// DataType definitions
BasicDataMap _basicDataMap;
SimpleDataMap _simpleDataMap;
std::string _enumeratedDataName;
EnumeratedDataMap _enumeratedDataMap;
ArrayDataMap _arrayDataMap;
std::string _fixedRecordDataName;
FixedRecordDataMap _fixedRecordDataMap;
std::string _variantRecordDataName;
VariantRecordDataMap _variantRecordDataMap;
};
} // namespace simgear
#endif

View File

@@ -0,0 +1,302 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAObjectClass.hxx"
#include "RTIFederate.hxx"
#include "RTIObjectClass.hxx"
#include "RTIObjectInstance.hxx"
#include "HLADataType.hxx"
#include "HLAFederate.hxx"
#include "HLAObjectInstance.hxx"
namespace simgear {
HLAObjectClass::InstanceCallback::~InstanceCallback()
{
}
void
HLAObjectClass::InstanceCallback::discoverInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance, const RTIData& tag)
{
}
void
HLAObjectClass::InstanceCallback::removeInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance, const RTIData& tag)
{
}
void
HLAObjectClass::InstanceCallback::registerInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance)
{
}
void
HLAObjectClass::InstanceCallback::deleteInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance)
{
}
HLAObjectClass::RegistrationCallback::~RegistrationCallback()
{
}
HLAObjectClass::HLAObjectClass(const std::string& name, HLAFederate& federate) :
_name(name)
{
_rtiObjectClass = federate._rtiFederate->createObjectClass(name, this);
if (!_rtiObjectClass.valid())
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::HLAObjectClass(): No RTIObjectClass found for \"" << name << "\"!");
}
HLAObjectClass::~HLAObjectClass()
{
}
unsigned
HLAObjectClass::getNumAttributes() const
{
if (!_rtiObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::getAttributeIndex(): No RTIObject class for object class \"" << getName() << "\"!");
return 0;
}
return _rtiObjectClass->getNumAttributes();
}
unsigned
HLAObjectClass::getAttributeIndex(const std::string& name) const
{
if (!_rtiObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::getAttributeIndex(): No RTIObject class for object class \"" << getName() << "\"!");
return ~0u;
}
return _rtiObjectClass->getOrCreateAttributeIndex(name);
}
std::string
HLAObjectClass::getAttributeName(unsigned index) const
{
if (!_rtiObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::getAttributeIndex(): No RTIObject class for object class \"" << getName() << "\"!");
return 0;
}
return _rtiObjectClass->getAttributeName(index);
}
const HLADataType*
HLAObjectClass::getAttributeDataType(unsigned index) const
{
if (!_rtiObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::getAttributeDataType(): No RTIObject class for object class \"" << getName() << "\"!");
return 0;
}
return _rtiObjectClass->getAttributeDataType(index);
}
void
HLAObjectClass::setAttributeDataType(unsigned index, const HLADataType* dataType)
{
if (!_rtiObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::setAttributeDataType(): No RTIObject class for object class \"" << getName() << "\"!");
return;
}
_rtiObjectClass->setAttributeDataType(index, dataType);
}
HLAUpdateType
HLAObjectClass::getAttributeUpdateType(unsigned index) const
{
if (!_rtiObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::getAttributeUpdateType(): No RTIObject class for object class \"" << getName() << "\"!");
return HLAUndefinedUpdate;
}
return _rtiObjectClass->getAttributeUpdateType(index);
}
void
HLAObjectClass::setAttributeUpdateType(unsigned index, HLAUpdateType updateType)
{
if (!_rtiObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::setAttributeUpdateType(): "
"No RTIObject class for object class \"" << getName() << "\"!");
return;
}
_rtiObjectClass->setAttributeUpdateType(index, updateType);
}
HLADataElement::IndexPathPair
HLAObjectClass::getIndexPathPair(const HLADataElement::AttributePathPair& attributePathPair) const
{
unsigned index = getAttributeIndex(attributePathPair.first);
if (getNumAttributes() <= index) {
SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass::getIndexPathPair(\""
<< HLADataElement::toString(attributePathPair)
<< "\"): Could not resolve attribute \"" << attributePathPair.first
<< "\" for object class \"" << getName() << "\"!");
}
return HLADataElement::IndexPathPair(index, attributePathPair.second);
}
HLADataElement::IndexPathPair
HLAObjectClass::getIndexPathPair(const std::string& path) const
{
return getIndexPathPair(HLADataElement::toAttributePathPair(path));
}
bool
HLAObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
{
if (!_rtiObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::subscribe(): No RTIObject class for object class \"" << getName() << "\"!");
return false;
}
return _rtiObjectClass->subscribe(indexSet, active);
}
bool
HLAObjectClass::unsubscribe()
{
if (!_rtiObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unsubscribe(): No RTIObject class for object class \"" << getName() << "\"!");
return false;
}
return _rtiObjectClass->unsubscribe();
}
bool
HLAObjectClass::publish(const std::set<unsigned>& indexSet)
{
if (!_rtiObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::publish(): No RTIObject class for object class \"" << getName() << "\"!");
return false;
}
return _rtiObjectClass->publish(indexSet);
}
bool
HLAObjectClass::unpublish()
{
if (!_rtiObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unpublish(): No RTIObject class for object class \"" << getName() << "\"!");
return false;
}
return _rtiObjectClass->unpublish();
}
void
HLAObjectClass::startRegistration() const
{
}
void
HLAObjectClass::stopRegistration() const
{
}
HLAObjectInstance*
HLAObjectClass::createObjectInstance(RTIObjectInstance* rtiObjectInstance)
{
return new HLAObjectInstance(this, rtiObjectInstance);
}
void
HLAObjectClass::discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag)
{
SGSharedPtr<HLAObjectInstance> hlaObjectInstance = createObjectInstance(objectInstance);
if (hlaObjectInstance.valid()) {
SG_LOG(SG_NETWORK, SG_INFO, "RTI: create new object instance for discovered \""
<< hlaObjectInstance->getName() << "\" object");
_objectInstanceSet.insert(hlaObjectInstance);
discoverInstanceCallback(*hlaObjectInstance, tag);
} else {
SG_LOG(SG_NETWORK, SG_INFO, "RTI: local delete of \"" << objectInstance->getName() << "\"");
objectInstance->localDeleteObjectInstance();
}
}
void
HLAObjectClass::removeInstance(HLAObjectInstance& hlaObjectInstance, const RTIData& tag)
{
SG_LOG(SG_NETWORK, SG_INFO, "RTI: remove object instance \"" << hlaObjectInstance.getName() << "\"");
removeInstanceCallback(hlaObjectInstance, tag);
_objectInstanceSet.erase(&hlaObjectInstance);
}
void
HLAObjectClass::registerInstance(HLAObjectInstance& objectInstance)
{
_objectInstanceSet.insert(&objectInstance);
registerInstanceCallback(objectInstance);
}
void
HLAObjectClass::deleteInstance(HLAObjectInstance& objectInstance)
{
deleteInstanceCallback(objectInstance);
_objectInstanceSet.erase(&objectInstance);
}
void
HLAObjectClass::discoverInstanceCallback(HLAObjectInstance& objectInstance, const RTIData& tag) const
{
if (!_instanceCallback.valid())
return;
_instanceCallback->discoverInstance(*this, objectInstance, tag);
}
void
HLAObjectClass::removeInstanceCallback(HLAObjectInstance& objectInstance, const RTIData& tag) const
{
if (!_instanceCallback.valid())
return;
_instanceCallback->removeInstance(*this, objectInstance, tag);
}
void
HLAObjectClass::registerInstanceCallback(HLAObjectInstance& objectInstance) const
{
if (!_instanceCallback.valid())
return;
_instanceCallback->registerInstance(*this, objectInstance);
}
void
HLAObjectClass::deleteInstanceCallback(HLAObjectInstance& objectInstance) const
{
if (!_instanceCallback.valid())
return;
_instanceCallback->deleteInstance(*this, objectInstance);
}
void
HLAObjectClass::startRegistrationCallback()
{
if (_registrationCallback.valid())
_registrationCallback->startRegistration(*this);
else
startRegistration();
}
void
HLAObjectClass::stopRegistrationCallback()
{
if (_registrationCallback.valid())
_registrationCallback->stopRegistration(*this);
else
stopRegistration();
}
} // namespace simgear

View File

@@ -0,0 +1,131 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAObjectClass_hxx
#define HLAObjectClass_hxx
#include <set>
#include <string>
#include <vector>
#include "HLADataType.hxx"
#include "HLAObjectInstance.hxx"
namespace simgear {
class RTIObjectClass;
class HLAFederate;
class HLAObjectClass : public SGWeakReferenced {
public:
HLAObjectClass(const std::string& name, HLAFederate& federate);
virtual ~HLAObjectClass();
const std::string& getName() const
{ return _name; }
unsigned getNumAttributes() const;
unsigned getAttributeIndex(const std::string& name) const;
std::string getAttributeName(unsigned index) const;
const HLADataType* getAttributeDataType(unsigned index) const;
void setAttributeDataType(unsigned index, const HLADataType*);
HLAUpdateType getAttributeUpdateType(unsigned index) const;
void setAttributeUpdateType(unsigned index, HLAUpdateType updateType);
HLADataElement::IndexPathPair getIndexPathPair(const HLADataElement::AttributePathPair&) const;
HLADataElement::IndexPathPair getIndexPathPair(const std::string& path) const;
bool subscribe(const std::set<unsigned>& indexSet, bool active);
bool unsubscribe();
bool publish(const std::set<unsigned>& indexSet);
bool unpublish();
// Object instance creation and destruction
class InstanceCallback : public SGReferenced {
public:
virtual ~InstanceCallback();
virtual void discoverInstance(const HLAObjectClass& objectClass, HLAObjectInstance& objectInstance, const RTIData& tag);
virtual void removeInstance(const HLAObjectClass& objectClass, HLAObjectInstance& objectInstance, const RTIData& tag);
virtual void registerInstance(const HLAObjectClass& objectClass, HLAObjectInstance& objectInstance);
virtual void deleteInstance(const HLAObjectClass& objectClass, HLAObjectInstance& objectInstance);
};
void setInstanceCallback(const SGSharedPtr<InstanceCallback>& instanceCallback)
{ _instanceCallback = instanceCallback; }
const SGSharedPtr<InstanceCallback>& getInstanceCallback() const
{ return _instanceCallback; }
// Handles startRegistrationForObjectClass and stopRegistrationForObjectClass events
class RegistrationCallback : public SGReferenced {
public:
virtual ~RegistrationCallback();
virtual void startRegistration(HLAObjectClass& objectClass) = 0;
virtual void stopRegistration(HLAObjectClass& objectClass) = 0;
};
void setRegistrationCallback(const SGSharedPtr<RegistrationCallback>& registrationCallback)
{ _registrationCallback = registrationCallback; }
const SGSharedPtr<RegistrationCallback>& getRegistrationCallback() const
{ return _registrationCallback; }
// Is called by the default registration callback if installed
void startRegistration() const;
void stopRegistration() const;
protected:
virtual HLAObjectInstance* createObjectInstance(RTIObjectInstance* rtiObjectInstance);
private:
// The internal entry points from the RTILObjectClass callback functions
void discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag);
void removeInstance(HLAObjectInstance& objectInstance, const RTIData& tag);
void registerInstance(HLAObjectInstance& objectInstance);
void deleteInstance(HLAObjectInstance& objectInstance);
void discoverInstanceCallback(HLAObjectInstance& objectInstance, const RTIData& tag) const;
void removeInstanceCallback(HLAObjectInstance& objectInstance, const RTIData& tag) const;
void registerInstanceCallback(HLAObjectInstance& objectInstance) const;
void deleteInstanceCallback(HLAObjectInstance& objectInstance) const;
void startRegistrationCallback();
void stopRegistrationCallback();
friend class HLAObjectInstance;
friend class RTIObjectClass;
// The object class name
std::string _name;
// The underlying rti dispatcher class
SGSharedPtr<RTIObjectClass> _rtiObjectClass;
// Callback classes
SGSharedPtr<InstanceCallback> _instanceCallback;
SGSharedPtr<RegistrationCallback> _registrationCallback;
// The set of active objects
typedef std::set<SGSharedPtr<HLAObjectInstance> > ObjectInstanceSet;
ObjectInstanceSet _objectInstanceSet;
};
} // namespace simgear
#endif

View File

@@ -0,0 +1,544 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAObjectInstance.hxx"
#include <algorithm>
#include "HLAArrayDataElement.hxx"
#include "HLABasicDataElement.hxx"
#include "HLADataElement.hxx"
#include "HLAEnumeratedDataElement.hxx"
#include "HLAFixedRecordDataElement.hxx"
#include "HLAObjectClass.hxx"
#include "HLAVariantDataElement.hxx"
#include "RTIObjectClass.hxx"
#include "RTIObjectInstance.hxx"
namespace simgear {
HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass) :
_objectClass(objectClass)
{
}
HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass, RTIObjectInstance* rtiObjectInstance) :
_objectClass(objectClass),
_rtiObjectInstance(rtiObjectInstance)
{
_rtiObjectInstance->_hlaObjectInstance = this;
_name = _rtiObjectInstance->getName();
}
HLAObjectInstance::~HLAObjectInstance()
{
}
SGSharedPtr<HLAObjectClass>
HLAObjectInstance::getObjectClass() const
{
return _objectClass.lock();
}
unsigned
HLAObjectInstance::getNumAttributes() const
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to get number of attributes for inactive object!");
return 0;
}
return _rtiObjectInstance->getNumAttributes();
}
unsigned
HLAObjectInstance::getAttributeIndex(const std::string& name) const
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute index for inactive object!");
return 0;
}
return _rtiObjectInstance->getAttributeIndex(name);
}
std::string
HLAObjectInstance::getAttributeName(unsigned index) const
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute name for inactive object!");
return std::string();
}
return _rtiObjectInstance->getAttributeName(index);
}
const HLADataType*
HLAObjectInstance::getAttributeDataType(unsigned index) const
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute index for inactive object!");
return 0;
}
return _rtiObjectInstance->getAttributeDataType(index);
}
void
HLAObjectInstance::setAttributeDataElement(unsigned index, SGSharedPtr<HLADataElement> dataElement)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
return;
}
_rtiObjectInstance->setDataElement(index, dataElement);
}
HLADataElement*
HLAObjectInstance::getAttributeDataElement(unsigned index)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
return 0;
}
return _rtiObjectInstance->getDataElement(index);
}
const HLADataElement*
HLAObjectInstance::getAttributeDataElement(unsigned index) const
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
return 0;
}
return _rtiObjectInstance->getDataElement(index);
}
class HLAObjectInstance::DataElementFactoryVisitor : public HLADataTypeVisitor {
public:
DataElementFactoryVisitor(const HLAPathElementMap& pathElementMap) :
_pathElementMap(pathElementMap)
{ }
DataElementFactoryVisitor(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
_pathElementMap(pathElementMap),
_path(path)
{ }
virtual ~DataElementFactoryVisitor() {}
virtual void apply(const HLADataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Can not find a suitable data element for data type \""
<< dataType.getName() << "\"");
}
virtual void apply(const HLAInt8DataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
_dataElement = new HLASCharDataElement(&dataType);
}
virtual void apply(const HLAUInt8DataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
_dataElement = new HLAUCharDataElement(&dataType);
}
virtual void apply(const HLAInt16DataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
_dataElement = new HLAShortDataElement(&dataType);
}
virtual void apply(const HLAUInt16DataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
_dataElement = new HLAUShortDataElement(&dataType);
}
virtual void apply(const HLAInt32DataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
_dataElement = new HLAIntDataElement(&dataType);
}
virtual void apply(const HLAUInt32DataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
_dataElement = new HLAUIntDataElement(&dataType);
}
virtual void apply(const HLAInt64DataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
_dataElement = new HLALongDataElement(&dataType);
}
virtual void apply(const HLAUInt64DataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
_dataElement = new HLAULongDataElement(&dataType);
}
virtual void apply(const HLAFloat32DataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
_dataElement = new HLAFloatDataElement(&dataType);
}
virtual void apply(const HLAFloat64DataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
_dataElement = new HLADoubleDataElement(&dataType);
}
class ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory {
public:
ArrayDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
_path(path)
{
for (HLAPathElementMap::const_iterator i = pathElementMap.lower_bound(path);
i != pathElementMap.end(); ++i) {
if (i->first.begin() != std::search(i->first.begin(), i->first.end(),
path.begin(), path.end()))
break;
_pathElementMap.insert(*i);
}
}
virtual HLADataElement* createElement(const HLAArrayDataElement& element, unsigned index)
{
const HLADataType* dataType = element.getElementDataType();
if (!dataType)
return 0;
HLADataElement::Path path = _path;
path.push_back(HLADataElement::PathElement(index));
DataElementFactoryVisitor visitor(path, _pathElementMap);
dataType->accept(visitor);
return visitor._dataElement.release();
}
private:
HLADataElement::Path _path;
HLAPathElementMap _pathElementMap;
};
virtual void apply(const HLAFixedArrayDataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
SGSharedPtr<HLAArrayDataElement> arrayDataElement;
arrayDataElement = new HLAArrayDataElement(&dataType);
arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_path, _pathElementMap));
arrayDataElement->setNumElements(dataType.getNumElements());
_dataElement = arrayDataElement;
}
virtual void apply(const HLAVariableArrayDataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
SGSharedPtr<HLAArrayDataElement> arrayDataElement;
arrayDataElement = new HLAArrayDataElement(&dataType);
arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_path, _pathElementMap));
_dataElement = arrayDataElement;
}
virtual void apply(const HLAEnumeratedDataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
_dataElement = new HLAEnumeratedDataElement(&dataType);
}
virtual void apply(const HLAFixedRecordDataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
SGSharedPtr<HLAFixedRecordDataElement> recordDataElement;
recordDataElement = new HLAFixedRecordDataElement(&dataType);
unsigned numFields = dataType.getNumFields();
for (unsigned i = 0; i < numFields; ++i) {
_path.push_back(HLADataElement::PathElement(dataType.getFieldName(i)));
dataType.getFieldDataType(i)->accept(*this);
recordDataElement->setField(i, _dataElement.release());
_path.pop_back();
}
_dataElement = recordDataElement;
}
class VariantDataElementFactory : public HLAVariantDataElement::DataElementFactory {
public:
VariantDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
_path(path)
{
for (HLAPathElementMap::const_iterator i = pathElementMap.lower_bound(path);
i != pathElementMap.end(); ++i) {
if (i->first.begin() != std::search(i->first.begin(), i->first.end(),
path.begin(), path.end()))
break;
_pathElementMap.insert(*i);
}
}
virtual HLADataElement* createElement(const HLAVariantDataElement& element, unsigned index)
{
const HLAVariantDataType* dataType = element.getDataType();
if (!dataType)
return 0;
const HLADataType* alternativeDataType = element.getAlternativeDataType();
if (!alternativeDataType)
return 0;
HLADataElement::Path path = _path;
path.push_back(HLADataElement::PathElement(dataType->getAlternativeName(index)));
DataElementFactoryVisitor visitor(path, _pathElementMap);
alternativeDataType->accept(visitor);
return visitor._dataElement.release();
}
private:
HLADataElement::Path _path;
HLAPathElementMap _pathElementMap;
};
virtual void apply(const HLAVariantDataType& dataType)
{
_dataElement = createDataElement(_path, dataType);
if (_dataElement.valid())
return;
SGSharedPtr<HLAVariantDataElement> variantDataElement;
variantDataElement = new HLAVariantDataElement(&dataType);
variantDataElement->setDataElementFactory(new VariantDataElementFactory(_path, _pathElementMap));
_dataElement = variantDataElement;
}
const SGSharedPtr<HLADataElement>& getDataElement() const
{ return _dataElement; }
private:
SGSharedPtr<HLADataElement> createDataElement(const HLADataElement::Path& path, const HLADataType& dataType)
{
HLAPathElementMap::const_iterator i = _pathElementMap.find(path);
if (i == _pathElementMap.end()) {
SG_LOG(SG_IO, SG_WARN, "No dataElement provided for \""
<< HLADataElement::toString(path) << "\".");
return 0;
}
SGSharedPtr<HLADataElement> dataElement = i->second.getDataElement(path);
if (!dataElement->setDataType(&dataType)) {
SG_LOG(SG_IO, SG_ALERT, "Cannot set data type for data element at \""
<< HLADataElement::toString(path) << "\"!");
return 0;
}
SG_LOG(SG_IO, SG_DEBUG, "Using provided dataElement for \""
<< HLADataElement::toString(path) << "\".");
return dataElement;
}
SGSharedPtr<HLADataElement> _dataElement;
const HLAPathElementMap& _pathElementMap;
HLADataElement::Path _path;
};
void
HLAObjectInstance::setAttribute(unsigned index, const HLAPathElementMap& pathElementMap)
{
const HLADataType* dataType = getAttributeDataType(index);
if (!dataType) {
SG_LOG(SG_IO, SG_ALERT, "Cannot get attribute data type for setting attribute at index "
<< index << "!");
return;
}
SG_LOG(SG_IO, SG_DEBUG, "Setting DataElement for attribute \""
<< getAttributeName(index) << "\".");
DataElementFactoryVisitor visitor(pathElementMap);
dataType->accept(visitor);
setAttributeDataElement(index, visitor.getDataElement());
}
void
HLAObjectInstance::setAttributes(const HLAAttributePathElementMap& attributePathElementMap)
{
for (HLAAttributePathElementMap::const_iterator i = attributePathElementMap.begin();
i != attributePathElementMap.end(); ++i) {
setAttribute(i->first, i->second);
}
}
void
HLAObjectInstance::requestAttributeUpdate(unsigned index)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to request attribute update for inactive object!");
return;
}
_rtiObjectInstance->setRequestAttributeUpdate(index, true);
}
void
HLAObjectInstance::requestAttributeUpdate()
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to request attribute update for inactive object!");
return;
}
_rtiObjectInstance->setRequestAttributeUpdate(true);
}
void
HLAObjectInstance::registerInstance()
{
if (_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to register object " << getName() << " already known to the RTI!");
return;
}
SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
if (!objectClass.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not register object with unknown object class!");
return;
}
// This error must have been flagged before
if (!objectClass->_rtiObjectClass.valid())
return;
_rtiObjectInstance = objectClass->_rtiObjectClass->registerObjectInstance(this);
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not register object at the RTI!");
return;
}
_name = _rtiObjectInstance->getName();
objectClass->registerInstance(*this);
}
void
HLAObjectInstance::deleteInstance(const RTIData& tag)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to delete inactive object!");
return;
}
SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
if (!objectClass.valid())
return;
objectClass->deleteInstance(*this);
_rtiObjectInstance->deleteObjectInstance(tag);
}
void
HLAObjectInstance::localDeleteInstance()
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to delete inactive object!");
return;
}
_rtiObjectInstance->localDeleteObjectInstance();
}
void
HLAObjectInstance::updateAttributeValues(const RTIData& tag)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
return;
}
if (_attributeCallback.valid())
_attributeCallback->updateAttributeValues(*this, tag);
_rtiObjectInstance->updateAttributeValues(tag);
}
void
HLAObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
return;
}
if (_attributeCallback.valid())
_attributeCallback->updateAttributeValues(*this, tag);
_rtiObjectInstance->updateAttributeValues(timeStamp, tag);
}
void
HLAObjectInstance::reflectQueuedAttributeValues(const SGTimeStamp& timeStamp)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
return;
}
_rtiObjectInstance->reflectQueuedAttributeValues(timeStamp);
}
void
HLAObjectInstance::removeInstance(const RTIData& tag)
{
SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
if (!objectClass.valid())
return;
objectClass->removeInstanceCallback(*this, tag);
}
void
HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag)
{
if (!_attributeCallback.valid())
return;
_attributeCallback->reflectAttributeValues(*this, dataPairList, tag);
}
void
HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList,
const SGTimeStamp& timeStamp, const RTIData& tag)
{
if (!_attributeCallback.valid())
return;
_attributeCallback->reflectAttributeValues(*this, dataPairList, timeStamp, tag);
}
} // namespace simgear

View File

@@ -0,0 +1,111 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAObjectInstance_hxx
#define HLAObjectInstance_hxx
#include <simgear/structure/SGWeakPtr.hxx>
#include "HLADataElement.hxx"
class SGTimeStamp;
namespace simgear {
class RTIObjectInstance;
class HLAObjectClass;
class HLAObjectInstance : public SGWeakReferenced {
public:
HLAObjectInstance(HLAObjectClass* objectClass);
HLAObjectInstance(HLAObjectClass* objectClass, RTIObjectInstance* rtiObjectInstance);
virtual ~HLAObjectInstance();
const std::string& getName() const
{ return _name; }
SGSharedPtr<HLAObjectClass> getObjectClass() const;
unsigned getNumAttributes() const;
unsigned getAttributeIndex(const std::string& name) const;
std::string getAttributeName(unsigned index) const;
const HLADataType* getAttributeDataType(unsigned index) const;
void setAttributeDataElement(unsigned index, SGSharedPtr<HLADataElement> dataElement);
HLADataElement* getAttributeDataElement(unsigned index);
const HLADataElement* getAttributeDataElement(unsigned index) const;
void setAttribute(unsigned index, const HLAPathElementMap& pathElementMap);
void setAttributes(const HLAAttributePathElementMap& attributePathElementMap);
// Ask the rti to provide the attribute at index
void requestAttributeUpdate(unsigned index);
void requestAttributeUpdate();
void registerInstance();
void deleteInstance(const RTIData& tag);
void localDeleteInstance();
class AttributeCallback : public SGReferenced {
public:
virtual ~AttributeCallback() {}
// Notification about reflect and whatever TBD
// Hmm, don't know yet how this should look like
virtual void updateAttributeValues(HLAObjectInstance& objectInstance, const RTIData& tag)
{ }
virtual void reflectAttributeValues(HLAObjectInstance& objectInstance,
const RTIIndexDataPairList& dataPairList, const RTIData& tag)
{ }
virtual void reflectAttributeValues(HLAObjectInstance& objectInstance, const RTIIndexDataPairList& dataPairList,
const SGTimeStamp& timeStamp, const RTIData& tag)
{ reflectAttributeValues(objectInstance, dataPairList, tag); }
};
void setAttributeCallback(const SGSharedPtr<AttributeCallback>& attributeCallback)
{ _attributeCallback = attributeCallback; }
const SGSharedPtr<AttributeCallback>& getAttributeCallback() const
{ return _attributeCallback; }
// Push the current values into the RTI
void updateAttributeValues(const RTIData& tag);
void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag);
// Retrieve queued up updates up to and including timestamp,
// Note that this only applies to timestamped updates.
// The unordered updates are reflected as they arrive
void reflectQueuedAttributeValues(const SGTimeStamp& timeStamp);
private:
void removeInstance(const RTIData& tag);
void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag);
void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const SGTimeStamp& timeStamp, const RTIData& tag);
friend class RTIObjectInstance;
friend class HLAObjectClass;
class DataElementFactoryVisitor;
std::string _name;
SGWeakPtr<HLAObjectClass> _objectClass;
SGSharedPtr<RTIObjectInstance> _rtiObjectInstance;
SGSharedPtr<AttributeCallback> _attributeCallback;
};
} // namespace simgear
#endif

View File

@@ -0,0 +1,269 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAPropertyDataElement.hxx"
#include "HLADataTypeVisitor.hxx"
namespace simgear {
class HLAPropertyDataElement::DecodeVisitor : public HLADataTypeDecodeVisitor {
public:
DecodeVisitor(HLADecodeStream& stream, HLAPropertyReference& propertyReference) :
HLADataTypeDecodeVisitor(stream),
_propertyReference(propertyReference)
{ }
virtual void apply(const HLAInt8DataType& dataType)
{
int8_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
}
virtual void apply(const HLAUInt8DataType& dataType)
{
uint8_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
}
virtual void apply(const HLAInt16DataType& dataType)
{
int16_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
}
virtual void apply(const HLAUInt16DataType& dataType)
{
uint16_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
}
virtual void apply(const HLAInt32DataType& dataType)
{
int32_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
}
virtual void apply(const HLAUInt32DataType& dataType)
{
uint32_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
}
virtual void apply(const HLAInt64DataType& dataType)
{
int64_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setLongValue(value);
}
virtual void apply(const HLAUInt64DataType& dataType)
{
uint64_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setLongValue(value);
}
virtual void apply(const HLAFloat32DataType& dataType)
{
float value = 0;
dataType.decode(_stream, value);
_propertyReference.setFloatValue(value);
}
virtual void apply(const HLAFloat64DataType& dataType)
{
double value = 0;
dataType.decode(_stream, value);
_propertyReference.setDoubleValue(value);
}
virtual void apply(const HLAFixedArrayDataType& dataType)
{
unsigned numElements = dataType.getNumElements();
std::string value;
value.reserve(numElements);
for (unsigned i = 0; i < numElements; ++i) {
HLATemplateDecodeVisitor<char> visitor(_stream);
dataType.getElementDataType()->accept(visitor);
value.push_back(visitor.getValue());
}
_propertyReference.setStringValue(value);
}
virtual void apply(const HLAVariableArrayDataType& dataType)
{
HLATemplateDecodeVisitor<unsigned> numElementsVisitor(_stream);
dataType.getSizeDataType()->accept(numElementsVisitor);
unsigned numElements = numElementsVisitor.getValue();
std::string value;
value.reserve(numElements);
for (unsigned i = 0; i < numElements; ++i) {
HLATemplateDecodeVisitor<char> visitor(_stream);
dataType.getElementDataType()->accept(visitor);
value.push_back(visitor.getValue());
}
_propertyReference.setStringValue(value);
}
protected:
HLAPropertyReference& _propertyReference;
};
class HLAPropertyDataElement::EncodeVisitor : public HLADataTypeEncodeVisitor {
public:
EncodeVisitor(HLAEncodeStream& stream, const HLAPropertyReference& propertyReference) :
HLADataTypeEncodeVisitor(stream),
_propertyReference(propertyReference)
{ }
virtual void apply(const HLAInt8DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
}
virtual void apply(const HLAUInt8DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
}
virtual void apply(const HLAInt16DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
}
virtual void apply(const HLAUInt16DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
}
virtual void apply(const HLAInt32DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
}
virtual void apply(const HLAUInt32DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
}
virtual void apply(const HLAInt64DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getLongValue());
}
virtual void apply(const HLAUInt64DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getLongValue());
}
virtual void apply(const HLAFloat32DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getFloatValue());
}
virtual void apply(const HLAFloat64DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getDoubleValue());
}
virtual void apply(const HLAFixedArrayDataType& dataType)
{
unsigned numElements = dataType.getNumElements();
std::string value = _propertyReference.getStringValue();
for (unsigned i = 0; i < numElements; ++i) {
if (i < value.size()) {
HLATemplateEncodeVisitor<char> visitor(_stream, value[i]);
dataType.getElementDataType()->accept(visitor);
} else {
HLADataTypeEncodeVisitor visitor(_stream);
dataType.getElementDataType()->accept(visitor);
}
}
}
virtual void apply(const HLAVariableArrayDataType& dataType)
{
std::string value = _propertyReference.getStringValue();
HLATemplateEncodeVisitor<std::string::size_type> numElementsVisitor(_stream, value.size());
dataType.getSizeDataType()->accept(numElementsVisitor);
for (unsigned i = 0; i < value.size(); ++i) {
HLATemplateEncodeVisitor<char> visitor(_stream, value[i]);
dataType.getElementDataType()->accept(visitor);
}
}
protected:
const HLAPropertyReference& _propertyReference;
};
HLAPropertyDataElement::HLAPropertyDataElement(HLAPropertyReference* propertyReference) :
_propertyReference(propertyReference)
{
}
HLAPropertyDataElement::HLAPropertyDataElement(const simgear::HLADataType* dataType, HLAPropertyReference* propertyReference) :
_dataType(dataType),
_propertyReference(propertyReference)
{
}
HLAPropertyDataElement::~HLAPropertyDataElement()
{
}
bool
HLAPropertyDataElement::encode(HLAEncodeStream& stream) const
{
if (!_dataType.valid())
return false;
if (_propertyReference.valid()) {
EncodeVisitor visitor(stream, *_propertyReference);
_dataType->accept(visitor);
} else {
HLADataTypeEncodeVisitor visitor(stream);
_dataType->accept(visitor);
}
return true;
}
bool
HLAPropertyDataElement::decode(HLADecodeStream& stream)
{
if (!_dataType.valid())
return false;
if (_propertyReference.valid()) {
DecodeVisitor visitor(stream, *_propertyReference);
_dataType->accept(visitor);
} else {
HLADataTypeDecodeVisitor visitor(stream);
_dataType->accept(visitor);
}
return true;
}
const HLADataType*
HLAPropertyDataElement::getDataType() const
{
return _dataType.get();
}
bool
HLAPropertyDataElement::setDataType(const HLADataType* dataType)
{
if (dataType->toBasicDataType()) {
_dataType = dataType;
return true;
} else {
const HLAArrayDataType* arrayDataType = dataType->toArrayDataType();
if (arrayDataType && arrayDataType->getElementDataType() &&
arrayDataType->getElementDataType()->toBasicDataType()) {
_dataType = dataType;
return true;
}
}
return false;
}
} // namespace simgear

View File

@@ -0,0 +1,172 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAPropertyDataElement_hxx
#define HLAPropertyDataElement_hxx
#include <set>
#include <simgear/props/props.hxx>
#include "HLADataElement.hxx"
namespace simgear {
class HLAPropertyReference : public SGReferenced {
public:
HLAPropertyReference()
{ }
HLAPropertyReference(const std::string& relativePath) :
_relativePath(relativePath)
{ }
void setIntValue(int value)
{
if (!_propertyNode.valid())
return;
_propertyNode->setIntValue(value);
}
int getIntValue() const
{
if (!_propertyNode.valid())
return 0;
return _propertyNode->getIntValue();
}
void setLongValue(long value)
{
if (!_propertyNode.valid())
return;
_propertyNode->setLongValue(value);
}
long getLongValue() const
{
if (!_propertyNode.valid())
return 0;
return _propertyNode->getLongValue();
}
void setFloatValue(float value)
{
if (!_propertyNode.valid())
return;
_propertyNode->setFloatValue(value);
}
float getFloatValue() const
{
if (!_propertyNode.valid())
return 0;
return _propertyNode->getFloatValue();
}
void setDoubleValue(double value)
{
if (!_propertyNode.valid())
return;
_propertyNode->setDoubleValue(value);
}
double getDoubleValue() const
{
if (!_propertyNode.valid())
return 0;
return _propertyNode->getDoubleValue();
}
void setStringValue(const std::string& value)
{
if (!_propertyNode.valid())
return;
_propertyNode->setStringValue(value);
}
std::string getStringValue() const
{
if (!_propertyNode.valid())
return std::string();
return _propertyNode->getStringValue();
}
SGPropertyNode* getPropertyNode()
{ return _propertyNode.get(); }
void setRootNode(SGPropertyNode* rootNode)
{
if (!rootNode)
_propertyNode.clear();
else
_propertyNode = rootNode->getNode(_relativePath, true);
}
private:
std::string _relativePath;
SGSharedPtr<SGPropertyNode> _propertyNode;
};
class HLAPropertyReferenceSet : public SGReferenced {
public:
void insert(const SGSharedPtr<HLAPropertyReference>& propertyReference)
{
_propertyReferenceSet.insert(propertyReference);
propertyReference->setRootNode(_rootNode.get());
}
void remove(const SGSharedPtr<HLAPropertyReference>& propertyReference)
{
PropertyReferenceSet::iterator i = _propertyReferenceSet.find(propertyReference);
if (i == _propertyReferenceSet.end())
return;
_propertyReferenceSet.erase(i);
propertyReference->setRootNode(0);
}
void setRootNode(SGPropertyNode* rootNode)
{
_rootNode = rootNode;
for (PropertyReferenceSet::iterator i = _propertyReferenceSet.begin();
i != _propertyReferenceSet.end(); ++i) {
(*i)->setRootNode(_rootNode.get());
}
}
SGPropertyNode* getRootNode()
{ return _rootNode.get(); }
private:
SGSharedPtr<SGPropertyNode> _rootNode;
typedef std::set<SGSharedPtr<HLAPropertyReference> > PropertyReferenceSet;
PropertyReferenceSet _propertyReferenceSet;
};
class HLAPropertyDataElement : public HLADataElement {
public:
HLAPropertyDataElement(HLAPropertyReference* propertyReference);
HLAPropertyDataElement(const simgear::HLADataType* dataType, HLAPropertyReference* propertyReference);
~HLAPropertyDataElement();
virtual bool encode(HLAEncodeStream& stream) const;
virtual bool decode(HLADecodeStream& stream);
virtual const HLADataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType);
private:
class DecodeVisitor;
class EncodeVisitor;
SGSharedPtr<const HLADataType> _dataType;
SGSharedPtr<HLAPropertyReference> _propertyReference;
};
} // namespace simgear
#endif

View File

@@ -0,0 +1,60 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLARawDataElement.hxx"
namespace simgear {
HLARawDataElement::HLARawDataElement(const HLADataType* dataType) :
_dataType(dataType)
{
}
HLARawDataElement::~HLARawDataElement()
{
}
bool
HLARawDataElement::encode(HLAEncodeStream& stream) const
{
stream.setData(_rtiData);
stream.skip(_rtiData.size());
return true;
}
bool
HLARawDataElement::decode(HLADecodeStream& stream)
{
_rtiData = stream.getData();
stream.skip(_rtiData.size());
return true;
}
const HLADataType*
HLARawDataElement::getDataType() const
{
return _dataType.get();
}
bool
HLARawDataElement::setDataType(const HLADataType* dataType)
{
_dataType = dataType;
return true;
}
}

View File

@@ -0,0 +1,52 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLARawDataElement_hxx
#define HLARawDataElement_hxx
#include "RTIData.hxx"
#include "HLADataElement.hxx"
#include "HLADataType.hxx"
namespace simgear {
class HLARawDataElement : public HLADataElement {
public:
HLARawDataElement(const HLADataType* dataType);
virtual ~HLARawDataElement();
virtual bool encode(HLAEncodeStream& stream) const;
virtual bool decode(HLADecodeStream& stream);
virtual const HLADataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType);
const RTIData& getData() const
{ return _rtiData; }
RTIData& getData()
{ return _rtiData; }
void setData(const RTIData& rtiData)
{ _rtiData = rtiData; }
protected:
SGSharedPtr<const HLADataType> _dataType;
RTIData _rtiData;
};
}
#endif

View File

@@ -0,0 +1,155 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAVariantDataElement.hxx"
#include <simgear/debug/logstream.hxx>
namespace simgear {
HLAAbstractVariantDataElement::HLAAbstractVariantDataElement(const HLAVariantDataType* dataType) :
_dataType(dataType)
{
}
HLAAbstractVariantDataElement::~HLAAbstractVariantDataElement()
{
}
bool
HLAAbstractVariantDataElement::decode(HLADecodeStream& stream)
{
if (!_dataType.valid())
return false;
return _dataType->decode(stream, *this);
}
bool
HLAAbstractVariantDataElement::encode(HLAEncodeStream& stream) const
{
if (!_dataType.valid())
return false;
return _dataType->encode(stream, *this);
}
const HLAVariantDataType*
HLAAbstractVariantDataElement::getDataType() const
{
return _dataType.get();
}
bool
HLAAbstractVariantDataElement::setDataType(const HLADataType* dataType)
{
const HLAVariantDataType* variantDataType = dataType->toVariantDataType();
if (!variantDataType) {
SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantDataType: unable to set data type!");
return false;
}
setDataType(variantDataType);
return true;
}
void
HLAAbstractVariantDataElement::setDataType(const HLAVariantDataType* dataType)
{
_dataType = dataType;
}
std::string
HLAAbstractVariantDataElement::getAlternativeName() const
{
if (!_dataType.valid())
return std::string();
return _dataType->getAlternativeName(getAlternativeIndex());
}
const HLADataType*
HLAAbstractVariantDataElement::getAlternativeDataType() const
{
if (!_dataType.valid())
return 0;
return _dataType->getAlternativeDataType(getAlternativeIndex());
}
HLAVariantDataElement::DataElementFactory::~DataElementFactory()
{
}
HLAVariantDataElement::HLAVariantDataElement(const HLAVariantDataType* dataType) :
HLAAbstractVariantDataElement(dataType),
_alternativeIndex(~0u)
{
}
HLAVariantDataElement::~HLAVariantDataElement()
{
}
bool
HLAVariantDataElement::setAlternativeIndex(unsigned index)
{
if (_alternativeIndex == index)
return true;
SGSharedPtr<HLADataElement> dataElement = newElement(index);
if (!dataElement.valid())
return false;
_dataElement.swap(dataElement);
_alternativeIndex = index;
return true;
}
bool
HLAVariantDataElement::decodeAlternative(HLADecodeStream& stream)
{
return _dataElement->decode(stream);
}
unsigned
HLAVariantDataElement::getAlternativeIndex() const
{
return _alternativeIndex;
}
bool
HLAVariantDataElement::encodeAlternative(HLAEncodeStream& stream) const
{
return _dataElement->encode(stream);
}
void
HLAVariantDataElement::setDataElementFactory(HLAVariantDataElement::DataElementFactory* dataElementFactory)
{
_dataElementFactory = dataElementFactory;
}
HLAVariantDataElement::DataElementFactory*
HLAVariantDataElement::getDataElementFactory()
{
return _dataElementFactory;
}
HLADataElement*
HLAVariantDataElement::newElement(unsigned index)
{
if (!_dataElementFactory.valid())
return 0;
return _dataElementFactory->createElement(*this, index);
}
}

View File

@@ -0,0 +1,82 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAVariantDataElement_hxx
#define HLAVariantDataElement_hxx
#include <string>
#include <simgear/structure/SGSharedPtr.hxx>
#include "HLADataElement.hxx"
#include "HLAVariantDataType.hxx"
namespace simgear {
class HLAAbstractVariantDataElement : public HLADataElement {
public:
HLAAbstractVariantDataElement(const HLAVariantDataType* dataType);
virtual ~HLAAbstractVariantDataElement();
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;
virtual const HLAVariantDataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType);
void setDataType(const HLAVariantDataType* dataType);
std::string getAlternativeName() const;
const HLADataType* getAlternativeDataType() const;
virtual bool setAlternativeIndex(unsigned index) = 0;
virtual bool decodeAlternative(HLADecodeStream& stream) = 0;
virtual unsigned getAlternativeIndex() const = 0;
virtual bool encodeAlternative(HLAEncodeStream& stream) const = 0;
private:
SGSharedPtr<const HLAVariantDataType> _dataType;
};
class HLAVariantDataElement : public HLAAbstractVariantDataElement {
public:
HLAVariantDataElement(const HLAVariantDataType* dataType);
virtual ~HLAVariantDataElement();
virtual bool setAlternativeIndex(unsigned index);
virtual bool decodeAlternative(HLADecodeStream& stream);
virtual unsigned getAlternativeIndex() const;
virtual bool encodeAlternative(HLAEncodeStream& stream) const;
class DataElementFactory : public SGReferenced {
public:
virtual ~DataElementFactory();
virtual HLADataElement* createElement(const HLAVariantDataElement&, unsigned) = 0;
};
void setDataElementFactory(DataElementFactory* dataElementFactory);
DataElementFactory* getDataElementFactory();
private:
HLADataElement* newElement(unsigned index);
SGSharedPtr<HLADataElement> _dataElement;
unsigned _alternativeIndex;
SGSharedPtr<DataElementFactory> _dataElementFactory;
};
}
#endif

View File

@@ -0,0 +1,101 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HLAVariantDataType.hxx"
#include "HLADataTypeVisitor.hxx"
#include "HLAVariantDataElement.hxx"
namespace simgear {
HLAVariantDataType::HLAVariantDataType(const std::string& name) :
HLADataType(name)
{
}
HLAVariantDataType::~HLAVariantDataType()
{
}
void
HLAVariantDataType::accept(HLADataTypeVisitor& visitor) const
{
visitor.apply(*this);
}
const HLAVariantDataType*
HLAVariantDataType::toVariantDataType() const
{
return this;
}
bool
HLAVariantDataType::decode(HLADecodeStream& stream, HLAAbstractVariantDataElement& value) const
{
if (!stream.alignOffsetForSize(getAlignment()))
return false;
if (!_enumeratedDataType.valid())
return false;
unsigned index = ~0u;
if (!_enumeratedDataType->decode(stream, index))
return false;
if (!value.setAlternativeIndex(index))
return false;
if (!value.decodeAlternative(stream))
return false;
return true;
}
bool
HLAVariantDataType::encode(HLAEncodeStream& stream, const HLAAbstractVariantDataElement& value) const
{
if (!stream.alignOffsetForSize(getAlignment()))
return false;
if (!_enumeratedDataType.valid())
return false;
unsigned index = value.getAlternativeIndex();
if (!_enumeratedDataType->encode(stream, index))
return false;
if (!value.encodeAlternative(stream))
return false;
return true;
}
void
HLAVariantDataType::setEnumeratedDataType(HLAEnumeratedDataType* dataType)
{
_enumeratedDataType = dataType;
}
bool
HLAVariantDataType::addAlternative(const std::string& name, const std::string& enumerator,
const HLADataType* dataType, const std::string& semantics)
{
if (!_enumeratedDataType.valid())
return false;
unsigned index = _enumeratedDataType->getIndex(enumerator);
if (_enumeratedDataType->getNumEnumerators() <= index)
return false;
_alternativeList.resize(_enumeratedDataType->getNumEnumerators());
_alternativeList[index]._name = name;
_alternativeList[index]._dataType = dataType;
_alternativeList[index]._semantics = semantics;
setAlignment(SGMisc<unsigned>::max(getAlignment(), dataType->getAlignment()));
return true;
}
} // namespace simgear

View File

@@ -0,0 +1,102 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef HLAVariantDataType_hxx
#define HLAVariantDataType_hxx
#include <string>
#include <vector>
#include "simgear/structure/SGSharedPtr.hxx"
#include "HLADataType.hxx"
#include "HLAEnumeratedDataType.hxx"
namespace simgear {
class HLAAbstractVariantDataElement;
class HLAVariantDataType : public HLADataType {
public:
HLAVariantDataType(const std::string& name = "HLAVariantDataType");
virtual ~HLAVariantDataType();
virtual void accept(HLADataTypeVisitor& visitor) const;
virtual const HLAVariantDataType* toVariantDataType() const;
virtual bool decode(HLADecodeStream& stream, HLAAbstractVariantDataElement& value) const;
virtual bool encode(HLAEncodeStream& stream, const HLAAbstractVariantDataElement& value) const;
const HLAEnumeratedDataType* getEnumeratedDataType() const
{ return _enumeratedDataType.get(); }
void setEnumeratedDataType(HLAEnumeratedDataType* dataType);
bool addAlternative(const std::string& name, const std::string& enumerator,
const HLADataType* dataType, const std::string& semantics);
unsigned getNumAlternatives() const
{ return _alternativeList.size(); }
unsigned getAlternativeIndex(const std::string& enumerator) const
{
if (!_enumeratedDataType.valid())
return ~unsigned(0);
return _enumeratedDataType->getIndex(enumerator);
}
const HLADataType* getAlternativeDataType(unsigned index) const
{
if (_alternativeList.size() <= index)
return 0;
return _alternativeList[index]._dataType.get();
}
const HLADataType* getAlternativeDataType(const std::string& enumerator) const
{ return getAlternativeDataType(getAlternativeIndex(enumerator)); }
std::string getAlternativeName(unsigned index) const
{
if (_alternativeList.size() <= index)
return std::string();
return _alternativeList[index]._name;
}
std::string getAlternativeName(const std::string& enumerator) const
{ return getAlternativeName(getAlternativeIndex(enumerator)); }
std::string getAlternativeSemantics(unsigned index) const
{
if (_alternativeList.size() <= index)
return std::string();
return _alternativeList[index]._semantics;
}
std::string getAlternativeSemantics(const std::string& enumerator) const
{ return getAlternativeSemantics(getAlternativeIndex(enumerator)); }
private:
SGSharedPtr<HLAEnumeratedDataType> _enumeratedDataType;
struct Alternative {
std::string _name;
SGSharedPtr<const HLADataType> _dataType;
std::string _semantics;
};
typedef std::vector<Alternative> AlternativeList;
AlternativeList _alternativeList;
};
} // namespace simgear
#endif

69
simgear/hla/Makefile.am Normal file
View File

@@ -0,0 +1,69 @@
INCLUDES = -I$(top_srcdir)
lib_LIBRARIES = libsghla.a
libsghla_adir = @includedir@/hla
libsghla_a_HEADERS = \
RTIData.hxx \
HLAArrayDataElement.hxx \
HLAArrayDataType.hxx \
HLABasicDataElement.hxx \
HLABasicDataType.hxx \
HLADataElement.hxx \
HLADataType.hxx \
HLADataTypeVisitor.hxx \
HLAEnumeratedDataElement.hxx \
HLAEnumeratedDataType.hxx \
HLAFixedRecordDataElement.hxx \
HLAFixedRecordDataType.hxx \
HLAFederate.hxx \
HLAInteractionClass.hxx \
HLALocation.hxx \
HLAObjectClass.hxx \
HLAObjectInstance.hxx \
HLAOMTXmlVisitor.hxx \
HLAPropertyDataElement.hxx \
HLARawDataElement.hxx \
HLAVariantDataElement.hxx \
HLAVariantDataType.hxx
libsghla_a_SOURCES = \
RTIObjectClass.cxx \
RTIObjectInstance.cxx \
RTIFederate.cxx \
HLAArrayDataElement.cxx \
HLAArrayDataType.cxx \
HLABasicDataElement.cxx \
HLABasicDataType.cxx \
HLADataElement.cxx \
HLADataType.cxx \
HLAEnumeratedDataElement.cxx \
HLAEnumeratedDataType.cxx \
HLAFederate.cxx \
HLAFixedRecordDataElement.cxx \
HLAFixedRecordDataType.cxx \
HLAObjectClass.cxx \
HLAObjectInstance.cxx \
HLAOMTXmlVisitor.cxx \
HLAPropertyDataElement.cxx \
HLARawDataElement.cxx \
HLAVariantDataElement.cxx \
HLAVariantDataType.cxx
if ENABLE_HLA13
lib_LIBRARIES += libsghla13.a
libsghla13_adir = @includedir@/hla
libsghla13_a_HEADERS = \
HLA13Federate.hxx
libsghla13_a_SOURCES = \
RTI13ObjectClass.cxx \
RTI13ObjectInstance.cxx \
RTI13Federate.cxx \
HLA13Federate.cxx
endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,510 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "RTI13Federate.hxx"
#include "RTI13Ambassador.hxx"
namespace simgear {
RTI13Federate::RTI13Federate() :
_tickTimeout(10),
_ambassador(new RTI13Ambassador)
{
}
RTI13Federate::~RTI13Federate()
{
}
bool
RTI13Federate::createFederationExecution(const std::string& federationName, const std::string& objectModel)
{
try {
_ambassador->createFederationExecution(federationName, objectModel);
return true;
} catch (RTI::FederationExecutionAlreadyExists& e) {
return true;
} catch (RTI::CouldNotOpenFED& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::ErrorReadingFED& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason);
return false;
}
}
bool
RTI13Federate::destroyFederationExecution(const std::string& federation)
{
try {
_ambassador->destroyFederationExecution(federation);
return true;
} catch (RTI::FederatesCurrentlyJoined& e) {
return true;
} catch (RTI::FederationExecutionDoesNotExist& e) {
return true;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not destroy federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not destroy federation execution: " << e._name << " " << e._reason);
return false;
}
}
bool
RTI13Federate::join(const std::string& federateType, const std::string& federationName)
{
try {
_federateHandle = _ambassador->joinFederationExecution(federateType, federationName);
SG_LOG(SG_NETWORK, SG_INFO, "RTI: Joined federation \""
<< federationName << "\" as \"" << federateType << "\"");
setFederateType(federateType);
setFederationName(federationName);
return true;
} catch (RTI::FederateAlreadyExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederationExecutionDoesNotExist& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::CouldNotOpenFED& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::ErrorReadingFED& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason);
return false;
}
}
bool
RTI13Federate::resign()
{
try {
_ambassador->resignFederationExecution();
SG_LOG(SG_NETWORK, SG_INFO, "RTI: Resigned from federation.");
_federateHandle = -1;
return true;
} catch (RTI::FederateOwnsAttributes& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::InvalidResignAction& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
}
}
bool
RTI13Federate::registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag)
{
try {
_ambassador->registerFederationSynchronizationPoint(label, tag);
SG_LOG(SG_NETWORK, SG_INFO, "RTI: registerFederationSynchronizationPoint(" << label << ", tag )");
return true;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register federation synchronization point: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register federation synchronization point: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register federation synchronization point: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register federation synchronization point: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register federation synchronization point: " << e._name << " " << e._reason);
return false;
}
}
bool
RTI13Federate::waitForFederationSynchronizationPointAnnounced(const std::string& label)
{
while (!_ambassador->getFederationSynchronizationPointAnnounced(label)) {
_ambassador->tick(_tickTimeout, 0);
_ambassador->processQueues();
}
return true;
}
bool
RTI13Federate::synchronizationPointAchieved(const std::string& label)
{
try {
_ambassador->synchronizationPointAchieved(label);
SG_LOG(SG_NETWORK, SG_INFO, "RTI: synchronizationPointAchieved(" << label << ")");
return true;
} catch (RTI::SynchronizationPointLabelWasNotAnnounced& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not signal synchronization point: " << e._name << " " << e._reason);
return false;
}
}
bool
RTI13Federate::waitForFederationSynchronized(const std::string& label)
{
while (!_ambassador->getFederationSynchronized(label)) {
_ambassador->tick(_tickTimeout, 0);
_ambassador->processQueues();
}
return true;
}
bool
RTI13Federate::enableTimeConstrained()
{
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not enable time constrained at unconnected federate.");
return false;
}
if (_ambassador->getTimeConstrainedEnabled()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time constrained is already enabled.");
return false;
}
try {
_ambassador->enableTimeConstrained();
} catch (RTI::TimeConstrainedAlreadyEnabled& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::EnableTimeConstrainedPending& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::TimeAdvanceAlreadyInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
}
while (!_ambassador->getTimeConstrainedEnabled()) {
_ambassador->tick(_tickTimeout, 0);
_ambassador->processQueues();
}
return true;
}
bool
RTI13Federate::disableTimeConstrained()
{
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time constrained at unconnected federate.");
return false;
}
if (!_ambassador->getTimeConstrainedEnabled()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time constrained is not enabled.");
return false;
}
try {
_ambassador->disableTimeConstrained();
} catch (RTI::TimeConstrainedWasNotEnabled& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
}
return true;
}
bool
RTI13Federate::enableTimeRegulation(const SGTimeStamp& lookahead)
{
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not enable time regulation at unconnected federate.");
return false;
}
if (_ambassador->getTimeRegulationEnabled()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time regulation already enabled.");
return false;
}
try {
_ambassador->enableTimeRegulation(SGTimeStamp(), lookahead);
} catch (RTI::TimeRegulationAlreadyEnabled& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::EnableTimeRegulationPending& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::TimeAdvanceAlreadyInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::InvalidFederationTime& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::InvalidLookahead& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
}
while (!_ambassador->getTimeRegulationEnabled()) {
_ambassador->tick(_tickTimeout, 0);
_ambassador->processQueues();
}
return true;
}
bool
RTI13Federate::disableTimeRegulation()
{
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time regulation at unconnected federate.");
return false;
}
if (!_ambassador->getTimeRegulationEnabled()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time regulation is not enabled.");
return false;
}
try {
_ambassador->disableTimeRegulation();
} catch (RTI::TimeRegulationWasNotEnabled& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
}
return true;
}
bool
RTI13Federate::timeAdvanceRequestBy(const SGTimeStamp& dt)
{
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time regulation at unconnected federate.");
return false;
}
SGTimeStamp fedTime = _ambassador->getCurrentLogicalTime() + dt;
return timeAdvanceRequest(fedTime);
}
bool
RTI13Federate::timeAdvanceRequest(const SGTimeStamp& fedTime)
{
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time regulation at unconnected federate.");
return false;
}
try {
_ambassador->timeAdvanceRequest(fedTime);
} catch (RTI::InvalidFederationTime& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederationTimeAlreadyPassed& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::TimeAdvanceAlreadyInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::EnableTimeRegulationPending& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::EnableTimeConstrainedPending& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
return false;
}
while (_ambassador->getTimeAdvancePending()) {
_ambassador->tick(_tickTimeout, 0);
_ambassador->processQueues();
}
return true;
}
bool
RTI13Federate::tick()
{
bool result = _ambassador->tick();
_ambassador->processQueues();
return result;
}
bool
RTI13Federate::tick(const double& minimum, const double& maximum)
{
bool result = _ambassador->tick(minimum, maximum);
_ambassador->processQueues();
return result;
}
RTI13ObjectClass*
RTI13Federate::createObjectClass(const std::string& objectClassName, HLAObjectClass* hlaObjectClass)
{
try {
return _ambassador->createObjectClass(objectClassName, hlaObjectClass);
} catch (RTI::NameNotFound& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
return 0;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
return 0;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
return 0;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
return 0;
}
}
RTI13ObjectInstance*
RTI13Federate::getObjectInstance(const std::string& objectInstanceName)
{
try {
return _ambassador->getObjectInstance(objectInstanceName);
} catch (RTI::ObjectNotKnown& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
return 0;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
return 0;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
return 0;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason);
return 0;
}
}
}

View File

@@ -0,0 +1,88 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef RTI13Federate_hxx
#define RTI13Federate_hxx
#ifndef RTI_USES_STD_FSTREAM
#define RTI_USES_STD_FSTREAM
#endif
#include <RTI.hh>
#include "RTIFederate.hxx"
#include "RTI13ObjectClass.hxx"
#include "RTI13ObjectInstance.hxx"
namespace simgear {
class RTI13Ambassador;
class RTI13Federate : public RTIFederate {
public:
RTI13Federate();
virtual ~RTI13Federate();
virtual bool createFederationExecution(const std::string& federation, const std::string& objectModel);
virtual bool destroyFederationExecution(const std::string& federation);
/// Join with federateName the federation execution federation
virtual bool join(const std::string& federateType, const std::string& federation);
virtual bool resign();
/// Synchronization Point handling
virtual bool registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag);
virtual bool waitForFederationSynchronizationPointAnnounced(const std::string& label);
virtual bool synchronizationPointAchieved(const std::string& label);
virtual bool waitForFederationSynchronized(const std::string& label);
/// Time management
virtual bool enableTimeConstrained();
virtual bool disableTimeConstrained();
virtual bool enableTimeRegulation(const SGTimeStamp& lookahead);
virtual bool disableTimeRegulation();
virtual bool timeAdvanceRequestBy(const SGTimeStamp& dt);
virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime);
/// Process messages
virtual bool tick();
virtual bool tick(const double& minimum, const double& maximum);
virtual RTI13ObjectClass* createObjectClass(const std::string& name, HLAObjectClass* hlaObjectClass);
virtual RTI13ObjectInstance* getObjectInstance(const std::string& name);
private:
RTI13Federate(const RTI13Federate&);
RTI13Federate& operator=(const RTI13Federate&);
/// The federate handle
RTI::FederateHandle _federateHandle;
/// The timeout for the single callback tick function in
/// syncronous operations that need to wait for a callback
double _tickTimeout;
/// RTI connection
SGSharedPtr<RTI13Ambassador> _ambassador;
};
}
#endif

View File

@@ -0,0 +1,405 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "RTI13ObjectClass.hxx"
#include "RTI13Ambassador.hxx"
namespace simgear {
RTI13ObjectClass::RTI13ObjectClass(HLAObjectClass* hlaObjectClass, RTI::ObjectClassHandle& handle, RTI13Ambassador* ambassador) :
RTIObjectClass(hlaObjectClass),
_handle(handle),
_ambassador(ambassador)
{
if (0 != getOrCreateAttributeIndex("privilegeToDelete") &&
0 != getOrCreateAttributeIndex("HLAprivilegeToDeleteObject"))
SG_LOG(SG_NETWORK, SG_WARN, "RTI13ObjectClass: Cannot find object root attribute.");
}
RTI13ObjectClass::~RTI13ObjectClass()
{
}
std::string
RTI13ObjectClass::getName() const
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return std::string();
}
return ambassador->getObjectClassName(_handle);
}
unsigned
RTI13ObjectClass::getNumAttributes() const
{
return _attributeHandleVector.size();
}
unsigned
RTI13ObjectClass::getAttributeIndex(const std::string& name) const
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return ~0u;
}
try {
RTI::AttributeHandle attributeHandle = ambassador->getAttributeHandle(name, _handle);
AttributeHandleIndexMap::const_iterator i = _attributeHandleIndexMap.find(attributeHandle);
if (i != _attributeHandleIndexMap.end())
return i->second;
return ~0u;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
return ~0u;
} catch (RTI::NameNotFound& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
return ~0u;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
return ~0u;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
return ~0u;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
return ~0u;
} catch (...) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute.");
return ~0u;
}
}
unsigned
RTI13ObjectClass::getOrCreateAttributeIndex(const std::string& name)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return ~0u;
}
try {
RTI::AttributeHandle attributeHandle = ambassador->getAttributeHandle(name, _handle);
AttributeHandleIndexMap::const_iterator i = _attributeHandleIndexMap.find(attributeHandle);
if (i != _attributeHandleIndexMap.end())
return i->second;
unsigned index = _attributeHandleVector.size();
_attributeHandleIndexMap[attributeHandle] = index;
_attributeHandleVector.push_back(attributeHandle);
_attributeDataVector.push_back(name);
return index;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
return ~0u;
} catch (RTI::NameNotFound& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
return ~0u;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
return ~0u;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
return ~0u;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute: " << e._name << " " << e._reason);
return ~0u;
} catch (...) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute.");
return ~0u;
}
}
// std::string
// RTI13ObjectClass::getAttributeName(unsigned index) const
// {
// SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
// if (!ambassador.valid()) {
// SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
// return std::string();
// }
// try {
// return ambassador->getAttributeName(getAttributeHandle(index), _handle);
// } catch (RTI::ObjectClassNotDefined& e) {
// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name: " << e._name << " " << e._reason);
// return std::string();
// } catch (RTI::AttributeNotDefined& e) {
// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name: " << e._name << " " << e._reason);
// return std::string();
// } catch (RTI::FederateNotExecutionMember& e) {
// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name: " << e._name << " " << e._reason);
// return std::string();
// } catch (RTI::ConcurrentAccessAttempted& e) {
// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name: " << e._name << " " << e._reason);
// return std::string();
// } catch (RTI::RTIinternalError& e) {
// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name: " << e._name << " " << e._reason);
// return std::string();
// } catch (...) {
// SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class attribute name.");
// return std::string();
// }
// }
bool
RTI13ObjectClass::publish(const std::set<unsigned>& indexSet)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return false;
}
try {
std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(indexSet.size()));
for (std::set<unsigned>::const_iterator i = indexSet.begin(); i != indexSet.end(); ++i) {
if (_attributeHandleVector.size() <= *i) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI13ObjectClass::publish(): Invalid attribute index!");
continue;
}
attributeHandleSet->add(_attributeHandleVector[*i]);
}
ambassador->publishObjectClass(_handle, *attributeHandleSet);
for (unsigned i = 0; i < getNumAttributes(); ++i) {
_attributeDataVector[i]._published = true;
}
return true;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::AttributeNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::OwnershipAcquisitionPending& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class: " << e._name << " " << e._reason);
return false;
} catch (...) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not publish object class.");
return false;
}
}
bool
RTI13ObjectClass::unpublish()
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return false;
}
try {
ambassador->unpublishObjectClass(_handle);
for (unsigned i = 0; i < getNumAttributes(); ++i) {
_attributeDataVector[i]._published = false;
}
return true;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::ObjectClassNotPublished& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::OwnershipAcquisitionPending& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class: " << e._name << " " << e._reason);
return false;
} catch (...) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unpublish object class.");
return false;
}
}
bool
RTI13ObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return false;
}
try {
std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(indexSet.size()));
for (std::set<unsigned>::const_iterator i = indexSet.begin();
i != indexSet.end(); ++i) {
if (_attributeHandleVector.size() <= *i) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI13ObjectClass::subscribe(): Invalid attribute index!");
continue;
}
attributeHandleSet->add(_attributeHandleVector[*i]);
}
ambassador->subscribeObjectClassAttributes(_handle, *attributeHandleSet, active);
for (unsigned i = 0; i < getNumAttributes(); ++i) {
_attributeDataVector[i]._subscribed = true;
}
return true;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::AttributeNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class: " << e._name << " " << e._reason);
return false;
} catch (...) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not subscribe object class.");
return false;
}
}
bool
RTI13ObjectClass::unsubscribe()
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return 0;
}
try {
ambassador->unsubscribeObjectClass(_handle);
for (unsigned i = 0; i < getNumAttributes(); ++i) {
_attributeDataVector[i]._subscribed = false;
}
return true;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::ObjectClassNotSubscribed& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
return false;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class: " << e._name << " " << e._reason);
return false;
} catch (...) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not unsubscribe object class.");
return false;
}
}
RTIObjectInstance*
RTI13ObjectClass::registerObjectInstance(HLAObjectInstance* hlaObjectInstance)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return 0;
}
try {
return ambassador->registerObjectInstance(this, hlaObjectInstance);
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
return 0;
} catch (RTI::ObjectClassNotPublished& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
return 0;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
return 0;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
return 0;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
return 0;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
return 0;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
return 0;
}
}
}

View File

@@ -0,0 +1,87 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef RTI13ObjectClass_hxx
#define RTI13ObjectClass_hxx
#include <map>
#ifndef RTI_USES_STD_FSTREAM
#define RTI_USES_STD_FSTREAM
#endif
#include <RTI.hh>
#include <simgear/structure/SGWeakPtr.hxx>
#include "RTIObjectClass.hxx"
namespace simgear {
class RTI13Ambassador;
class RTIObjectInstance;
class RTI13ObjectClass : public RTIObjectClass {
public:
RTI13ObjectClass(HLAObjectClass* hlaObjectClass, RTI::ObjectClassHandle& handle, RTI13Ambassador* ambassador);
virtual ~RTI13ObjectClass();
const RTI::ObjectClassHandle& getHandle() const
{ return _handle; }
virtual std::string getName() const;
virtual unsigned getNumAttributes() const;
virtual unsigned getAttributeIndex(const std::string& name) const;
virtual unsigned getOrCreateAttributeIndex(const std::string& name);
unsigned getAttributeIndex(const RTI::AttributeHandle& handle) const
{
AttributeHandleIndexMap::const_iterator i = _attributeHandleIndexMap.find(handle);
if (i == _attributeHandleIndexMap.end())
return ~0u;
return i->second;
}
RTI::AttributeHandle getAttributeHandle(unsigned index) const
{
if (_attributeHandleVector.size() <= index)
return -1;
return _attributeHandleVector[index];
}
virtual bool publish(const std::set<unsigned>& indexSet);
virtual bool unpublish();
virtual bool subscribe(const std::set<unsigned>& indexSet, bool);
virtual bool unsubscribe();
virtual RTIObjectInstance* registerObjectInstance(HLAObjectInstance* hlaObjectInstance);
private:
RTI::ObjectClassHandle _handle;
SGWeakPtr<RTI13Ambassador> _ambassador;
typedef std::map<RTI::AttributeHandle, unsigned> AttributeHandleIndexMap;
AttributeHandleIndexMap _attributeHandleIndexMap;
typedef std::vector<RTI::AttributeHandle> AttributeHandleVector;
AttributeHandleVector _attributeHandleVector;
};
}
#endif

View File

@@ -0,0 +1,488 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "RTIObjectInstance.hxx"
#include "RTI13Ambassador.hxx"
namespace simgear {
RTI13ObjectInstance::RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance,
const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador, bool owned) :
RTIObjectInstance(hlaObjectInstance),
_handle(handle),
_objectClass(objectClass),
_ambassador(ambassador),
_attributeValuePairSet(RTI::AttributeSetFactory::create(objectClass->getNumAttributes()))
{
updateAttributesFromClass(owned);
}
RTI13ObjectInstance::~RTI13ObjectInstance()
{
}
const RTIObjectClass*
RTI13ObjectInstance::getObjectClass() const
{
return _objectClass.get();
}
const RTI13ObjectClass*
RTI13ObjectInstance::get13ObjectClass() const
{
return _objectClass.get();
}
std::string
RTI13ObjectInstance::getName() const
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return std::string();
}
try {
return ambassador->getObjectInstanceName(_handle);
} catch (RTI::ObjectNotKnown& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
return std::string();
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
return std::string();
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
return std::string();
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
return std::string();
} catch (...) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name.");
return std::string();
}
}
void
RTI13ObjectInstance::addToRequestQueue()
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
ambassador->addObjectInstanceForCallback(this);
}
void
RTI13ObjectInstance::deleteObjectInstance(const RTIData& tag)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
try {
ambassador->deleteObjectInstance(_handle, tag);
} catch (RTI::ObjectNotKnown& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::DeletePrivilegeNotHeld& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
}
}
void
RTI13ObjectInstance::deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
try {
ambassador->deleteObjectInstance(_handle, timeStamp, tag);
} catch (RTI::ObjectNotKnown& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::DeletePrivilegeNotHeld& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::InvalidFederationTime& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
}
}
void
RTI13ObjectInstance::localDeleteObjectInstance()
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
try {
ambassador->localDeleteObjectInstance(_handle);
} catch (RTI::ObjectNotKnown& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::FederateOwnsAttributes& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
}
}
void
RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const RTIData& tag)
{
// Retrieve an empty update struct from the memory pool
UpdateList updateList;
getUpdateFromPool(updateList);
RTI::ULong numAttribs = attributeValuePairSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
unsigned index = getAttributeIndex(attributeValuePairSet.getHandle(i));
// Get a RTIData from the data pool
getDataFromPool(index, updateList.back()._indexDataPairList);
RTI::ULong length = attributeValuePairSet.getValueLength(i);
updateList.back()._indexDataPairList.back().second.resize(length);
attributeValuePairSet.getValue(i, updateList.back()._indexDataPairList.back().second.data(), length);
updateList.back()._tag = tag;
}
RTIObjectInstance::reflectAttributeValues(updateList.front()._indexDataPairList, tag);
// Return the update data back to the pool
putUpdateToPool(updateList);
}
void
RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const SGTimeStamp& timeStamp, const RTIData& tag)
{
// Retrieve an empty update struct from the memory pool
UpdateList updateList;
getUpdateFromPool(updateList);
RTI::ULong numAttribs = attributeValuePairSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
unsigned index = getAttributeIndex(attributeValuePairSet.getHandle(i));
// Get a RTIData from the data pool
getDataFromPool(index, updateList.back()._indexDataPairList);
RTI::ULong length = attributeValuePairSet.getValueLength(i);
updateList.back()._indexDataPairList.back().second.resize(length);
attributeValuePairSet.getValue(i, updateList.back()._indexDataPairList.back().second.data(), length);
updateList.back()._tag = tag;
}
scheduleUpdates(timeStamp, updateList);
}
void
RTI13ObjectInstance::requestObjectAttributeValueUpdate()
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
try {
unsigned numAttributes = getNumAttributes();
std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(numAttributes));
for (unsigned i = 0; i < numAttributes; ++i) {
if (!getRequestAttributeUpdate(i))
continue;
attributeHandleSet->add(getAttributeHandle(i));
}
if (!attributeHandleSet->size())
return;
ambassador->requestObjectAttributeValueUpdate(_handle, *attributeHandleSet);
for (unsigned i = 0; i < numAttributes; ++i)
setRequestAttributeUpdate(i, false);
return;
} catch (RTI::ObjectNotKnown& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
return;
} catch (RTI::AttributeNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
return;
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
return;
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
return;
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
return;
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
return;
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
return;
} catch (...) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance.");
return;
}
}
void
RTI13ObjectInstance::provideAttributeValueUpdate(const RTI::AttributeHandleSet& attributes)
{
// Called from the ambassador. Just marks some instance attributes dirty so that they are sent with the next update
RTI::ULong numAttribs = attributes.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
unsigned index = getAttributeIndex(attributes.getHandle(i));
setAttributeForceUpdate(index);
}
}
void
RTI13ObjectInstance::updateAttributeValues(const RTIData& tag)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
try {
// That means clear()
_attributeValuePairSet->empty();
unsigned numAttributes = getNumAttributes();
for (unsigned i = 0; i < numAttributes; ++i) {
if (!getAttributeEffectiveUpdateEnabled(i))
continue;
const HLADataElement* dataElement = getDataElement(i);
if (!dataElement)
continue;
// FIXME cache somewhere
RTIData data;
HLAEncodeStream stream(data);
dataElement->encode(stream);
_attributeValuePairSet->add(getAttributeHandle(i), data.data(), data.size());
}
if (!_attributeValuePairSet->size())
return;
ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, tag);
for (unsigned i = 0; i < numAttributes; ++i) {
setAttributeUpdated(i);
}
} catch (RTI::ObjectNotKnown& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::AttributeNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::AttributeNotOwned& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
}
// That means clear()
_attributeValuePairSet->empty();
}
void
RTI13ObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
try {
// That means clear()
_attributeValuePairSet->empty();
unsigned numAttributes = getNumAttributes();
for (unsigned i = 0; i < numAttributes; ++i) {
if (!getAttributeEffectiveUpdateEnabled(i))
continue;
const HLADataElement* dataElement = getDataElement(i);
if (!dataElement)
continue;
// FIXME cache somewhere
RTIData data;
HLAEncodeStream stream(data);
dataElement->encode(stream);
_attributeValuePairSet->add(getAttributeHandle(i), data.data(), data.size());
}
if (!_attributeValuePairSet->size())
return;
ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, timeStamp, tag);
for (unsigned i = 0; i < numAttributes; ++i) {
setAttributeUpdated(i);
}
} catch (RTI::ObjectNotKnown& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::AttributeNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::AttributeNotOwned& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::InvalidFederationTime& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::FederateNotExecutionMember& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::ConcurrentAccessAttempted& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::SaveInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::RestoreInProgress& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
} catch (RTI::RTIinternalError& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
}
// That means clear()
_attributeValuePairSet->empty();
}
void
RTI13ObjectInstance::attributesInScope(const RTI::AttributeHandleSet& attributeHandleSet)
{
RTI::ULong numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
setAttributeInScope(getAttributeIndex(attributeHandle), true);
}
}
void
RTI13ObjectInstance::attributesOutOfScope(const RTI::AttributeHandleSet& attributeHandleSet)
{
RTI::ULong numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
setAttributeInScope(getAttributeIndex(attributeHandle), false);
}
}
void
RTI13ObjectInstance::turnUpdatesOnForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
{
RTI::ULong numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), true);
}
}
void
RTI13ObjectInstance::turnUpdatesOffForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
{
RTI::ULong numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), false);
}
}
void
RTI13ObjectInstance::requestAttributeOwnershipAssumption(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
{
}
void
RTI13ObjectInstance::attributeOwnershipDivestitureNotification(const RTI::AttributeHandleSet& attributes)
{
}
void
RTI13ObjectInstance::attributeOwnershipAcquisitionNotification(const RTI::AttributeHandleSet& attributes)
{
}
void
RTI13ObjectInstance::attributeOwnershipUnavailable(const RTI::AttributeHandleSet& attributes)
{
}
void
RTI13ObjectInstance::requestAttributeOwnershipRelease(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
{
}
void
RTI13ObjectInstance::confirmAttributeOwnershipAcquisitionCancellation(const RTI::AttributeHandleSet& attributes)
{
}
void
RTI13ObjectInstance::informAttributeOwnership(RTI::AttributeHandle attributeHandle, RTI::FederateHandle federateHandle)
{
}
void
RTI13ObjectInstance::attributeIsNotOwned(RTI::AttributeHandle attributeHandle)
{
}
void
RTI13ObjectInstance::attributeOwnedByRTI(RTI::AttributeHandle attributeHandle)
{
}
}

View File

@@ -0,0 +1,106 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef RTI13ObjectInstance_hxx
#define RTI13ObjectInstance_hxx
#include <map>
#include <memory>
#ifndef RTI_USES_STD_FSTREAM
#define RTI_USES_STD_FSTREAM
#endif
#include <RTI.hh>
#include <simgear/structure/SGWeakPtr.hxx>
#include "RTIObjectInstance.hxx"
#include "RTI13ObjectClass.hxx"
namespace simgear {
class RTI13Ambassador;
class RTI13ObjectClass;
class RTI13ObjectInstance : public RTIObjectInstance {
public:
RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance, const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador, bool owned);
virtual ~RTI13ObjectInstance();
const RTI::ObjectHandle& getHandle() const
{ return _handle; }
void setHandle(const RTI::ObjectHandle& handle)
{ _handle = handle; }
virtual const RTIObjectClass* getObjectClass() const;
const RTI13ObjectClass* get13ObjectClass() const;
unsigned getNumAttributes() const
{ return get13ObjectClass()->getNumAttributes(); }
unsigned getAttributeIndex(const std::string& name) const
{ return get13ObjectClass()->getAttributeIndex(name); }
unsigned getAttributeIndex(const RTI::AttributeHandle& handle) const
{ return get13ObjectClass()->getAttributeIndex(handle); }
RTI::AttributeHandle getAttributeHandle(unsigned index) const
{ return get13ObjectClass()->getAttributeHandle(index); }
virtual std::string getName() const;
virtual void addToRequestQueue();
virtual void deleteObjectInstance(const RTIData& tag);
virtual void deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag);
virtual void localDeleteObjectInstance();
void reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const RTIData& tag);
void reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const SGTimeStamp& timeStamp, const RTIData& tag);
virtual void requestObjectAttributeValueUpdate();
void provideAttributeValueUpdate(const RTI::AttributeHandleSet& attributes);
virtual void updateAttributeValues(const RTIData& tag);
virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag);
void attributesInScope(const RTI::AttributeHandleSet& attributes);
void attributesOutOfScope(const RTI::AttributeHandleSet& attributes);
void turnUpdatesOnForObjectInstance(const RTI::AttributeHandleSet& attributes);
void turnUpdatesOffForObjectInstance(const RTI::AttributeHandleSet& attributes);
// Not yet sure what to do here. But the dispatch functions are already there
void requestAttributeOwnershipAssumption(const RTI::AttributeHandleSet& attributes, const RTIData& tag);
void attributeOwnershipDivestitureNotification(const RTI::AttributeHandleSet& attributes);
void attributeOwnershipAcquisitionNotification(const RTI::AttributeHandleSet& attributes);
void attributeOwnershipUnavailable(const RTI::AttributeHandleSet& attributes);
void requestAttributeOwnershipRelease(const RTI::AttributeHandleSet& attributes, const RTIData& tag);
void confirmAttributeOwnershipAcquisitionCancellation(const RTI::AttributeHandleSet& attributes);
void informAttributeOwnership(RTI::AttributeHandle attributeHandle, RTI::FederateHandle federateHandle);
void attributeIsNotOwned(RTI::AttributeHandle attributeHandle);
void attributeOwnedByRTI(RTI::AttributeHandle attributeHandle);
private:
RTI::ObjectHandle _handle;
SGSharedPtr<const RTI13ObjectClass> _objectClass;
SGWeakPtr<RTI13Ambassador> _ambassador;
// cached storage for updates
std::auto_ptr<RTI::AttributeHandleValuePairSet> _attributeValuePairSet;
};
}
#endif

573
simgear/hla/RTIData.hxx Normal file
View File

@@ -0,0 +1,573 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef RTIData_hxx
#define RTIData_hxx
#include <cstring>
#include <list>
#include <simgear/misc/stdint.hxx>
namespace simgear {
/// Sigh, this is std::vector<char>, except that
/// you could feed that with external pointers without copying ...
/// Note on alignment: the c++ standard garantees (5.3.4.10) that
/// new (unsigned) char returns sufficiently aligned memory
/// for all relevant cases
class RTIData {
public:
RTIData() :
_data(0),
_size(0),
_capacity(0)
{ }
RTIData(unsigned size) :
_data(0),
_size(0),
_capacity(0)
{ resize(size); }
RTIData(char* data, unsigned size) :
_data(data),
_size(size),
_capacity(0)
{ }
RTIData(const char* data, unsigned size) :
_data(0),
_size(0),
_capacity(0)
{ setData(data, size); }
RTIData(const char* data) :
_data(0),
_size(0),
_capacity(0)
{ setData(data); }
RTIData(const RTIData& data) :
_data(0),
_size(0),
_capacity(0)
{
unsigned size = data.size();
if (size) {
resize(size);
memcpy(_data, data.data(), size);
}
}
~RTIData()
{
if (_capacity)
delete [] _data;
_data = 0;
}
const char* data() const
{ return _data; }
char* data()
{ return _data; }
unsigned size() const
{ return _size; }
bool empty() const
{ return _size == 0; }
void clear()
{
if (_capacity == 0) {
_data = 0;
_size = 0;
} else
resize(0);
}
void resize(unsigned size)
{
if (size == _size)
return;
if (_capacity < size) {
unsigned capacity = 2*_capacity;
if (size < capacity)
ensureCapacity(capacity);
else
ensureCapacity(size);
}
_size = size;
}
void reserve(unsigned capacity)
{
if (capacity <= _capacity)
return;
ensureCapacity(capacity);
}
void setData(char* data, unsigned size)
{
if (_capacity)
delete [] _data;
_data = data;
_size = size;
_capacity = 0;
}
void setData(const char* data, unsigned size)
{
resize(size);
if (!size)
return;
memcpy(_data, data, size);
}
void setData(const char* data)
{
if (!data) {
setData("", 1);
} else {
size_t size = strlen(data) + 1;
setData(data, size);
}
}
RTIData& operator=(const RTIData& data)
{
unsigned size = data.size();
if (size) {
resize(size);
memcpy(_data, data.data(), size);
}
return *this;
}
void getData8(char data[1], unsigned offset = 0) const
{
data[0] = _data[offset];
}
void setData8(const char data[1], unsigned offset = 0)
{
_data[offset] = data[0];
}
void getData16LE(char data[2], unsigned offset = 0) const
{
if (hostIsLittleEndian()) {
data[0] = _data[offset];
data[1] = _data[offset+1];
} else {
data[1] = _data[offset];
data[0] = _data[offset+1];
}
}
void setData16LE(const char data[2], unsigned offset = 0)
{
if (hostIsLittleEndian()) {
_data[offset] = data[0];
_data[offset+1] = data[1];
} else {
_data[offset] = data[1];
_data[offset+1] = data[0];
}
}
void getData16BE(char data[2], unsigned offset = 0) const
{
if (hostIsLittleEndian()) {
data[1] = _data[offset];
data[0] = _data[offset+1];
} else {
data[0] = _data[offset];
data[1] = _data[offset+1];
}
}
void setData16BE(const char data[2], unsigned offset = 0)
{
if (hostIsLittleEndian()) {
_data[offset] = data[1];
_data[offset+1] = data[0];
} else {
_data[offset] = data[0];
_data[offset+1] = data[1];
}
}
void getData32LE(char data[4], unsigned offset = 0) const
{
if (hostIsLittleEndian()) {
data[0] = _data[offset];
data[1] = _data[offset+1];
data[2] = _data[offset+2];
data[3] = _data[offset+3];
} else {
data[3] = _data[offset];
data[2] = _data[offset+1];
data[1] = _data[offset+2];
data[0] = _data[offset+3];
}
}
void setData32LE(const char data[4], unsigned offset = 0)
{
if (hostIsLittleEndian()) {
_data[offset] = data[0];
_data[offset+1] = data[1];
_data[offset+2] = data[2];
_data[offset+3] = data[3];
} else {
_data[offset] = data[3];
_data[offset+1] = data[2];
_data[offset+2] = data[1];
_data[offset+3] = data[0];
}
}
void getData32BE(char data[4], unsigned offset = 0) const
{
if (hostIsLittleEndian()) {
data[3] = _data[offset];
data[2] = _data[offset+1];
data[1] = _data[offset+2];
data[0] = _data[offset+3];
} else {
data[0] = _data[offset];
data[1] = _data[offset+1];
data[2] = _data[offset+2];
data[3] = _data[offset+3];
}
}
void setData32BE(const char data[4], unsigned offset = 0)
{
if (hostIsLittleEndian()) {
_data[offset] = data[3];
_data[offset+1] = data[2];
_data[offset+2] = data[1];
_data[offset+3] = data[0];
} else {
_data[offset] = data[0];
_data[offset+1] = data[1];
_data[offset+2] = data[2];
_data[offset+3] = data[3];
}
}
void getData64LE(char data[8], unsigned offset = 0) const
{
if (hostIsLittleEndian()) {
data[0] = _data[offset];
data[1] = _data[offset+1];
data[2] = _data[offset+2];
data[3] = _data[offset+3];
data[4] = _data[offset+4];
data[5] = _data[offset+5];
data[6] = _data[offset+6];
data[7] = _data[offset+7];
} else {
data[7] = _data[offset];
data[6] = _data[offset+1];
data[5] = _data[offset+2];
data[4] = _data[offset+3];
data[3] = _data[offset+4];
data[2] = _data[offset+5];
data[1] = _data[offset+6];
data[0] = _data[offset+7];
}
}
void setData64LE(const char data[8], unsigned offset = 0)
{
if (hostIsLittleEndian()) {
_data[offset] = data[0];
_data[offset+1] = data[1];
_data[offset+2] = data[2];
_data[offset+3] = data[3];
_data[offset+4] = data[4];
_data[offset+5] = data[5];
_data[offset+6] = data[6];
_data[offset+7] = data[7];
} else {
_data[offset] = data[7];
_data[offset+1] = data[6];
_data[offset+2] = data[5];
_data[offset+3] = data[4];
_data[offset+4] = data[3];
_data[offset+5] = data[2];
_data[offset+6] = data[1];
_data[offset+7] = data[0];
}
}
void getData64BE(char data[8], unsigned offset = 0) const
{
if (hostIsLittleEndian()) {
data[7] = _data[offset];
data[6] = _data[offset+1];
data[5] = _data[offset+2];
data[4] = _data[offset+3];
data[3] = _data[offset+4];
data[2] = _data[offset+5];
data[1] = _data[offset+6];
data[0] = _data[offset+7];
} else {
data[0] = _data[offset];
data[1] = _data[offset+1];
data[2] = _data[offset+2];
data[3] = _data[offset+3];
data[4] = _data[offset+4];
data[5] = _data[offset+5];
data[6] = _data[offset+6];
data[7] = _data[offset+7];
}
}
void setData64BE(const char data[8], unsigned offset = 0)
{
if (hostIsLittleEndian()) {
_data[offset] = data[7];
_data[offset+1] = data[6];
_data[offset+2] = data[5];
_data[offset+3] = data[4];
_data[offset+4] = data[3];
_data[offset+5] = data[2];
_data[offset+6] = data[1];
_data[offset+7] = data[0];
} else {
_data[offset] = data[0];
_data[offset+1] = data[1];
_data[offset+2] = data[2];
_data[offset+3] = data[3];
_data[offset+4] = data[4];
_data[offset+5] = data[5];
_data[offset+6] = data[6];
_data[offset+7] = data[7];
}
}
#define TYPED_GETSET_IMPLEMENTATION(type, base, suffix) \
type get##base##suffix(unsigned offset = 0) const \
{ \
union { \
type t; \
char u8[sizeof(type)]; \
} u; \
getData##suffix(u.u8, offset); \
return u.t; \
} \
void set##base##suffix(type value, unsigned offset = 0) \
{ \
union { \
type t; \
char u8[sizeof(type)]; \
} u; \
u.t = value; \
setData##suffix(u.u8, offset); \
}
TYPED_GETSET_IMPLEMENTATION(uint8_t, UInt, 8)
TYPED_GETSET_IMPLEMENTATION(int8_t, Int, 8)
TYPED_GETSET_IMPLEMENTATION(uint16_t, UInt, 16LE)
TYPED_GETSET_IMPLEMENTATION(uint16_t, UInt, 16BE)
TYPED_GETSET_IMPLEMENTATION(int16_t, Int, 16LE)
TYPED_GETSET_IMPLEMENTATION(int16_t, Int, 16BE)
TYPED_GETSET_IMPLEMENTATION(uint32_t, UInt, 32LE)
TYPED_GETSET_IMPLEMENTATION(uint32_t, UInt, 32BE)
TYPED_GETSET_IMPLEMENTATION(int32_t, Int, 32LE)
TYPED_GETSET_IMPLEMENTATION(int32_t, Int, 32BE)
TYPED_GETSET_IMPLEMENTATION(uint64_t, UInt, 64LE)
TYPED_GETSET_IMPLEMENTATION(uint64_t, UInt, 64BE)
TYPED_GETSET_IMPLEMENTATION(int64_t, Int, 64LE)
TYPED_GETSET_IMPLEMENTATION(int64_t, Int, 64BE)
TYPED_GETSET_IMPLEMENTATION(float, Float, 32LE)
TYPED_GETSET_IMPLEMENTATION(float, Float, 32BE)
TYPED_GETSET_IMPLEMENTATION(double, Float, 64LE)
TYPED_GETSET_IMPLEMENTATION(double, Float, 64BE)
#undef TYPED_GETSET_IMPLEMENTATION
private:
static inline bool hostIsLittleEndian()
{
union {
uint16_t u16;
uint8_t u8[2];
} u;
u.u16 = 1;
return u.u8[0] == 1;
}
void ensureCapacity(unsigned capacity)
{
if (capacity < 32)
capacity = 32;
char* data = new char[capacity];
if (_size)
memcpy(data, _data, _size);
if (_capacity)
delete [] _data;
_data = data;
_capacity = capacity;
}
char* _data;
unsigned _size;
unsigned _capacity;
};
// A single attribute/parameter update blob
typedef std::pair<unsigned, RTIData> RTIIndexDataPair;
// A complete set of updates we received in one reflect/receive call
typedef std::list<RTIIndexDataPair> RTIIndexDataPairList;
/// Gets an own header at some time
class RTIBasicDataStream {
public:
RTIBasicDataStream() : _offset(0) {}
/// Get aligned offset that aligns to a multiple of size
static inline unsigned getAlignedOffset(unsigned offset, unsigned size)
{
return ((offset + size - 1)/size) * size;
}
protected:
unsigned _offset;
};
class HLADecodeStream : public RTIBasicDataStream {
public:
HLADecodeStream(const RTIData& value) :
_value(value)
{ }
bool alignOffsetForSize(unsigned size)
{
_offset = getAlignedOffset(_offset, size);
return _offset <= _value.size();
}
bool skip(unsigned size)
{
_offset += size;
return _offset <= _value.size();
}
bool eof() const
{ return _value.size() <= _offset; }
const RTIData& getData() const
{ return _value; }
#define TYPED_READ_IMPLEMENTATION(type, base, suffix) \
bool decode##base##suffix(type& value) \
{ \
if (_value.size() < _offset + sizeof(type)) \
return false; \
value = _value.get##base##suffix(_offset); \
_offset += sizeof(type); \
return true; \
}
TYPED_READ_IMPLEMENTATION(uint8_t, UInt, 8)
TYPED_READ_IMPLEMENTATION(int8_t, Int, 8)
TYPED_READ_IMPLEMENTATION(uint16_t, UInt, 16LE)
TYPED_READ_IMPLEMENTATION(uint16_t, UInt, 16BE)
TYPED_READ_IMPLEMENTATION(int16_t, Int, 16LE)
TYPED_READ_IMPLEMENTATION(int16_t, Int, 16BE)
TYPED_READ_IMPLEMENTATION(uint32_t, UInt, 32LE)
TYPED_READ_IMPLEMENTATION(uint32_t, UInt, 32BE)
TYPED_READ_IMPLEMENTATION(int32_t, Int, 32LE)
TYPED_READ_IMPLEMENTATION(int32_t, Int, 32BE)
TYPED_READ_IMPLEMENTATION(uint64_t, UInt, 64LE)
TYPED_READ_IMPLEMENTATION(uint64_t, UInt, 64BE)
TYPED_READ_IMPLEMENTATION(int64_t, Int, 64LE)
TYPED_READ_IMPLEMENTATION(int64_t, Int, 64BE)
TYPED_READ_IMPLEMENTATION(float, Float, 32LE)
TYPED_READ_IMPLEMENTATION(float, Float, 32BE)
TYPED_READ_IMPLEMENTATION(double, Float, 64LE)
TYPED_READ_IMPLEMENTATION(double, Float, 64BE)
#undef TYPED_READ_IMPLEMENTATION
private:
const RTIData& _value;
};
class HLAEncodeStream : public RTIBasicDataStream {
public:
HLAEncodeStream(RTIData& value) :
_value(value)
{ }
bool alignOffsetForSize(unsigned size)
{
_offset = getAlignedOffset(_offset, size);
_value.resize(_offset);
return true;
}
bool skip(unsigned size)
{
_offset += size;
_value.resize(_offset);
return true;
}
bool eof() const
{ return _value.size() <= _offset; }
void setData(const RTIData& data)
{ _value = data; }
#define TYPED_WRITE_IMPLEMENTATION(type, base, suffix) \
bool encode##base##suffix(type value) \
{ \
unsigned nextOffset = _offset + sizeof(type); \
_value.resize(nextOffset); \
_value.set##base##suffix(value, _offset); \
_offset = nextOffset; \
return true; \
}
TYPED_WRITE_IMPLEMENTATION(uint8_t, UInt, 8)
TYPED_WRITE_IMPLEMENTATION(int8_t, Int, 8)
TYPED_WRITE_IMPLEMENTATION(uint16_t, UInt, 16LE)
TYPED_WRITE_IMPLEMENTATION(uint16_t, UInt, 16BE)
TYPED_WRITE_IMPLEMENTATION(int16_t, Int, 16LE)
TYPED_WRITE_IMPLEMENTATION(int16_t, Int, 16BE)
TYPED_WRITE_IMPLEMENTATION(uint32_t, UInt, 32LE)
TYPED_WRITE_IMPLEMENTATION(uint32_t, UInt, 32BE)
TYPED_WRITE_IMPLEMENTATION(int32_t, Int, 32LE)
TYPED_WRITE_IMPLEMENTATION(int32_t, Int, 32BE)
TYPED_WRITE_IMPLEMENTATION(uint64_t, UInt, 64LE)
TYPED_WRITE_IMPLEMENTATION(uint64_t, UInt, 64BE)
TYPED_WRITE_IMPLEMENTATION(int64_t, Int, 64LE)
TYPED_WRITE_IMPLEMENTATION(int64_t, Int, 64BE)
TYPED_WRITE_IMPLEMENTATION(float, Float, 32LE)
TYPED_WRITE_IMPLEMENTATION(float, Float, 32BE)
TYPED_WRITE_IMPLEMENTATION(double, Float, 64LE)
TYPED_WRITE_IMPLEMENTATION(double, Float, 64BE)
#undef TYPED_WRITE_IMPLEMENTATION
private:
RTIData& _value;
};
} // namespace simgear
#endif

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "RTIFederate.hxx"
namespace simgear {
RTIFederate::RTIFederate()
{
}
RTIFederate::~RTIFederate()
{
}
}

View File

@@ -0,0 +1,96 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef RTIFederate_hxx
#define RTIFederate_hxx
#include <string>
#include "simgear/structure/SGWeakReferenced.hxx"
#include "RTIObjectClass.hxx"
#include "RTIObjectInstance.hxx"
class SGTimeStamp;
namespace simgear {
class RTIFederate : public SGWeakReferenced {
public:
RTIFederate();
virtual ~RTIFederate();
/// Get the name of the joined federate/federation
const std::string& getFederateType() const
{ return _federateType; }
const std::string& getFederationName() const
{ return _federationName; }
/// Create a federation execution
/// Semantically this methods should be static,
/// but the nonstatic case could reuse the connection to the server
/// FIXME: cannot determine from the return value if we created the execution
virtual bool createFederationExecution(const std::string& federation, const std::string& objectModel) = 0;
virtual bool destroyFederationExecution(const std::string& federation) = 0;
/// Join with federateName the federation execution federation
virtual bool join(const std::string& federateType, const std::string& federation) = 0;
virtual bool resign() = 0;
/// Synchronization Point handling
virtual bool registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag) = 0;
virtual bool waitForFederationSynchronizationPointAnnounced(const std::string& label) = 0;
virtual bool synchronizationPointAchieved(const std::string& label) = 0;
virtual bool waitForFederationSynchronized(const std::string& label) = 0;
/// Time management
virtual bool enableTimeConstrained() = 0;
virtual bool disableTimeConstrained() = 0;
virtual bool enableTimeRegulation(const SGTimeStamp& lookahead) = 0;
virtual bool disableTimeRegulation() = 0;
virtual bool timeAdvanceRequestBy(const SGTimeStamp& dt) = 0;
virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime) = 0;
/// Process messages
virtual bool tick() = 0;
virtual bool tick(const double& minimum, const double& maximum) = 0;
virtual RTIObjectClass* createObjectClass(const std::string& name, HLAObjectClass* hlaObjectClass) = 0;
// virtual RTIInteractionClass* createInteractionClass(const std::string& name) = 0;
virtual RTIObjectInstance* getObjectInstance(const std::string& name) = 0;
protected:
void setFederateType(const std::string& federateType)
{ _federateType = federateType; }
void setFederationName(const std::string& federationName)
{ _federationName = federationName; }
private:
RTIFederate(const RTIFederate&);
RTIFederate& operator=(const RTIFederate&);
/// The federates name
std::string _federateType;
/// The federation execution name
std::string _federationName;
};
}
#endif

View File

@@ -0,0 +1,63 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef RTIInteractionClass_hxx
#define RTIInteractionClass_hxx
#include <set>
#include <string>
#include <vector>
#include "simgear/structure/SGReferenced.hxx"
#include "simgear/structure/SGSharedPtr.hxx"
#include "simgear/structure/SGReferenced.hxx"
#include "RTIData.hxx"
namespace simgear {
class RTIInteractionClass : public SGReferenced {
public:
RTIInteractionClass(const std::string& name);
virtual ~RTIInteractionClass();
const std::string& getName() const
{ return _name; }
virtual unsigned getNumParameters() const = 0;
virtual unsigned getParameterIndex(const std::string& name) const = 0;
virtual unsigned getOrCreateParameterIndex(const std::string& name) = 0;
virtual bool publish(const std::set<unsigned>& indexSet) = 0;
virtual bool unpublish() = 0;
virtual bool subscribe(const std::set<unsigned>& indexSet, bool) = 0;
virtual bool unsubscribe() = 0;
virtual void send(const RTIData& tag) = 0;
virtual void send(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
class ReceiveCallback : public SGReferenced {
public:
virtual ~ReceiveCallback() {}
};
private:
std::string _name;
};
}
#endif

View File

@@ -0,0 +1,66 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "RTIObjectClass.hxx"
#include "RTIObjectInstance.hxx"
namespace simgear {
RTIObjectClass::RTIObjectClass(HLAObjectClass* hlaObjectClass) :
_hlaObjectClass(hlaObjectClass)
{
}
RTIObjectClass::~RTIObjectClass()
{
}
void
RTIObjectClass::discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag) const
{
SGSharedPtr<HLAObjectClass> hlaObjectClass = _hlaObjectClass.lock();
if (!hlaObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid hla object class pointer in RTIObjectClass::discoverInstance().");
return;
}
hlaObjectClass->discoverInstance(objectInstance, tag);
}
void
RTIObjectClass::startRegistration() const
{
SGSharedPtr<HLAObjectClass> hlaObjectClass = _hlaObjectClass.lock();
if (!hlaObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid hla object class pointer in RTIObjectClass::startRegstration().");
return;
}
hlaObjectClass->startRegistrationCallback();
}
void
RTIObjectClass::stopRegistration() const
{
SGSharedPtr<HLAObjectClass> hlaObjectClass = _hlaObjectClass.lock();
if (!hlaObjectClass.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid hla object class pointer in RTIObjectClass::stopRegistration().");
return;
}
hlaObjectClass->stopRegistrationCallback();
}
}

View File

@@ -0,0 +1,122 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef RTIObjectClass_hxx
#define RTIObjectClass_hxx
#include <string>
#include <vector>
#include "simgear/structure/SGReferenced.hxx"
#include "simgear/structure/SGSharedPtr.hxx"
#include "simgear/structure/SGWeakPtr.hxx"
#include "RTIData.hxx"
#include "HLAObjectClass.hxx"
namespace simgear {
class RTIObjectInstance;
class HLAObjectClass;
class RTIObjectClass : public SGReferenced {
public:
RTIObjectClass(HLAObjectClass* hlaObjectClass);
virtual ~RTIObjectClass();
virtual std::string getName() const = 0;
virtual unsigned getNumAttributes() const = 0;
virtual unsigned getAttributeIndex(const std::string& name) const = 0;
virtual unsigned getOrCreateAttributeIndex(const std::string& name) = 0;
virtual bool publish(const std::set<unsigned>& indexSet) = 0;
virtual bool unpublish() = 0;
virtual bool subscribe(const std::set<unsigned>& indexSet, bool) = 0;
virtual bool unsubscribe() = 0;
// Factory to create an object instance that can be used in this current federate
virtual RTIObjectInstance* registerObjectInstance(HLAObjectInstance*) = 0;
void discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag) const;
void startRegistration() const;
void stopRegistration() const;
void setAttributeDataType(unsigned index, SGSharedPtr<const HLADataType> dataType)
{
if (_attributeDataVector.size() <= index)
return;
_attributeDataVector[index]._dataType = dataType;
}
const HLADataType* getAttributeDataType(unsigned index) const
{
if (_attributeDataVector.size() <= index)
return 0;
return _attributeDataVector[index]._dataType.get();
}
HLAUpdateType getAttributeUpdateType(unsigned index) const
{
if (_attributeDataVector.size() <= index)
return HLAUndefinedUpdate;
return _attributeDataVector[index]._updateType;
}
void setAttributeUpdateType(unsigned index, HLAUpdateType updateType)
{
if (_attributeDataVector.size() <= index)
return;
_attributeDataVector[index]._updateType = updateType;
}
bool getAttributeSubscribed(unsigned index) const
{
if (_attributeDataVector.size() <= index)
return false;
return _attributeDataVector[index]._subscribed;
}
bool getAttributePublished(unsigned index) const
{
if (_attributeDataVector.size() <= index)
return false;
return _attributeDataVector[index]._published;
}
std::string getAttributeName(unsigned index) const
{
if (_attributeDataVector.size() <= index)
return std::string();
return _attributeDataVector[index]._name;
}
protected:
struct AttributeData {
AttributeData(const std::string& name) : _name(name), _subscribed(false), _published(false), _updateType(HLAUndefinedUpdate) {}
std::string _name;
SGSharedPtr<const HLADataType> _dataType;
bool _subscribed;
bool _published;
HLAUpdateType _updateType;
};
typedef std::vector<AttributeData> AttributeDataVector;
AttributeDataVector _attributeDataVector;
private:
SGWeakPtr<HLAObjectClass> _hlaObjectClass;
};
}
#endif

View File

@@ -0,0 +1,90 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "RTIObjectInstance.hxx"
#include "RTIObjectClass.hxx"
#include "HLAObjectInstance.hxx"
namespace simgear {
RTIObjectInstance::RTIObjectInstance(HLAObjectInstance* hlaObjectInstance) :
_hlaObjectInstance(hlaObjectInstance),
_pendingAttributeUpdateRequest(false)
{
}
RTIObjectInstance::~RTIObjectInstance()
{
}
unsigned
RTIObjectInstance::getNumAttributes() const
{
return getObjectClass()->getNumAttributes();
}
unsigned
RTIObjectInstance::getAttributeIndex(const std::string& name) const
{
return getObjectClass()->getAttributeIndex(name);
}
std::string
RTIObjectInstance::getAttributeName(unsigned index) const
{
return getObjectClass()->getAttributeName(index);
}
void
RTIObjectInstance::removeInstance(const RTIData& tag)
{
SGSharedPtr<HLAObjectInstance> hlaObjectInstance = _hlaObjectInstance.lock();
if (!hlaObjectInstance.valid())
return;
hlaObjectInstance->removeInstance(tag);
}
void
RTIObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag)
{
for (RTIIndexDataPairList::const_iterator i = dataPairList.begin();
i != dataPairList.end(); ++i) {
reflectAttributeValue(i->first, i->second);
}
SGSharedPtr<HLAObjectInstance> hlaObjectInstance = _hlaObjectInstance.lock();
if (!hlaObjectInstance.valid())
return;
hlaObjectInstance->reflectAttributeValues(dataPairList, tag);
}
void
RTIObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList,
const SGTimeStamp& timeStamp, const RTIData& tag)
{
for (RTIIndexDataPairList::const_iterator i = dataPairList.begin();
i != dataPairList.end(); ++i) {
reflectAttributeValue(i->first, i->second);
}
SGSharedPtr<HLAObjectInstance> hlaObjectInstance = _hlaObjectInstance.lock();
if (!hlaObjectInstance.valid())
return;
hlaObjectInstance->reflectAttributeValues(dataPairList, timeStamp, tag);
}
}

View File

@@ -0,0 +1,354 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef RTIObjectInstance_hxx
#define RTIObjectInstance_hxx
#include <list>
#include <map>
#include <string>
#include <vector>
#include "simgear/debug/logstream.hxx"
#include "simgear/structure/SGReferenced.hxx"
#include "simgear/structure/SGWeakPtr.hxx"
#include "simgear/timing/timestamp.hxx"
#include "RTIData.hxx"
#include "RTIObjectClass.hxx"
#include "HLADataElement.hxx"
class SGTimeStamp;
namespace simgear {
class RTIObjectClass;
class HLAObjectInstance;
class RTIObjectInstance : public SGReferenced {
public:
RTIObjectInstance(HLAObjectInstance* hlaObjectInstance);
virtual ~RTIObjectInstance();
virtual const RTIObjectClass* getObjectClass() const = 0;
virtual std::string getName() const = 0;
unsigned getNumAttributes() const;
unsigned getAttributeIndex(const std::string& name) const;
std::string getAttributeName(unsigned index) const;
// FIXME: factor out an ambassador base
virtual void addToRequestQueue() = 0;
virtual void deleteObjectInstance(const RTIData& tag) = 0;
virtual void deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
virtual void localDeleteObjectInstance() = 0;
virtual void requestObjectAttributeValueUpdate() = 0;
virtual void updateAttributeValues(const RTIData& tag) = 0;
virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
void removeInstance(const RTIData& tag);
// Call this if you want to roll up the queued timestamed updates
// and reflect that into the attached data elements.
void reflectQueuedAttributeValues(const SGTimeStamp& timeStamp)
{
// replay all updates up to the given timestamp
UpdateListMap::iterator last = _updateListMap.upper_bound(timeStamp);
for (UpdateListMap::iterator i = _updateListMap.begin(); i != last; ++i) {
for (UpdateList::iterator j = i->second.begin(); j != i->second.end(); ++j) {
// FIXME have a variant that takes the timestamp?
reflectAttributeValues(j->_indexDataPairList, j->_tag);
}
putUpdateToPool(i->second);
}
}
void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag);
void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const SGTimeStamp& timeStamp, const RTIData& tag);
void reflectAttributeValue(unsigned i, const RTIData& data)
{
if (_attributeData.size() <= i)
return;
HLADataElement* dataElement = _attributeData[i]._dataElement.get();
if (!dataElement)
return;
HLADecodeStream stream(data);
dataElement->decode(stream);
}
const HLADataType* getAttributeDataType(unsigned i) const
{
return getObjectClass()->getAttributeDataType(i);
}
HLAUpdateType getAttributeUpdateType(unsigned i) const
{
return getObjectClass()->getAttributeUpdateType(i);
}
bool getAttributeSubscribed(unsigned i) const
{
return getObjectClass()->getAttributeSubscribed(i);
}
bool getAttributePublished(unsigned i) const
{
return getObjectClass()->getAttributePublished(i);
}
HLADataElement* getDataElement(unsigned i)
{
if (_attributeData.size() <= i)
return 0;
return _attributeData[i]._dataElement.get();
}
const HLADataElement* getDataElement(unsigned i) const
{
if (_attributeData.size() <= i)
return 0;
return _attributeData[i]._dataElement.get();
}
void setDataElement(unsigned i, HLADataElement* dataElement)
{
if (_attributeData.size() <= i)
return;
_attributeData[i]._dataElement = dataElement;
}
void updateAttributesFromClass(bool owned)
{
// FIXME: rethink that!!!
unsigned numAttributes = getNumAttributes();
unsigned i = 0;
for (; i < _attributeData.size(); ++i) {
if (getAttributePublished(i)) {
} else {
_attributeData[i].setUpdateEnabled(false);
_attributeData[i].setOwned(false);
}
}
_attributeData.resize(numAttributes);
for (; i < numAttributes; ++i) {
if (getAttributePublished(i)) {
_attributeData[i].setUpdateEnabled(true);
_attributeData[i].setOwned(owned);
} else {
_attributeData[i].setUpdateEnabled(false);
_attributeData[i].setOwned(false);
}
}
}
void setAttributeForceUpdate(unsigned i)
{
if (_attributeData.size() <= i)
return;
_attributeData[i].setForceUpdate(true);
}
void setAttributeInScope(unsigned i, bool inScope)
{
if (_attributeData.size() <= i)
return;
_attributeData[i].setInScope(inScope);
}
void setAttributeUpdateEnabled(unsigned i, bool enabled)
{
if (_attributeData.size() <= i)
return;
_attributeData[i].setUpdateEnabled(enabled);
}
void setAttributeUpdated(unsigned i)
{
if (_attributeData.size() <= i)
return;
_attributeData[i].setForceUpdate(false);
}
bool getAttributeEffectiveUpdateEnabled(unsigned i)
{
if (_attributeData.size() <= i)
return false;
if (!getAttributePublished(i))
return false;
if (!_attributeData[i]._updateEnabled)
return false;
if (!_attributeData[i]._inScope)
return false;
if (_attributeData[i]._forceUpdate)
return true;
switch (getAttributeUpdateType(i)) {
case HLAPeriodicUpdate:
return true;
case HLAConditionalUpdate:
return true; // FIXME
case HLAStaticUpdate:
return false;
default:
return false;
}
}
void setRequestAttributeUpdate(bool request)
{
for (unsigned i = 0; i < getNumAttributes(); ++i) {
if (getAttributeUpdateType(i) == HLAPeriodicUpdate)
continue;
setRequestAttributeUpdate(i, request);
}
}
void setRequestAttributeUpdate(unsigned i, bool request)
{
if (_attributeData.size() <= i)
return;
_attributeData[i].setRequestUpdate(request);
if (request) {
if (!_pendingAttributeUpdateRequest) {
_pendingAttributeUpdateRequest = true;
addToRequestQueue();
}
}
}
bool getRequestAttributeUpdate(unsigned i) const
{
if (_attributeData.size() <= i)
return false;
return _attributeData[i]._requestUpdate;
}
void flushPendingRequests()
{
if (_pendingAttributeUpdateRequest) {
requestObjectAttributeValueUpdate();
_pendingAttributeUpdateRequest = false;
}
}
protected:
// The backward reference to the user visible object
SGWeakPtr<HLAObjectInstance> _hlaObjectInstance;
// Is true if we should emit a requestattr
bool _pendingAttributeUpdateRequest;
// Contains a full update as it came in from the RTI
struct Update {
RTIIndexDataPairList _indexDataPairList;
RTIData _tag;
};
// A bunch of updates for the same timestamp
typedef std::list<Update> UpdateList;
// The timestamp sorted list of updates
typedef std::map<SGTimeStamp, UpdateList> UpdateListMap;
// The timestamped updates sorted by timestamp
UpdateListMap _updateListMap;
// The pool of unused updates so that we do not need to malloc/free each time
UpdateList _updateList;
void getUpdateFromPool(UpdateList& updateList)
{
if (_updateList.empty())
updateList.push_back(Update());
else
updateList.splice(updateList.end(), _updateList, _updateList.begin());
}
void putUpdateToPool(UpdateList& updateList)
{
for (UpdateList::iterator i = updateList.begin(); i != updateList.end(); ++i)
putDataToPool(i->_indexDataPairList);
_updateList.splice(_updateList.end(), updateList);
}
// Appends the updates in the list to the given timestamps updates
void scheduleUpdates(const SGTimeStamp& timeStamp, UpdateList& updateList)
{
UpdateListMap::iterator i = _updateListMap.find(timeStamp);
if (i == _updateListMap.end())
i = _updateListMap.insert(UpdateListMap::value_type(timeStamp, UpdateList())).first;
i->second.splice(i->second.end(), updateList);
}
// This adds raw storage for attribute index i to the end of the dataPairList.
void getDataFromPool(unsigned i, RTIIndexDataPairList& dataPairList)
{
if (_attributeData.size() <= i) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid object attribute index!");
return;
}
// Nothing left in the pool - so allocate something
if (_attributeData[i]._indexDataPairList.empty()) {
dataPairList.push_back(RTIIndexDataPairList::value_type());
dataPairList.back().first = i;
return;
}
// Take one from the pool
dataPairList.splice(dataPairList.end(),
_attributeData[i]._indexDataPairList,
_attributeData[i]._indexDataPairList.begin());
}
void putDataToPool(RTIIndexDataPairList& dataPairList)
{
while (!dataPairList.empty()) {
// Put back into the pool
unsigned i = dataPairList.front().first;
if (_attributeData.size() <= i) {
// should not happen!!!
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid object attribute index!");
dataPairList.pop_front();
} else {
_attributeData[i]._indexDataPairList.splice(_attributeData[i]._indexDataPairList.begin(),
dataPairList, dataPairList.begin());
}
}
}
struct AttributeData {
AttributeData() : _owned(false), _inScope(true), _updateEnabled(true), _forceUpdate(false), _requestUpdate(false)
{ }
// The hla level data element with tha actual local program
// accessible data.
SGSharedPtr<HLADataElement> _dataElement;
// SGSharedPtr<HLADataElement::TimeStamp> _timeStamp;
// Pool of already allocated raw data used for reflection of updates
RTIIndexDataPairList _indexDataPairList;
void setOwned(bool owned)
{ _owned = owned; }
void setInScope(bool inScope)
{ _inScope = inScope; }
void setUpdateEnabled(bool updateEnabled)
{ _updateEnabled = updateEnabled; }
void setForceUpdate(bool forceUpdate)
{ _forceUpdate = forceUpdate; }
void setRequestUpdate(bool requestUpdate)
{ _requestUpdate = requestUpdate; }
bool _owned;
bool _inScope;
bool _updateEnabled;
bool _forceUpdate;
bool _requestUpdate;
};
std::vector<AttributeData> _attributeData;
friend class HLAObjectInstance;
};
}
#endif

Some files were not shown because too many files have changed in this diff Show More