Compare commits

..

289 Commits

Author SHA1 Message Date
Torsten Dreyer
b20a49b018 bump version number to 2.7.0 2012-01-17 08:35:57 +01:00
Torsten Dreyer
5a6b760847 bump version number to 2.6.0 2012-01-17 07:46:13 +01:00
Mathias Froehlich
7e2dc443ec Use the original filename for the compressed image message. 2012-01-15 13:07:35 +01:00
ThorstenB
21f2e1f250 #599: Don't crash when a path does not exist. 2012-01-13 19:58:45 +01:00
ThorstenB
cee8c5b5c7 #199: ADd method to return the absolute (real) path. 2012-01-12 21:44:15 +01:00
Mathias Froehlich
7ee2633164 Do not disable the portability warnings on mac/win.
Since the message should help people doing textures to
provide texture files that run everywhere, do not omit
the messages just because the build platform did not
know these.
2012-01-12 18:49:54 +01:00
James Turner
6c31a721b8 #ifdefs for option GL texture compression constants - should fix Windows as well as Mac 2012-01-11 23:41:02 +00:00
Mathias Froehlich
8fc97ea1ce Log images containing data depending on an extension.
Print a descriptive warning on images that are given
in a texture format that do only work in presence of an
extension that might not be there at runtime.
2012-01-11 18:38:06 +01:00
ThorstenB
423eba3733 Alas. Fix #pragma magic for GCC <= 4.5.
push/pop was introduced for GCC4.6 only - so avoid it.
Also, properly fix the fgets warning.
2012-01-09 22:18:17 +01:00
ThorstenB
49a23fdc2e Fix final simgear GCC warnings. 2012-01-09 21:51:09 +01:00
ThorstenB
fddac2443d More #pragma magic.
Same magic as for SGSphere.
2012-01-09 21:49:34 +01:00
ThorstenB
182037ad67 Slightly better error message for invalid taxiway signs. 2012-01-09 20:27:27 +01:00
ThorstenB
5923956045 #587: don't crash on negative sizes 2012-01-09 20:21:28 +01:00
ThorstenB
a89b9f6158 #581, invalid gcc pragma syntax
Thanks to Olaf Flebbe.
2012-01-09 20:19:26 +01:00
Frederic Bouvier
d7931a28ce MSVC: don't try to compile unknown pragma 2012-01-03 21:20:37 +01:00
Stuart Buchanan
cc47d33b32 Adjust LoD ranges for 3D clouds so that they become visible at maximum range, taking into account the current cloud visibility range, and the possible size of the clouds themselves. 2012-01-02 23:10:20 +00:00
ThorstenB
68625e48b9 Fix compiler warning / test issue. 2012-01-02 23:04:40 +01:00
Erik Hofman
3496d64a52 sounds tied to listeners are never out of range 2011-12-30 11:16:58 +01:00
ThorstenB
f97ced2240 Add version suffix when building shared objects 2011-12-29 14:45:29 +01:00
Torsten Dreyer
3d44f1c825 Revert changes to xmlparse.[ch]
These files are copies from libexpat and should not be touched.
Thanks to Mathias for pointing this one out.
2011-12-26 11:40:57 +01:00
Torsten Dreyer
306c58e7ed Some more trivial warning fixes 2011-12-25 20:28:38 +01:00
Torsten Dreyer
82588b0daf Remove stray ';' 2011-12-25 20:12:48 +01:00
Torsten Dreyer
aef8f13290 Use of copy-constructors
explicitly initialize the base class in a copy-constructor instead
of implicitly calling the default constructor.
2011-12-25 20:11:06 +01:00
Torsten Dreyer
4ae7c90d49 Small warning fixes, mostly unused variables 2011-12-25 14:40:07 +01:00
Erik Hofman
cc2234bf54 Degarde lack of free sounds message from alert to bulk for this release. 2011-12-24 11:13:49 +01:00
Erik Hofman
368d280da2 surpress unitialized variuable warning for SGSphere() only 2011-12-20 10:08:20 +01:00
Erik Hofman
4faf727f1b Do not initialize _center to save unneeded initialization time. 2011-12-20 10:00:33 +01:00
Erik Hofman
f28e472f59 Throw a warning even is NDEBUG is defined 2011-12-19 15:34:11 +01:00
Erik Hofman
69c5d5c86e Intialize to prevent a 'may be used uninitialized' warning 2011-12-19 15:29:25 +01:00
Erik Hofman
f9332b813e Intialize to prevent a 'may be used uninitialized' warning 2011-12-19 15:28:11 +01:00
Erik Hofman
052ce499c9 Intialize the center to prevent a 'may be used uninitialized' warning 2011-12-19 15:25:58 +01:00
ThorstenB
54db2e0ab1 #479: avoid issues due to trailing path separators
Cut trailing separators when converting from string to sgpath.
Also, SGPath::fix does NOT replace ":". It only replaces "\" with "/",
so the "i!=1" check for Windows made no sense (rule #9: never believe
a source code comment).
2011-12-18 17:04:31 +01:00
ThorstenB
b261836f71 #512: fix compatibility issue with boost 1.48.0
Thanks to handigehansje.
2011-12-18 14:06:27 +01:00
Mathias Froehlich
a0290954d6 Return ReadResult::FILE_NOT_HANDLED for unknown extensions.
This fixes a problem with fonts no longer being correctly
loaded as a side effect of the spt meta object loader.
The readObject slot is obviously being called for several
unrelated file extensions. To make sure the search continues,
osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED needs to
be returned in this case.
2011-12-17 19:11:26 +01:00
Frederic Bouvier
112eb04079 Add new files in the MSVC project 2011-12-17 16:45:19 +01:00
Mathias Froehlich
057cbe7cc3 Correct scenery load path extension. 2011-12-16 07:39:25 +01:00
Mathias Froehlich
945a9e0ac2 Implement osg native scenery paging.
Add an in memory osg scenery loader that provides
paged scenery loading using PagedLOD nodes.
2011-12-16 07:39:25 +01:00
Erik Hofman
a92ea7f822 No need to start non looping samples automatically when getting in-range. 2011-12-13 11:40:08 +01:00
Erik Hofman
b57b223a59 Add an out_of_range property to sound samples. If set the sound is set to non playing (which allows the OpenAL sound the be free'd) 2011-12-13 11:09:12 +01:00
Erik Hofman
f377c75dbd Add vi(m) .swp files and a [Bb]uild directory 2011-12-12 13:20:49 +01:00
Erik Hofman
8d3de8dee5 Free OpenAL sounds of objects that are farther away than the max_distance. 2011-12-12 13:19:43 +01:00
ThorstenB
cfdf992600 Improve logging classes.
Replace SG_GENERAL by more specific log classes in many places.
2011-12-11 13:57:54 +01:00
Frederic Bouvier
fd8c677b87 Update MSVC 90 project (moved files) 2011-12-10 18:50:08 +01:00
Erik Hofman
ff2eb6d2d3 Properly handle stereo wav files; remove data buffer and set buffer to FAILED_BUFFER 2011-12-07 10:41:57 +01:00
ThorstenB
97fcf48caa fix sound buffer resource leak
Openal doesn't remove buffers unless they were disconnected form
their source.
2011-12-04 21:25:42 +01:00
ThorstenB
e17b3a753e sound: fix "source" resource leak
Sound resources were eaten up when a sample could not be loaded.
Restores sound for aircraft attempting to use stereo files for sound effects.
However, when loading fails, sound code still tries to load the same file
again and again (always resulting in the same "stereo files not supported"
error), which slows down simulation.
2011-12-04 20:16:36 +01:00
ThorstenB
865b0a3e56 sound manager: report a few more errors 2011-12-04 17:10:58 +01:00
Frederic Bouvier
0d1ddc5f44 Fix a copy/paste typo in Effect depth attributes 2011-12-01 19:45:18 +01:00
ThorstenB
6780a0c8d4 Fixed lib64 auto-detection (again)
Reverting the "LIB_SUFFIX" change.
Assuming recent change was unintentional (otherwise let me know James! :) ).
2011-11-30 19:50:09 +01:00
James Turner
fee652d54a Fix header installation for shared build 2011-11-30 09:45:32 +00:00
James Turner
42b7c48671 Move some OSG-dependant code into scene/util. 2011-11-29 10:23:09 +00:00
James Turner
75afee59c3 Get all the tests linking with shared-simgear, and duplicate the awkward core functions into a new file, pending a proper cleanup. 2011-11-28 23:22:43 +00:00
James Turner
ae3f718fe3 Fix naming of core library, get IO tests linking shared, and exclude OSG symbols from the core lib by setting headless mode. 2011-11-28 23:05:05 +00:00
James Turner
4b02335637 Build system tweaks to support SIMGEAR_SHARED building two libraries. Work in progress, does not link yet. 2011-11-28 22:43:57 +00:00
ThorstenB
7a52c2fa71 cmake: add option to disable building tests 2011-11-26 16:39:40 +01:00
ThorstenB
ec5d067d28 CMake: Proper support for lib vs lib64 installation
Determine name of library installation directory, i.e. "lib" vs "lib64",
which differs between all Debian-based vs all other Linux distros.
See cmake bug #11964, http://cmake.org/gitweb?p=cmake.git;a=commit;h=126c993d
Also provide a script for older (<=2.8.4) cmake
2011-11-25 12:06:54 +01:00
Erik Hofman
3c9fec78fa Slightly rearrange the buffer removing code. This should make sure the source is always stopped (required by the OpenAL spec) before a buffer is removed and added to the free source list. 2011-11-23 09:41:13 +01:00
Erik Hofman
0a08ee836c Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-11-20 19:08:04 +01:00
ThorstenB
5f804cb0eb Add another subsystem group.
Sound subsystem wants to be the last in processing - so use a
separate group.
2011-11-20 15:50:56 +01:00
Erik Hofman
a0fd942048 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-11-20 10:19:52 +01:00
Frederic Bouvier
dad1577fe3 Update VS2008 project 2011-11-19 21:19:08 +01:00
ThorstenB
338f2311d4 Merge commit 'refs/merge-requests/17' of git://gitorious.org/fg/simgear into merge-requests/17 2011-11-19 15:25:22 +01:00
ThorstenB
27a1c0288b Separate module to monitor (subsystem-)performance.
Move some code from the subsystem manager to a separate module.
Add module to evaluate performance and expose statistics to properties.
2011-11-19 15:24:43 +01:00
ThorstenB
dd45be518f Improve error messages, report file name. 2011-11-17 21:26:02 +01:00
Christian Schmitt
a9c058ba9d Allow 6-lights VASI as well (2 bars a 3 lights). 2011-11-17 17:19:58 +01:00
James Turner
3e07423778 Fix a std:: namespace issue on Windows. 2011-11-13 21:27:15 +00:00
James Turner
63ccb3df4c std:: namespace fixes, and sink some code from the subsystem header into the implementation. (Hopefully more to follow) 2011-11-13 20:34:39 +00:00
James Turner
906ef85d90 using std:: fix 2011-11-13 20:33:25 +00:00
Frederic Bouvier
895edf4f17 Fix MSVC build 2011-11-13 20:06:39 +01:00
Mathias Froehlich
ff1c035d42 Use osgDB::read*File instead of dereferencing the osgDB Registry instance. 2011-11-13 18:35:18 +01:00
Mathias Froehlich
f61fe80f60 Consolidate the different ReaderWriterOptions classes. 2011-11-13 18:35:18 +01:00
ThorstenB
dfbdcc1bf0 Replace OpenThreads with SGThread to avoid useless OSG dependency.
Untangle SG subsystems by replacing direct TileCache call with callback.
2011-11-13 15:37:49 +01:00
ThorstenB
b09636f5ca Fixed typo. 2011-11-10 22:08:23 +01:00
Erik Hofman
8727e609f0 Also stop the source if it is paused when exit. 2011-11-10 12:52:17 +01:00
Erik Hofman
40fc2907a1 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-11-10 10:29:07 +01:00
Martin Spott
81fd5535fc OpenSceneGraph 3.0 required 2011-11-09 13:55:49 +01:00
Mathias Froehlich
ad079b8ed4 modellib: Add method for deferred model loading.
Add method that schedules a ProxyNode to do
just deferred model loading instead of full scenery paging.
Add support for ProxyNodes to CheckSceneryVisitor.
Use PagedLOD instead of our own derived method.
2011-11-08 21:31:18 +01:00
PSadrozinski
a543560f7d Adding Icecode GL's polygon-offset support for effects 2011-11-06 09:47:29 -05:00
Erik Hofman
bb2cc6ef2d Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-11-05 11:41:07 +01:00
Mathias Froehlich
977f23f0e7 Remove automake ignores. 2011-11-01 13:53:29 +01:00
James Turner
24c047c94e Remove the remaining Makefiles from the code. 2011-11-01 09:28:26 +00:00
James Turner
22b4aa4d8b Remove the automake / autoconf build files. 2011-11-01 09:26:22 +00:00
Erik Hofman
110753e92c Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-10-30 10:40:00 +01:00
Mathias Froehlich
be70656745 Add a HLADataElementVisitor implementation. 2011-10-30 10:23:59 +01:00
James Turner
d36e13e8ed Make tiedpropertylist quieter. 2011-10-30 07:55:44 +00:00
James Turner
2e9896a9ab Enhancements to property-object support, add a default ctor and some typedefs. 2011-10-30 07:55:29 +00:00
Csaba Halasz
ee06ec0c40 terrasync build fix: added #include <string.h> for strlen 2011-10-30 02:14:27 +02:00
ThorstenB
aa0e3e3c9f #453: Using = as Nasal function argument crashes FG
Keep Nasal parser from crashing when "=" function misses a left-hand
element, i.e. when parsing "sin(=)".
(Or do people writing such terrible syntax deserve a crash? ;-) ).
2011-10-29 21:20:46 +02:00
ThorstenB
3477e1a4f5 terrasync improvements
Detach from console to make "Ctrl-C" work for fgfs on Linux.
Immediately start synchronization of current position when
starting at run-time.
2011-10-29 21:15:29 +02:00
ThorstenB
a4b788980c Fix terrasync airport synchronization sequence
Airport A-J were skipped. Thanks to James for spotting this.
Also corrects actual sync order.
2011-10-29 21:13:12 +02:00
James Turner
519a843340 Move ALUT 1.0 variables inside the #ifdef, to avoid some compiler warnings. 2011-10-29 11:06:24 +01:00
Mathias Froehlich
269299d913 Remove sg_sleep.*. 2011-10-28 19:11:43 +02:00
Mathias Froehlich
cc4b16b50d Fix mac build. 2011-10-28 19:10:20 +02:00
Mathias Froehlich
d10bcc8a53 Hopefully fix jenkins build. 2011-10-28 19:05:46 +02:00
Mathias Froehlich
92db9682e0 Make use of SGTimeStamp::sleep*. 2011-10-28 18:45:23 +02:00
Mathias Froehlich
cd773e4764 Add sleep implementations to SGTimeStamp.
Implement sleeping to an absolute timestamp
as well as sleeping for a relative time in
SGtimeStamp.
The reason for including this into SGTimeStamp
is that the timestamps internals are required to
do accurate sleeps to and absolute timestamp
for the posix timer implementation.
2011-10-28 18:45:23 +02:00
James Turner
f14ffd5b1d Fix a bug affecting TerraGear, and extend unit-tests to cover this. (SGPath::file returned an empty string for paths with no directory separator) 2011-10-28 12:57:07 +01:00
James Turner
e34f597fe2 Add sound test programs to the CMake build. 2011-10-28 12:29:26 +01:00
James Turner
95ddc04a73 Fix assorted compiler warnings found by Clang 2011-10-28 12:07:35 +01:00
Torsten Dreyer
c6d5cbd52c Keep VC90 project file working with SGAtomic 2011-10-27 08:18:54 +02:00
James Turner
75b695664a Change (revert!) behaviour of SGPath::base, which broke TerraGear, when used with multiple file suffixes (hgt.zip, for example). Test cases updated to match TG-required behaviour. 2011-10-26 19:57:57 +01:00
James Turner
59ecf48b72 Support stream output by SGPath directly. 2011-10-25 21:44:57 +01:00
James Turner
2fb13c76f5 Address warnings found via Clang - especially related to destructor visibility with ref_ptrs of various kinds. 2011-10-24 18:09:42 +01:00
Mathias Froehlich
7438aea869 Fix SGAtomic mutex logic. 2011-10-23 23:27:38 +02:00
Mathias Froehlich
83772c87ac Rework SGAtomic, move more into the implementation.
Mainly move many cases into the implementation file.
2011-10-23 23:03:15 +02:00
James Turner
6250f675db Fixes for headless mode. 2011-10-23 17:56:28 +01:00
James Turner
a31639682b Use a compile test to see if we need to provide the GCC atomic built-ins ourselves, or not. 2011-10-23 15:59:27 +01:00
James Turner
576979c562 Make lat/lon points in the ocean tile configurable at run-time. Not hooked up to a property yet, but soon. 2011-10-23 11:26:19 +01:00
Erik Hofman
c53989adb8 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-10-23 10:39:26 +02:00
Stuart Buchanan
a1bb62f43c Fixes to 3D clouds
- Wrap 3D clouds (e.g. Global Weather) on the surface of a sphere rather than on a plane. Cloud altitude no-longer increases with distance from the start position
 - Fix altitude of individual clouds, which where being places approx 1/2 the sprite height too high. Note that this means sprite positions in the cloud are the center of the cloud rather than the bottom.
 - Improve LOD radii, which were far too large.
2011-10-22 21:28:09 +01:00
James Turner
5eec2e7889 Support for creating a source package via CPack 2011-10-22 15:37:17 +01:00
James Turner
f4bb236c04 Add FUZZY_COMPARE to me tar unit-test, tolerate lower-order imprecision in FPUs 2011-10-21 11:21:52 +01:00
James Turner
c82df0590d SGPath rename wrapper. Let's see what Win32 makes of it. 2011-10-21 09:36:33 +01:00
James Turner
43e13f0cf2 Remove-on-destroy option for simgear::Dir, to help with cleaning up temporary directories. 2011-10-21 09:36:10 +01:00
James Turner
63a8209a83 Remove using std:: from the metar header, remove HTTP support, add very basic unit-test harness. 2011-10-21 09:35:37 +01:00
James Turner
7984f055e2 string list joining, and a test case for that and splitting. 2011-10-20 11:12:54 +01:00
Erik Hofman
3104898c7c Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-10-18 18:32:57 +02:00
James Turner
8cb716fe8e std:: namespace fixes. 2011-10-17 09:50:35 +01:00
James Turner
9cdf5ab9a1 Add another helper to strutils, to compare version strings. 2011-10-17 09:50:21 +01:00
Csaba Halasz
bcf7ed501d Compile fix: add this-> in SGExpression.hxx due to two-phase name lookup (reported by gcc 4.7) 2011-10-16 14:00:39 +02:00
Frederic Bouvier
09b0dd2b2d Fix windows build 2011-10-15 09:42:15 +02:00
James Turner
04a47dfb8d Use mkdtemp where available, avoiding linker warnings about dangerous tempnam 2011-10-15 02:06:35 +01:00
James Turner
bc9b3f6ff1 Unit test for SGBinObj, and fix a bug in large-indice handling the test revealed. 2011-10-14 21:57:34 +01:00
James Turner
086a30e61a Add default constructor to simgear::Dir 2011-10-14 19:28:21 +01:00
Erik Hofman
cd8e7a1030 Warn for stereo files. 2011-10-03 08:34:20 +02:00
Mathias Froehlich
8e92c5d985 hla: fix typo resulting in an endless loop. 2011-10-02 15:13:06 +02:00
Mathias Froehlich
5708ec5a89 hla: provide main loop capabilities for HLAFederate. 2011-10-02 14:36:33 +02:00
Mathias Froehlich
f665431132 hla: lift the event loop logic from RTI to HLAFederate. 2011-10-02 10:11:10 +02:00
Mathias Froehlich
9e27511ef9 hla: Provide createJoin and resignDestroy methods. 2011-10-01 17:46:16 +02:00
Mathias Froehlich
344f876b0a hla: disable copying for HLA*Class. 2011-10-01 10:11:33 +02:00
Mathias Froehlich
10217a3b19 rti: Implement query{GALT,LITS} in the interface and RTI13. 2011-10-01 10:04:23 +02:00
Mathias Froehlich
778cc4c435 clouds: remove unused bump mapping flags. 2011-10-01 09:21:57 +02:00
Mathias Froehlich
bd999ca090 hla: Move callbacks into the rti federate implementation. 2011-10-01 09:10:57 +02:00
Mathias Froehlich
4d9980b0e6 HLAPropertyDataElement: add virtual qualifier to destructor. 2011-10-01 08:34:13 +02:00
James Turner
a459b8fdbb Make the common case the default: no library suffix for RelWithDbg or MinSizeRel builds. Of course you can still specify a suffix if desired. 2011-09-26 13:32:34 +01:00
Mathias Froehlich
c925c02e69 automake: add thread libs to the io tests. 2011-09-24 09:55:01 +02:00
James Turner
4566bece90 Alternate, WinSock friendly reporting for host lookup failures. 2011-09-16 16:43:09 +01:00
James Turner
403b7c14aa Fix a crash where hostlookup fails entirely, thanks to Andreas Gaeb for the catch. 2011-09-16 11:37:02 +01:00
Mathias Froehlich
b3e07077fa cmake: clear the svn libraries variable if not found. 2011-09-14 17:24:49 +02:00
Andreas Gaeb
f7cee2ed56 cmake: Add headers to library components
Add headers to library components so that they get
included into the IDE project files.
2011-09-14 08:56:17 +02:00
Torsten Dreyer
b7173100c8 Merge commit 'refs/merge-requests/11' of git://gitorious.org/fg/simgear into merge-requests/11 2011-09-12 17:26:01 +02:00
Frederic Bouvier
cb496379bc Typo 2011-09-12 12:20:03 +02:00
Frederic Bouvier
c37b9c95e6 Attempt to make FindSvnClient.cmake portable 2011-09-12 12:17:06 +02:00
Frederic Bouvier
919e01f26e Fix SVN detection for Windows 2011-09-12 10:54:03 +02:00
Frederic Bouvier
cad21935d6 Auto detect 3rd Party root for Windows 2011-09-12 10:53:18 +02:00
Mathias Froehlich
d290fdfc5f cmake: Use a default build type that builds fast executables. 2011-09-12 08:10:20 +02:00
Mathias Froehlich
c77161e2b0 cmake: add quotes to string split. 2011-09-11 23:27:03 +02:00
Stuart Buchanan
d2dfb81a09 Place clouds on a curved field, rather than completely flat, so
they curve with the earth surface. Note that this does not fix
"wrapped" clouds.
2011-09-11 22:11:27 +01:00
Stuart Buchanan
4acf7ce840 Merge branch 'next' of gitorious.org:fg/simgear into next 2011-09-11 21:38:54 +01:00
Frederic Bouvier
2f6b84a2cc Lower the requirements on Cmake version (at least until Jenkins is updated) 2011-09-11 21:43:54 +02:00
Frederic Bouvier
2c00a4ac35 Enforce the use of Cmake 2.8 2011-09-11 20:48:50 +02:00
Stuart Buchanan
c27ca18674 Merge branch 'next' of gitorious.org:fg/simgear into next 2011-09-09 18:42:56 +01:00
James Turner
7c7f3d4fcd Hopefully fix test compilation on MSVC 2008+CMake 2011-09-09 11:48:11 +01:00
Mathias Froehlich
8fba4b0cbe Fix win32 SGThread::join timeout. 2011-09-08 17:41:21 +02:00
James Turner
b0015ab6e8 Further Windows Cmake tweaks. 2011-09-07 20:41:55 +01:00
James Turner
3a210d6fa6 Make sgio tests friendly to Windows. 2011-09-07 20:12:35 +01:00
James Turner
b5a4a55370 Cmake Windows tweaks. 2011-09-07 19:58:26 +01:00
Mathias Froehlich
35a449c7d0 Update the automake based build system to the last changes. 2011-09-07 18:39:04 +02:00
James Turner
1305e16425 Work (in progress) on CPack packaging for SimGear 2011-09-07 16:54:28 +01:00
Mathias Froehlich
08003ceba9 Revert to simgears thread support.
For all source directories outside of simgear/scene,
which really depends very hard on osg, avoid using osg
classes. This should reenable the use of some basic and
scenegraph independent parts of simgear without the
the need for osg.
2011-09-07 17:32:43 +02:00
Mathias Froehlich
059db643bc Reimplement SGThread and friends.
Reimplement the threading stuff using either pthreads
or win32 threads. These simple classes should help us
to stay osg independent for simgears core classes.
2011-09-07 17:32:43 +02:00
Martin Spott
39731debdc Merge commit 'refs/merge-requests/10' of git://gitorious.org/fg/simgear into next 2011-09-05 14:17:00 +02:00
Torsten Dreyer
9ef56cbc48 Merge commit 'refs/merge-requests/7' of git://gitorious.org/fg/simgear into merge-requests/7 2011-09-02 12:11:42 +02:00
Stuart Buchanan
becea84955 Merge branch 'next' of gitorious.org:fg/simgear into next 2011-09-01 19:55:11 +01:00
Dmitry Marakasov
ceac7b46fc Fix bashisms in configure.ac 2011-09-01 22:53:59 +04:00
Mathias Froehlich
594095a363 Introduce quaternion finite difference method.
This implements a function for the quaternion implementation
that computes the angular velocity that matches an explicit euler
step that propagates from a starting quaternion orientation to a
destination quaternion orientation.
2011-09-01 17:11:25 +02:00
James Turner
3397066343 One more Linux compile fix. 2011-08-31 07:26:11 -07:00
James Turner
d1d8c68bf1 Missing include on Linux 2011-10-14 12:05:31 +01:00
James Turner
d37bf8a4ae SGPath/Dir extensions to ease file handling in TerraGear. Also a unit-test, shocking. 2011-10-14 11:37:36 +01:00
James Turner
e4e31be7d4 Fix BTG writer for non-included index arrays. 2011-10-12 17:01:52 +01:00
ThorstenB
5ede8c12ba Make SGModelPlacement safe on reinit
Remove old model When init is called multiple times (i.e. reinit).
Also allow explicit removal of submodel (= init(0) ).
2011-10-11 21:28:37 +02:00
Torsten Dreyer
db509f4075 Merge branch 'next' of gitorious.org:fg/simgear into next 2011-10-08 20:36:20 +02:00
Mathias Froehlich
85e58b4a49 hla: for rti13 queue all callbacks.
This is to avoid running into the rti13 ambassadors
recursion guards. Newer rti standards will not requires this.
2011-10-08 17:44:53 +02:00
Martin Spott
64b6a4ebf2 Add missing header for printf 2011-10-07 09:57:09 +02:00
Martin Spott
a0c48de39d Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-10-07 09:39:12 +02:00
James Turner
d9a281c493 Support for 32-bit vertex indices in BTG files 2011-10-06 21:28:55 +01:00
Torsten Dreyer
eb52f38c47 Stuart Buchanan:
A further fix to the cloud placement, to make it more accurate over longer distances.
2011-10-06 16:49:09 +02:00
Torsten Dreyer
c1f51d5be7 Stuart Buchanan:
Add additional lighting factors for 3D clouds so you can set the bottom, middle, top, and shade lighting factors.
2011-10-06 16:47:03 +02:00
Torsten Dreyer
08cb2039c5 Merge commit 'refs/merge-requests/12' of git://gitorious.org/fg/simgear into merge-requests/12 2011-10-06 16:42:36 +02:00
Mathias Froehlich
6485ea4051 hla: Add flush queue request, fix comments. 2011-10-05 21:03:52 +02:00
Frederic Bouvier
aa9e91f926 Fix win32 build of decode_binobj 2011-10-05 08:13:31 +02:00
Mathias Froehlich
70ac6614e8 hla: Remove interface functions that should not be called explicitly. 2011-10-04 21:07:24 +02:00
Mathias Froehlich
64ce231705 hla: Initially request update for subscribed unowned attributes. 2011-10-04 20:55:44 +02:00
Mathias Froehlich
7a98f89e1b hla: provide a more general property data element implementation. 2011-10-04 20:32:34 +02:00
Mathias Froehlich
264e336a49 hla: add missing file fir the last commit. 2011-10-04 20:27:59 +02:00
Mathias Froehlich
595328963a hla: provide a data type visitor building a default data element tree. 2011-10-04 20:21:12 +02:00
Mathias Froehlich
d951a55be0 hla: detect string and opaque data types. 2011-10-04 19:48:34 +02:00
James Turner
7ffc84fb86 Fix decode_bin linkage with GNU ld. 2011-10-04 17:53:53 +01:00
James Turner
5871b54172 Build decode_bin helper under CMake. 2011-10-04 15:06:12 +01:00
Mathias Froehlich
92976b7735 hla: remove the now unused HLAPropertyReference{,Set}. 2011-10-03 13:11:52 +02:00
ThorstenB
2e13c1fa4b Add convenience class for change listener callbacks. 2011-10-03 11:57:48 +02:00
Martin Spott
b5134f15b4 Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-10-03 11:45:57 +02:00
Mathias Froehlich
bcb320b537 hla: Provide a directly property based api for property data element. 2011-10-03 11:21:27 +02:00
Martin Spott
1475964145 Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-10-03 10:42:38 +02:00
Martin Spott
1802ccf374 Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-10-01 22:05:53 +02:00
Martin Spott
3849de1931 Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-26 16:23:58 +02:00
Martin Spott
1a46974cb9 Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-26 11:18:56 +02:00
Martin Spott
25918b8b76 Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-16 22:55:44 +02:00
Stuart Buchanan
20bd0737a2 Make tree textures consistent across runs by replacing rand() call with
something deterministic.
2011-09-15 21:11:00 +01:00
Martin Spott
31fdfbaf38 Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-14 19:55:27 +02:00
Martin Spott
8428cae1c8 Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-14 15:50:19 +02:00
Martin Spott
65ae34169d Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-13 13:37:12 +02:00
Martin Spott
ecff995e7c Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-12 16:02:00 +02:00
Martin Spott
40dc9ff95e Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-12 09:30:27 +02:00
Martin Spott
24a421c83e Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-12 00:57:50 +02:00
Martin Spott
b204b3c8eb Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-09 18:13:12 +02:00
Martin Spott
34738bb20a Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-08 18:09:24 +02:00
Martin Spott
1b1068248d Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-08 11:48:56 +02:00
Martin Spott
9f684978cf Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-07 19:21:53 +02:00
Martin Spott
747717e2ee Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-07 18:35:40 +02:00
Martin Spott
ed7f2df04e Merge branch 'next' of git.gitorious.org:fg/simgear into next 2011-09-07 17:42:54 +02:00
Martin Spott
b159a72ce9 Fix CMake HLA fix 2011-09-05 18:45:33 +02:00
Mathias Froehlich
29faf13afd Move the decision which rti to use into HLAFederate. 2011-08-30 22:18:29 +02:00
James Turner
427d6c3316 Async lookup attempt #3 - use OpenThreads instead - I'm going to kill off SGThread imminently. 2011-08-30 15:14:14 +01:00
James Turner
eafea28266 Revert "Asynchronous host lookups+caching, attempt #2"
Bah, SGThread is a pain, need to switch to OpenThreads

This reverts commit 1cb9a79fd4.
2011-08-30 13:41:06 +01:00
James Turner
1cb9a79fd4 Asynchronous host lookups+caching, attempt #2 2011-08-30 12:51:03 +01:00
Mathias Froehlich
959791ffde Add modifyLookahead to the rti abstraction. 2011-08-30 07:28:13 +02:00
Mathias Froehlich
a5775cdb94 Add SGVec* convinience hla data elements. 2011-08-30 07:27:24 +02:00
Stuart Buchanan
05272d1070 Merge branch 'next' of gitorious.org:fg/simgear into next 2011-08-29 14:33:02 +01:00
Mathias Froehlich
b5d2cfdbea Fix error message in RTI13ObjectInstance. 2011-08-28 22:26:16 +02:00
Mathias Froehlich
e716f82670 Add query{Looahead,FederateTime} to the hla interface. 2011-08-28 21:22:02 +02:00
ThorstenB
dc5af66748 Merge commit 'refs/merge-requests/9' of git://gitorious.org/fg/simgear into merge-requests/9 2011-08-28 14:10:11 +02:00
ThorstenB
40e177a02e #329: fix issue with mismatching sound volume
Sounds played after changing view position sometimes had incorrect volume
2011-08-27 12:00:17 +02:00
ThorstenB
36a8243f73 Support absolute paths for XML includes.
Use standard path resolver when searching for includes. Includes like
  <foo include="/Aircraft/Instruments/myfile.xml">
are now also supported - no need for
  <foo include="../../../Aircraft/Instruments/myfile.xml">.
2011-08-27 11:53:15 +02:00
Stuart Buchanan
d90647e9ba Merge branch 'next' of gitorious.org:fg/simgear into next 2011-08-26 19:09:51 +01:00
James Turner
c7152af191 Further tweaks to only consider IP4 addresses for the moment, when using getaddrinfo. 2011-08-26 11:27:50 +01:00
James Turner
2f9ba31b0a Request only IP4 addresses for the moment, further work required to deal with IP6 addresses. 2011-08-26 09:36:59 +01:00
Stuart Buchanan
ef48baafcc Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-08-25 22:01:07 +01:00
Christian Schmitt
1227bd4898 Don't make CMake install HLA libs and headers in every case.
Only install them when RTI is enabled. The autotools build system
handles this equally.
2011-08-25 14:03:52 +02:00
Torsten Dreyer
09e610b900 Implement #327 Add condition checking the range of a value
New feature for <condition> elements:
An (optional) element <precision> allows for fuzzy equals checks
example:
<condition>
  <equals>
    <property>/foo</property>
    <value type="double">0.0</value>
    <precision>0.1</precision>
  </equals>
</condition>

This condition evaluates as true if /foo is within [-0.05..0.05]
(both inclusive)
The precision tag works for int, long, float and double propeties.
It has no meaning for bool properties. For string properties,
precision sets the length of the strings to compare.
2011-08-24 21:26:02 +02:00
Christian Schmitt
b317520543 Make RTI configurable 2011-08-24 13:25:46 +02:00
Christian Schmitt
25c3881782 fix some of the CMake syntax and correctly print the headless option 2011-08-24 13:23:46 +02:00
James Turner
27e8916843 Another Windows typo-fix. 2011-08-24 11:29:09 +01:00
James Turner
fa27207351 Include ws2tcpip.h header (for getaddrinfo) on Windows 2011-08-24 11:25:37 +01:00
James Turner
3753d50992 Fix a release build issue, meaning of IDLE state was overloaded, add an explicit state when we're waiting for the response start. 2011-08-24 02:30:27 -07:00
James Turner
b7654c181d Copy constructor and assignment operator for revised IPAddress 2011-08-24 02:30:02 -07:00
James Turner
50e226a146 Change IPAddress to use getaddrinfo internally, and store the sockaddr data via a pointer 2011-08-24 09:46:20 +01:00
Stuart Buchanan
991f28906e Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-08-22 21:15:58 +01:00
James Turner
f18a9493b3 Revert "Support non-blocking address lookups, and switch to getaddrinfo over gethostbyname. (Only affects netChannel - raw socket will use blocking behaviour by default, as previously)"
This reverts commit 878b504f8e.
2011-08-22 10:15:05 +01:00
James Turner
bca9a787f6 Revert "Keep automake working, added new files"
This reverts commit a175033e3b.
2011-08-22 10:15:00 +01:00
James Turner
9699d76dcb Revert "Ick, further fixes for Linux/MSVC"
This reverts commit 5f07efa12a.
2011-08-22 10:14:55 +01:00
James Turner
5f07efa12a Ick, further fixes for Linux/MSVC 2011-08-22 09:10:38 +01:00
James Turner
a175033e3b Keep automake working, added new files 2011-08-21 22:37:01 +01:00
James Turner
878b504f8e Support non-blocking address lookups, and switch to getaddrinfo over gethostbyname. (Only affects netChannel - raw socket will use blocking behaviour by default, as previously) 2011-08-21 22:30:04 +01:00
Torsten Dreyer
669ab640da Remove (last) reference to obsolete visual_enviro.hxx 2011-08-21 21:13:38 +02:00
Stuart Buchanan
2f381c22e3 Further enhancements/bug fixes to the 3D clouds:
1) Default values for [min|max]_[cloud|sprite]_[width|height] changed to be
   more logical.

2) Cloud bounding box expanded slightly to ensure they aren't over-culled

3) Cloud location now defines the _base_ of the cloud.

4) Sprites that would extend below the bottom of the cloud are now shifted
   upwards to ensure no cloud appears below the base.
2011-08-21 19:18:24 +01:00
ThorstenB
ee06c12374 Fix sg_dir dot-file handling
File dialogs never showed ".." directories for navigation, since these were
filtered by the "INCLUDE_HIDDEN" option. Only the "NO_DOT_OR_DOTDOT"
option should be used for filtering - otherwise it's impossible to show
the "."/".." directories while all other files are still hidden.
2011-08-21 14:31:08 +02:00
Torsten Dreyer
225c2803ac remove reference to obsolete visual_enviro.hxx 2011-08-20 08:51:39 +02:00
Curtis L. Olson
1e0bd6717e Add visual_enviro.hxx to the source distribution (why isn't visual_enviro.cxx
built here?)
2011-08-15 22:45:44 -05:00
Curtis L. Olson
33c84965ad Make sure hla tree is added to source distribution. 2011-08-15 22:05:18 -05:00
ThorstenB
a668e47fa1 Introduce some more logging classes.
The current habit of almost everything being in either SG_GENERAL or
SG_ALL really sucks :).
2011-08-11 23:45:19 +02:00
Curtis L. Olson
c95d76266a Fix "make dist" 2011-08-11 09:47:07 -05:00
James Turner
902948e3c6 Tweaks to queuing of HTTP/1.0 connections, and tests for sequential connections in both 1.0 and 1.1 modes. 2011-08-08 18:09:30 +01:00
Stuart Buchanan
2805a2d0cc Add support for "squashing" the billboarding of individual 3D cloud sprites, to allow thin layers of stratus to be generated by large textures. 2011-08-07 12:56:10 +01:00
Stuart Buchanan
410c5ae919 Add control of 3D cloud field wrapping. Base code was already present, but without accessor methods. 2011-08-07 11:41:25 +01:00
James Turner
7525fd5e3e Update HTTP code to support HTTP/1.0 responses, eg metarproxy 2011-08-07 10:49:13 +01:00
Frederic Bouvier
55208d7d1f Remove obsolete files 2011-08-06 16:41:02 +02:00
Frederic Bouvier
88e2cdd283 Fix issue #392: mktime takes a localtime as input. Assumption that if HAVE_DAYLIGHT is missing imply that mktime takes a gmt time is wrong (sg_time.cxx, line 482) 2011-08-06 16:26:21 +02:00
Frederic Bouvier
6ac69b604e Fix a typo 2011-08-06 15:58:31 +02:00
James Turner
76ba747706 Whoops, fix tests for user-agent being HTTP/1.1 spec 2011-08-04 19:37:30 +01:00
ThorstenB
469c0242d4 Improved CMake support for libsvn
Added missing CMake defines for SVN_CLIENT.
Don't detect libsvn without APR.
When installed, enable libsvn support by default (same as for automake).
When enabled, provide libsvn include dir to libtsync.
gitignore temporary CMake files
2011-08-04 19:28:13 +02:00
James Turner
115531e944 Further HTTP improvements, correct proxy support, spec compliance, support for chunked encoding. 2011-08-04 18:03:56 +01:00
ThorstenB
6edfacbf4e Ove Kåven: Fix property refcounting for particles 2011-08-01 19:47:19 +02:00
James Turner
a2249becba Further HTTP improvements, wget-alike test program to check it all behaves! 2011-08-01 09:03:12 +01:00
ThorstenB
b53c53d9d8 #232: resurrect the "point sprites for runway lights" switch
Automatic GL/OSG feature detection still not working, since we don't have
a "context" - but at least the manual switch works (on start-up only).
2011-07-31 14:00:48 +02:00
James Turner
13736219ff Ooops, forgot automake 2011-07-30 12:41:54 +01:00
James Turner
3ac5ff0cac Clean header dependencies of condition.hxx - introduce a new header, propsfwd.hxx, for common case of headers that only need SGPropertyNode_ptr and SGCondition_ptr 2011-07-30 10:48:37 +01:00
James Turner
19119cc4ae Tweaks to HTTP code, in preparation for using it for metar - especially, test code for proxies 2011-07-30 10:43:49 +01:00
Stuart Buchanan
38ac7b41ad Updates to random forest:
- Bug fix - use multiple textures per tile
- Graduate LoD so tree cover fades in/out.
2011-07-29 15:22:24 +01:00
Stuart Buchanan
b47d1ad5fd Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-07-26 22:17:14 +01:00
Torsten Dreyer
45f642c4e4 Don't rely on simgear/version.h
version.h is generated by the build system for official builds of
FlightGear. To avoid complicating the life of regular developers,
especially on Windows, we set HAVE_VERSION_H if version.h is generated.
If that define is not set, we include this file instead, which provides
placeholder values instead.
2011-07-25 20:22:57 +02:00
Stuart Buchanan
04dc28cb33 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-07-21 18:45:13 +01:00
Mathias Froehlich
f7e9d79322 Make it compile with gcc-4.6 2011-07-19 19:23:53 +02:00
James Turner
5c6076d72d Merge branch 'next' of gitorious.org:fg/simgear into next 2011-07-19 17:56:04 +01:00
James Turner
ee1901225b Ooof, lurking PLIB reference in the tests 2011-07-19 17:55:40 +01:00
Mathias Froehlich
b61ba449fb Fix case of SGGeometryTest.cxx 2011-07-19 18:54:02 +02:00
James Turner
d53e2fa8c1 Enable more unit-tests via CTest 2011-07-19 17:30:08 +01:00
James Turner
20ac2dcd04 Remove some debug output, fix version.h include path 2011-07-19 14:34:07 +01:00
James Turner
ac7db26f17 But of course, Mac lacks malloc.h - so you cstdlib instead. <sigh> 2011-07-19 06:17:05 -07:00
James Turner
4a65a23706 test linkage needs librt on Linux. Need to tidy this up on the FG side. 2011-07-19 13:53:13 +01:00
James Turner
425d83c497 Fix Linux compilation of netChat - explicit include of malloc.h required. 2011-07-19 05:32:39 -07:00
James Turner
a7d338a58e And not forgetting VC90 either. 2011-07-19 13:10:01 +01:00
James Turner
6a612972e2 Not forgetting automake for the moment 2011-07-19 12:56:49 +01:00
James Turner
f06f25532c Tiny HTTP client layer on top of NetChat - and CTest support for some SimGear tests. 2011-07-19 12:55:55 +01:00
ThorstenB
116c487384 Fix locale setting for Windows 2011-07-18 20:29:11 +02:00
ThorstenB
5f70abb16d Clean solution for locale problem.
Changing and reverting the locale isn't thread-safe. Instead, setup the
environment to ensure the active locale sticks to default "C" locale at
any time.
2011-07-18 20:15:50 +02:00
Stuart Buchanan
c17110f6e7 Merge branch 'next' of git://gitorious.org/fg/simgear into next 2011-07-18 19:11:25 +01:00
Torsten Dreyer
69cbc2feb5 Bump to version 2.5.0 2011-07-17 11:06:45 +02:00
Stuart Buchanan
03796f2337 Merge branches 'next' and 'next' of git://gitorious.org/fg/simgear into next 2011-07-03 19:03:06 +01:00
278 changed files with 12009 additions and 7627 deletions

17
.gitignore vendored
View File

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

View File

@@ -1,8 +1,8 @@
cmake_minimum_required (VERSION 2.6)
cmake_minimum_required (VERSION 2.6.4)
include (CheckFunctionExists)
include (CheckIncludeFile)
include (CheckCXXSourceCompiles)
include (CPack)
project(SimGear)
@@ -10,19 +10,78 @@ project(SimGear)
file(READ version versionFile)
string(STRIP ${versionFile} SIMGEAR_VERSION)
# use simgear version also as the SO version (if building SOs)
SET(SIMGEAR_SOVERSION ${SIMGEAR_VERSION})
#packaging
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simulation support libraries for FlightGear and related projects")
SET(CPACK_PACKAGE_VENDOR "The FlightGear project")
SET(CPACK_GENERATOR "TBZ2")
SET(CPACK_INSTALL_CMAKE_PROJECTS ${CMAKE_CURRENT_BINARY_DIR};SimGear;ALL;/)
# split version string into components, note CMAKE_MATCH_0 is the entire regexp match
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" CPACK_PACKAGE_VERSION ${SIMGEAR_VERSION} )
set(CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1})
set(CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2})
set(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3})
message(STATUS "version is ${CPACK_PACKAGE_VERSION_MAJOR} dot ${CPACK_PACKAGE_VERSION_MINOR} dot ${CPACK_PACKAGE_VERSION_PATCH}")
set(CPACK_SOURCE_GENERATOR TBZ2)
set(CPACK_SOURCE_PACKAGE_FILE_NAME "simgear-${SIMGEAR_VERSION}" CACHE INTERNAL "tarball basename")
set(CPACK_SOURCE_IGNORE_FILES
"^${PROJECT_SOURCE_DIR}/.git;\\\\.gitignore;Makefile.am;~$;${CPACK_SOURCE_IGNORE_FILES}")
message(STATUS "ignoring: ${CPACK_SOURCE_IGNORE_FILES}")
include (CPack)
# 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)
# Change the default build type to something fast
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)
endif(NOT CMAKE_BUILD_TYPE)
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
# Determine name of library installation directory, i.e. "lib" vs "lib64", which
# differs between all Debian-based vs all other Linux distros.
# See cmake bug #11964, http://cmake.org/gitweb?p=cmake.git;a=commit;h=126c993d
# GNUInstallDirs requires CMake >= 2.8.5, use own file for older cmake
if(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
include(GNUInstallDirs)
else(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
include(OldGNUInstallDirs)
endif(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
message(STATUS "Library installation directory: ${CMAKE_INSTALL_LIBDIR}")
option(SIMGEAR_SHARED "Set to ON to build SimGear as a shared library/framework" OFF)
option(SIMGEAR_HEADLESS "Set to ON to build SimGear without GUI/graphics support" OFF)
option(JPEG_FACTORY "Enable JPEG-factory support" OFF)
option(ENABLE_LIBSVN "Set to ON to build SimGear with libsvnclient support" ON)
option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
option(ENABLE_TESTS "Set to OFF to disable building SimGear's test applications" ON)
if (MSVC)
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_SOURCE_DIR} PATH)
if (CMAKE_CL_64)
SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty.x64")
else (CMAKE_CL_64)
SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty")
endif (CMAKE_CL_64)
if (EXISTS ${TEST_3RDPARTY_DIR})
set(MSVC_3RDPARTY_ROOT ${PARENT_DIR} CACHE PATH "Location where the third-party dependencies are extracted")
else (EXISTS ${TEST_3RDPARTY_DIR})
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
endif (EXISTS ${TEST_3RDPARTY_DIR})
else (MSVC)
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
endif (MSVC)
if (MSVC AND MSVC_3RDPARTY_ROOT)
message(STATUS "3rdparty files located in ${MSVC_3RDPARTY_ROOT}")
@@ -42,6 +101,7 @@ if (MSVC AND MSVC_3RDPARTY_ROOT)
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)
message(STATUS "BOOST_ROOT is ${BOOST_ROOT}")
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)
@@ -53,29 +113,31 @@ set (BOOST_CXX_FLAGS "-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DBOOST_BIMAP_DI
find_package(ZLIB REQUIRED)
find_package(Threads REQUIRED)
if (${SIMGEAR_HEADLESS})
message(STATUS "headlesss mode")
if(SIMGEAR_HEADLESS)
message(STATUS "headless 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()
find_package(OpenSceneGraph 3.0.0 REQUIRED osgText osgSim osgDB osgParticle osgUtil)
endif(SIMGEAR_HEADLESS)
if(JPEG_FACTORY)
message(STATUS "JPEG-factory enabled")
find_package(JPEG REQUIRED)
include_directories(${JPEG_INCLUDE_DIR})
endif()
endif(JPEG_FACTORY)
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)
else()
message(STATUS "Missing libsvn, unable to enable SVN in SimGear")
endif(LIBSVN_FOUND)
endif(ENABLE_LIBSVN)
@@ -84,18 +146,45 @@ 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)
if(ENABLE_RTI)
# See if we have any rti library variant installed
find_package(RTI)
find_package(RTI)
endif(ENABLE_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)
check_function_exists(mkdtemp HAVE_MKDTEMP)
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually d on windows")
if(HAVE_UNISTD_H)
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
check_cxx_source_compiles(
"#include <unistd.h>
#if !defined(_POSIX_TIMERS) || (0 >= _POSIX_TIMERS)
#error clock_gettime is not supported
#endif
int main() { return 0; }
"
HAVE_CLOCK_GETTIME)
endif(HAVE_UNISTD_H)
set(RT_LIBRARY "")
if(HAVE_CLOCK_GETTIME)
check_function_exists(clock_gettime CLOCK_GETTIME_IN_LIBC)
if(NOT CLOCK_GETTIME_IN_LIBC)
check_library_exists(rt clock_gettime "" HAVE_RT)
if(HAVE_RT)
set(RT_LIBRARY rt)
endif(HAVE_RT)
endif(NOT CLOCK_GETTIME_IN_LIBC)
endif(HAVE_CLOCK_GETTIME)
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")
SET(CMAKE_RELWITHDEBINFO_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
SET(CMAKE_MINSIZEREL_POSTFIX "" 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(
@@ -105,6 +194,13 @@ check_cxx_source_compiles(
if(CMAKE_COMPILER_IS_GNUCXX)
set(WARNING_FLAGS -Wall)
# certain GCC versions don't provide the atomic builds, and hence
# require is to provide them in SGAtomic.cxx
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
check_cxx_source_compiles(
"int main() { unsigned mValue; return __sync_add_and_fetch(&mValue, 1); }"
GCC_ATOMIC_BUILTINS_FOUND)
endif(CMAKE_COMPILER_IS_GNUCXX)
if(WIN32)
@@ -115,11 +211,14 @@ if(WIN32)
# 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")
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS /wd4996")
endif(MSVC)
# assumed on Windows
set(HAVE_GETLOCALTIME 1)
set( WINSOCK_LIBRARY "ws2_32.lib" )
set( RT_LIBRARY "winmm" )
endif(WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} ${MSVC_FLAGS}")
@@ -141,7 +240,14 @@ configure_file (
"${PROJECT_SOURCE_DIR}/simgear/simgear_config_cmake.h.in"
"${PROJECT_BINARY_DIR}/simgear/simgear_config.h"
)
if(ENABLE_TESTS)
# enable CTest / make test target
include (Dart)
enable_testing()
endif(ENABLE_TESTS)
install (FILES ${PROJECT_BINARY_DIR}/simgear/simgear_config.h DESTINATION include/simgear/)
add_subdirectory(simgear)
@@ -155,4 +261,3 @@ CONFIGURE_FILE(
ADD_CUSTOM_TARGET(uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")

View File

@@ -3,6 +3,31 @@
include (CheckFunctionExists)
include (CheckIncludeFile)
include (CheckLibraryExists)
macro(find_static_component comp libs)
# account for alternative Windows svn distribution naming
if(MSVC)
set(compLib "lib${comp}")
else(MSVC)
set(compLib "${comp}")
endif(MSVC)
string(TOUPPER "${comp}" compLibBase)
set( compLibName ${compLibBase}_LIBRARY )
FIND_LIBRARY(${compLibName}
NAMES ${compLib}
HINTS $ENV{PLIBDIR}
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
/usr/local
/usr
/opt
)
list(APPEND ${libs} ${${compLibName}})
endmacro()
find_program(HAVE_APR_CONFIG apr-1-config)
if(HAVE_APR_CONFIG)
@@ -16,33 +41,36 @@ if(HAVE_APR_CONFIG)
OUTPUT_STRIP_TRAILING_WHITESPACE)
# clean up some vars, or other CMake pieces complain
string(STRIP ${RAW_APR_LIBS} APR_LIBS)
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
)
if(HAVE_APR_CONFIG OR MSVC)
find_path(LIBSVN_INCLUDE_DIR svn_client.h
HINTS
$ENV{LIBSVN_DIR}
PATH_SUFFIXES include/subversion-1
PATHS
/usr/local
/usr
/opt
)
set(LIBSVN_LIBRARIES "")
if (MSVC)
find_static_component("apr-1" LIBSVN_LIBRARIES)
else (MSVC)
list(APPEND LIBSVN_LIBRARIES ${APR_LIBS})
endif (MSVC)
find_static_component("svn_client-1" LIBSVN_LIBRARIES)
find_static_component("svn_subr-1" LIBSVN_LIBRARIES)
find_static_component("svn_ra-1" LIBSVN_LIBRARIES)
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)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG LIBSVN_LIBRARIES LIBSVN_INCLUDE_DIR)
if(NOT LIBSVN_FOUND)
set(LIBSVN_LIBRARIES "")
endif(NOT LIBSVN_FOUND)
endif(HAVE_APR_CONFIG OR MSVC)

View File

@@ -0,0 +1,182 @@
# - Define GNU standard installation directories
# Provides install directory variables as defined for GNU software:
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
# Inclusion of this module defines the following variables:
# CMAKE_INSTALL_<dir> - destination for files of a given type
# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
# where <dir> is one of:
# BINDIR - user executables (bin)
# SBINDIR - system admin executables (sbin)
# LIBEXECDIR - program executables (libexec)
# SYSCONFDIR - read-only single-machine data (etc)
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
# LOCALSTATEDIR - modifiable single-machine data (var)
# LIBDIR - object code libraries (lib or lib64)
# INCLUDEDIR - C header files (include)
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
# DATAROOTDIR - read-only architecture-independent data root (share)
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
# INFODIR - info documentation (DATAROOTDIR/info)
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
# MANDIR - man documentation (DATAROOTDIR/man)
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
# install() commands for the corresponding file type. If the includer does
# not define a value the above-shown default will be used and the value will
# appear in the cache for editing by the user.
# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
# from the corresponding destination by prepending (if necessary) the value
# of CMAKE_INSTALL_PREFIX.
#=============================================================================
# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
# Copyright 2011 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 distribute this file outside of CMake, substitute the full
# License text for the above reference.)
# Installation directories
#
if(NOT DEFINED CMAKE_INSTALL_BINDIR)
set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SBINDIR)
set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR)
set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR)
set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
set(_LIBDIR_DEFAULT "lib")
# Override this default 'lib' with 'lib64' iff:
# - we are on Linux system but NOT cross-compiling
# - we are NOT on debian
# - we are on a 64 bits system
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
# Note that the future of multi-arch handling may be even
# more complicated than that: http://wiki.debian.org/Multiarch
if(CMAKE_SYSTEM_NAME MATCHES "Linux"
AND NOT CMAKE_CROSSCOMPILING
AND NOT EXISTS "/etc/debian_version")
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
message(AUTHOR_WARNING
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
"Please enable at least one language before including GNUInstallDirs.")
else()
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(_LIBDIR_DEFAULT "lib64")
endif()
endif()
endif()
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
endif()
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
endif()
if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR)
set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)")
endif()
if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR)
set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)")
endif()
#-----------------------------------------------------------------------------
# Values whose defaults are relative to DATAROOTDIR. Store empty values in
# the cache and store the defaults in local variables if the cache values are
# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes.
if(NOT CMAKE_INSTALL_DATADIR)
set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)")
set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}")
endif()
if(NOT CMAKE_INSTALL_INFODIR)
set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
endif()
if(NOT CMAKE_INSTALL_LOCALEDIR)
set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)")
set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale")
endif()
if(NOT CMAKE_INSTALL_MANDIR)
set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
endif()
if(NOT CMAKE_INSTALL_DOCDIR)
set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)")
set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}")
endif()
#-----------------------------------------------------------------------------
mark_as_advanced(
CMAKE_INSTALL_BINDIR
CMAKE_INSTALL_SBINDIR
CMAKE_INSTALL_LIBEXECDIR
CMAKE_INSTALL_SYSCONFDIR
CMAKE_INSTALL_SHAREDSTATEDIR
CMAKE_INSTALL_LOCALSTATEDIR
CMAKE_INSTALL_LIBDIR
CMAKE_INSTALL_INCLUDEDIR
CMAKE_INSTALL_OLDINCLUDEDIR
CMAKE_INSTALL_DATAROOTDIR
CMAKE_INSTALL_DATADIR
CMAKE_INSTALL_INFODIR
CMAKE_INSTALL_LOCALEDIR
CMAKE_INSTALL_MANDIR
CMAKE_INSTALL_DOCDIR
)
# Result directories
#
foreach(dir
BINDIR
SBINDIR
LIBEXECDIR
SYSCONFDIR
SHAREDSTATEDIR
LOCALSTATEDIR
LIBDIR
INCLUDEDIR
OLDINCLUDEDIR
DATAROOTDIR
DATADIR
INFODIR
LOCALEDIR
MANDIR
DOCDIR
)
if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
else()
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
endif()
endforeach()

View File

@@ -1,10 +1,10 @@
macro(simgear_component name includePath sources headers)
macro(simgear_component_common name includePath sourcesList sources headers)
if (SIMGEAR_SHARED)
foreach(s ${sources})
set_property(GLOBAL
APPEND PROPERTY ALL_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${s}")
APPEND PROPERTY ${sourcesList} "${CMAKE_CURRENT_SOURCE_DIR}/${s}")
endforeach()
foreach(h ${headers})
@@ -14,10 +14,18 @@ macro(simgear_component name includePath sources headers)
else()
set(libName "sg${name}")
add_library(${libName} STATIC ${sources} )
add_library(${libName} STATIC ${sources} ${headers})
install (TARGETS ${libName} ARCHIVE DESTINATION lib${LIB_SUFFIX})
install (FILES ${headers} DESTINATION include/simgear/${includePath})
install (TARGETS ${libName} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
install (FILES ${headers} DESTINATION include/simgear/${includePath})
endmacro()
function(simgear_component name includePath sources headers)
simgear_component_common(${name} ${includePath} CORE_SOURCES "${sources}" "${headers}")
endfunction()
function(simgear_scene_component name includePath sources headers)
simgear_component_common(${name} ${includePath} SCENE_SOURCES "${sources}" "${headers}")
endfunction()

View File

@@ -1,18 +0,0 @@
EXTRA_DIST = \
acinclude.m4 \
autogen.sh \
DoxygenMain.cxx \
README.zlib \
README.plib \
README.OpenAL \
README.OSG \
projects
SUBDIRS = simgear
#
# Rule to build RPM distribution package
#
rpm: dist
rpm -ta $(PACKAGE)-$(VERSION).tar.gz

View File

@@ -1,10 +1,9 @@
[This file is mirrored in both the FlightGear and SimGear packages.]
You *must* have OpenSceneGraph (OSG) installed to build this version of
You *must* have OpenSceneGraph (OSG) installed to build this version of
FlightGear.
Notice that FlightGear 1.9.0 requires at least version 2.7.8. Using earlier
versions of OSG will yield serious rendering bugs.
Notice that FlightGear 2.6.0 requires at least version 3.0.0.
You can get the latest version of OSG from:
@@ -22,6 +21,6 @@ ccmake .
[ While running ccmake: press 'c' to configure, press 'c' once more, and
then press 'g' to generate and exit ]
make
make
sudo make install

View File

@@ -1,706 +0,0 @@
dnl
dnl originally from ncftp 2.3.0
dnl added wi_EXTRA_PDIR and wi_ANSI_C
dnl $Id$
dnl
AC_DEFUN([wi_EXTRA_IDIR], [
incdir="$1"
if test -r $incdir ; then
already=""
for CPPflag in $CPPFLAGS ; do
if test "_$CPPflag" = "_-I${incdir}" ; then
already=yes
break
fi
done
if test -n "$already" ; then
echo " + already had -I$incdir" 1>&AS_MESSAGE_LOG_FD
else
if test "$CPPFLAGS" = "" ; then
CPPFLAGS="-I$incdir"
else
CPPFLAGS="$CPPFLAGS -I$incdir"
fi
echo " + added -I$incdir" 1>&AS_MESSAGE_LOG_FD
fi
else
echo " + IDIR is not accessible: '$myincdir'" 1>&AS_MESSAGE_LOG_FD
fi
])
dnl
dnl
dnl
dnl
AC_DEFUN([wi_EXTRA_LDIR], [
mylibdir="$1"
if test -r $mylibdir ; then
already=""
for LDflag in $LDFLAGS ; do
if test "_$LDflag" = "_-L${mylibdir}" ; then
already=yes
break
fi
done
if test -n "$already" ; then
echo " + already had -L$mylibdir" 1>&AS_MESSAGE_LOG_FD
else
if test "$LDFLAGS" = "" ; then
LDFLAGS="-L$mylibdir"
else
LDFLAGS="$LDFLAGS -L$mylibdir"
fi
echo " + added -L$mylibdir" 1>&AS_MESSAGE_LOG_FD
fi
else
echo " + LDIR is not accessible: '$mylibdir'" 1>&AS_MESSAGE_LOG_FD
fi
])
dnl
dnl __FP__
dnl
dnl
AC_DEFUN([wi_EXTRA_PDIR], [
progdir="$1"
if test -r $progdir ; then
case ":$PATH:" in
*:${progdir}:*)
echo " + already had $progdir in \$PATH" 1>&AS_MESSAGE_LOG_FD
;;
*)
if test "$PATH" = "" ; then
PATH="$progdir"
else
PATH="$PATH:$progdir"
fi
echo " + appended $progdir to \$PATH" 1>&AS_MESSAGE_LOG_FD
;;
esac
else
echo " + PDIR is not accessible: '$progdir'" 1>&AS_MESSAGE_LOG_FD
fi
])
dnl
dnl
dnl If you want to also look for include and lib subdirectories in the
dnl $HOME tree, you supply "yes" as the first argument to this macro.
dnl
dnl If you want to look for subdirectories in include/lib directories,
dnl you pass the names in argument 3, otherwise pass a dash.
dnl
AC_DEFUN([wi_EXTRA_DIRS], [echo "checking for extra include and lib directories..." 1>&6
ifelse([$1], yes, [dnl
b1=`cd .. ; pwd`
b2=`cd ../.. ; pwd`
exdirs="$HOME $j $b1 $b2 $prefix $2"
],[dnl
exdirs="$prefix $2"
])
subexdirs="$3"
if test "$subexdirs" = "" ; then
subexdirs="-"
fi
for subexdir in $subexdirs ; do
if test "$subexdir" = "-" ; then
subexdir=""
else
subexdir="/$subexdir"
fi
for exdir in $exdirs ; do
if test "$exdir" != "/usr" || test "$subexdir" != ""; then
incdir="${exdir}/include${subexdir}"
wi_EXTRA_IDIR($incdir)
dnl On 64-bit machines, if lib64/ exists and is not identical to lib/
dnl then it should be listed here, listed ahead of lib/.
mylibdir64="${exdir}/lib64${subexdir}"
mylibdir32="${exdir}/lib${subexdir}"
if test "x86_64" = $(uname -m) \
-a ! ${mylibdir64} -ef ${mylibdir32} ; then
wi_EXTRA_LDIR($mylibdir64)
fi
wi_EXTRA_LDIR($mylibdir32)
progdir="${exdir}/bin${subexdir}"
wi_EXTRA_PDIR($progdir)
fi
done
done
])
dnl
dnl
dnl
AC_DEFUN([wi_HPUX_CFLAGS],
[AC_MSG_CHECKING(if HP-UX ansi C compiler flags are needed)
AC_REQUIRE([AC_PROG_CC])
os=`uname -s | tr '[A-Z]' '[a-z]'`
ac_cv_hpux_flags=no
if test "$os" = hp-ux ; then
if test "$ac_cv_prog_gcc" = yes ; then
if test "$CFLAGS" != "" ; then
# Shouldn't be in there.
CFLAGS=`echo "$CFLAGS" | sed 's/-Aa//g'`
fi
else
# If you're not using gcc, then you better have a cc/c89
# that is usable. If you have the barebones compiler, it
# won't work. The good compiler uses -Aa for the ANSI
# compatible stuff.
x=`echo $CFLAGS | grep 'Aa' 2>/dev/null`
if test "$x" = "" ; then
CFLAGS="$CFLAGS -Aa"
fi
ac_cv_hpux_flags=yes
fi
# Also add _HPUX_SOURCE to get the extended namespace.
x=`echo $CFLAGS | grep '_HPUX_SOURCE' 2>/dev/null`
if test "$x" = "" ; then
CFLAGS="$CFLAGS -D_HPUX_SOURCE"
fi
fi
AC_MSG_RESULT($ac_cv_hpux_flags)
])
dnl
dnl
dnl
AC_DEFUN([wi_CFLAGS], [AC_REQUIRE([AC_PROG_CC])
wi_HPUX_CFLAGS
if test "$CFLAGS" = "" ; then
CFLAGS="-O"
elif test "$ac_cv_prog_gcc" = "yes" ; then
case "$CFLAGS" in
*"-g -O"*)
#echo "using -g as default gcc CFLAGS" 1>&6
CFLAGS=`echo $CFLAGS | sed 's/-g\ -O/-O/'`
;;
*"-O -g"*)
# Leave the -g, but remove all -O options.
#echo "using -g as default gcc CFLAGS" 1>&6
CFLAGS=`echo $CFLAGS | sed 's/-O\ -g/-O/'`
;;
esac
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_PROTOTYPES], [
AC_MSG_CHECKING(if the compiler supports function prototypes)
AC_TRY_COMPILE(,[extern void exit(int status);],[wi_cv_prototypes=yes
AC_DEFINE(PROTOTYPES)],wi_cv_prototypes=no)
AC_MSG_RESULT($wi_cv_prototypes)
])
dnl
dnl
dnl
AC_DEFUN([wi_ANSI_C], [
AC_MSG_CHECKING(ANSI-style function definitions)
AC_TRY_COMPILE(,[int blubb(int x) { return 0; }],[wi_cv_ansi_funcs=yes
AC_DEFINE(ANSI_FUNCS)],wi_cv_ansi_funcs=no)
AC_MSG_RESULT($wi_cv_ansi_funcs)
])
dnl
dnl
dnl
AC_DEFUN([wi_HEADER_SYS_SELECT_H], [
# See if <sys/select.h> is includable after <sys/time.h>
if test "$ac_cv_header_sys_time_h" = no ; then
AC_CHECK_HEADERS(sys/time.h sys/select.h)
else
AC_CHECK_HEADERS(sys/select.h)
fi
if test "$ac_cv_header_sys_select_h" = yes ; then
AC_MSG_CHECKING([if <sys/select.h> is compatible with <sys/time.h>])
selecth=yes
if test "$ac_cv_header_sys_time_h" = yes ; then
AC_TRY_COMPILE([#include <sys/time.h>
#include <sys/select.h>],[
fd_set a;
struct timeval tmval;
tmval.tv_sec = 0;],selecth=yes,selecth=no)
if test "$selecth" = yes ; then
AC_DEFINE(CAN_USE_SYS_SELECT_H)
fi
fi
AC_MSG_RESULT($selecth)
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_LIB_RESOLV], [
# See if we could access two well-known sites without help of any special
# libraries, like resolv.
AC_TRY_RUN([
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
main()
{
struct hostent *hp1, *hp2;
int result;
hp1 = gethostbyname("gatekeeper.dec.com");
hp2 = gethostbyname("ftp.ncsa.uiuc.edu");
result = ((hp1 != (struct hostent *) 0) && (hp2 != (struct hostent *) 0));
exit(! result);
}],look_for_resolv=no,look_for_resolv=yes,look_for_resolv=yes)
AC_MSG_CHECKING([if we need to look for -lresolv])
AC_MSG_RESULT($look_for_resolv)
if test "$look_for_resolv" = yes ; then
AC_CHECK_LIB(resolv,main)
else
ac_cv_lib_resolv=no
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_LIB_NSL], [
AC_MSG_CHECKING(if we can use -lnsl)
ac_save_LIBS="$LIBS";
LIBS="$LIBS -lnsl";
AC_CACHE_VAL(r_cv_use_libnsl, [
AC_TRY_RUN(
main() { if (getpwuid(getuid())) exit(0); exit(-1); },
nc_cv_use_libnsl=yes, nc_cv_use_libnsl=no, nc_cv_use_libnsl=no)
])
if test "$nc_cv_use_libnsl" = "no"; then LIBS="$ac_save_LIBS"; fi
AC_MSG_RESULT($nc_cv_use_libnsl)
])dnl
dnl
dnl
dnl
AC_DEFUN([nc_PATH_PROG_ZCAT], [
AC_PATH_PROG(GZCAT,gzcat)
AC_PATH_PROG(ZCAT,zcat)
if test "x$GZCAT" = x ; then
if test "x$ZCAT" != x ; then
# See if zcat is really gzcat. gzcat has a --version option, regular
# zcat does not.
AC_MSG_CHECKING(if zcat is really gzcat in disguise)
if $ZCAT --version 2> /dev/null ; then
AC_DEFINE_UNQUOTED(GZCAT, "$ZCAT")
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
fi
else
AC_DEFINE_UNQUOTED(GZCAT, "$GZCAT")
fi
if test "x$ZCAT" != x ; then
AC_DEFINE_UNQUOTED(ZCAT, "$ZCAT")
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_SYSV_EXTRA_DIRS], [
# Use System V because their curses extensions are required. This must
# be done early so we use the -I and -L in the library checks also.
# This is mostly a Solaris/SunOS hack. Note that doing this will also
# use all of the other System V libraries and headers.
AC_MSG_CHECKING(for alternative System V libraries)
if test -f /usr/5include/curses.h ; then
CPPFLAGS="$CPPFLAGS -I/usr/5include"
LDFLAGS="$LDFLAGS -L/usr/5lib"
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_DEFINE_UNAME], [
# Get first 127 chars of all uname information. Some folks have
# way too much stuff there, so grab only the first 127.
unam=`uname -a 2>/dev/null | cut -c1-127`
if test "$unam" != "" ; then
AC_DEFINE_UNQUOTED(UNAME, "$unam")
fi
])
dnl
dnl
dnl
AC_DEFUN([wi_READLINE_WITH_NCURSES], [
# Readline and Ncurses could both define "backspace".
# Warn about this if we have both things in our definitions list.
if test "$ac_cv_lib_readline" = yes && test "$ac_cv_lib_ncurses" = yes ; then
AC_MSG_CHECKING(if readline and ncurses will link together)
j="$LIBS"
LIBS="-lreadline -lncurses"
AC_TRY_LINK(,[
readline("prompt");
endwin();
],k=yes,k=no)
if test "$k" = no ; then
AC_MSG_RESULT(no)
# Remove '-lreadline' from LIBS.
LIBS=`echo $j | sed s/-lreadline//g`
ac_cv_lib_readline=no
AC_WARN([The versions of GNU readline and ncurses you have installed on this system
can't be used together, because they use the same symbol, backspace. If
possible, recompile one of the libraries with -Dbackspace=back_space, then
re-run configure.])
else
AC_MSG_RESULT(yes)
LIBS="$j"
fi
fi
])
dnl
dnl
dnl
dnl AC_EXT_DAYLIGHT
dnl Check for an external variable daylight. Stolen from w3c-libwww.
AC_DEFUN([AC_EXT_DAYLIGHT],
[ AC_MSG_CHECKING(int daylight variable)
AC_TRY_COMPILE([#include <time.h>], [return daylight;],
have_daylight=yes,
have_daylight=no)
AC_MSG_RESULT($have_daylight)
])dnl
dnl AC_EXT_TIMEZONE
dnl Check for an external variable timezone. Stolen from tcl-8.0.
AC_DEFUN([AC_EXT_TIMEZONE],
[
#
# Its important to include time.h in this check, as some systems (like convex)
# have timezone functions, etc.
#
have_timezone=no
AC_MSG_CHECKING([long timezone variable])
AC_TRY_COMPILE([#include <time.h>],
[extern long timezone;
timezone += 1;
exit (0);],
[have_timezone=yes
AC_MSG_RESULT(yes)],
AC_MSG_RESULT(no))
#
# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
#
if test "$have_timezone" = no; then
AC_MSG_CHECKING([time_t timezone variable])
AC_TRY_COMPILE([#include <time.h>],
[extern time_t timezone;
timezone += 1;
exit (0);],
[have_timezone=yes
AC_MSG_RESULT(yes)],
AC_MSG_RESULT(no))
fi
])dnl
## AC_BZ_SET_COMPILER: Addition by Theodore Papadopoulo
## Patch by Jim McKelvey: change sed -e 's/ /@/g' to sed -e 's/ /@/'
AC_DEFUN([AC_SG_SET_COMPILER],
[cxxwith=`echo $1 | sed -e 's/ /@/'`
case "$cxxwith" in
*:*@*) # Full initialization syntax
CXX=`echo "$cxxwith" | sed -n -e 's/.*:\(.*\)@.*/\1/p'`
CXXFLAGS=`echo "$cxxwith" | sed -n -e 's/.*:.*@\(.*\)/\1/p'`
;;
*:*) # Simple initialization syntax
CXX=`echo "$cxxwith" | sed -n -e 's/.*:\(.*\)/\1/p'`
CXXFLAGS=$3
;;
*) # Default values
CXX=$2
CXXFLAGS=$3
CC="$2 --c"
## CFLAGS=
;;
esac])
pushdef([AC_PROG_INSTALL],
[
dnl our own version, testing for a -p flag
popdef([AC_PROG_INSTALL])
dnl as AC_PROG_INSTALL works as it works we first have
dnl to save if the user didn't specify INSTALL, as the
dnl autoconf one overwrites INSTALL and we have no chance to find
dnl out afterwards
AC_PROG_INSTALL
# OK, user hasn't given any INSTALL, autoconf found one for us
# now we test, if it supports the -p flag
AC_MSG_CHECKING(for -p flag to install)
rm -f confinst.$$.* > /dev/null 2>&1
echo "Testtest" > confinst.$$.orig
ac_res=no
if ${INSTALL} -p confinst.$$.orig confinst.$$.new > /dev/null 2>&1 ; then
if test -f confinst.$$.new ; then
# OK, -p seems to do no harm to install
INSTALL="${INSTALL} -p"
ac_res=yes
fi
fi
rm -f confinst.$$.*
AC_MSG_RESULT($ac_res)
dnl the following tries to resolve some signs and wonders coming up
dnl with different autoconf/automake versions
dnl e.g.:
dnl *automake 1.4 install-strip sets A_M_INSTALL_PROGRAM_FLAGS to -s
dnl and has INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(A_M_INSTALL_PROGRAM_FLAGS)
dnl it header-vars.am, so there the actual INSTALL_PROGRAM gets the -s
dnl *automake 1.4a (and above) use INSTALL_STRIP_FLAG and only has
dnl INSTALL_PROGRAM = @INSTALL_PROGRAM@ there, but changes the
dnl install-@DIR@PROGRAMS targets to explicitly use that flag
dnl *autoconf 2.13 is dumb, and thinks it can use INSTALL_PROGRAM as
dnl INSTALL_SCRIPT, which breaks with automake <= 1.4
dnl *autoconf >2.13 (since 10.Apr 1999) has not that failure
dnl to clean up that mess we:
dnl +set INSTALL_PROGRAM to use INSTALL_STRIP_FLAG
dnl which cleans KDE's program with automake > 1.4;
dnl +set INSTALL_SCRIPT to only use INSTALL, to clean up autoconf's problems
dnl with automake<=1.4
dnl note that dues to this sometimes two '-s' flags are used
INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)'
INSTALL_SCRIPT='${INSTALL}'
])dnl
# ===========================================================================
# http://autoconf-archive.cryp.to/ax_boost_base.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_BOOST_BASE([MINIMUM-VERSION])
#
# DESCRIPTION
#
# Test for the Boost C++ libraries of a particular version (or newer)
#
# If no path to the installed boost library is given the macro searchs
# under /usr, /usr/local, /opt and /opt/local and evaluates the
# $BOOST_ROOT environment variable. Further documentation is available at
# <http://randspringer.de/boost/index.html>.
#
# This macro calls:
#
# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
#
# And sets:
#
# HAVE_BOOST
#
# LAST MODIFICATION
#
# 2008-04-12
#
# COPYLEFT
#
# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved.
AC_DEFUN([AX_BOOST_BASE],
[
AC_ARG_WITH([boost],
AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]),
[
if test "$withval" = "no"; then
want_boost="no"
elif test "$withval" = "yes"; then
want_boost="yes"
ac_boost_path=""
else
want_boost="yes"
ac_boost_path="$withval"
fi
],
[want_boost="yes"])
AC_ARG_WITH([boost-libdir],
AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
[Force given directory for boost libraries. Note that this will overwrite library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]),
[
if test -d $withval
then
ac_boost_lib_path="$withval"
else
AC_MSG_ERROR(--with-boost-libdir expected directory name)
fi
],
[ac_boost_lib_path=""]
)
if test "x$want_boost" = "xyes"; then
boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
if test "x$boost_lib_version_req_sub_minor" = "x" ; then
boost_lib_version_req_sub_minor="0"
fi
WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
succeeded=no
dnl first we check the system location for boost libraries
dnl this location ist chosen if boost libraries are installed with the --layout=system option
dnl or if you install boost with RPM
if test "$ac_boost_path" != ""; then
BOOST_LDFLAGS="-L$ac_boost_path/lib"
BOOST_CPPFLAGS="-I$ac_boost_path/include"
else
for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
break;
fi
done
fi
dnl overwrite ld flags if we have required special directory with
dnl --with-boost-libdir parameter
if test "$ac_boost_lib_path" != ""; then
BOOST_LDFLAGS="-L$ac_boost_lib_path"
fi
CPPFLAGS_SAVED="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <boost/version.hpp>
]], [[
#if BOOST_VERSION >= $WANT_BOOST_VERSION
// Everything is okay
#else
# error Boost version is too old
#endif
]])],[
AC_MSG_RESULT(yes)
succeeded=yes
found_system=yes
],[
])
AC_LANG_POP([C++])
dnl if we found no boost with system layout we search for boost libraries
dnl built and installed without the --layout=system option or for a staged(not installed) version
if test "x$succeeded" != "xyes"; then
_version=0
if test "$ac_boost_path" != ""; then
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
V_CHECK=`expr $_version_tmp \> $_version`
if test "$V_CHECK" = "1" ; then
_version=$_version_tmp
fi
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
done
fi
else
for ac_boost_path in /usr /usr/local /opt /opt/local ; do
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
V_CHECK=`expr $_version_tmp \> $_version`
if test "$V_CHECK" = "1" ; then
_version=$_version_tmp
best_path=$ac_boost_path
fi
done
fi
done
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
if test "$ac_boost_lib_path" = ""
then
BOOST_LDFLAGS="-L$best_path/lib"
fi
if test "x$BOOST_ROOT" != "x"; then
if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then
version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
V_CHECK=`expr $stage_version_shorten \>\= $_version`
if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
BOOST_CPPFLAGS="-I$BOOST_ROOT"
BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib"
fi
fi
fi
fi
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <boost/version.hpp>
]], [[
#if BOOST_VERSION >= $WANT_BOOST_VERSION
// Everything is okay
#else
# error Boost version is too old
#endif
]])],[
AC_MSG_RESULT(yes)
succeeded=yes
found_system=yes
],[
])
AC_LANG_POP([C++])
fi
if test "$succeeded" != "yes" ; then
if test "$_version" = "0" ; then
AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
else
AC_MSG_ERROR([Your boost libraries seems to old (version $_version).])
fi
else
AC_SUBST(BOOST_CPPFLAGS)
AC_SUBST(BOOST_LDFLAGS)
AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
fi
CPPFLAGS="$CPPFLAGS_SAVED"
LDFLAGS="$LDFLAGS_SAVED"
fi
])

View File

@@ -1,38 +0,0 @@
type = StaticLibrary,Multithreaded,
exclude_dir = threads
include_path = .
include_path = ..
include_path = .\SimGear
include_path = ..\zlib-1.2.3
include_path = "..\OpenAL 1.0 Software Development Kit\include"
define = _USE_MATH_DEFINES
define = _CRT_SECURE_NO_DEPRECATE
define = HAVE_CONFIG_H
# Rule to create simgear_config.h
add_source_file = SOURCE=.\simgear\simgear_config.h.vc5\
\
!IF "$(CFG)" == "SimGear - Win32 Release"\
\
# Begin Custom Build - Creating config.h\
InputPath=.\simgear\simgear_config.h.vc5\
\
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h\
\
# End Custom Build\
\
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"\
\
# Begin Custom Build - Creating config.h\
InputPath=.\simgear\simgear_config.h.vc5\
\
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h\
\
# End Custom Build\
\
!ENDIF\

View File

@@ -1,52 +0,0 @@
#!/bin/sh
OSTYPE=`uname -s`
MACHINE=`uname -m`
AUTO_MAKE_VERSION=`automake --version | head -1 | awk '{print $4}' | sed -e 's/\.\([0-9]*\).*/\1/'`
if test $AUTO_MAKE_VERSION -lt 15; then
echo ""
echo "You need to upgrade to automake version 1.5 or greater."
echo "Most distributions have packages available to install or you can"
echo "find the source for the most recent version at"
echo "ftp://ftp.gnu.org/gnu/automake"
exit 1
fi
echo "Host info: $OSTYPE $MACHINE"
echo -n " automake: `automake --version | head -1 | awk '{print $4}'`"
echo " ($AUTO_MAKE_VERSION)"
echo ""
echo "Running aclocal"
aclocal
echo "Running autoheader"
autoheader
if [ ! -e simgear/simgear_config.h.in ]; then
echo "ERROR: autoheader didn't create simgear/simgear_config.h.in!"
exit 1
fi
echo "Running automake --add-missing"
automake --add-missing
echo "Running autoconf"
autoconf
if [ ! -e configure ]; then
echo "ERROR: configure was not created!"
exit 1
fi
echo ""
echo "======================================"
if [ -f config.cache ]; then
echo "config.cache exists. Removing the config.cache file will force"
echo "the ./configure script to rerun all it's tests rather than using"
echo "the previously cached values."
echo ""
fi
echo "Now you are ready to run './configure'"
echo "======================================"

View File

@@ -1,670 +0,0 @@
dnl Process this file with autogen.sh to produce a working configure
dnl script.
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
dnl Specify KAI C++ compiler and flags.
dnl Borrowed with slight modification from blitz distribution.
AC_ARG_WITH(cxx,
[ --with-cxx=COMPILER[:name-flags] set options for COMPILER (KCC)],
[case "$withval" in
KCC*) # KAI C++ http://www.kai.com/
echo "Configuring for KAI C++"
AC_SG_SET_COMPILER($withval,"KCC","--restrict --strict_warnings")
CXX_OPTIMIZE_FLAGS=="+K3 -O3"
CXX_DEBUG_FLAGS="-g +K0"
;;
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])
AC_MSG_CHECKING([CC])
AC_MSG_RESULT([$CC])
dnl Checks for programs.
AC_PROG_MAKE_SET
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_CXXCPP
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_PROG_LN_S
AX_BOOST_BASE([1.37.0])
if test "x$BOOST_CPPFLAGS" != "x-I/usr/include" ; then
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
fi
dnl set the $host variable based on local machine/os
AC_CANONICAL_HOST
dnl Used on the Irix platform
case "${host}" in
*-*-irix*)
if test "x$CXX" = "xCC" -o "x$CXX" = "xccache CC"; then
AR="$CXX -ar"
ARFLAGS="-o"
CXXFLAGS="$CXXFLAGS -I$(top_srcdir)/simgear/compatibility/MIPSpro740"
compatibility_DIR="compatibility"
MIPSpro_DIRS="MIPSpro740"
AC_MSG_CHECKING([for MIPSpro compiler version 7.4 or newer])
AC_TRY_RUN([
int main() {
if ( _COMPILER_VERSION < 740 ) {
return -1;
}
return 0;
}
], AC_MSG_RESULT(yes),
[ AC_MSG_RESULT(no)
CXXFLAGS="$CXXFLAGS -I$(top_srcdir)/simgear/compatibility/MIPSpro721"
MIPSpro_DIRS="$(MIPSpro_DIRS) MIPSpro721"
AC_MSG_WARN([Using our own subset of the STL headers])
], AC_MSG_RESULT(yes))
AC_SUBST(MIPSpro_DIRS)
fi
;;
*)
AR="ar"
ARFLAGS="cru"
compatibility_DIR=
;;
esac
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
AC_DEFINE([FG_NDEBUG], 1, [Define for no logging output])
fi
# Specify if we want to build with Norman's jpeg image server support.
# This requires libjpeg to be installed and available.
# Default to with_jpeg_server=no
JPEGLIB=''
AC_ARG_WITH(jpeg_factory, [ --with-jpeg-factory Include Norman's jpeg image factory support code])
if test "x$with_jpeg_factory" = "xyes" ; then
echo "Building with Norman's jpeg image factory support"
AC_CHECK_LIB(jpeg, jpeg_start_compress)
if test "x$ac_cv_lib_jpeg_jpeg_start_compress" != "xyes" ; then
echo
echo "In order to build the jpeg factory code you need libjpeg installed."
echo "otherwise please configure with the --with-jpeg-sever=no option"
echo
echo "libjpeg is available at :"
echo " ftp://ftp.uu.net in the directory graphics/jpeg"
exit 1
fi
else
echo "Building without Norman's jpeg image server support"
fi
AM_CONDITIONAL(ENABLE_JPEG_SERVER, test "x$with_jpeg_factory" = "xyes")
# specify the osg location
AC_ARG_WITH(osg, [ --with-osg=PREFIX Specify the prefix path to osg])
if test "x$with_osg" != "x" ; then
echo "osg prefix is $with_osg"
EXTRA_DIRS="${EXTRA_DIRS} $with_osg"
fi
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"
CPPFLAGS = "$CPPFLAGS -F$with-osg-framework"
export DYLD_FRAMEWORK_PATH="$DYLD_FRAMEWORK_PATH:$with_osg_framework"
fi
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_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
case "${host}" in
*-apple-darwin* | *-*-cygwin* | *-*-mingw32*)
echo no EXTRA_DIRS for $host
;;
*)
if test -d /usr/X11R6 ; then
EXTRA_DIR1="/usr/X11R6"
fi
if test -d /opt/X11R6 ; then
EXTRA_DIR2="/opt/X11R6"
fi
EXTRA_DIRS="${EXTRA_DIRS} $EXTRA_DIR1 $EXTRA_DIR2"
;;
esac
wi_EXTRA_DIRS(no, ${EXTRA_DIRS})
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
dnl build a Makefile.in from a Makefile.am which lets us define custom
dnl includes, compile alternative source files, etc.
dnl X11 might be installed on Mac OS X or cygwin/mingwin, we don't want
dnl to use it if it is.
case "${host}" in
*-apple-darwin* | *-*-cygwin* | *-*-mingw32*)
echo no fancy X11 check
;;
*)
AC_PATH_XTRA
;;
esac
dnl Checks for libraries.
dnl Thread related checks
AC_CHECK_HEADER(pthread.h)
AC_SEARCH_LIBS(pthread_exit, [pthread c_r])
if test "x$ac_cv_header_pthread_h" = "xyes"; then
CXXFLAGS="$CXXFLAGS -D_REENTRANT"
CFLAGS="$CFLAGS -D_REENTRANT"
if test "x$ac_cv_search_pthread_exit" = "x-lc_r"; then
CXXFLAGS="-pthread $CXXFLAGS"
CFLAGS="-pthread $CFLAGS"
fi
fi
AM_CONDITIONAL(HAVE_THREADS, test "x$ac_cv_header_pthread_h" = "xyes")
thread_LIBS="$LIBS"
LIBS=""
dnl search for network related libraries
AC_SEARCH_LIBS(inet_addr, xnet)
AC_SEARCH_LIBS(socket, socket)
network_LIBS="$LIBS"
LIBS=""
dnl check for some default libraries
AC_SEARCH_LIBS(cos, m)
AC_SEARCH_LIBS(clock_gettime, rt)
base_LIBS="$LIBS"
dnl check for OpenGL related libraries
case "${host}" in
*-*-cygwin* | *-*-mingw32*)
dnl CygWin under Windoze.
echo Win32 specific hacks...
AC_DEFINE([WIN32], 1, [Define for Win32 platforms])
AC_DEFINE([NOMINMAX], 1, [Define for Win32 platforms])
LIBS="$LIBS -lglu32 -lopengl32"
LIBS="$LIBS -luser32 -lgdi32 -lwinmm"
dnl add -lwsock32 for mingwin
case "${host}" in
*-*-mingw32*)
base_LIBS="$base_LIBS -lws2_32"
;;
esac
echo "Will link apps with $LIBS"
;;
*-apple-darwin*)
dnl Mac OS X
LIBS="$LIBS -framework OpenGL -framework Carbon -lobjc"
;;
*)
dnl X-Windows based machines
AC_SEARCH_LIBS(XCreateWindow, X11)
AC_SEARCH_LIBS(XShmCreateImage, Xext)
AC_SEARCH_LIBS(XGetExtensionVersion, Xi)
AC_SEARCH_LIBS(IceOpenConnection, ICE)
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
AC_SEARCH_LIBS(glXCreateContext, GL)
fi
dnl if using mesa, check for xmesa.h
if test "x$ac_cv_search_glNewList" = "x-lMesaGL"; then
AC_CHECK_HEADER(GL/fxmesa.h)
if test "x$ac_cv_header_GL_fxmesa_h" = "xyes"; then
AC_DEFINE([XMESA], 1, [Define for fxmesa])
AC_DEFINE([FX], 1, [Define for fxmesa])
fi
fi
AC_SEARCH_LIBS(gluLookAt, [ GLU MesaGLU ])
;;
esac
opengl_LIBS="$LIBS"
LIBS="$base_LIBS"
dnl check for OpenAL libraries
OPENAL_OK="no"
ALUT_OK="no"
case "${host}" in
*-*-cygwin* | *-*-mingw32*)
dnl CygWin under Windoze.
INCLUDES="$INCLUDES -I/usr/local/include/"
LIBS="$LIBS -L/usr/local/lib"
AC_SEARCH_LIBS(alGenBuffers, [ openal32 openal 'openal -ldsound -lwinmm' ] )
AC_SEARCH_LIBS(alutInit, [ openal32 ALut alut ] )
LIBS="$LIBS -lwinmm -ldsound -ldxguid -lole32"
openal_LIBS="$LIBS"
OPENAL_OK="$ac_cv_search_alGenBuffers"
ALUT_OK="$ac_cv_search_alutInit"
;;
*-apple-darwin*)
dnl Mac OS X
LIBS="$LIBS -framework IOKit -framework OpenAL -framework ALUT"
openal_LIBS="$LIBS"
if test "x$with_openal_lib" != "x"; then
echo "libopenal is not supported on Mac OS platform."
openal_LIBS=""
fi
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, $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],
ac_Framework, [
saved_LIBS="$LIBS"
FRAMEWORKS="$FRAMEWORKS -framework $1"
if test "$3" = ""; then
FRAMEWORKS="$FRAMEWORKS $ADD2LD"
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"
fi
AC_TRY_LINK(
[$2], [],
[AS_VAR_SET(ac_Framework, yes)], [AS_VAR_SET(ac_Framework, no); LIBS="$saved_LIBS"]
)
])
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 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
;;
*)
dnl default unix style machines
save_LIBS=$LIBS
LIBS="$LIBS $thread_LIBS"
AC_SEARCH_LIBS(alGenBuffers, openal)
AC_SEARCH_LIBS(alutInit, [ alut openal ] )
OPENAL_OK="$ac_cv_search_alGenBuffers"
ALUT_OK="$ac_cv_search_alutInit"
openal_LIBS="$LIBS"
LIBS=$save_LIBS
;;
esac
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!"
echo
echo "Please see README.OpenAL for more details."
echo
echo "configure aborted."
exit
fi
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!"
echo
echo "Please see README.OpenAL for more details."
echo
echo "configure aborted."
exit
fi
LIBS="$base_LIBS"
AC_SUBST(base_LIBS)
AC_SUBST(openal_LIBS)
AC_SUBST(opengl_LIBS)
AC_SUBST(thread_LIBS)
AC_SUBST(network_LIBS)
dnl Check for MS Windows environment
AC_CHECK_HEADER(windows.h)
AM_CONDITIONAL(EXTGL_NEEDED, test "x$ac_cv_header_windows_h" = "xyes")
# The following are C++ items that need to be tested for with the c++
# compiler
CXXCPP="g++ -E"
AC_LANG_PUSH(C++)
# OpenSceneGraph
case "${host}" in
*-apple-darwin*)
if test "x$with_osg_framework" != "x"; then
# AC_CHECK_FRAMEWORK(osgViewer, [#include <osgViewer/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgGA, [#include <osgGA/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgText, [#include <osgText/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgFX, [#include <osgFX/AnisotropicLighting>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgUtil, [#include <osgUtil/Version>], $with_osg_framework)
# 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)
# osg_FRAMEWORKS="$FRAMEWORKS"
# FRAMEWORKS=""
# AC_SUBST(osg_FRAMEWORKS)
AC_CHECK_FRAMEWORK(OpenThreads, [#include <OpenThreads/Version>], $with_osg_framework)
openthreads_FRAMEWORK="$FRAMEWORKS"
FRAMEWORKS=""
AC_SUBST(openthreads_FRAMEWORK)
else
dnl
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)
fi
;;
*)
if test "x$enable_osgdebug" = "xyes"; then
AC_CHECK_LIB(OpenThreadsd,OpenThreadsGetVersion)
else
AC_CHECK_LIB(OpenThreads,OpenThreadsGetVersion)
fi
;;
esac
AM_CONDITIONAL(HAVE_FRAMEWORK_OSG, test "x$ac_cv_framework_osg" != "x")
AC_CHECK_HEADER(osg/Version)
if test "x$ac_cv_header_osg_Version" != "xyes" -o "x$ac_cv_lib_OpenThreads_OpenThreadsGetVersion" != "xyes"; then
if test "x$ac_cv_framework_osg" != "xyes"; then
echo
echo "You *must* have the OpenThreads library installed on your system"
echo "to build this version of SimGear!"
echo " Maybe you need to specify --with-osg=DIR."
echo " Maybe you need to specify some LDFLAGS to help the linker."
echo
echo " LIBS: '$LIBS'"
echo " LDFLAGS: '$LDFLAGS'"
echo " CPPFLAGS: '$CPPFLAGS'"
echo
echo "Please see README.OSG for more details."
echo
echo "configure aborted."
exit
fi
fi
AC_CHECK_HEADER(boost/version.hpp)
if test "x$ac_cv_header_boost_version_hpp" != "xyes"; then
echo
echo "You *must* have the Boost library installed on your system"
echo "to build this version of SimGear!"
echo
echo " LIBS: '$LIBS'"
echo " LDFLAGS: '$LDFLAGS'"
echo " CPPFLAGS: '$CPPFLAGS'"
echo
echo "configure aborted."
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
AC_CHECK_HEADER(zlib.h)
if test "x$ac_cv_header_zlib_h" != "xyes"; then
echo
echo "zlib library not found."
echo
echo "If your OS does not provide an installable package for zlib"
echo "you will have to compile and install it first yourself. A copy"
echo "of zlib-1.1.4.tar.gz is included with SimGear. You will"
echo "have to untar this source code, and follow its included instructions"
echo "to compile and install on your system."
echo
echo "configure aborted."
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( \
fcntl.h getopt.h malloc.h memory.h stdint.h stdlib.h sys/param.h \
sys/stat.h sys/time.h sys/timeb.h unistd.h values.h )
if test "x$ac_cv_header_stdint_h" = "xyes"; then
AC_DEFINE([HAVE_STDINT_H], 1, [Define if stdint.h exists])
fi
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
AC_TYPE_MODE_T
AC_HEADER_TIME
AC_STRUCT_TM
dnl Checks for library functions.
old_LIBS=$LIBS
LIBS="$base_LIBS $network_LIBS $opengl_LIBS"
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS( [ \
ftime gettimeofday timegm memcpy bcopy mktime strstr rand \
random drand48 setitimer getitimer signal GetLocalTime rint getrusage ] )
LIBS=$old_LIBS
AM_CONFIG_HEADER(simgear/simgear_config.h)
AC_CONFIG_FILES([ \
Makefile \
SimGear.spec \
simgear/Makefile \
simgear/version.h \
simgear/compatibility/Makefile \
simgear/compatibility/MIPSpro721/Makefile \
simgear/compatibility/MIPSpro740/Makefile \
simgear/bucket/Makefile \
simgear/debug/Makefile \
simgear/ephemeris/Makefile \
simgear/hla/Makefile \
simgear/io/Makefile \
simgear/magvar/Makefile \
simgear/math/Makefile \
simgear/environment/Makefile \
simgear/misc/Makefile \
simgear/nasal/Makefile \
simgear/props/Makefile \
simgear/route/Makefile \
simgear/scene/Makefile \
simgear/scene/bvh/Makefile \
simgear/scene/material/Makefile \
simgear/scene/model/Makefile \
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 \
simgear/structure/Makefile \
simgear/threads/Makefile \
simgear/timing/Makefile \
simgear/xml/Makefile \
])
AC_OUTPUT
echo ""
echo "Configure Summary"
echo "================="
echo "Prefix: $prefix"
if test "x$with_logging" != "x"; then
echo "Debug messages: $with_logging"
else
echo "Debug messages: yes"
fi
echo -n "Automake version: "
automake --version | head -1
if test "x$with_jpeg_factory" = "xyes"; then
echo "With JPEG Factory support"
else
echo "Without JPEG Factory support"
fi
if test "x$ac_cv_header_pthread_h" = "xyes"; then
echo "Threads: pthread lib found."
else
echo "Threads: no threads (pthread lib not found.)"
fi

View File

@@ -439,6 +439,22 @@
<Filter
Name="Lib_sgio"
>
<File
RelativePath="..\..\simgear\io\HTTPClient.cxx"
>
</File>
<File
RelativePath="..\..\simgear\io\HTTPClient.hxx"
>
</File>
<File
RelativePath="..\..\simgear\io\HTTPRequest.cxx"
>
</File>
<File
RelativePath="..\..\simgear\io\HTTPRequest.hxx"
>
</File>
<File
RelativePath="..\..\simgear\io\iochannel.cxx"
>
@@ -583,14 +599,6 @@
RelativePath="..\..\simgear\math\localconsts.hxx"
>
</File>
<File
RelativePath="..\..\simgear\math\project.cxx"
>
</File>
<File
RelativePath="..\..\simgear\math\project.hxx"
>
</File>
<File
RelativePath="..\..\simgear\math\sg_geodesy.hxx"
>
@@ -635,14 +643,6 @@
RelativePath="..\..\simgear\misc\interpolator.hxx"
>
</File>
<File
RelativePath="..\..\simgear\misc\PathOptions.cxx"
>
</File>
<File
RelativePath="..\..\simgear\misc\PathOptions.hxx"
>
</File>
<File
RelativePath="..\..\simgear\misc\ResourceManager.cxx"
>
@@ -667,14 +667,6 @@
RelativePath="..\..\simgear\misc\sg_path.hxx"
>
</File>
<File
RelativePath="..\..\simgear\misc\sg_sleep.cxx"
>
</File>
<File
RelativePath="..\..\simgear\misc\sg_sleep.hxx"
>
</File>
<File
RelativePath="..\..\simgear\misc\sgstream.cxx"
>
@@ -1015,10 +1007,6 @@
RelativePath="..\..\simgear\props\propertyObject.hxx"
>
</File>
<File
RelativePath="..\..\simgear\props\tiedpropertylist.hxx"
>
</File>
<File
RelativePath="..\..\simgear\props\props.cxx"
>
@@ -1035,6 +1023,10 @@
RelativePath="..\..\simgear\props\props_io.hxx"
>
</File>
<File
RelativePath="..\..\simgear\props\tiedpropertylist.hxx"
>
</File>
</Filter>
<Filter
Name="Lib_sgmodel"
@@ -1143,14 +1135,6 @@
RelativePath="..\..\simgear\scene\model\SGOffsetTransform.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\SGPagedLOD.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\SGPagedLOD.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\SGReaderWriterXML.cxx"
>
@@ -1159,10 +1143,6 @@
RelativePath="..\..\simgear\scene\model\SGReaderWriterXML.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\SGReaderWriterXMLOptions.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\SGRotateTransform.cxx"
>
@@ -1359,6 +1339,10 @@
RelativePath="..\..\simgear\scene\tgdb\apt_signs.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\BucketBox.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\GroundLightManager.cxx"
>
@@ -1383,6 +1367,14 @@
RelativePath="..\..\simgear\scene\tgdb\pt_lights.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\ReaderWriterSPT.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\ReaderWriterSPT.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\ReaderWriterSTG.cxx"
>
@@ -1407,10 +1399,6 @@
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTG.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTGOptions.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGVasiDrawable.cxx"
>
@@ -1459,7 +1447,7 @@
RelativePath="..\..\simgear\scene\tgdb\userdata.hxx"
>
</File>
</Filter>
</Filter>
<Filter
Name="Lib_sgtsync"
>
@@ -1483,6 +1471,14 @@
RelativePath="..\..\simgear\threads\SGQueue.hxx"
>
</File>
<File
RelativePath="..\..\simgear\threads\SGThread.cxx"
>
</File>
<File
RelativePath="..\..\simgear\threads\SGThread.hxx"
>
</File>
</Filter>
<Filter
Name="Lib_sgstructure"
@@ -1551,6 +1547,14 @@
RelativePath="..\..\simgear\structure\OSGVersion.hxx"
>
</File>
<File
RelativePath="..\..\simgear\structure\SGAtomic.cxx"
>
</File>
<File
RelativePath="..\..\simgear\structure\SGAtomic.hxx"
>
</File>
<File
RelativePath="..\..\simgear\structure\SGBinding.cxx"
>
@@ -1567,6 +1571,14 @@
RelativePath="..\..\simgear\structure\SGExpression.hxx"
>
</File>
<File
RelativePath="..\..\simgear\structure\SGPerfMon.cxx"
>
</File>
<File
RelativePath="..\..\simgear\structure\SGPerfMon.hxx"
>
</File>
<File
RelativePath="..\..\simgear\structure\SGReferenced.hxx"
>
@@ -1591,6 +1603,10 @@
RelativePath="..\..\simgear\structure\SGSmplstat.hxx"
>
</File>
<File
RelativePath="..\..\simgear\structure\Singleton.hxx"
>
</File>
<File
RelativePath="..\..\simgear\structure\subsystem_mgr.cxx"
>
@@ -1777,6 +1793,14 @@
RelativePath="..\..\simgear\scene\util\NodeAndDrawableVisitor.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\util\PathOptions.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\util\PathOptions.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\util\PrimitiveUtils.cxx"
>
@@ -1785,6 +1809,14 @@
RelativePath="..\..\simgear\scene\util\PrimitiveUtils.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\util\project.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\util\project.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\util\QuadTreeBuilder.cxx"
>

1
simgear/.gitignore vendored
View File

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

View File

@@ -5,7 +5,6 @@ foreach( mylibfolder
bucket
debug
ephemeris
hla
io
magvar
math
@@ -24,35 +23,75 @@ foreach( mylibfolder
endforeach( mylibfolder )
if (NOT SIMGEAR_HEADLESS)
if(NOT SIMGEAR_HEADLESS)
add_subdirectory(environment)
add_subdirectory(screen)
add_subdirectory(scene)
add_subdirectory(sound)
endif()
endif(NOT SIMGEAR_HEADLESS)
if(ENABLE_RTI)
add_subdirectory(hla)
endif(ENABLE_RTI)
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(coreSources GLOBAL PROPERTY CORE_SOURCES)
get_property(sceneSources GLOBAL PROPERTY SCENE_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)
add_library(SimGearCore SHARED ${coreSources})
set_property(TARGET SimGearCore PROPERTY COMPILE_FLAGS "-DNO_OPENSCENEGRAPH_INTERFACE=1")
# set_property(TARGET SimGearCore PROPERTY FRAMEWORK 1)
# message(STATUS "public header: ${publicHeaders}")
# set_property(TARGET SimGearCore PROPERTY PUBLIC_HEADER "${publicHeaders}")
set_property(TARGET SimGearCore PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET SimGearCore PROPERTY VERSION ${SIMGEAR_VERSION})
set_property(TARGET SimGearCore PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
target_link_libraries(SimGearCore ${ZLIB_LIBRARY} ${RT_LIBRARY})
install(TARGETS SimGearCore LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(NOT SIMGEAR_HEADLESS)
if(LIBSVN_FOUND)
add_definitions(${APR_CFLAGS})
IF(APPLE)
set_property(SOURCE scene/tsync/terrasync.cxx PROPERTY COMPILE_FLAGS "-iwithsysroot ${LIBSVN_INCLUDE_DIR}")
ELSE()
include_directories(${LIBSVN_INCLUDE_DIR})
ENDIF(APPLE)
endif(LIBSVN_FOUND)
list(APPEND sceneSources scene/util/SGCoreOSGDependant.cxx)
add_library(SimGearScene SHARED ${sceneSources})
# set_property(TARGET SimGearScene PROPERTY FRAMEWORK 1)
# set_property(TARGET SimGearScene PROPERTY PUBLIC_HEADER "${publicHeaders}")
set_property(TARGET SimGearScene PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET SimGearScene PROPERTY VERSION ${SIMGEAR_VERSION})
set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
target_link_libraries(SimGearScene
SimGearCore
${ZLIB_LIBRARY}
${OPENSCENEGRAPH_LIBRARIES}
${OPENAL_LIBRARY} ${ALUT_LIBRARY}
${OPENGL_LIBRARY})
if(LIBSVN_FOUND)
target_link_libraries(SimGearScene ${LIBSVN_LIBRARIES})
endif(LIBSVN_FOUND)
install(TARGETS SimGearScene LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
endif(SIMGEAR_SHARED)

View File

@@ -1,50 +0,0 @@
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
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 \
nasal \
props \
route \
serial \
timing
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,17 +0,0 @@
includedir = @includedir@/bucket
lib_LIBRARIES = libsgbucket.a
include_HEADERS = newbucket.hxx
libsgbucket_a_SOURCES = newbucket.cxx
# noinst_PROGRAMS = testbucket
# testbucket_SOURCES = testbucket.cxx
# testbucket_LDADD = \
# libsgbucket.a \
# $(top_builddir)/misc/libsgmisc.a
INCLUDES = -I$(top_srcdir)

View File

@@ -1,14 +0,0 @@
includedir = @includedir@/compatibility/
include_HEADERS = \
iostream \
strstream \
sstream \
istream \
fstream \
iterator \
iomanip \
new \
streambuf \
\
irix_string

View File

@@ -1,22 +0,0 @@
includedir = @includedir@/compatibility
EXTRA_DIST = README
include_HEADERS = \
cfloat \
csetjmp \
cstdio \
cwchar \
cassert \
climits \
csignal \
cstdlib \
cwctype \
cctype \
clocale \
cstdarg \
cstring \
cerrno \
cmath \
cstddef \
ctime

View File

@@ -1,3 +0,0 @@
SUBDIRS = $(MIPSpro_DIRS)
DIST_SUBDIRS = MIPSpro721 MIPSpro740

View File

@@ -1,11 +0,0 @@
includedir = @includedir@/debug
EXTRA_DIST = logtest.cxx
lib_LIBRARIES = libsgdebug.a
include_HEADERS = debug_types.h logstream.hxx
libsgdebug_a_SOURCES = logstream.cxx
INCLUDES = -I$(top_srcdir)

View File

@@ -1,35 +1,38 @@
/** \file debug_types.h
* Define the various logging classes and prioritiess
* Define the various logging classes and priorities
*/
/**
* Define the possible classes/categories of logging messages
*/
typedef enum {
SG_NONE = 0x00000000,
SG_NONE = 0x00000000,
SG_TERRAIN = 0x00000001,
SG_ASTRO = 0x00000002,
SG_FLIGHT = 0x00000004,
SG_INPUT = 0x00000008,
SG_GL = 0x00000010,
SG_VIEW = 0x00000020,
SG_COCKPIT = 0x00000040,
SG_GENERAL = 0x00000080,
SG_MATH = 0x00000100,
SG_EVENT = 0x00000200,
SG_AIRCRAFT = 0x00000400,
SG_AUTOPILOT = 0x00000800,
SG_IO = 0x00001000,
SG_CLIPPER = 0x00002000,
SG_NETWORK = 0x00004000,
SG_ATC = 0x00008000,
SG_NASAL = 0x00010000,
SG_INSTR = 0x00020000,
SG_SYSTEMS = 0x00040000,
SG_UNDEFD = 0x00080000, // For range checking
SG_TERRAIN = 0x00000001,
SG_ASTRO = 0x00000002,
SG_FLIGHT = 0x00000004,
SG_INPUT = 0x00000008,
SG_GL = 0x00000010,
SG_VIEW = 0x00000020,
SG_COCKPIT = 0x00000040,
SG_GENERAL = 0x00000080,
SG_MATH = 0x00000100,
SG_EVENT = 0x00000200,
SG_AIRCRAFT = 0x00000400,
SG_AUTOPILOT = 0x00000800,
SG_IO = 0x00001000,
SG_CLIPPER = 0x00002000,
SG_NETWORK = 0x00004000,
SG_ATC = 0x00008000,
SG_NASAL = 0x00010000,
SG_INSTR = 0x00020000,
SG_SYSTEMS = 0x00040000,
SG_AI = 0x00080000,
SG_ENVIRONMENT = 0x00100000,
SG_SOUND = 0x00200000,
SG_UNDEFD = 0x00400000, // For range checking
SG_ALL = 0xFFFFFFFF
SG_ALL = 0xFFFFFFFF
} sgDebugClass;

View File

@@ -4,4 +4,20 @@ include (SimGearComponent)
set(HEADERS metar.hxx precipitation.hxx)
set(SOURCES metar.cxx precipitation.cxx)
simgear_component(environment environment "${SOURCES}" "${HEADERS}")
simgear_scene_component(environment environment "${SOURCES}" "${HEADERS}")
if(ENABLE_TESTS)
add_executable(test_metar test_metar.cxx)
if (SIMGEAR_SHARED)
target_link_libraries(test_metar SimGearScene)
else()
target_link_libraries(test_metar
sgenvironment sgstructure sgmisc sgdebug
${CMAKE_THREAD_LIBS_INIT}
${ZLIB_LIBRARY}
${RT_LIBRARY})
endif()
add_test(metar ${EXECUTABLE_OUTPUT_PATH}/test_metar)
endif(ENABLE_TESTS)

View File

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

View File

@@ -32,7 +32,6 @@
#include <time.h>
#include <cstring>
#include <simgear/io/sg_socket.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
@@ -40,32 +39,28 @@
#define NaN SGMetarNaN
using std::string;
using std::map;
using std::vector;
/**
* The constructor takes a Metar string, or a four-letter ICAO code. In the
* latter case the metar string is downloaded from
* http://weather.noaa.gov/pub/data/observations/metar/stations/.
* The constructor takes a Metar string
* The constructor throws sg_io_exceptions on failure. The "METAR"
* keyword has no effect (apart from incrementing the group counter
* @a grpcount) and can be left away. A keyword "SPECI" is
* likewise accepted.
*
* @param m ICAO station id or metar string
* @param proxy proxy host (optional; default: "")
* @param port proxy port (optional; default: "80")
* @param auth proxy authorization information (optional; default: "")
*
* @par Examples:
* @code
* SGMetar *m = new SGMetar("METAR KSFO 061656Z 19004KT 9SM SCT100 OVC200 08/03 A3013");
* double t = m->getTemperature_F();
* delete m;
*
* SGMetar n("KSFO", "proxy.provider.foo", "3128", "proxy-password");
* double d = n.getDewpoint_C();
* @endcode
*/
SGMetar::SGMetar(const string& m, const string& proxy, const string& port,
const string& auth, const time_t time) :
SGMetar::SGMetar(const string& m) :
_grpcount(0),
_x_proxy(false),
_year(-1),
@@ -87,16 +82,10 @@ SGMetar::SGMetar(const string& m, const string& proxy, const string& port,
_snow(false),
_cavok(false)
{
if (m.length() == 4 && isalnum(m[0]) && isalnum(m[1]) && isalnum(m[2]) && isalnum(m[3])) {
for (int i = 0; i < 4; i++)
_icao[i] = toupper(m[i]);
_icao[4] = '\0';
_data = loadData(_icao, proxy, port, auth, time);
} else {
_data = new char[m.length() + 2]; // make room for " \0"
strcpy(_data, m.c_str());
_url = _data;
}
_data = new char[m.length() + 2]; // make room for " \0"
strcpy(_data, m.c_str());
_url = _data;
normalizeData();
_m = _data;
@@ -169,85 +158,6 @@ void SGMetar::useCurrentDate()
_month = now.tm_mon + 1;
}
/**
* If called with "KSFO" loads data from
* @code
* http://weather.noaa.gov/pub/data/observations/metar/stations/KSFO.TXT.
* @endcode
* Throws sg_io_exception on failure. Gives up after waiting longer than 10 seconds.
*
* @param id four-letter ICAO Metar station code, e.g. "KSFO".
* @param proxy proxy host (optional; default: "")
* @param port proxy port (optional; default: "80")
* @param auth proxy authorization information (optional; default: "")
* @return pointer to Metar data string, allocated by new char[].
* @see rfc2068.txt for proxy spec ("Proxy-Authorization")
*/
char *SGMetar::loadData(const char *id, const string& proxy, const string& port,
const string& auth, time_t time)
{
const int buflen = 512;
char buf[2 * buflen];
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://" + metar_server + path;
SGSocket *sock = new SGSocket(host, port.empty() ? "80" : port, "tcp");
sock->set_timeout(10000);
if (!sock->open(SG_IO_OUT)) {
delete sock;
throw sg_io_exception("cannot connect to ", sg_location(host));
}
string get = "GET ";
if (!proxy.empty())
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";
get += "\015\012";
sock->writestring(get.c_str());
int i;
// skip HTTP header
while ((i = sock->readline(buf, buflen))) {
if (i <= 2 && isspace(buf[0]) && (!buf[1] || isspace(buf[1])))
break;
if (!strncmp(buf, "X-MetarProxy: ", 13))
_x_proxy = true;
}
if (i) {
i = sock->readline(buf, buflen);
if (i)
sock->readline(&buf[i], buflen);
}
sock->close();
delete sock;
char *b = buf;
scanBoundary(&b);
if (*b == '<')
throw sg_io_exception("no metar data available from ",
sg_location(_url));
char *metar = new char[strlen(b) + 2]; // make room for " \0"
strcpy(metar, b);
return metar;
}
/**
* Replace any number of subsequent spaces by just one space, and add
* a trailing space. This makes scanning for things like "ALL RWY" easier.

View File

@@ -29,18 +29,12 @@
#include <simgear/constants.h>
using std::vector;
using std::map;
using std::string;
const double SGMetarNaN = -1E20;
#define NaN SGMetarNaN
struct Token {
const char *id;
const char *text;
};
const double SGMetarNaN = -1E20;
class SGMetar;
@@ -48,7 +42,7 @@ class SGMetarVisibility {
friend class SGMetar;
public:
SGMetarVisibility() :
_distance(NaN),
_distance(SGMetarNaN),
_direction(-1),
_modifier(EQUALS),
_tendency(NONE) {}
@@ -70,8 +64,8 @@ public:
void set(double dist, int dir = -1, int mod = -1, int tend = -1);
inline double getVisibility_m() const { return _distance; }
inline double getVisibility_ft() const { return _distance == NaN ? NaN : _distance * SG_METER_TO_FEET; }
inline double getVisibility_sm() const { return _distance == NaN ? NaN : _distance * SG_METER_TO_SM; }
inline double getVisibility_ft() const { return _distance == SGMetarNaN ? SGMetarNaN : _distance * SG_METER_TO_FEET; }
inline double getVisibility_sm() const { return _distance == SGMetarNaN ? SGMetarNaN : _distance * SG_METER_TO_SM; }
inline int getDirection() const { return _direction; }
inline int getModifier() const { return _modifier; }
inline int getTendency() const { return _tendency; }
@@ -93,8 +87,8 @@ public:
_deposit_string(0),
_extent(-1),
_extent_string(0),
_depth(NaN),
_friction(NaN),
_depth(SGMetarNaN),
_friction(SGMetarNaN),
_friction_string(0),
_comment(0),
_wind_shear(false) {}
@@ -107,7 +101,7 @@ public:
inline double getFriction() const { return _friction; }
inline const char *getFrictionString() const { return _friction_string; }
inline const char *getComment() const { return _comment; }
inline const bool getWindShear() const { return _wind_shear; }
inline bool getWindShear() const { return _wind_shear; }
inline const SGMetarVisibility& getMinVisibility() const { return _min_visibility; }
inline const SGMetarVisibility& getMaxVisibility() const { return _max_visibility; }
@@ -146,14 +140,14 @@ public:
static const char * COVERAGE_BROKEN_STRING;
static const char * COVERAGE_OVERCAST_STRING;
SGMetarCloud() : _coverage(COVERAGE_NIL), _altitude(NaN), _type(0), _type_long(0) {}
SGMetarCloud() : _coverage(COVERAGE_NIL), _altitude(SGMetarNaN), _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 double getAltitude_ft() const { return _altitude == SGMetarNaN ? SGMetarNaN : _altitude * SG_METER_TO_FEET; }
inline const char *getTypeString() const { return _type; }
inline const char *getTypeLongString() const { return _type_long; }
@@ -167,8 +161,7 @@ protected:
class SGMetar {
public:
SGMetar(const string& m, const string& proxy = "", const string& port = "",
const string &auth = "", const time_t time = 0);
SGMetar(const std::string& m);
~SGMetar();
enum ReportType {
@@ -189,13 +182,13 @@ public:
Weather() { intensity = NIL; vincinity = false; }
Intensity intensity;
bool vincinity;
vector<string> descriptions;
vector<string> phenomena;
std::vector<std::string> descriptions;
std::vector<std::string> phenomena;
};
inline const char *getData() const { return _data; }
inline const char *getUnusedData() const { return _m; }
inline const bool getProxy() const { return _x_proxy; }
inline bool getProxy() const { return _x_proxy; }
inline const char *getId() const { return _icao; }
inline int getYear() const { return _year; }
inline int getMonth() const { return _month; }
@@ -206,14 +199,14 @@ public:
inline int getWindDir() const { return _wind_dir; }
inline double getWindSpeed_mps() const { return _wind_speed; }
inline double getWindSpeed_kmh() const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_KMH; }
inline double getWindSpeed_kt() const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_KT; }
inline double getWindSpeed_mph() const { return _wind_speed == NaN ? NaN : _wind_speed * SG_MPS_TO_MPH; }
inline double getWindSpeed_kmh() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_KMH; }
inline double getWindSpeed_kt() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_KT; }
inline double getWindSpeed_mph() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_MPH; }
inline double getGustSpeed_mps() const { return _gust_speed; }
inline double getGustSpeed_kmh() const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_KMH; }
inline double getGustSpeed_kt() const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_KT; }
inline double getGustSpeed_mph() const { return _gust_speed == NaN ? NaN : _gust_speed * SG_MPS_TO_MPH; }
inline double getGustSpeed_kmh() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_KMH; }
inline double getGustSpeed_kt() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_KT; }
inline double getGustSpeed_mph() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_MPH; }
inline int getWindRangeFrom() const { return _wind_range_from; }
inline int getWindRangeTo() const { return _wind_range_to; }
@@ -224,11 +217,11 @@ public:
inline const SGMetarVisibility *getDirVisibility() const { return _dir_visibility; }
inline double getTemperature_C() const { return _temp; }
inline double getTemperature_F() const { return _temp == NaN ? NaN : 1.8 * _temp + 32; }
inline double getTemperature_F() const { return _temp == SGMetarNaN ? SGMetarNaN : 1.8 * _temp + 32; }
inline double getDewpoint_C() const { return _dewp; }
inline double getDewpoint_F() const { return _dewp == NaN ? NaN : 1.8 * _dewp + 32; }
inline double getPressure_hPa() const { return _pressure == NaN ? NaN : _pressure / 100; }
inline double getPressure_inHg() const { return _pressure == NaN ? NaN : _pressure * SG_PA_TO_INHG; }
inline double getDewpoint_F() const { return _dewp == SGMetarNaN ? SGMetarNaN : 1.8 * _dewp + 32; }
inline double getPressure_hPa() const { return _pressure == SGMetarNaN ? SGMetarNaN : _pressure / 100; }
inline double getPressure_inHg() const { return _pressure == SGMetarNaN ? SGMetarNaN : _pressure * SG_PA_TO_INHG; }
inline int getRain() const { return _rain; }
inline int getHail() const { return _hail; }
@@ -237,13 +230,13 @@ public:
double getRelHumidity() const;
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; }
inline const std::vector<SGMetarCloud>& getClouds() const { return _clouds; }
inline const std::map<std::string, SGMetarRunway>& getRunways() const { return _runways; }
inline const std::vector<std::string>& getWeather() const { return _weather; }
inline const std::vector<struct Weather> getWeather2() const { return _weather2; }
protected:
string _url;
std::string _url;
int _grpcount;
bool _x_proxy;
char *_data;
@@ -267,15 +260,15 @@ protected:
int _hail;
int _snow;
bool _cavok;
vector<struct Weather> _weather2;
std::vector<struct Weather> _weather2;
SGMetarVisibility _min_visibility;
SGMetarVisibility _max_visibility;
SGMetarVisibility _vert_visibility;
SGMetarVisibility _dir_visibility[8];
vector<SGMetarCloud> _clouds;
map<string, SGMetarRunway> _runways;
vector<string> _weather;
std::vector<SGMetarCloud> _clouds;
std::map<std::string, SGMetarRunway> _runways;
std::vector<std::string> _weather;
bool scanPreambleDate();
bool scanPreambleTime();
@@ -303,10 +296,7 @@ protected:
int scanNumber(char **str, int *num, int min, int max = 0);
bool scanBoundary(char **str);
const struct Token *scanToken(char **str, const struct Token *list);
char *loadData(const char *id, const string& proxy, const string& port,
const string &auth, time_t time);
void normalizeData();
};
#undef NaN
#endif // _METAR_HXX

View File

@@ -0,0 +1,76 @@
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#ifdef _MSC_VER
# define random rand
#endif
#include <simgear/misc/sg_dir.hxx>
#include <simgear/structure/exception.hxx>
#include "metar.hxx"
using std::cout;
using std::cerr;
using std::endl;
using std::string;
#define COMPARE(a, b) \
if ((a) != (b)) { \
cerr << "failed:" << #a << " != " << #b << endl; \
cerr << "\tgot:" << a << endl; \
exit(1); \
}
#define FUZZY_COMPARE(a, b, epsilon) \
if (fabs(a - b) > epsilon) { \
cerr << "failed:" << #a << " != " << #b << endl; \
cerr << "\tgot:" << a << endl; \
cerr << "\tepsilon:" << epsilon << endl; \
}
#define VERIFY(a) \
if (!(a)) { \
cerr << "failed:" << #a << endl; \
exit(1); \
}
const double TEST_EPSILON = 1e-9;
void test_basic()
{
SGMetar m1("2011/10/20 11:25 EHAM 201125Z 27012KT 240V300 9999 VCSH FEW025CB SCT048 10/05 Q1025 TEMPO VRB03KT");
COMPARE(m1.getYear(), 2011);
COMPARE(m1.getMonth(), 10);
COMPARE(m1.getDay(), 20);
COMPARE(m1.getHour(), 11);
COMPARE(m1.getMinute(), 25);
COMPARE(m1.getReportType(), -1); // should default to NIL?
COMPARE(m1.getWindDir(), 270);
FUZZY_COMPARE(m1.getWindSpeed_kt(), 12, TEST_EPSILON);
FUZZY_COMPARE(m1.getTemperature_C(), 10, TEST_EPSILON);
FUZZY_COMPARE(m1.getDewpoint_C(), 5, TEST_EPSILON);
FUZZY_COMPARE(m1.getPressure_hPa(), 1025, TEST_EPSILON);
}
int main(int argc, char* argv[])
{
try {
test_basic();
} catch (sg_exception& e) {
cerr << "got exception:" << e.getMessage() << endl;
return -1;
}
return 0;
}

View File

@@ -1,34 +0,0 @@
includedir = @includedir@/ephemeris
lib_LIBRARIES = libsgephem.a
include_HEADERS = \
celestialBody.hxx \
ephemeris.hxx \
jupiter.hxx \
mars.hxx \
mercury.hxx \
moonpos.hxx \
neptune.hxx \
saturn.hxx \
star.hxx \
stardata.hxx \
uranus.hxx \
venus.hxx
libsgephem_a_SOURCES = \
celestialBody.cxx \
ephemeris.cxx \
jupiter.cxx \
mars.cxx \
mercury.cxx \
moonpos.cxx \
neptune.cxx \
pluto.hxx \
saturn.cxx \
star.cxx \
stardata.cxx \
uranus.cxx \
venus.cxx
INCLUDES = -I$(top_srcdir)

View File

@@ -7,6 +7,7 @@ set(HLA_HEADERS
HLABasicDataElement.hxx
HLABasicDataType.hxx
HLADataElement.hxx
HLADataElementVisitor.hxx
HLADataType.hxx
HLADataTypeVisitor.hxx
HLAEnumeratedDataElement.hxx
@@ -26,15 +27,13 @@ set(HLA_HEADERS
)
set(HLA_SOURCES
RTIObjectClass.cxx
RTIObjectInstance.cxx
RTIFederate.cxx
HLAArrayDataElement.cxx
HLAArrayDataType.cxx
HLABasicDataElement.cxx
HLABasicDataType.cxx
HLADataElement.cxx
HLADataType.cxx
HLADataTypeVisitor.cxx
HLAEnumeratedDataElement.cxx
HLAEnumeratedDataType.cxx
HLAFederate.cxx
@@ -51,15 +50,18 @@ set(HLA_SOURCES
simgear_component(hla hla "${HLA_SOURCES}" "${HLA_HEADERS}")
if(RTI_FOUND)
set(HLA13_HEADERS
HLA13Federate.hxx
)
set(HLA13_SOURCES
set(RTI13_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}")
simgear_component(rti13 hla "${RTI13_SOURCES}" "")
set_property(TARGET sgrti13 APPEND PROPERTY COMPILE_FLAGS "-I${RTI_INCLUDE_DIR}")
endif()
set(RTI_SOURCES
RTIObjectClass.cxx
RTIObjectInstance.cxx
RTIFederate.cxx
)
simgear_component(rti hla "${RTI_SOURCES}" "")

View File

@@ -1,33 +0,0 @@
// 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

@@ -1,33 +0,0 @@
// 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

@@ -19,6 +19,8 @@
#include <simgear/debug/logstream.hxx>
#include "HLADataElementVisitor.hxx"
namespace simgear {
HLAAbstractArrayDataElement::HLAAbstractArrayDataElement(const HLAArrayDataType* dataType) :
@@ -30,6 +32,18 @@ HLAAbstractArrayDataElement::~HLAAbstractArrayDataElement()
{
}
void
HLAAbstractArrayDataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLAAbstractArrayDataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
bool
HLAAbstractArrayDataElement::decode(HLADecodeStream& stream)
{

View File

@@ -33,6 +33,9 @@ public:
HLAAbstractArrayDataElement(const HLAArrayDataType* dataType);
virtual ~HLAAbstractArrayDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;
@@ -248,6 +251,43 @@ private:
SGVec2<T> _value;
};
template<typename T>
class HLAVec2Data {
public:
HLAVec2Data() :
_value(new HLAVec2DataElement<T>(0))
{ }
HLAVec2Data(const SGVec2<T>& value) :
_value(new HLAVec2DataElement<T>(0, value))
{ }
operator const SGVec2<T>&() const
{ return _value->getValue(); }
HLAVec2Data& operator=(const SGVec2<T>& value)
{ _value->setValue(value); return *this; }
const SGVec2<T>& getValue() const
{ return _value->getValue(); }
void setValue(const SGVec2<T>& value)
{ _value->setValue(value); }
const HLAVec2DataElement<T>* getDataElement() const
{ return _value.get(); }
HLAVec2DataElement<T>* getDataElement()
{ return _value.get(); }
const HLAArrayDataType* getDataType() const
{ return _value->getDataType(); }
void setDataType(const HLAArrayDataType* dataType)
{ _value->setDataType(dataType); }
private:
SGSharedPtr<HLAVec2DataElement<T> > _value;
};
typedef HLAVec2Data<float> HLAVec2fData;
typedef HLAVec2Data<double> HLAVec2dData;
template<typename T>
class HLAVec3DataElement : public HLAAbstractArrayDataElement {
public:
@@ -303,6 +343,43 @@ private:
SGVec3<T> _value;
};
template<typename T>
class HLAVec3Data {
public:
HLAVec3Data() :
_value(new HLAVec3DataElement<T>(0))
{ }
HLAVec3Data(const SGVec3<T>& value) :
_value(new HLAVec3DataElement<T>(0, value))
{ }
operator const SGVec3<T>&() const
{ return _value->getValue(); }
HLAVec3Data& operator=(const SGVec3<T>& value)
{ _value->setValue(value); return *this; }
const SGVec3<T>& getValue() const
{ return _value->getValue(); }
void setValue(const SGVec3<T>& value)
{ _value->setValue(value); }
const HLAVec3DataElement<T>* getDataElement() const
{ return _value.get(); }
HLAVec3DataElement<T>* getDataElement()
{ return _value.get(); }
const HLAArrayDataType* getDataType() const
{ return _value->getDataType(); }
void setDataType(const HLAArrayDataType* dataType)
{ _value->setDataType(dataType); }
private:
SGSharedPtr<HLAVec3DataElement<T> > _value;
};
typedef HLAVec3Data<float> HLAVec3fData;
typedef HLAVec3Data<double> HLAVec3dData;
template<typename T>
class HLAVec4DataElement : public HLAAbstractArrayDataElement {
public:
@@ -358,6 +435,43 @@ private:
SGVec4<T> _value;
};
template<typename T>
class HLAVec4Data {
public:
HLAVec4Data() :
_value(new HLAVec4DataElement<T>(0))
{ }
HLAVec4Data(const SGVec4<T>& value) :
_value(new HLAVec4DataElement<T>(0, value))
{ }
operator const SGVec4<T>&() const
{ return _value->getValue(); }
HLAVec4Data& operator=(const SGVec4<T>& value)
{ _value->setValue(value); return *this; }
const SGVec4<T>& getValue() const
{ return _value->getValue(); }
void setValue(const SGVec4<T>& value)
{ _value->setValue(value); }
const HLAVec4DataElement<T>* getDataElement() const
{ return _value.get(); }
HLAVec4DataElement<T>* getDataElement()
{ return _value.get(); }
const HLAArrayDataType* getDataType() const
{ return _value->getDataType(); }
void setDataType(const HLAArrayDataType* dataType)
{ _value->setDataType(dataType); }
private:
SGSharedPtr<HLAVec4DataElement<T> > _value;
};
typedef HLAVec4Data<float> HLAVec4fData;
typedef HLAVec4Data<double> HLAVec4dData;
template<typename T>
class HLAQuatDataElement : public HLAAbstractArrayDataElement {
public:

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
// Copyright (C) 2009 - 2011 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
@@ -22,7 +22,9 @@
namespace simgear {
HLAArrayDataType::HLAArrayDataType(const std::string& name) :
HLADataType(name)
HLADataType(name),
_isOpaque(false),
_isString(false)
{
}
@@ -51,6 +53,18 @@ HLAArrayDataType::setElementDataType(const HLADataType* elementDataType)
_elementDataType = elementDataType;
}
void
HLAArrayDataType::setIsOpaque(bool isOpaque)
{
_isOpaque = isOpaque;
}
void
HLAArrayDataType::setIsString(bool isString)
{
_isString = isString;
}
///////////////////////////////////////////////////////////////////////////////////
HLAFixedArrayDataType::HLAFixedArrayDataType(const std::string& name) :

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
// Copyright (C) 2009 - 2011 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
@@ -42,8 +42,18 @@ public:
const HLADataType* getElementDataType() const
{ return _elementDataType.get(); }
void setIsOpaque(bool isOpaque);
bool getIsOpaque() const
{ return _isOpaque; }
void setIsString(bool isString);
bool getIsString() const
{ return _isString; }
private:
SGSharedPtr<const HLADataType> _elementDataType;
bool _isOpaque;
bool _isString;
};
class HLAFixedArrayDataType : public HLAArrayDataType {

View File

@@ -17,6 +17,7 @@
#include "HLABasicDataElement.hxx"
#include "HLADataElementVisitor.hxx"
#include "HLADataTypeVisitor.hxx"
namespace simgear {
@@ -30,6 +31,18 @@ HLABasicDataElement::~HLABasicDataElement()
{
}
void
HLABasicDataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLABasicDataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
const HLABasicDataType*
HLABasicDataElement::getDataType() const
{

View File

@@ -28,6 +28,12 @@ public:
HLABasicDataElement(const HLABasicDataType* dataType);
virtual ~HLABasicDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool encode(HLAEncodeStream& stream) const = 0;
virtual bool decode(HLADecodeStream& stream) = 0;
virtual const HLABasicDataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType);
void setDataType(const HLABasicDataType* dataType);
@@ -41,6 +47,7 @@ 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); \
\

View File

@@ -19,6 +19,8 @@
#include <simgear/debug/logstream.hxx>
#include "HLADataElementVisitor.hxx"
namespace simgear {
HLADataElement::PathElement::Data::~Data()
@@ -129,6 +131,18 @@ HLADataElement::~HLADataElement()
{
}
void
HLADataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLADataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
std::string
HLADataElement::toString(const Path& path)
{

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
// Copyright (C) 2009 - 2011 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
@@ -30,10 +30,16 @@ class SGTimeStamp;
namespace simgear {
class HLADataElementVisitor;
class HLAConstDataElementVisitor;
class HLADataElement : public SGReferenced {
public:
virtual ~HLADataElement();
virtual void accept(HLADataElementVisitor& visitor) = 0;
virtual void accept(HLAConstDataElementVisitor& visitor) const = 0;
virtual bool encode(HLAEncodeStream& stream) const = 0;
virtual bool decode(HLADecodeStream& stream) = 0;

View File

@@ -0,0 +1,57 @@
// Copyright (C) 2009 - 2011 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 HLADataElementVisitor_hxx
#define HLADataElementVisitor_hxx
namespace simgear {
class HLABasicDataElement;
class HLAAbstractEnumeratedDataElement;
class HLAAbstractFixedRecordDataElement;
class HLAAbstractArrayDataElement;
class HLAAbstractVariantDataElement;
class HLADataElementVisitor {
public:
virtual ~HLADataElementVisitor() {}
virtual void apply(HLADataElement&);
virtual void apply(HLABasicDataElement&);
virtual void apply(HLAAbstractEnumeratedDataElement&);
virtual void apply(HLAAbstractArrayDataElement&);
virtual void apply(HLAAbstractFixedRecordDataElement&);
virtual void apply(HLAAbstractVariantDataElement&);
};
class HLAConstDataElementVisitor {
public:
virtual ~HLAConstDataElementVisitor() {}
virtual void apply(const HLADataElement&);
virtual void apply(const HLABasicDataElement&);
virtual void apply(const HLAAbstractEnumeratedDataElement&);
virtual void apply(const HLAAbstractArrayDataElement&);
virtual void apply(const HLAAbstractFixedRecordDataElement&);
virtual void apply(const HLAAbstractVariantDataElement&);
};
}
#endif

View File

@@ -0,0 +1,188 @@
// 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 "HLADataTypeVisitor.hxx"
#include "HLAArrayDataElement.hxx"
#include "HLABasicDataElement.hxx"
#include "HLADataTypeVisitor.hxx"
#include "HLAEnumeratedDataElement.hxx"
#include "HLAFixedRecordDataElement.hxx"
#include "HLAVariantDataElement.hxx"
namespace simgear {
HLADataElementFactoryVisitor::~HLADataElementFactoryVisitor()
{
}
void
HLADataElementFactoryVisitor::apply(const HLADataType& dataType)
{
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Can not find a suitable data element for data type \""
<< dataType.getName() << "\"");
}
void
HLADataElementFactoryVisitor::apply(const HLAInt8DataType& dataType)
{
_dataElement = new HLASCharDataElement(&dataType);
}
void
HLADataElementFactoryVisitor::apply(const HLAUInt8DataType& dataType)
{
_dataElement = new HLAUCharDataElement(&dataType);
}
void
HLADataElementFactoryVisitor::apply(const HLAInt16DataType& dataType)
{
_dataElement = new HLAShortDataElement(&dataType);
}
void
HLADataElementFactoryVisitor::apply(const HLAUInt16DataType& dataType)
{
_dataElement = new HLAUShortDataElement(&dataType);
}
void
HLADataElementFactoryVisitor::apply(const HLAInt32DataType& dataType)
{
_dataElement = new HLAIntDataElement(&dataType);
}
void
HLADataElementFactoryVisitor::apply(const HLAUInt32DataType& dataType)
{
_dataElement = new HLAUIntDataElement(&dataType);
}
void
HLADataElementFactoryVisitor::apply(const HLAInt64DataType& dataType)
{
_dataElement = new HLALongDataElement(&dataType);
}
void
HLADataElementFactoryVisitor::apply(const HLAUInt64DataType& dataType)
{
_dataElement = new HLAULongDataElement(&dataType);
}
void
HLADataElementFactoryVisitor::apply(const HLAFloat32DataType& dataType)
{
_dataElement = new HLAFloatDataElement(&dataType);
}
void
HLADataElementFactoryVisitor::apply(const HLAFloat64DataType& dataType)
{
_dataElement = new HLADoubleDataElement(&dataType);
}
class HLADataElementFactoryVisitor::ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory {
public:
virtual HLADataElement* createElement(const HLAArrayDataElement& element, unsigned index)
{
const HLADataType* dataType = element.getElementDataType();
if (!dataType)
return 0;
HLADataElementFactoryVisitor visitor;
dataType->accept(visitor);
return visitor.getDataElement();
}
};
void
HLADataElementFactoryVisitor::apply(const HLAFixedArrayDataType& dataType)
{
if (dataType.getIsString()) {
_dataElement = new HLAStringDataElement(&dataType);
} else {
SGSharedPtr<HLAArrayDataElement> arrayDataElement;
arrayDataElement = new HLAArrayDataElement(&dataType);
arrayDataElement->setDataElementFactory(new ArrayDataElementFactory);
arrayDataElement->setNumElements(dataType.getNumElements());
_dataElement = arrayDataElement;
}
}
void
HLADataElementFactoryVisitor::apply(const HLAVariableArrayDataType& dataType)
{
if (dataType.getIsString()) {
_dataElement = new HLAStringDataElement(&dataType);
} else {
SGSharedPtr<HLAArrayDataElement> arrayDataElement;
arrayDataElement = new HLAArrayDataElement(&dataType);
arrayDataElement->setDataElementFactory(new ArrayDataElementFactory);
_dataElement = arrayDataElement;
}
}
void
HLADataElementFactoryVisitor::apply(const HLAEnumeratedDataType& dataType)
{
_dataElement = new HLAEnumeratedDataElement(&dataType);
}
void
HLADataElementFactoryVisitor::apply(const HLAFixedRecordDataType& dataType)
{
SGSharedPtr<HLAFixedRecordDataElement> recordDataElement;
recordDataElement = new HLAFixedRecordDataElement(&dataType);
unsigned numFields = dataType.getNumFields();
for (unsigned i = 0; i < numFields; ++i) {
HLADataElementFactoryVisitor visitor;
dataType.getFieldDataType(i)->accept(visitor);
recordDataElement->setField(i, visitor._dataElement.get());
}
_dataElement = recordDataElement;
}
class HLADataElementFactoryVisitor::VariantDataElementFactory : public HLAVariantDataElement::DataElementFactory {
public:
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;
HLADataElementFactoryVisitor visitor;
alternativeDataType->accept(visitor);
return visitor.getDataElement();
}
};
void
HLADataElementFactoryVisitor::apply(const HLAVariantDataType& dataType)
{
SGSharedPtr<HLAVariantDataElement> variantDataElement;
variantDataElement = new HLAVariantDataElement(&dataType);
variantDataElement->setDataElementFactory(new VariantDataElementFactory);
_dataElement = variantDataElement;
}
} // namespace simgear

View File

@@ -24,7 +24,7 @@
#include <simgear/math/SGMath.hxx>
#include "HLAArrayDataType.hxx"
#include "HLABasicDataType.hxx"
#include "HLADataTypeVisitor.hxx"
#include "HLADataElement.hxx"
#include "HLAEnumeratedDataType.hxx"
#include "HLAFixedRecordDataType.hxx"
#include "HLAVariantDataType.hxx"
@@ -629,6 +629,43 @@ inline void HLADataTypeEncodeVisitor::apply(const HLAVariableArrayDataType& data
dataType.getSizeDataType()->accept(numElementsVisitor);
}
/// Generate standard data elements according to the traversed type
class HLADataElementFactoryVisitor : public HLADataTypeVisitor {
public:
virtual ~HLADataElementFactoryVisitor();
virtual void apply(const HLADataType& dataType);
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);
virtual void apply(const HLAVariableArrayDataType& dataType);
virtual void apply(const HLAEnumeratedDataType& dataType);
virtual void apply(const HLAFixedRecordDataType& dataType);
virtual void apply(const HLAVariantDataType& dataType);
HLADataElement* getDataElement()
{ return _dataElement.release(); }
protected:
class ArrayDataElementFactory;
class VariantDataElementFactory;
SGSharedPtr<HLADataElement> _dataElement;
};
} // namespace simgear
#endif

View File

@@ -19,6 +19,8 @@
#include <simgear/debug/logstream.hxx>
#include "HLADataElementVisitor.hxx"
namespace simgear {
HLAAbstractEnumeratedDataElement::HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType) :
@@ -30,6 +32,18 @@ HLAAbstractEnumeratedDataElement::~HLAAbstractEnumeratedDataElement()
{
}
void
HLAAbstractEnumeratedDataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLAAbstractEnumeratedDataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
bool
HLAAbstractEnumeratedDataElement::decode(HLADecodeStream& stream)
{

View File

@@ -28,6 +28,9 @@ public:
HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType);
virtual ~HLAAbstractEnumeratedDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
// Copyright (C) 2009 - 2011 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
@@ -17,6 +17,7 @@
#include "HLAFederate.hxx"
#include "RTI13Federate.hxx"
#include "RTIFederate.hxx"
#include "RTIInteractionClass.hxx"
#include "RTIObjectClass.hxx"
@@ -26,8 +27,13 @@
namespace simgear {
HLAFederate::HLAFederate(const SGSharedPtr<RTIFederate>& rtiFederate) :
_rtiFederate(rtiFederate)
HLAFederate::HLAFederate() :
_version(RTI13),
_createFederationExecution(true),
_timeConstrained(false),
_timeRegulating(false),
_timeConstrainedByLocalClock(false),
_done(false)
{
}
@@ -35,88 +41,707 @@ HLAFederate::~HLAFederate()
{
}
const std::string&
HLAFederate::getFederateType() const
HLAFederate::Version
HLAFederate::getVersion() const
{
return _rtiFederate->getFederateType();
return _version;
}
bool
HLAFederate::setVersion(HLAFederate::Version version)
{
if (_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
return false;
}
_version = version;
return true;
}
const std::list<std::string>&
HLAFederate::getConnectArguments() const
{
return _connectArguments;
}
bool
HLAFederate::setConnectArguments(const std::list<std::string>& connectArguments)
{
if (_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
return false;
}
_connectArguments = connectArguments;
return true;
}
bool
HLAFederate::getCreateFederationExecution() const
{
return _createFederationExecution;
}
bool
HLAFederate::setCreateFederationExecution(bool createFederationExecution)
{
_createFederationExecution = createFederationExecution;
return true;
}
const std::string&
HLAFederate::getFederationName() const
HLAFederate::getFederationExecutionName() const
{
return _rtiFederate->getFederationName();
return _federationExecutionName;
}
bool
HLAFederate::setFederationExecutionName(const std::string& federationExecutionName)
{
if (_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
return false;
}
_federationExecutionName = federationExecutionName;
return true;
}
const std::string&
HLAFederate::getFederationObjectModel() const
{
return _federationObjectModel;
}
bool
HLAFederate::setFederationObjectModel(const std::string& federationObjectModel)
{
if (_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
return false;
}
_federationObjectModel = federationObjectModel;
return true;
}
const std::string&
HLAFederate::getFederateType() const
{
return _federateType;
}
bool
HLAFederate::setFederateType(const std::string& federateType)
{
if (_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
return false;
}
_federateType = federateType;
return true;
}
const std::string&
HLAFederate::getFederateName() const
{
return _federateName;
}
bool
HLAFederate::setFederateName(const std::string& federateName)
{
if (_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
return false;
}
_federateName = federateName;
return true;
}
bool
HLAFederate::connect(Version version, const std::list<std::string>& stringList)
{
if (_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!");
return false;
}
switch (version) {
case RTI13:
_rtiFederate = new RTI13Federate(stringList);
_version = version;
_connectArguments = stringList;
break;
case RTI1516:
SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported.");
// _rtiFederate = new RTI1516Federate(stringList);
break;
case RTI1516E:
SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
// _rtiFederate = new RTI1516eFederate(stringList);
break;
default:
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
}
return _rtiFederate.valid();
}
bool
HLAFederate::connect()
{
if (_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!");
return false;
}
switch (_version) {
case RTI13:
_rtiFederate = new RTI13Federate(_connectArguments);
break;
case RTI1516:
SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported.");
// _rtiFederate = new RTI1516Federate(_connectArguments);
break;
case RTI1516E:
SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
// _rtiFederate = new RTI1516eFederate(_connectArguments);
break;
default:
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
}
return _rtiFederate.valid();
}
bool
HLAFederate::disconnect()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
_rtiFederate = 0;
return true;
}
bool
HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
{
return _rtiFederate->createFederationExecution(federation, objectModel);
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
RTIFederate::FederationManagementResult createResult;
createResult = _rtiFederate->createFederationExecution(federation, objectModel);
if (createResult == RTIFederate::FederationManagementFatal)
return false;
_federationExecutionName = federation;
_federationObjectModel = objectModel;
return true;
}
bool
HLAFederate::destroyFederationExecution(const std::string& federation)
{
return _rtiFederate->destroyFederationExecution(federation);
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
RTIFederate::FederationManagementResult destroyResult;
destroyResult = _rtiFederate->destroyFederationExecution(federation);
if (destroyResult == RTIFederate::FederationManagementFatal)
return false;
return true;
}
bool
HLAFederate::createFederationExecution()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
RTIFederate::FederationManagementResult createResult;
createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
if (createResult != RTIFederate::FederationManagementSuccess)
return false;
return true;
}
bool
HLAFederate::destroyFederationExecution()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
RTIFederate::FederationManagementResult destroyResult;
destroyResult = _rtiFederate->destroyFederationExecution(_federationExecutionName);
if (destroyResult != RTIFederate::FederationManagementSuccess)
return false;
return true;
}
bool
HLAFederate::join(const std::string& federateType, const std::string& federation)
{
return _rtiFederate->join(federateType, federation);
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
RTIFederate::FederationManagementResult joinResult;
joinResult = _rtiFederate->join(federateType, federation);
if (joinResult == RTIFederate::FederationManagementFatal)
return false;
return true;
}
bool
HLAFederate::join()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
RTIFederate::FederationManagementResult joinResult;
joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
if (joinResult != RTIFederate::FederationManagementSuccess)
return false;
return true;
}
bool
HLAFederate::resign()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
return _rtiFederate->resign();
}
bool
HLAFederate::createJoinFederationExecution()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
for (;;) {
// Try to join.
RTIFederate::FederationManagementResult joinResult;
joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
switch (joinResult) {
case RTIFederate::FederationManagementSuccess:
// Fast return on success
return true;
case RTIFederate::FederationManagementFatal:
// Abort on fatal errors
return false;
default:
break;
};
// If not already joinable, try to create the requested federation
RTIFederate::FederationManagementResult createResult;
createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
switch (createResult) {
case RTIFederate::FederationManagementFatal:
// Abort on fatal errors
return false;
default:
// Try again to join
break;
}
}
}
bool
HLAFederate::resignDestroyFederationExecution()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
// Resign ourselves
bool success = _rtiFederate->resign();
// and try to destroy, non fatal if still some federates joined
if (_rtiFederate->destroyFederationExecution(_federationExecutionName) == RTIFederate::FederationManagementFatal)
success = false;
return success;
}
bool
HLAFederate::getTimeConstrained() const
{
return _timeConstrained;
}
bool
HLAFederate::setTimeConstrained(bool timeConstrained)
{
_timeConstrained = timeConstrained;
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
if (_timeConstrained && !_rtiFederate->getTimeConstrainedEnabled()) {
if (!enableTimeConstrained())
return false;
} else if (!_timeConstrained && _rtiFederate->getTimeConstrainedEnabled()) {
if (!disableTimeConstrained())
return false;
}
}
return true;
}
bool
HLAFederate::getTimeConstrainedByLocalClock() const
{
return _timeConstrainedByLocalClock;
}
bool
HLAFederate::setTimeConstrainedByLocalClock(bool timeConstrainedByLocalClock)
{
_timeConstrainedByLocalClock = timeConstrainedByLocalClock;
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
if (_timeConstrainedByLocalClock) {
if (!enableTimeConstrainedByLocalClock())
return false;
}
}
return true;
}
bool
HLAFederate::getTimeRegulating() const
{
return _timeRegulating;
}
bool
HLAFederate::setTimeRegulating(bool timeRegulating)
{
_timeRegulating = timeRegulating;
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
if (_timeRegulating && !_rtiFederate->getTimeRegulationEnabled()) {
if (!enableTimeRegulation())
return false;
} else if (!_timeRegulating && _rtiFederate->getTimeRegulationEnabled()) {
if (!disableTimeRegulation())
return false;
}
}
return true;
}
bool
HLAFederate::setLeadTime(const SGTimeStamp& leadTime)
{
if (leadTime < SGTimeStamp::fromSec(0)) {
SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative lead time!");
return false;
}
_leadTime = leadTime;
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
return false;
}
}
return true;
}
const SGTimeStamp&
HLAFederate::getLeadTime() const
{
return _leadTime;
}
bool
HLAFederate::setTimeIncrement(const SGTimeStamp& timeIncrement)
{
if (timeIncrement < SGTimeStamp::fromSec(0)) {
SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative time increment!");
return false;
}
_timeIncrement = timeIncrement;
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
return false;
}
}
return true;
}
const SGTimeStamp&
HLAFederate::getTimeIncrement() const
{
return _timeIncrement;
}
bool
HLAFederate::enableTimeConstrained()
{
return _rtiFederate->enableTimeConstrained();
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
if (!_rtiFederate->enableTimeConstrained()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time constrained!");
return false;
}
while (!_rtiFederate->getTimeConstrainedEnabled()) {
_rtiFederate->processMessage();
}
return true;
}
bool
HLAFederate::disableTimeConstrained()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
return _rtiFederate->disableTimeConstrained();
}
bool
HLAFederate::enableTimeConstrainedByLocalClock()
{
// Compute the time offset from the system time to the simulation time
SGTimeStamp federateTime;
if (!queryFederateTime(federateTime)) {
SG_LOG(SG_NETWORK, SG_WARN, "Cannot get federate time!");
return false;
}
_localClockOffset = SGTimeStamp::now() - federateTime;
return true;
}
bool
HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
{
return _rtiFederate->enableTimeRegulation(lookahead);
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
if (!_rtiFederate->enableTimeRegulation(lookahead)) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time regulation!");
return false;
}
while (!_rtiFederate->getTimeRegulationEnabled()) {
_rtiFederate->processMessage();
}
return true;
}
bool
HLAFederate::enableTimeRegulation()
{
if (!enableTimeRegulation(SGTimeStamp::fromSec(0))) {
SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time regulation!");
return false;
}
if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
return false;
}
return true;
}
bool
HLAFederate::disableTimeRegulation()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
return _rtiFederate->disableTimeRegulation();
}
bool
HLAFederate::timeAdvanceRequestBy(const SGTimeStamp& dt)
HLAFederate::modifyLookahead(const SGTimeStamp& timeStamp)
{
return _rtiFederate->timeAdvanceRequestBy(dt);
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
return _rtiFederate->modifyLookahead(timeStamp);
}
bool
HLAFederate::timeAdvanceRequest(const SGTimeStamp& dt)
HLAFederate::timeAdvanceBy(const SGTimeStamp& timeIncrement)
{
return _rtiFederate->timeAdvanceRequest(dt);
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
SGTimeStamp timeStamp;
if (!_rtiFederate->queryFederateTime(timeStamp)) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query federate time!");
return false;
}
if (!_rtiFederate->timeAdvanceRequest(timeStamp + timeIncrement)) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
return false;
}
return processMessages();
}
bool
HLAFederate::tick()
HLAFederate::timeAdvance(const SGTimeStamp& timeStamp)
{
return _rtiFederate->tick();
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
if (!_rtiFederate->timeAdvanceRequest(timeStamp)) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
return false;
}
return processMessages();
}
bool
HLAFederate::timeAdvanceAvailable()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
SGTimeStamp timeStamp;
if (!_rtiFederate->queryGALT(timeStamp)) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query GALT!");
return false;
}
if (!_rtiFederate->timeAdvanceRequestAvailable(timeStamp)) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
return false;
}
return processMessages();
}
bool
HLAFederate::queryFederateTime(SGTimeStamp& timeStamp)
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
return _rtiFederate->queryFederateTime(timeStamp);
}
bool
HLAFederate::queryLookahead(SGTimeStamp& timeStamp)
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
return _rtiFederate->queryLookahead(timeStamp);
}
bool
HLAFederate::processMessage()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
return _rtiFederate->processMessage();
}
bool
HLAFederate::processMessage(const SGTimeStamp& timeout)
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
return _rtiFederate->processMessages(timeout.toSecs(), 0);
}
bool
HLAFederate::processMessages()
{
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
while (_rtiFederate->getTimeAdvancePending()) {
_rtiFederate->processMessage();
}
if (_timeConstrainedByLocalClock) {
SGTimeStamp federateTime;
if (!_rtiFederate->queryFederateTime(federateTime)) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Error querying federate time!");
return false;
}
SGTimeStamp systemTime = federateTime + _localClockOffset;
for (;;) {
double rest = (systemTime - SGTimeStamp::now()).toSecs();
if (rest < 0)
break;
_rtiFederate->processMessages(rest, rest);
}
}
// Now flush just what is left
while (_rtiFederate->processMessages(0, 0));
return true;
}
bool
HLAFederate::tick(const double& minimum, const double& maximum)
{
return _rtiFederate->tick(minimum, maximum);
if (!_rtiFederate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
return _rtiFederate->processMessages(minimum, maximum);
}
bool
@@ -124,8 +749,7 @@ 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!");
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
return false;
}
@@ -243,4 +867,146 @@ HLAFederate::getInteractionClass(const std::string& name) const
return i->second.get();
}
void
HLAFederate::setDone(bool done)
{
_done = done;
}
bool
HLAFederate::getDone() const
{
return _done;
}
bool
HLAFederate::readObjectModel()
{
/// Currently empty, but is called at the right time so that
/// the object model is present when it is needed
return true;
}
bool
HLAFederate::subscribe()
{
/// Currently empty, but is called at the right time
return true;
}
bool
HLAFederate::publish()
{
/// Currently empty, but is called at the right time
return true;
}
bool
HLAFederate::init()
{
// We need to talk to the rti
if (!connect())
return false;
// Join ...
if (_createFederationExecution) {
if (!createJoinFederationExecution())
return false;
} else {
if (!join())
return false;
}
// Read the xml file containing the object model
if (!readObjectModel()) {
shutdown();
return false;
}
// start being time constrained if required
if (_timeConstrained) {
if (!enableTimeConstrained()) {
shutdown();
return false;
}
}
// Now that we are potentially time constrained, we can subscribe.
// This is to make sure we do not get any time stamped message
// converted to a non time stamped message by the rti.
if (!subscribe()) {
shutdown();
return false;
}
// Before we publish anything start getting regulating if required
if (_timeRegulating) {
if (!enableTimeRegulation()) {
shutdown();
return false;
}
}
// Note that starting from here, we need to be careful with things
// requireing unbounded time. The rest of the federation might wait
// for us to finish!
// Compute the time offset from the system time to the simulation time
if (_timeConstrainedByLocalClock) {
if (!enableTimeConstrainedByLocalClock()) {
SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time constrained by local clock!");
shutdown();
return false;
}
}
// Publish what we want to write
if (!publish()) {
shutdown();
return false;
}
return true;
}
bool
HLAFederate::update()
{
return timeAdvanceBy(_timeIncrement);
}
bool
HLAFederate::shutdown()
{
// On shutdown, just try all in order.
// If something goes wrong, continue and try to get out here as good as possible.
bool ret = true;
if (_createFederationExecution) {
if (!resignDestroyFederationExecution())
ret = false;
} else {
if (!resign())
ret = false;
}
if (!disconnect())
ret = false;
return ret;
}
bool
HLAFederate::exec()
{
if (!init())
return false;
while (!getDone()) {
if (!update()) {
shutdown();
return false;
}
}
if (!shutdown())
return false;
return true;
}
} // namespace simgear

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
// Copyright (C) 2009 - 2011 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
@@ -32,34 +32,136 @@ class RTIFederate;
class HLAFederate : public SGWeakReferenced {
public:
HLAFederate();
virtual ~HLAFederate();
/// Get the name of the joined federate/federation
enum Version {
RTI13,
RTI1516,
RTI1516E
};
/// The rti version backend to connect
Version getVersion() const;
bool setVersion(HLAFederate::Version version);
/// The rti backends connect arguments, depends on the version
const std::list<std::string>& getConnectArguments() const;
bool setConnectArguments(const std::list<std::string>& connectArguments);
/// If true try to create on join and try to destroy on resign
bool getCreateFederationExecution() const;
bool setCreateFederationExecution(bool createFederationExecution);
/// The federation execution name to use on create, join and destroy
const std::string& getFederationExecutionName() const;
bool setFederationExecutionName(const std::string& federationExecutionName);
/// The federation object model name to use on create and possibly join
const std::string& getFederationObjectModel() const;
bool setFederationObjectModel(const std::string& federationObjectModel);
/// The federate type used on join
const std::string& getFederateType() const;
const std::string& getFederationName() const;
bool setFederateType(const std::string& federateType);
/// The federate name possibly used on join
const std::string& getFederateName() const;
bool setFederateName(const std::string& federateName);
/// connect to an rti
bool connect(Version version, const std::list<std::string>& stringList);
bool connect();
bool disconnect();
/// 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);
bool createFederationExecution();
bool destroyFederationExecution();
/// Join with federateType the federation execution
bool join(const std::string& federateType, const std::string& federation);
bool join();
bool resign();
/// Try to create and join the federation execution.
bool createJoinFederationExecution();
bool resignDestroyFederationExecution();
/// Time management
/// If set to true, time constrained mode is entered on init
bool getTimeConstrained() const;
bool setTimeConstrained(bool timeConstrained);
/// If set to true, time advance is constrained by the local system clock
bool getTimeConstrainedByLocalClock() const;
bool setTimeConstrainedByLocalClock(bool timeConstrainedByLocalClock);
/// If set to true, time regulation mode is entered on init
bool getTimeRegulating() const;
bool setTimeRegulating(bool timeRegulating);
/// If set to a non zero value, this federate leads the federations
/// locical time advance by this amount of time.
const SGTimeStamp& getLeadTime() const;
bool setLeadTime(const SGTimeStamp& leadTime);
/// The time increment for use in the default update method.
const SGTimeStamp& getTimeIncrement() const;
bool setTimeIncrement(const SGTimeStamp& timeIncrement);
/// Actually enable time constrained mode.
/// This method blocks until time constrained mode is enabled.
bool enableTimeConstrained();
/// Actually disable time constrained mode.
bool disableTimeConstrained();
/// Actually enable time constrained by local clock mode.
bool enableTimeConstrainedByLocalClock();
/// Actually enable time regulation mode.
/// This method blocks until time regulation mode is enabled.
bool enableTimeRegulation(const SGTimeStamp& lookahead);
bool enableTimeRegulation();
/// Actually disable time regulation mode.
bool disableTimeRegulation();
/// Actually modify the lookahead time.
bool modifyLookahead(const SGTimeStamp& lookahead);
bool timeAdvanceRequestBy(const SGTimeStamp& dt);
bool timeAdvanceRequest(const SGTimeStamp& dt);
/// Advance the logical time by the given time increment.
/// Depending on the time constrained mode, this might
/// block until the time advance is granted.
bool timeAdvanceBy(const SGTimeStamp& timeIncrement);
/// Advance the logical time to the given time.
/// Depending on the time constrained mode, this might
/// block until the time advance is granted.
bool timeAdvance(const SGTimeStamp& timeStamp);
/// Advance the logical time as far as time advances are available.
/// This call should not block and advance the logical time
/// as far as currently possible.
bool timeAdvanceAvailable();
/// Process messages
bool tick();
/// Get the current federates time
bool queryFederateTime(SGTimeStamp& timeStamp);
/// Get the current federates lookahead
bool queryLookahead(SGTimeStamp& timeStamp);
/// Process one messsage
bool processMessage();
/// Process one message but do not wait longer than the relative timeout.
bool processMessage(const SGTimeStamp& timeout);
/// Process messages until the federate can proceed with the
/// next simulation step. That is flush all pending messages and
/// depending on the time constrained mode process messages until
/// a pending time advance is granted.
bool processMessages();
/// Legacy tick call
bool tick(const double& minimum, const double& maximum);
class ObjectModelFactory {
@@ -84,18 +186,67 @@ public:
bool readObjectModelTemplate(const std::string& objectModel,
ObjectModelFactory& objectModelFactory);
/// Get the object class of a given name
HLAObjectClass* getObjectClass(const std::string& name);
const HLAObjectClass* getObjectClass(const std::string& name) const;
/// Get the interaction class of a given name
HLAInteractionClass* getInteractionClass(const std::string& name);
const HLAInteractionClass* getInteractionClass(const std::string& name) const;
protected:
HLAFederate(const SGSharedPtr<RTIFederate>& rtiFederate);
/// Tells the main exec loop to continue or not.
void setDone(bool done);
bool getDone() const;
virtual bool readObjectModel();
virtual bool subscribe();
virtual bool publish();
virtual bool init();
virtual bool update();
virtual bool shutdown();
virtual bool exec();
private:
HLAFederate(const HLAFederate&);
HLAFederate& operator=(const HLAFederate&);
/// The underlying interface to the rti implementation
SGSharedPtr<RTIFederate> _rtiFederate;
/// Parameters required to connect to an rti
Version _version;
std::list<std::string> _connectArguments;
/// Parameters for the federation execution
std::string _federationExecutionName;
std::string _federationObjectModel;
bool _createFederationExecution;
/// Parameters for the federate
std::string _federateType;
std::string _federateName;
/// Time management related parameters
/// If true, the federate is expected to enter time constrained mode
bool _timeConstrained;
/// If true, the federate is expected to enter time regulating mode
bool _timeRegulating;
/// The amount of time this federate leads the others.
SGTimeStamp _leadTime;
/// The regular time increment we do on calling update()
SGTimeStamp _timeIncrement;
/// The reference system time at initialization time.
/// Is used to implement being time constrained on the
/// local system time.
bool _timeConstrainedByLocalClock;
SGTimeStamp _localClockOffset;
/// If true the exec method returns.
bool _done;
typedef std::map<std::string, SGSharedPtr<HLAObjectClass> > ObjectClassMap;
ObjectClassMap _objectClassMap;

View File

@@ -20,6 +20,8 @@
#include <string>
#include <vector>
#include <simgear/debug/logstream.hxx>
#include "HLADataElementVisitor.hxx"
#include "HLADataTypeVisitor.hxx"
namespace simgear {
@@ -33,6 +35,18 @@ HLAAbstractFixedRecordDataElement::~HLAAbstractFixedRecordDataElement()
{
}
void
HLAAbstractFixedRecordDataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLAAbstractFixedRecordDataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
bool
HLAAbstractFixedRecordDataElement::decode(HLADecodeStream& stream)
{

View File

@@ -30,6 +30,9 @@ public:
HLAAbstractFixedRecordDataElement(const HLAFixedRecordDataType* dataType);
virtual ~HLAAbstractFixedRecordDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;

View File

@@ -25,6 +25,10 @@ class RTIInteractionClass;
class HLAInteractionClass : public SGWeakReferenced {
public:
virtual ~HLAInteractionClass() {}
private:
HLAInteractionClass(const HLAInteractionClass&);
HLAInteractionClass& operator=(const HLAInteractionClass&);
};
} // namespace simgear

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
// Copyright (C) 2009 - 2011 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
@@ -439,6 +439,15 @@ HLAOMTXmlVisitor::getArrayDataType(const std::string& dataTypeName, HLAOMTXmlVis
}
arrayDataType->setElementDataType(elementDataType.get());
// Check if this should be a string data type
if (elementDataType->toBasicDataType()) {
if (dataTypeName == "HLAopaqueData") {
arrayDataType->setIsOpaque(true);
} else if (dataTypeName.find("String") != std::string::npos || dataTypeName.find("string") != std::string::npos) {
arrayDataType->setIsString(true);
}
}
return arrayDataType;
}

View File

@@ -95,6 +95,9 @@ protected:
virtual HLAObjectInstance* createObjectInstance(RTIObjectInstance* rtiObjectInstance);
private:
HLAObjectClass(const HLAObjectClass&);
HLAObjectClass& operator=(const HLAObjectClass&);
// The internal entry points from the RTILObjectClass callback functions
void discoverInstance(RTIObjectInstance* objectInstance, const RTIData& tag);
void removeInstance(HLAObjectInstance& objectInstance, const RTIData& tag);

View File

@@ -123,7 +123,7 @@ HLAObjectInstance::getAttributeDataElement(unsigned index) const
return _rtiObjectInstance->getDataElement(index);
}
class HLAObjectInstance::DataElementFactoryVisitor : public HLADataTypeVisitor {
class HLAObjectInstance::DataElementFactoryVisitor : public HLADataElementFactoryVisitor {
public:
DataElementFactoryVisitor(const HLAPathElementMap& pathElementMap) :
_pathElementMap(pathElementMap)
@@ -150,7 +150,7 @@ public:
if (_dataElement.valid())
return;
_dataElement = new HLASCharDataElement(&dataType);
HLADataElementFactoryVisitor::apply(dataType);
}
virtual void apply(const HLAUInt8DataType& dataType)
{
@@ -158,7 +158,7 @@ public:
if (_dataElement.valid())
return;
_dataElement = new HLAUCharDataElement(&dataType);
HLADataElementFactoryVisitor::apply(dataType);
}
virtual void apply(const HLAInt16DataType& dataType)
{
@@ -166,7 +166,7 @@ public:
if (_dataElement.valid())
return;
_dataElement = new HLAShortDataElement(&dataType);
HLADataElementFactoryVisitor::apply(dataType);
}
virtual void apply(const HLAUInt16DataType& dataType)
{
@@ -174,7 +174,7 @@ public:
if (_dataElement.valid())
return;
_dataElement = new HLAUShortDataElement(&dataType);
HLADataElementFactoryVisitor::apply(dataType);
}
virtual void apply(const HLAInt32DataType& dataType)
{
@@ -182,7 +182,7 @@ public:
if (_dataElement.valid())
return;
_dataElement = new HLAIntDataElement(&dataType);
HLADataElementFactoryVisitor::apply(dataType);
}
virtual void apply(const HLAUInt32DataType& dataType)
{
@@ -190,7 +190,7 @@ public:
if (_dataElement.valid())
return;
_dataElement = new HLAUIntDataElement(&dataType);
HLADataElementFactoryVisitor::apply(dataType);
}
virtual void apply(const HLAInt64DataType& dataType)
{
@@ -198,7 +198,7 @@ public:
if (_dataElement.valid())
return;
_dataElement = new HLALongDataElement(&dataType);
HLADataElementFactoryVisitor::apply(dataType);
}
virtual void apply(const HLAUInt64DataType& dataType)
{
@@ -206,7 +206,7 @@ public:
if (_dataElement.valid())
return;
_dataElement = new HLAULongDataElement(&dataType);
HLADataElementFactoryVisitor::apply(dataType);
}
virtual void apply(const HLAFloat32DataType& dataType)
{
@@ -214,7 +214,7 @@ public:
if (_dataElement.valid())
return;
_dataElement = new HLAFloatDataElement(&dataType);
HLADataElementFactoryVisitor::apply(dataType);
}
virtual void apply(const HLAFloat64DataType& dataType)
{
@@ -222,7 +222,7 @@ public:
if (_dataElement.valid())
return;
_dataElement = new HLADoubleDataElement(&dataType);
HLADataElementFactoryVisitor::apply(dataType);
}
class ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory {
@@ -287,7 +287,7 @@ public:
if (_dataElement.valid())
return;
_dataElement = new HLAEnumeratedDataElement(&dataType);
HLADataElementFactoryVisitor::apply(dataType);
}
virtual void apply(const HLAFixedRecordDataType& dataType)
@@ -357,9 +357,6 @@ public:
_dataElement = variantDataElement;
}
const SGSharedPtr<HLADataElement>& getDataElement() const
{ return _dataElement; }
private:
SGSharedPtr<HLADataElement> createDataElement(const HLADataElement::Path& path, const HLADataType& dataType)
{
@@ -381,7 +378,6 @@ private:
return dataElement;
}
SGSharedPtr<HLADataElement> _dataElement;
const HLAPathElementMap& _pathElementMap;
HLADataElement::Path _path;
};
@@ -413,26 +409,6 @@ HLAObjectInstance::setAttributes(const HLAAttributePathElementMap& attributePath
}
}
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()
{
@@ -471,16 +447,6 @@ HLAObjectInstance::deleteInstance(const RTIData& tag)
_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)
{
@@ -505,16 +471,6 @@ HLAObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTI
_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)
{

View File

@@ -52,13 +52,8 @@ public:
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:
@@ -85,11 +80,6 @@ public:
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);

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
// Copyright (C) 2009 - 2011 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
@@ -17,195 +17,416 @@
#include "HLAPropertyDataElement.hxx"
#include "HLAArrayDataElement.hxx"
#include "HLABasicDataElement.hxx"
#include "HLADataElementVisitor.hxx"
#include "HLADataTypeVisitor.hxx"
#include "HLAFixedRecordDataElement.hxx"
#include "HLAVariantDataElement.hxx"
namespace simgear {
class HLAPropertyDataElement::DecodeVisitor : public HLADataTypeDecodeVisitor {
class HLAPropertyDataElement::ScalarDecodeVisitor : public HLADataTypeDecodeVisitor {
public:
DecodeVisitor(HLADecodeStream& stream, HLAPropertyReference& propertyReference) :
ScalarDecodeVisitor(HLADecodeStream& stream, SGPropertyNode& propertyNode) :
HLADataTypeDecodeVisitor(stream),
_propertyReference(propertyReference)
_propertyNode(propertyNode)
{ }
virtual ~ScalarDecodeVisitor()
{ }
virtual void apply(const HLAInt8DataType& dataType)
{
int8_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
_propertyNode.setIntValue(value);
}
virtual void apply(const HLAUInt8DataType& dataType)
{
uint8_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
_propertyNode.setIntValue(value);
}
virtual void apply(const HLAInt16DataType& dataType)
{
int16_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
_propertyNode.setIntValue(value);
}
virtual void apply(const HLAUInt16DataType& dataType)
{
uint16_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
_propertyNode.setIntValue(value);
}
virtual void apply(const HLAInt32DataType& dataType)
{
int32_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
_propertyNode.setIntValue(value);
}
virtual void apply(const HLAUInt32DataType& dataType)
{
uint32_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setIntValue(value);
_propertyNode.setIntValue(value);
}
virtual void apply(const HLAInt64DataType& dataType)
{
int64_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setLongValue(value);
_propertyNode.setLongValue(value);
}
virtual void apply(const HLAUInt64DataType& dataType)
{
uint64_t value = 0;
dataType.decode(_stream, value);
_propertyReference.setLongValue(value);
_propertyNode.setLongValue(value);
}
virtual void apply(const HLAFloat32DataType& dataType)
{
float value = 0;
dataType.decode(_stream, value);
_propertyReference.setFloatValue(value);
_propertyNode.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);
_propertyNode.setDoubleValue(value);
}
protected:
HLAPropertyReference& _propertyReference;
SGPropertyNode& _propertyNode;
};
class HLAPropertyDataElement::EncodeVisitor : public HLADataTypeEncodeVisitor {
class HLAPropertyDataElement::ScalarEncodeVisitor : public HLADataTypeEncodeVisitor {
public:
EncodeVisitor(HLAEncodeStream& stream, const HLAPropertyReference& propertyReference) :
ScalarEncodeVisitor(HLAEncodeStream& stream, const SGPropertyNode& propertyNode) :
HLADataTypeEncodeVisitor(stream),
_propertyReference(propertyReference)
_propertyNode(propertyNode)
{ }
virtual ~ScalarEncodeVisitor()
{ }
virtual void apply(const HLAInt8DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
dataType.encode(_stream, _propertyNode.getIntValue());
}
virtual void apply(const HLAUInt8DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
dataType.encode(_stream, _propertyNode.getIntValue());
}
virtual void apply(const HLAInt16DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
dataType.encode(_stream, _propertyNode.getIntValue());
}
virtual void apply(const HLAUInt16DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
dataType.encode(_stream, _propertyNode.getIntValue());
}
virtual void apply(const HLAInt32DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
dataType.encode(_stream, _propertyNode.getIntValue());
}
virtual void apply(const HLAUInt32DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getIntValue());
dataType.encode(_stream, _propertyNode.getIntValue());
}
virtual void apply(const HLAInt64DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getLongValue());
dataType.encode(_stream, _propertyNode.getLongValue());
}
virtual void apply(const HLAUInt64DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getLongValue());
dataType.encode(_stream, _propertyNode.getLongValue());
}
virtual void apply(const HLAFloat32DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getFloatValue());
dataType.encode(_stream, _propertyNode.getFloatValue());
}
virtual void apply(const HLAFloat64DataType& dataType)
{
dataType.encode(_stream, _propertyReference.getDoubleValue());
dataType.encode(_stream, _propertyNode.getDoubleValue());
}
protected:
const SGPropertyNode& _propertyNode;
};
class HLAPropertyDataElement::ScalarDataElement : public HLABasicDataElement {
public:
ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode);
virtual ~ScalarDataElement();
virtual bool encode(HLAEncodeStream& stream) const;
virtual bool decode(HLADecodeStream& stream);
private:
SGSharedPtr<SGPropertyNode> _propertyNode;
};
HLAPropertyDataElement::ScalarDataElement::ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode) :
HLABasicDataElement(dataType),
_propertyNode(propertyNode)
{
}
HLAPropertyDataElement::ScalarDataElement::~ScalarDataElement()
{
}
bool
HLAPropertyDataElement::ScalarDataElement::encode(HLAEncodeStream& stream) const
{
ScalarEncodeVisitor visitor(stream, *_propertyNode);
_dataType->accept(visitor);
return true;
}
bool
HLAPropertyDataElement::ScalarDataElement::decode(HLADecodeStream& stream)
{
ScalarDecodeVisitor visitor(stream, *_propertyNode);
_dataType->accept(visitor);
return true;
}
class HLAPropertyDataElement::StringDataElement : public HLAStringDataElement {
public:
StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode);
virtual ~StringDataElement();
virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
class Listener : public SGPropertyChangeListener {
public:
Listener(StringDataElement* stringDataElement);
virtual ~Listener();
virtual void valueChanged (SGPropertyNode * node);
private:
StringDataElement* _stringDataElement;
};
private:
SGSharedPtr<SGPropertyNode> _propertyNode;
Listener* _listener;
};
HLAPropertyDataElement::StringDataElement::Listener::Listener(StringDataElement* stringDataElement) :
_stringDataElement(stringDataElement)
{
}
HLAPropertyDataElement::StringDataElement::Listener::~Listener()
{
}
void
HLAPropertyDataElement::StringDataElement::Listener::valueChanged (SGPropertyNode * node)
{
_stringDataElement->setValue(node->getStringValue());
}
HLAPropertyDataElement::StringDataElement::StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode) :
HLAStringDataElement(dataType),
_propertyNode(propertyNode),
_listener(new Listener(this))
{
_propertyNode->addChangeListener(_listener, true);
}
HLAPropertyDataElement::StringDataElement::~StringDataElement()
{
_propertyNode->removeChangeListener(_listener);
delete _listener;
_listener = 0;
}
bool
HLAPropertyDataElement::StringDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
{
if (!HLAStringDataElement::decodeElement(stream, i))
return false;
if (i + 1 == getValue().size())
_propertyNode->setStringValue(getValue());
return true;
}
class HLAPropertyDataElement::DataElementFactoryVisitor : public HLADataTypeVisitor {
public:
DataElementFactoryVisitor(SGPropertyNode* propertyNode) :
_propertyNode(propertyNode)
{ }
virtual ~DataElementFactoryVisitor()
{ }
virtual void apply(const HLADataType& dataType)
{
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 = new ScalarDataElement(&dataType, _propertyNode.get());
}
virtual void apply(const HLAUInt8DataType& dataType)
{
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
}
virtual void apply(const HLAInt16DataType& dataType)
{
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
}
virtual void apply(const HLAUInt16DataType& dataType)
{
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
}
virtual void apply(const HLAInt32DataType& dataType)
{
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
}
virtual void apply(const HLAUInt32DataType& dataType)
{
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
}
virtual void apply(const HLAInt64DataType& dataType)
{
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
}
virtual void apply(const HLAUInt64DataType& dataType)
{
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
}
virtual void apply(const HLAFloat32DataType& dataType)
{
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
}
virtual void apply(const HLAFloat64DataType& dataType)
{
_dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
}
class ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory {
public:
ArrayDataElementFactory(SGPropertyNode* propertyNode) :
_propertyNode(propertyNode)
{ }
virtual HLADataElement* createElement(const HLAArrayDataElement& element, unsigned index)
{
const HLADataType* dataType = element.getElementDataType();
if (!dataType)
return 0;
SGPropertyNode* parent = _propertyNode->getParent();
DataElementFactoryVisitor visitor(parent->getChild(_propertyNode->getNameString(), index, true));
dataType->accept(visitor);
return visitor.getDataElement();
}
private:
SGSharedPtr<SGPropertyNode> _propertyNode;
};
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);
}
if (dataType.getIsString()) {
_dataElement = new StringDataElement(&dataType, _propertyNode.get());
} else {
SGSharedPtr<HLAArrayDataElement> arrayDataElement;
arrayDataElement = new HLAArrayDataElement(&dataType);
arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_propertyNode.get()));
arrayDataElement->setNumElements(dataType.getNumElements());
_dataElement = arrayDataElement;
}
}
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);
if (dataType.getIsString()) {
_dataElement = new StringDataElement(&dataType, _propertyNode.get());
} else {
SGSharedPtr<HLAArrayDataElement> arrayDataElement;
arrayDataElement = new HLAArrayDataElement(&dataType);
arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_propertyNode.get()));
_dataElement = arrayDataElement;
}
}
protected:
const HLAPropertyReference& _propertyReference;
virtual void apply(const HLAEnumeratedDataType& dataType)
{
_dataElement = new ScalarDataElement(dataType.getRepresentation(), _propertyNode.get());
}
virtual void apply(const HLAFixedRecordDataType& dataType)
{
SGSharedPtr<HLAFixedRecordDataElement> recordDataElement;
recordDataElement = new HLAFixedRecordDataElement(&dataType);
unsigned numFields = dataType.getNumFields();
for (unsigned i = 0; i < numFields; ++i) {
DataElementFactoryVisitor visitor(_propertyNode->getChild(dataType.getFieldName(i), 0, true));
dataType.getFieldDataType(i)->accept(visitor);
recordDataElement->setField(i, visitor._dataElement.get());
}
_dataElement = recordDataElement;
}
class VariantDataElementFactory : public HLAVariantDataElement::DataElementFactory {
public:
VariantDataElementFactory(SGPropertyNode* propertyNode) :
_propertyNode(propertyNode)
{ }
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;
DataElementFactoryVisitor visitor(_propertyNode->getChild(dataType->getAlternativeName(index), 0, true));
alternativeDataType->accept(visitor);
return visitor.getDataElement();
}
private:
SGSharedPtr<SGPropertyNode> _propertyNode;
};
virtual void apply(const HLAVariantDataType& dataType)
{
SGSharedPtr<HLAVariantDataElement> variantDataElement;
variantDataElement = new HLAVariantDataElement(&dataType);
variantDataElement->setDataElementFactory(new VariantDataElementFactory(_propertyNode.get()));
_dataElement = variantDataElement;
}
HLADataElement* getDataElement()
{ return _dataElement.release(); }
private:
SGSharedPtr<SGPropertyNode> _propertyNode;
SGSharedPtr<HLADataElement> _dataElement;
};
HLAPropertyDataElement::HLAPropertyDataElement(HLAPropertyReference* propertyReference) :
_propertyReference(propertyReference)
HLAPropertyDataElement::HLAPropertyDataElement()
{
}
HLAPropertyDataElement::HLAPropertyDataElement(const simgear::HLADataType* dataType, HLAPropertyReference* propertyReference) :
_dataType(dataType),
_propertyReference(propertyReference)
HLAPropertyDataElement::HLAPropertyDataElement(SGPropertyNode* propertyNode)
{
setPropertyNode(propertyNode);
}
HLAPropertyDataElement::HLAPropertyDataElement(const HLADataType* dataType, SGPropertyNode* propertyNode) :
_dataType(dataType)
{
setPropertyNode(propertyNode);
}
HLAPropertyDataElement::HLAPropertyDataElement(const HLADataType* dataType) :
_dataType(dataType)
{
}
@@ -213,34 +434,72 @@ HLAPropertyDataElement::~HLAPropertyDataElement()
{
}
void
HLAPropertyDataElement::accept(HLADataElementVisitor& visitor)
{
if (_dataElement.valid()) {
visitor.apply(*_dataElement);
} else {
// We cant do anything if the data type is not valid
if (_dataType.valid()) {
HLADataElementFactoryVisitor factoryVisitor;
_dataType->accept(factoryVisitor);
_dataElement = factoryVisitor.getDataElement();
if (_dataElement.valid()) {
visitor.apply(*_dataElement);
} else {
HLADataElement::accept(visitor);
}
} else {
HLADataElement::accept(visitor);
}
}
}
void
HLAPropertyDataElement::accept(HLAConstDataElementVisitor& visitor) const
{
if (_dataElement.valid()) {
visitor.apply(*_dataElement);
} else {
HLADataElement::accept(visitor);
}
}
bool
HLAPropertyDataElement::encode(HLAEncodeStream& stream) const
{
if (!_dataType.valid())
return false;
if (_propertyReference.valid()) {
EncodeVisitor visitor(stream, *_propertyReference);
_dataType->accept(visitor);
if (_dataElement.valid()) {
return _dataElement->encode(stream);
} else {
if (!_dataType.valid())
return false;
HLADataTypeEncodeVisitor visitor(stream);
_dataType->accept(visitor);
return true;
}
return true;
}
bool
HLAPropertyDataElement::decode(HLADecodeStream& stream)
{
if (!_dataType.valid())
if (_dataElement.valid()) {
return _dataElement->decode(stream);
} else if (!_dataType.valid()) {
// We cant do anything if the data type is not valid
return false;
if (_propertyReference.valid()) {
DecodeVisitor visitor(stream, *_propertyReference);
_dataType->accept(visitor);
} else {
HLADataTypeDecodeVisitor visitor(stream);
HLADataElementFactoryVisitor visitor;
_dataType->accept(visitor);
_dataElement = visitor.getDataElement();
if (_dataElement.valid()) {
return _dataElement->decode(stream);
} else {
HLADataTypeDecodeVisitor visitor(stream);
_dataType->accept(visitor);
return true;
}
}
return true;
}
const HLADataType*
@@ -252,18 +511,52 @@ HLAPropertyDataElement::getDataType() const
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;
_dataType = dataType;
if (_dataType.valid() && _propertyNode.valid())
_dataElement = createDataElement(_dataType, _propertyNode);
return true;
}
void
HLAPropertyDataElement::setPropertyNode(SGPropertyNode* propertyNode)
{
_propertyNode = propertyNode;
if (_dataType.valid() && _propertyNode.valid())
_dataElement = createDataElement(_dataType, _propertyNode);
}
SGPropertyNode*
HLAPropertyDataElement::getPropertyNode()
{
return _propertyNode.get();
}
const SGPropertyNode*
HLAPropertyDataElement::getPropertyNode() const
{
return _propertyNode.get();
}
HLADataElement*
HLAPropertyDataElement::createDataElement(const SGSharedPtr<const HLADataType>& dataType,
const SGSharedPtr<SGPropertyNode>& propertyNode)
{
DataElementFactoryVisitor visitor(propertyNode);
dataType->accept(visitor);
SGSharedPtr<HLADataElement> dataElement = visitor.getDataElement();
// Copy over the content of the previous data element if there is any.
if (_dataElement.valid()) {
// FIXME is encode/decode the right tool here??
RTIData data;
HLAEncodeStream encodeStream(data);
if (_dataElement->encode(encodeStream)) {
HLADecodeStream decodeStream(data);
dataElement->decode(decodeStream);
}
}
return false;
return dataElement.release();
}
} // namespace simgear

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
// Copyright (C) 2009 - 2011 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
@@ -18,140 +18,21 @@
#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();
HLAPropertyDataElement();
HLAPropertyDataElement(SGPropertyNode* propertyNode);
HLAPropertyDataElement(const HLADataType* dataType, SGPropertyNode* propertyNode);
HLAPropertyDataElement(const HLADataType* dataType);
virtual ~HLAPropertyDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool encode(HLAEncodeStream& stream) const;
virtual bool decode(HLADecodeStream& stream);
@@ -159,12 +40,25 @@ public:
virtual const HLADataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType);
void setPropertyNode(SGPropertyNode* propertyNode);
SGPropertyNode* getPropertyNode();
const SGPropertyNode* getPropertyNode() const;
private:
class DecodeVisitor;
class EncodeVisitor;
HLADataElement*
createDataElement(const SGSharedPtr<const HLADataType>& dataType, const SGSharedPtr<SGPropertyNode>& propertyNode);
class ScalarDecodeVisitor;
class ScalarEncodeVisitor;
class ScalarDataElement;
class StringDecodeVisitor;
class StringEncodeVisitor;
class StringDataElement;
class DataElementFactoryVisitor;
SGSharedPtr<const HLADataType> _dataType;
SGSharedPtr<HLAPropertyReference> _propertyReference;
SGSharedPtr<HLADataElement> _dataElement;
SGSharedPtr<SGPropertyNode> _propertyNode;
};
} // namespace simgear

View File

@@ -19,6 +19,8 @@
#include <simgear/debug/logstream.hxx>
#include "HLADataElementVisitor.hxx"
namespace simgear {
HLAAbstractVariantDataElement::HLAAbstractVariantDataElement(const HLAVariantDataType* dataType) :
@@ -30,6 +32,18 @@ HLAAbstractVariantDataElement::~HLAAbstractVariantDataElement()
{
}
void
HLAAbstractVariantDataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLAAbstractVariantDataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
bool
HLAAbstractVariantDataElement::decode(HLADecodeStream& stream)
{

View File

@@ -30,6 +30,9 @@ public:
HLAAbstractVariantDataElement(const HLAVariantDataType* dataType);
virtual ~HLAAbstractVariantDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;

View File

@@ -1,69 +0,0 @@
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

View File

@@ -15,8 +15,8 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef RTIAmbassador_hxx
#define RTIAmbassador_hxx
#ifndef RTI13Ambassador_hxx
#define RTI13Ambassador_hxx
#include <cstdlib>
#include <list>
@@ -45,58 +45,20 @@
namespace simgear {
class RTI13Ambassador : public SGWeakReferenced {
class RTI13Federate;
class RTI13Ambassador : public SGReferenced {
public:
RTI13Ambassador() :
_federateAmbassador(*this),
_timeRegulationEnabled(false),
_timeConstrainedEnabled(false),
_timeAdvancePending(false)
~RTI13Ambassador()
{ }
virtual ~RTI13Ambassador()
{ }
// processes the queues that filled up during the past
void processQueues()
{
while (!_queueCallbackList.empty()) {
(*_queueCallbackList.front())();
_queueCallbackList.pop_front();
}
while (!_objectInstancePendingCallbackList.empty()) {
(*_objectInstancePendingCallbackList.begin())->flushPendingRequests();
_objectInstancePendingCallbackList.erase(_objectInstancePendingCallbackList.begin());
}
}
bool getTimeRegulationEnabled() const
{ return _timeRegulationEnabled; }
bool getTimeConstrainedEnabled() const
{ return _timeConstrainedEnabled; }
bool getTimeAdvancePending() const
{ return _timeAdvancePending; }
const SGTimeStamp& getCurrentLogicalTime() const
{ return _federateTime; }
bool getFederationSynchronizationPointAnnounced(const std::string& label)
{ return _pendingSyncLabels.find(label) != _pendingSyncLabels.end(); }
bool getFederationSynchronized(const std::string& label)
{
std::set<std::string>::iterator i = _syncronizedSyncLabels.find(label);
if (i == _syncronizedSyncLabels.end())
return false;
_syncronizedSyncLabels.erase(i);
return true;
}
void createFederationExecution(const std::string& name, const std::string& objectModel)
{ _rtiAmbassador.createFederationExecution(name.c_str(), objectModel.c_str()); }
void destroyFederationExecution(const std::string& name)
{ _rtiAmbassador.destroyFederationExecution(name.c_str()); }
RTI::FederateHandle joinFederationExecution(const std::string& federate, const std::string& federation)
{ return _rtiAmbassador.joinFederationExecution(federate.c_str(), federation.c_str(), &_federateAmbassador); }
RTI::FederateHandle joinFederationExecution(const std::string& federate, const std::string& federation, RTI::FederateAmbassador* federateAmbassador)
{ return _rtiAmbassador.joinFederationExecution(federate.c_str(), federation.c_str(), federateAmbassador); }
void resignFederationExecution()
{ _rtiAmbassador.resignFederationExecution(RTI::DELETE_OBJECTS_AND_RELEASE_ATTRIBUTES); }
@@ -114,13 +76,8 @@ public:
void unsubscribeObjectClass(const RTI::ObjectClassHandle& handle)
{ _rtiAmbassador.unsubscribeObjectClass(handle); }
RTI13ObjectInstance* registerObjectInstance(const RTI13ObjectClass* objectClass, HLAObjectInstance* hlaObjectInstance)
{
RTI::ObjectHandle objectHandle = _rtiAmbassador.registerObjectInstance(objectClass->getHandle());
RTI13ObjectInstance* objectInstance = new RTI13ObjectInstance(objectHandle, hlaObjectInstance, objectClass, this, true);
_objectInstanceMap[objectHandle] = objectInstance;
return objectInstance;
}
RTI::ObjectHandle registerObjectInstance(const RTI::ObjectClassHandle& handle)
{ return _rtiAmbassador.registerObjectInstance(handle); }
void updateAttributeValues(const RTI::ObjectHandle& objectHandle, const RTI::AttributeHandleValuePairSet& attributeValues,
const SGTimeStamp& timeStamp, const RTIData& tag)
{ _rtiAmbassador.updateAttributeValues(objectHandle, attributeValues, toFedTime(timeStamp), tag.data()); }
@@ -133,38 +90,11 @@ public:
// { _rtiAmbassador.sendInteraction(interactionClassHandle, parameters, tag.data()); }
void deleteObjectInstance(const RTI::ObjectHandle& objectHandle, const SGTimeStamp& timeStamp, const RTIData& tag)
{
RTI::EventRetractionHandle h = _rtiAmbassador.deleteObjectInstance(objectHandle, toFedTime(timeStamp), tag.data());
ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle);
if (i == _objectInstanceMap.end()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: ObjectInstance not found.");
return;
}
_objectInstancePendingCallbackList.erase(i->second);
_objectInstanceMap.erase(i);
}
{ /* RTI::EventRetractionHandle h = */ _rtiAmbassador.deleteObjectInstance(objectHandle, toFedTime(timeStamp), tag.data()); }
void deleteObjectInstance(const RTI::ObjectHandle& objectHandle, const RTIData& tag)
{
_rtiAmbassador.deleteObjectInstance(objectHandle, tag.data());
ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle);
if (i == _objectInstanceMap.end()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: ObjectInstance not found.");
return;
}
_objectInstancePendingCallbackList.erase(i->second);
_objectInstanceMap.erase(i);
}
{ _rtiAmbassador.deleteObjectInstance(objectHandle, tag.data()); }
void localDeleteObjectInstance(const RTI::ObjectHandle& objectHandle)
{
_rtiAmbassador.localDeleteObjectInstance(objectHandle);
ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle);
if (i == _objectInstanceMap.end()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: ObjectInstance not found.");
return;
}
_objectInstancePendingCallbackList.erase(i->second);
_objectInstanceMap.erase(i);
}
{ _rtiAmbassador.localDeleteObjectInstance(objectHandle); }
void requestObjectAttributeValueUpdate(const RTI::ObjectHandle& handle, const RTI::AttributeHandleSet& attributeHandleSet)
{ _rtiAmbassador.requestObjectAttributeValueUpdate(handle, attributeHandleSet); }
@@ -351,81 +281,62 @@ public:
/// Time Management
void enableTimeRegulation(const SGTimeStamp& federateTime, const SGTimeStamp& lookahead)
{ _rtiAmbassador.enableTimeRegulation(toFedTime(federateTime), toFedTime(lookahead)); }
void enableTimeRegulation(const SGTimeStamp& lookahead)
{
RTIfedTime federateTime;
federateTime.setZero();
_rtiAmbassador.enableTimeRegulation(federateTime, toFedTime(lookahead));
}
void disableTimeRegulation()
{ _rtiAmbassador.disableTimeRegulation(); _timeRegulationEnabled = false; }
{ _rtiAmbassador.disableTimeRegulation();}
void enableTimeConstrained()
{ _rtiAmbassador.enableTimeConstrained(); }
void disableTimeConstrained()
{ _rtiAmbassador.disableTimeConstrained(); _timeConstrainedEnabled = false; }
{ _rtiAmbassador.disableTimeConstrained(); }
void timeAdvanceRequest(const SGTimeStamp& time)
{ _rtiAmbassador.timeAdvanceRequest(toFedTime(time)); _timeAdvancePending = true; }
{ _rtiAmbassador.timeAdvanceRequest(toFedTime(time)); }
void timeAdvanceRequestAvailable(const SGTimeStamp& time)
{ _rtiAmbassador.timeAdvanceRequestAvailable(toFedTime(time)); _timeAdvancePending = true; }
{ _rtiAmbassador.timeAdvanceRequestAvailable(toFedTime(time)); }
void flushQueueRequest(const SGTimeStamp& time)
{ _rtiAmbassador.flushQueueRequest(toFedTime(time)); }
// bool queryLBTS(double& time)
// {
// try {
// RTIfedTime fedTime;
// _rtiAmbassador.queryLBTS(fedTime);
// time = fedTime.getTime();
// return true;
// } catch (RTI::FederateNotExecutionMember& e) {
// } catch (RTI::ConcurrentAccessAttempted& e) {
// } catch (RTI::SaveInProgress& e) {
// } catch (RTI::RestoreInProgress& e) {
// } catch (RTI::RTIinternalError& e) {
// }
// return false;
// }
// bool queryFederateTime(double& time)
// {
// try {
// RTIfedTime fedTime;
// _rtiAmbassador.queryFederateTime(fedTime);
// time = fedTime.getTime();
// return true;
// } catch (RTI::FederateNotExecutionMember& e) {
// } catch (RTI::ConcurrentAccessAttempted& e) {
// } catch (RTI::SaveInProgress& e) {
// } catch (RTI::RestoreInProgress& e) {
// } catch (RTI::RTIinternalError& e) {
// }
// return false;
// }
// bool queryLookahead(double& time)
// {
// try {
// RTIfedTime fedTime;
// _rtiAmbassador.queryLookahead(fedTime);
// time = fedTime.getTime();
// return true;
// } catch (RTI::FederateNotExecutionMember& e) {
// } catch (RTI::ConcurrentAccessAttempted& e) {
// } catch (RTI::SaveInProgress& e) {
// } catch (RTI::RestoreInProgress& e) {
// } catch (RTI::RTIinternalError& e) {
// }
// return false;
// }
RTI13ObjectClass* createObjectClass(const std::string& name, HLAObjectClass* hlaObjectClass)
bool queryGALT(SGTimeStamp& timeStamp)
{
RTI::ObjectClassHandle objectClassHandle;
objectClassHandle = getObjectClassHandle(name);
if (_objectClassMap.find(objectClassHandle) != _objectClassMap.end()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create object class, object class already exists!");
return 0;
}
RTI13ObjectClass* rtiObjectClass;
rtiObjectClass = new RTI13ObjectClass(hlaObjectClass, objectClassHandle, this);
_objectClassMap[objectClassHandle] = rtiObjectClass;
return rtiObjectClass;
RTIfedTime fedTime;
fedTime.setPositiveInfinity();
_rtiAmbassador.queryLBTS(fedTime);
if (fedTime.isPositiveInfinity())
return false;
timeStamp = toTimeStamp(fedTime);
return true;
}
bool queryLITS(SGTimeStamp& timeStamp)
{
RTIfedTime fedTime;
fedTime.setPositiveInfinity();
_rtiAmbassador.queryMinNextEventTime(fedTime);
if (fedTime.isPositiveInfinity())
return false;
timeStamp = toTimeStamp(fedTime);
return true;
}
void queryFederateTime(SGTimeStamp& timeStamp)
{
RTIfedTime fedTime;
_rtiAmbassador.queryFederateTime(fedTime);
timeStamp = toTimeStamp(fedTime);
}
void modifyLookahead(const SGTimeStamp& timeStamp)
{ _rtiAmbassador.modifyLookahead(toFedTime(timeStamp)); }
void queryLookahead(SGTimeStamp& timeStamp)
{
RTIfedTime fedTime;
_rtiAmbassador.queryLookahead(fedTime);
timeStamp = toTimeStamp(fedTime);
}
RTI::ObjectClassHandle getObjectClassHandle(const std::string& name)
{ return _rtiAmbassador.getObjectClassHandle(name.c_str()); }
std::string getObjectClassName(const RTI::ObjectClassHandle& handle)
@@ -486,17 +397,6 @@ public:
// return parameterName;
// }
RTI13ObjectInstance* getObjectInstance(const std::string& name)
{
RTI::ObjectHandle objectHandle;
objectHandle = getObjectInstanceHandle(name);
ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle);
if (i == _objectInstanceMap.end()) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: ObjectInstance not found.");
return 0;
}
return i->second;
}
RTI::ObjectHandle getObjectInstanceHandle(const std::string& name)
{ return _rtiAmbassador.getObjectInstanceHandle(name.c_str()); }
std::string getObjectInstanceName(const RTI::ObjectHandle& objectHandle)
@@ -552,498 +452,6 @@ public:
bool tick(double minimum, double maximum)
{ return _rtiAmbassador.tick(minimum, maximum); }
void addObjectInstanceForCallback(RTIObjectInstance* objectIntance)
{ _objectInstancePendingCallbackList.insert(objectIntance); }
private:
/// Generic callback to execute some notification on objects in a way that they are not prone to
/// ConcurrentAccess exceptions.
class QueueCallback : public SGReferenced {
public:
virtual ~QueueCallback() {}
virtual void operator()() = 0;
};
class RemoveObjectCallback : public QueueCallback {
public:
RemoveObjectCallback(SGSharedPtr<RTIObjectInstance> objectInstance, const RTIData& tag) :
_objectInstance(objectInstance),
_tag(tag)
{ }
virtual void operator()()
{
_objectInstance->removeInstance(_tag);
}
private:
SGSharedPtr<RTIObjectInstance> _objectInstance;
RTIData _tag;
};
/// Just the interface class doing the callbacks into the parent class
struct FederateAmbassador : public RTI::FederateAmbassador {
FederateAmbassador(RTI13Ambassador& rtiAmbassador) :
_rtiAmbassador(rtiAmbassador)
{
}
virtual ~FederateAmbassador()
throw (RTI::FederateInternalError)
{
}
/// RTI federate ambassador callback functions.
virtual void synchronizationPointRegistrationSucceeded(const char* label)
throw (RTI::FederateInternalError)
{
}
virtual void synchronizationPointRegistrationFailed(const char* label)
throw (RTI::FederateInternalError)
{
}
virtual void announceSynchronizationPoint(const char* label, const char* tag)
throw (RTI::FederateInternalError)
{
_rtiAmbassador._pendingSyncLabels.insert(toStdString(label));
}
virtual void federationSynchronized(const char* label)
throw (RTI::FederateInternalError)
{
std::string s = toStdString(label);
_rtiAmbassador._pendingSyncLabels.erase(s);
_rtiAmbassador._syncronizedSyncLabels.insert(s);
}
virtual void initiateFederateSave(const char* label)
throw (RTI::UnableToPerformSave,
RTI::FederateInternalError)
{
}
virtual void federationSaved()
throw (RTI::FederateInternalError)
{
}
virtual void federationNotSaved()
throw (RTI::FederateInternalError)
{
}
virtual void requestFederationRestoreSucceeded(const char* label)
throw (RTI::FederateInternalError)
{
}
virtual void requestFederationRestoreFailed(const char* label, const char* reason)
throw (RTI::FederateInternalError)
{
}
virtual void federationRestoreBegun()
throw (RTI::FederateInternalError)
{
}
virtual void initiateFederateRestore(const char* label, RTI::FederateHandle federateHandle)
throw (RTI::SpecifiedSaveLabelDoesNotExist,
RTI::CouldNotRestore,
RTI::FederateInternalError)
{
}
virtual void federationRestored()
throw (RTI::FederateInternalError)
{
}
virtual void federationNotRestored()
throw (RTI::FederateInternalError)
{
}
// Declaration Management
virtual void startRegistrationForObjectClass(RTI::ObjectClassHandle objectClassHandle)
throw (RTI::ObjectClassNotPublished,
RTI::FederateInternalError)
{
ObjectClassMap::iterator i = _rtiAmbassador._objectClassMap.find(objectClassHandle);
if (i == _rtiAmbassador._objectClassMap.end())
return;
if (!i->second.valid())
return;
i->second->startRegistration();
}
virtual void stopRegistrationForObjectClass(RTI::ObjectClassHandle objectClassHandle)
throw (RTI::ObjectClassNotPublished,
RTI::FederateInternalError)
{
ObjectClassMap::iterator i = _rtiAmbassador._objectClassMap.find(objectClassHandle);
if (i == _rtiAmbassador._objectClassMap.end())
return;
if (!i->second.valid())
return;
i->second->stopRegistration();
}
virtual void turnInteractionsOn(RTI::InteractionClassHandle interactionClassHandle)
throw (RTI::InteractionClassNotPublished,
RTI::FederateInternalError)
{
}
virtual void turnInteractionsOff(RTI::InteractionClassHandle interactionClassHandle)
throw (RTI::InteractionClassNotPublished,
RTI::FederateInternalError)
{
}
// Object Management
virtual void discoverObjectInstance(RTI::ObjectHandle objectHandle, RTI::ObjectClassHandle objectClassHandle, const char* tag)
throw (RTI::CouldNotDiscover,
RTI::ObjectClassNotKnown,
RTI::FederateInternalError)
{
ObjectClassMap::iterator i = _rtiAmbassador._objectClassMap.find(objectClassHandle);
if (i == _rtiAmbassador._objectClassMap.end())
throw RTI::ObjectClassNotKnown("Federate: discoverObjectInstance()!");
if (!i->second.valid())
return;
SGSharedPtr<RTI13ObjectInstance> objectInstance = new RTI13ObjectInstance(objectHandle, 0, i->second, &_rtiAmbassador, false);
_rtiAmbassador._objectInstanceMap[objectHandle] = objectInstance;
_rtiAmbassador._objectInstancePendingCallbackList.insert(objectInstance);
i->second->discoverInstance(objectInstance.get(), tagToData(tag));
}
virtual void reflectAttributeValues(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleValuePairSet& attributeValuePairSet,
const RTI::FedTime& fedTime, const char* tag, RTI::EventRetractionHandle eventRetractionHandle)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::FederateOwnsAttributes,
RTI::InvalidFederationTime,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("Reflect attributes for unknown object!");
if (!i->second.valid())
return;
i->second->reflectAttributeValues(attributeValuePairSet, toTimeStamp(fedTime), tagToData(tag));
}
virtual void reflectAttributeValues(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleValuePairSet& attributeValuePairSet,
const char* tag)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::FederateOwnsAttributes,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("Reflect attributes for unknown object!");
if (!i->second.valid())
return;
i->second->reflectAttributeValues(attributeValuePairSet, tagToData(tag));
}
virtual void receiveInteraction(RTI::InteractionClassHandle interactionClassHandle, const RTI::ParameterHandleValuePairSet& parameters,
const RTI::FedTime& fedTime, const char* tag, RTI::EventRetractionHandle eventRetractionHandle)
throw (RTI::InteractionClassNotKnown,
RTI::InteractionParameterNotKnown,
RTI::InvalidFederationTime,
RTI::FederateInternalError)
{
}
virtual void receiveInteraction(RTI::InteractionClassHandle interactionClassHandle,
const RTI::ParameterHandleValuePairSet& parameters, const char* tag)
throw (RTI::InteractionClassNotKnown,
RTI::InteractionParameterNotKnown,
RTI::FederateInternalError)
{
}
virtual void removeObjectInstance(RTI::ObjectHandle objectHandle, const RTI::FedTime& fedTime,
const char* tag, RTI::EventRetractionHandle eventRetractionHandle)
throw (RTI::ObjectNotKnown,
RTI::InvalidFederationTime,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("Federate: removeObjectInstance()!");
if (i->second.valid())
_rtiAmbassador._queueCallbackList.push_back(new RemoveObjectCallback(i->second, tagToData(tag)));
_rtiAmbassador._objectInstancePendingCallbackList.erase(i->second);
_rtiAmbassador._objectInstanceMap.erase(i);
}
virtual void removeObjectInstance(RTI::ObjectHandle objectHandle, const char* tag)
throw (RTI::ObjectNotKnown,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("Federate: removeObjectInstance()!");
if (i->second.valid())
_rtiAmbassador._queueCallbackList.push_back(new RemoveObjectCallback(i->second, tagToData(tag)));
_rtiAmbassador._objectInstancePendingCallbackList.erase(i->second);
_rtiAmbassador._objectInstanceMap.erase(i);
}
virtual void attributesInScope(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("Attributes in scope for unknown object!");
if (!i->second.valid())
return;
i->second->attributesInScope(attributes);
}
virtual void attributesOutOfScope(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("Attributes in scope for unknown object!");
if (!i->second.valid())
return;
i->second->attributesOutOfScope(attributes);
}
virtual void provideAttributeValueUpdate(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::AttributeNotOwned,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("Reflect attributes for unknown object!");
if (!i->second.valid())
return;
i->second->provideAttributeValueUpdate(attributes);
}
virtual void turnUpdatesOnForObjectInstance(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotOwned,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("Turn on attributes for unknown object!");
if (!i->second.valid())
return;
i->second->turnUpdatesOnForObjectInstance(attributes);
}
virtual void turnUpdatesOffForObjectInstance(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotOwned,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("Turn off attributes for unknown object!");
if (!i->second.valid())
return;
i->second->turnUpdatesOffForObjectInstance(attributes);
}
// Ownership Management
virtual void requestAttributeOwnershipAssumption(RTI::ObjectHandle objectHandle,
const RTI::AttributeHandleSet& attributes, const char* tag)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::AttributeAlreadyOwned,
RTI::AttributeNotPublished,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("requestAttributeOwnershipAssumption for unknown object!");
if (!i->second.valid())
return;
i->second->requestAttributeOwnershipAssumption(attributes, tagToData(tag));
}
virtual void attributeOwnershipDivestitureNotification(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::AttributeNotOwned,
RTI::AttributeDivestitureWasNotRequested,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("attributeOwnershipDivestitureNotification for unknown object!");
if (!i->second.valid())
return;
i->second->attributeOwnershipDivestitureNotification(attributes);
}
virtual void attributeOwnershipAcquisitionNotification(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::AttributeAcquisitionWasNotRequested,
RTI::AttributeAlreadyOwned,
RTI::AttributeNotPublished,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("attributeOwnershipAcquisitionNotification for unknown object!");
if (!i->second.valid())
return;
i->second->attributeOwnershipAcquisitionNotification(attributes);
}
virtual void attributeOwnershipUnavailable(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::AttributeAlreadyOwned,
RTI::AttributeAcquisitionWasNotRequested,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("attributeOwnershipUnavailable for unknown object!");
if (!i->second.valid())
return;
i->second->attributeOwnershipUnavailable(attributes);
}
virtual void requestAttributeOwnershipRelease(RTI::ObjectHandle objectHandle,
const RTI::AttributeHandleSet& attributes, const char* tag)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::AttributeNotOwned,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("requestAttributeOwnershipRelease for unknown object!");
if (!i->second.valid())
return;
i->second->requestAttributeOwnershipRelease(attributes, tagToData(tag));
}
virtual void confirmAttributeOwnershipAcquisitionCancellation(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::AttributeAlreadyOwned,
RTI::AttributeAcquisitionWasNotCanceled,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("confirmAttributeOwnershipAcquisitionCancellation for unknown object!");
if (!i->second.valid())
return;
i->second->confirmAttributeOwnershipAcquisitionCancellation(attributes);
}
virtual void informAttributeOwnership(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle,
RTI::FederateHandle federateHandle)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("informAttributeOwnership for unknown object!");
if (!i->second.valid())
return;
i->second->informAttributeOwnership(attributeHandle, federateHandle);
}
virtual void attributeIsNotOwned(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("attributeIsNotOwned for unknown object!");
if (!i->second.valid())
return;
i->second->attributeIsNotOwned(attributeHandle);
}
virtual void attributeOwnedByRTI(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle)
throw (RTI::ObjectNotKnown,
RTI::AttributeNotKnown,
RTI::FederateInternalError)
{
ObjectInstanceMap::iterator i = _rtiAmbassador._objectInstanceMap.find(objectHandle);
if (i == _rtiAmbassador._objectInstanceMap.end())
throw RTI::ObjectNotKnown("attributeOwnedByRTI for unknown object!");
if (!i->second.valid())
return;
i->second->attributeOwnedByRTI(attributeHandle);
}
// Time Management
virtual void timeRegulationEnabled(const RTI::FedTime& fedTime)
throw (RTI::InvalidFederationTime,
RTI::EnableTimeRegulationWasNotPending,
RTI::FederateInternalError)
{
_rtiAmbassador._timeRegulationEnabled = true;
_rtiAmbassador._federateTime = toTimeStamp(fedTime);
SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeRegulationEnabled: " << _rtiAmbassador._federateTime);
}
virtual void timeConstrainedEnabled(const RTI::FedTime& fedTime)
throw (RTI::InvalidFederationTime,
RTI::EnableTimeConstrainedWasNotPending,
RTI::FederateInternalError)
{
_rtiAmbassador._timeConstrainedEnabled = true;
_rtiAmbassador._federateTime = toTimeStamp(fedTime);
SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeConstrainedEnabled: " << _rtiAmbassador._federateTime);
}
virtual void timeAdvanceGrant(const RTI::FedTime& fedTime)
throw (RTI::InvalidFederationTime,
RTI::TimeAdvanceWasNotInProgress,
RTI::FederateInternalError)
{
_rtiAmbassador._federateTime = toTimeStamp(fedTime);
_rtiAmbassador._timeAdvancePending = false;
SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeAdvanceGrant: " << _rtiAmbassador._federateTime);
}
virtual void requestRetraction(RTI::EventRetractionHandle eventRetractionHandle)
throw (RTI::EventNotKnown,
RTI::FederateInternalError)
{
// No retraction concept yet
}
private:
const RTIData& tagToData(const char* tag)
{
if (tag)
_cachedTag.setData(tag, std::strlen(tag) + 1);
else
_cachedTag.setData("", 1);
return _cachedTag;
}
RTIData _cachedTag;
RTI13Ambassador& _rtiAmbassador;
};
static SGTimeStamp toTimeStamp(const RTI::FedTime& fedTime)
{
@@ -1069,45 +477,9 @@ private:
return s;
}
static std::string toStdString(const char* n)
{
if (!n)
return std::string();
return std::string(n);
}
// The connection class
RTI::RTIambassador _rtiAmbassador;
// The class with all the callbacks.
FederateAmbassador _federateAmbassador;
// All the sync labels we got an announcement for
std::set<std::string> _pendingSyncLabels;
std::set<std::string> _syncronizedSyncLabels;
// All that calls back into user code is just queued.
// That is to make sure we do not call recursively into the RTI
typedef std::list<SGSharedPtr<QueueCallback> > QueueCallbackList;
QueueCallbackList _queueCallbackList;
// All object instances that need to be called due to some event are noted here
// That is to make sure we do not call recursively into the RTI
typedef std::set<SGSharedPtr<RTIObjectInstance> > ObjectInstanceSet;
ObjectInstanceSet _objectInstancePendingCallbackList;
// Top level information for dispatching federate object attribute updates
typedef std::map<RTI::ObjectHandle, SGSharedPtr<RTI13ObjectInstance> > ObjectInstanceMap;
// Map of all available objects
ObjectInstanceMap _objectInstanceMap;
// Top level information for dispatching creation of federate objects
typedef std::map<RTI::ObjectClassHandle, SGSharedPtr<RTI13ObjectClass> > ObjectClassMap;
ObjectClassMap _objectClassMap;
bool _timeRegulationEnabled;
bool _timeConstrainedEnabled;
bool _timeAdvancePending;
SGTimeStamp _federateTime;
SGWeakPtr<RTI13Federate> _federate;
};
} // namespace simgear

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
// Copyright (C) 2009 - 2011 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
@@ -34,39 +34,53 @@ class RTI13Ambassador;
class RTI13Federate : public RTIFederate {
public:
RTI13Federate();
RTI13Federate(const std::list<std::string>& stringList);
virtual ~RTI13Federate();
virtual bool createFederationExecution(const std::string& federation, const std::string& objectModel);
virtual bool destroyFederationExecution(const std::string& federation);
/// Create a federation execution
/// Semantically this methods should be static,
virtual FederationManagementResult createFederationExecution(const std::string& federation, const std::string& objectModel);
virtual FederationManagementResult destroyFederationExecution(const std::string& federation);
/// Join with federateName the federation execution federation
virtual bool join(const std::string& federateType, const std::string& federation);
virtual FederationManagementResult join(const std::string& federateType, const std::string& federation);
virtual bool resign();
virtual bool getJoined() const;
/// Synchronization Point handling
virtual bool registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag);
virtual bool waitForFederationSynchronizationPointAnnounced(const std::string& label);
virtual bool getFederationSynchronizationPointAnnounced(const std::string& label);
virtual bool synchronizationPointAchieved(const std::string& label);
virtual bool waitForFederationSynchronized(const std::string& label);
virtual bool getFederationSynchronized(const std::string& label);
/// Time management
virtual bool enableTimeConstrained();
virtual bool disableTimeConstrained();
virtual bool getTimeConstrainedEnabled();
virtual bool enableTimeRegulation(const SGTimeStamp& lookahead);
virtual bool disableTimeRegulation();
virtual bool modifyLookahead(const SGTimeStamp& timeStamp);
virtual bool getTimeRegulationEnabled();
virtual bool timeAdvanceRequestBy(const SGTimeStamp& dt);
virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime);
virtual bool timeAdvanceRequest(const SGTimeStamp& timeStamp);
virtual bool timeAdvanceRequestAvailable(const SGTimeStamp& timeStamp);
virtual bool flushQueueRequest(const SGTimeStamp& timeStamp);
virtual bool getTimeAdvancePending();
virtual bool queryFederateTime(SGTimeStamp& timeStamp);
virtual bool queryLookahead(SGTimeStamp& timeStamp);
virtual bool queryGALT(SGTimeStamp& timeStamp);
virtual bool queryLITS(SGTimeStamp& timeStamp);
/// Process messages
virtual bool tick();
virtual bool tick(const double& minimum, const double& maximum);
virtual bool processMessage();
virtual bool processMessages(const double& minimum, const double& maximum);
virtual RTI13ObjectClass* createObjectClass(const std::string& name, HLAObjectClass* hlaObjectClass);
virtual RTI13ObjectInstance* getObjectInstance(const std::string& name);
void insertObjectInstance(RTI13ObjectInstance* objectInstance);
private:
RTI13Federate(const RTI13Federate&);
@@ -74,13 +88,14 @@ private:
/// 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;
bool _joined;
/// RTI connection
SGSharedPtr<RTI13Ambassador> _ambassador;
/// Callbacks from the rti are handled here.
struct FederateAmbassador;
FederateAmbassador* _federateAmbassador;
};
}

View File

@@ -37,12 +37,11 @@ RTI13ObjectClass::~RTI13ObjectClass()
std::string
RTI13ObjectClass::getName() const
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return std::string();
}
return ambassador->getObjectClassName(_handle);
return _ambassador->getObjectClassName(_handle);
}
unsigned
@@ -54,14 +53,13 @@ RTI13ObjectClass::getNumAttributes() const
unsigned
RTI13ObjectClass::getAttributeIndex(const std::string& name) const
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return ~0u;
}
try {
RTI::AttributeHandle attributeHandle = ambassador->getAttributeHandle(name, _handle);
RTI::AttributeHandle attributeHandle = _ambassador->getAttributeHandle(name, _handle);
AttributeHandleIndexMap::const_iterator i = _attributeHandleIndexMap.find(attributeHandle);
if (i != _attributeHandleIndexMap.end())
@@ -93,14 +91,13 @@ RTI13ObjectClass::getAttributeIndex(const std::string& name) const
unsigned
RTI13ObjectClass::getOrCreateAttributeIndex(const std::string& name)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return ~0u;
}
try {
RTI::AttributeHandle attributeHandle = ambassador->getAttributeHandle(name, _handle);
RTI::AttributeHandle attributeHandle = _ambassador->getAttributeHandle(name, _handle);
AttributeHandleIndexMap::const_iterator i = _attributeHandleIndexMap.find(attributeHandle);
if (i != _attributeHandleIndexMap.end())
@@ -169,8 +166,7 @@ RTI13ObjectClass::getOrCreateAttributeIndex(const std::string& name)
bool
RTI13ObjectClass::publish(const std::set<unsigned>& indexSet)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return false;
}
@@ -185,7 +181,7 @@ RTI13ObjectClass::publish(const std::set<unsigned>& indexSet)
attributeHandleSet->add(_attributeHandleVector[*i]);
}
ambassador->publishObjectClass(_handle, *attributeHandleSet);
_ambassador->publishObjectClass(_handle, *attributeHandleSet);
for (unsigned i = 0; i < getNumAttributes(); ++i) {
_attributeDataVector[i]._published = true;
@@ -225,14 +221,13 @@ RTI13ObjectClass::publish(const std::set<unsigned>& indexSet)
bool
RTI13ObjectClass::unpublish()
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return false;
}
try {
ambassador->unpublishObjectClass(_handle);
_ambassador->unpublishObjectClass(_handle);
for (unsigned i = 0; i < getNumAttributes(); ++i) {
_attributeDataVector[i]._published = false;
@@ -272,8 +267,7 @@ RTI13ObjectClass::unpublish()
bool
RTI13ObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return false;
}
@@ -289,7 +283,7 @@ RTI13ObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
attributeHandleSet->add(_attributeHandleVector[*i]);
}
ambassador->subscribeObjectClassAttributes(_handle, *attributeHandleSet, active);
_ambassador->subscribeObjectClassAttributes(_handle, *attributeHandleSet, active);
for (unsigned i = 0; i < getNumAttributes(); ++i) {
_attributeDataVector[i]._subscribed = true;
@@ -326,14 +320,13 @@ RTI13ObjectClass::subscribe(const std::set<unsigned>& indexSet, bool active)
bool
RTI13ObjectClass::unsubscribe()
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return 0;
}
try {
ambassador->unsubscribeObjectClass(_handle);
_ambassador->unsubscribeObjectClass(_handle);
for (unsigned i = 0; i < getNumAttributes(); ++i) {
_attributeDataVector[i]._subscribed = false;
@@ -370,14 +363,22 @@ RTI13ObjectClass::unsubscribe()
RTIObjectInstance*
RTI13ObjectClass::registerObjectInstance(HLAObjectInstance* hlaObjectInstance)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return 0;
}
SGSharedPtr<RTI13Federate> federate = _ambassador->_federate.lock();
if (!federate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Federate is zero.");
return 0;
}
try {
return ambassador->registerObjectInstance(this, hlaObjectInstance);
RTI::ObjectHandle objectHandle = _ambassador->registerObjectInstance(getHandle());
RTI13ObjectInstance* objectInstance = new RTI13ObjectInstance(objectHandle, hlaObjectInstance, this, _ambassador.get(), true);
federate->insertObjectInstance(objectInstance);
return objectInstance;
} catch (RTI::ObjectClassNotDefined& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not register object instance: " << e._name << " " << e._reason);
return 0;

View File

@@ -73,7 +73,7 @@ public:
private:
RTI::ObjectClassHandle _handle;
SGWeakPtr<RTI13Ambassador> _ambassador;
SGSharedPtr<RTI13Ambassador> _ambassador;
typedef std::map<RTI::AttributeHandle, unsigned> AttributeHandleIndexMap;
AttributeHandleIndexMap _attributeHandleIndexMap;

View File

@@ -50,14 +50,13 @@ RTI13ObjectInstance::get13ObjectClass() const
std::string
RTI13ObjectInstance::getName() const
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return std::string();
}
try {
return ambassador->getObjectInstanceName(_handle);
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();
@@ -77,28 +76,21 @@ RTI13ObjectInstance::getName() const
}
void
RTI13ObjectInstance::addToRequestQueue()
RTI13ObjectInstance::deleteObjectInstance(const RTIData& tag)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
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.");
SGSharedPtr<RTI13Federate> federate = _ambassador->_federate.lock();
if (!federate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Federate is zero.");
return;
}
try {
ambassador->deleteObjectInstance(_handle, tag);
_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) {
@@ -119,14 +111,19 @@ RTI13ObjectInstance::deleteObjectInstance(const RTIData& tag)
void
RTI13ObjectInstance::deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
SGSharedPtr<RTI13Federate> federate = _ambassador->_federate.lock();
if (!federate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Federate is zero.");
return;
}
try {
ambassador->deleteObjectInstance(_handle, timeStamp, tag);
_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) {
@@ -149,14 +146,19 @@ RTI13ObjectInstance::deleteObjectInstance(const SGTimeStamp& timeStamp, const RT
void
RTI13ObjectInstance::localDeleteObjectInstance()
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
SGSharedPtr<RTI13Federate> federate = _ambassador->_federate.lock();
if (!federate.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Federate is zero.");
return;
}
try {
ambassador->localDeleteObjectInstance(_handle);
_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) {
@@ -175,54 +177,62 @@ RTI13ObjectInstance::localDeleteObjectInstance()
}
void
RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const RTIData& tag)
RTI13ObjectInstance::reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, 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));
RTIIndexDataPairList indexDataPairList;
for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
i != attributeHandleDataPairList.end(); ++i) {
unsigned index = getAttributeIndex(i->first);
// 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;
getDataFromPool(indexDataPairList);
indexDataPairList.back().first = index;
indexDataPairList.back().second.swap(i->second);
}
RTIObjectInstance::reflectAttributeValues(indexDataPairList, tag);
RTIIndexDataPairList::iterator j = indexDataPairList.begin();
for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
i != attributeHandleDataPairList.end(); ++i, ++j) {
i->second.swap(j->second);
}
RTIObjectInstance::reflectAttributeValues(updateList.front()._indexDataPairList, tag);
// Return the update data back to the pool
putUpdateToPool(updateList);
putDataToPool(indexDataPairList);
}
void
RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const SGTimeStamp& timeStamp, const RTIData& tag)
RTI13ObjectInstance::reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList,
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));
RTIIndexDataPairList indexDataPairList;
for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
i != attributeHandleDataPairList.end(); ++i) {
unsigned index = getAttributeIndex(i->first);
// 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;
getDataFromPool(indexDataPairList);
indexDataPairList.back().first = index;
indexDataPairList.back().second.swap(i->second);
}
scheduleUpdates(timeStamp, updateList);
RTIObjectInstance::reflectAttributeValues(indexDataPairList, timeStamp, tag);
RTIIndexDataPairList::iterator j = indexDataPairList.begin();
for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
i != attributeHandleDataPairList.end(); ++i, ++j) {
i->second.swap(j->second);
}
// Return the update data back to the pool
putDataToPool(indexDataPairList);
}
void
RTI13ObjectInstance::requestObjectAttributeValueUpdate()
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
@@ -238,7 +248,7 @@ RTI13ObjectInstance::requestObjectAttributeValueUpdate()
if (!attributeHandleSet->size())
return;
ambassador->requestObjectAttributeValueUpdate(_handle, *attributeHandleSet);
_ambassador->requestObjectAttributeValueUpdate(_handle, *attributeHandleSet);
for (unsigned i = 0; i < numAttributes; ++i)
setRequestAttributeUpdate(i, false);
@@ -272,12 +282,12 @@ RTI13ObjectInstance::requestObjectAttributeValueUpdate()
}
void
RTI13ObjectInstance::provideAttributeValueUpdate(const RTI::AttributeHandleSet& attributes)
RTI13ObjectInstance::provideAttributeValueUpdate(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
{
// Called from the ambassador. Just marks some instance attributes dirty so that they are sent with the next update
RTI::ULong numAttribs = attributes.size();
size_t numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
unsigned index = getAttributeIndex(attributes.getHandle(i));
unsigned index = getAttributeIndex(attributeHandleSet[i]);
setAttributeForceUpdate(index);
}
}
@@ -285,8 +295,7 @@ RTI13ObjectInstance::provideAttributeValueUpdate(const RTI::AttributeHandleSet&
void
RTI13ObjectInstance::updateAttributeValues(const RTIData& tag)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
@@ -312,28 +321,28 @@ RTI13ObjectInstance::updateAttributeValues(const RTIData& tag)
if (!_attributeValuePairSet->size())
return;
ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, tag);
_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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values object instance: " << e._name << " " << e._reason);
}
// That means clear()
@@ -343,8 +352,7 @@ RTI13ObjectInstance::updateAttributeValues(const RTIData& tag)
void
RTI13ObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
{
SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
if (!ambassador.valid()) {
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
@@ -370,30 +378,30 @@ RTI13ObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const R
if (!_attributeValuePairSet->size())
return;
ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, timeStamp, tag);
_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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values 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);
SG_LOG(SG_NETWORK, SG_WARN, "RTI: could not update attribute values object instance: " << e._name << " " << e._reason);
}
// That means clear()
@@ -401,72 +409,72 @@ RTI13ObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const R
}
void
RTI13ObjectInstance::attributesInScope(const RTI::AttributeHandleSet& attributeHandleSet)
RTI13ObjectInstance::attributesInScope(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
{
RTI::ULong numAttribs = attributeHandleSet.size();
size_t numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
setAttributeInScope(getAttributeIndex(attributeHandle), true);
}
}
void
RTI13ObjectInstance::attributesOutOfScope(const RTI::AttributeHandleSet& attributeHandleSet)
RTI13ObjectInstance::attributesOutOfScope(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
{
RTI::ULong numAttribs = attributeHandleSet.size();
size_t numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
setAttributeInScope(getAttributeIndex(attributeHandle), false);
}
}
void
RTI13ObjectInstance::turnUpdatesOnForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
RTI13ObjectInstance::turnUpdatesOnForObjectInstance(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
{
RTI::ULong numAttribs = attributeHandleSet.size();
size_t numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), true);
}
}
void
RTI13ObjectInstance::turnUpdatesOffForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
RTI13ObjectInstance::turnUpdatesOffForObjectInstance(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
{
RTI::ULong numAttribs = attributeHandleSet.size();
size_t numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), false);
}
}
void
RTI13ObjectInstance::requestAttributeOwnershipAssumption(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
RTI13ObjectInstance::requestAttributeOwnershipAssumption(const std::vector<RTI::AttributeHandle>& attributes, const RTIData& tag)
{
}
void
RTI13ObjectInstance::attributeOwnershipDivestitureNotification(const RTI::AttributeHandleSet& attributes)
RTI13ObjectInstance::attributeOwnershipDivestitureNotification(const std::vector<RTI::AttributeHandle>& attributes)
{
}
void
RTI13ObjectInstance::attributeOwnershipAcquisitionNotification(const RTI::AttributeHandleSet& attributes)
RTI13ObjectInstance::attributeOwnershipAcquisitionNotification(const std::vector<RTI::AttributeHandle>& attributes)
{
}
void
RTI13ObjectInstance::attributeOwnershipUnavailable(const RTI::AttributeHandleSet& attributes)
RTI13ObjectInstance::attributeOwnershipUnavailable(const std::vector<RTI::AttributeHandle>& attributes)
{
}
void
RTI13ObjectInstance::requestAttributeOwnershipRelease(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
RTI13ObjectInstance::requestAttributeOwnershipRelease(const std::vector<RTI::AttributeHandle>& attributes, const RTIData& tag)
{
}
void
RTI13ObjectInstance::confirmAttributeOwnershipAcquisitionCancellation(const RTI::AttributeHandleSet& attributes)
RTI13ObjectInstance::confirmAttributeOwnershipAcquisitionCancellation(const std::vector<RTI::AttributeHandle>& attributes)
{
}

View File

@@ -37,6 +37,9 @@ namespace simgear {
class RTI13Ambassador;
class RTI13ObjectClass;
typedef std::pair<RTI::AttributeHandle, RTIData> RTI13AttributeHandleDataPair;
typedef std::list<RTI13AttributeHandleDataPair> RTI13AttributeHandleDataPairList;
class RTI13ObjectInstance : public RTIObjectInstance {
public:
RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance, const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador, bool owned);
@@ -61,33 +64,31 @@ public:
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);
void reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, const RTIData& tag);
void reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, const SGTimeStamp& timeStamp, const RTIData& tag);
virtual void requestObjectAttributeValueUpdate();
void provideAttributeValueUpdate(const RTI::AttributeHandleSet& attributes);
void provideAttributeValueUpdate(const std::vector<RTI::AttributeHandle>& 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 attributesInScope(const std::vector<RTI::AttributeHandle>& attributes);
void attributesOutOfScope(const std::vector<RTI::AttributeHandle>& attributes);
void turnUpdatesOnForObjectInstance(const RTI::AttributeHandleSet& attributes);
void turnUpdatesOffForObjectInstance(const RTI::AttributeHandleSet& attributes);
void turnUpdatesOnForObjectInstance(const std::vector<RTI::AttributeHandle>& attributes);
void turnUpdatesOffForObjectInstance(const std::vector<RTI::AttributeHandle>& 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 requestAttributeOwnershipAssumption(const std::vector<RTI::AttributeHandle>& attributes, const RTIData& tag);
void attributeOwnershipDivestitureNotification(const std::vector<RTI::AttributeHandle>& attributes);
void attributeOwnershipAcquisitionNotification(const std::vector<RTI::AttributeHandle>& attributes);
void attributeOwnershipUnavailable(const std::vector<RTI::AttributeHandle>& attributes);
void requestAttributeOwnershipRelease(const std::vector<RTI::AttributeHandle>& attributes, const RTIData& tag);
void confirmAttributeOwnershipAcquisitionCancellation(const std::vector<RTI::AttributeHandle>& attributes);
void informAttributeOwnership(RTI::AttributeHandle attributeHandle, RTI::FederateHandle federateHandle);
void attributeIsNotOwned(RTI::AttributeHandle attributeHandle);
void attributeOwnedByRTI(RTI::AttributeHandle attributeHandle);
@@ -95,7 +96,7 @@ public:
private:
RTI::ObjectHandle _handle;
SGSharedPtr<const RTI13ObjectClass> _objectClass;
SGWeakPtr<RTI13Ambassador> _ambassador;
SGSharedPtr<RTI13Ambassador> _ambassador;
// cached storage for updates
std::auto_ptr<RTI::AttributeHandleValuePairSet> _attributeValuePairSet;

View File

@@ -115,6 +115,13 @@ public:
ensureCapacity(capacity);
}
void swap(RTIData& data)
{
std::swap(_data, data._data);
std::swap(_size, data._size);
std::swap(_capacity, data._capacity);
}
void setData(char* data, unsigned size)
{
if (_capacity)

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
// Copyright (C) 2009 - 2011 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
@@ -32,63 +32,60 @@ 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;
enum FederationManagementResult {
FederationManagementSuccess,
FederationManagementFail,
FederationManagementFatal
};
virtual FederationManagementResult createFederationExecution(const std::string& federation, const std::string& objectModel) = 0;
virtual FederationManagementResult 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 FederationManagementResult join(const std::string& federateType, const std::string& federation) = 0;
virtual bool resign() = 0;
virtual bool getJoined() const = 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 getFederationSynchronizationPointAnnounced(const std::string& label) = 0;
virtual bool synchronizationPointAchieved(const std::string& label) = 0;
virtual bool waitForFederationSynchronized(const std::string& label) = 0;
virtual bool getFederationSynchronized(const std::string& label) = 0;
/// Time management
virtual bool enableTimeConstrained() = 0;
virtual bool disableTimeConstrained() = 0;
virtual bool getTimeConstrainedEnabled() = 0;
virtual bool enableTimeRegulation(const SGTimeStamp& lookahead) = 0;
virtual bool disableTimeRegulation() = 0;
virtual bool modifyLookahead(const SGTimeStamp& timeStamp) = 0;
virtual bool getTimeRegulationEnabled() = 0;
virtual bool timeAdvanceRequestBy(const SGTimeStamp& dt) = 0;
virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime) = 0;
virtual bool timeAdvanceRequestAvailable(const SGTimeStamp& timeStamp) = 0;
virtual bool flushQueueRequest(const SGTimeStamp& timeStamp) = 0;
virtual bool getTimeAdvancePending() = 0;
virtual bool queryFederateTime(SGTimeStamp& timeStamp) = 0;
virtual bool queryLookahead(SGTimeStamp& timeStamp) = 0;
virtual bool queryGALT(SGTimeStamp& timeStamp) = 0;
virtual bool queryLITS(SGTimeStamp& timeStamp) = 0;
/// Process messages
virtual bool tick() = 0;
virtual bool tick(const double& minimum, const double& maximum) = 0;
virtual bool processMessage() = 0;
virtual bool processMessages(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;
};
}

View File

@@ -39,6 +39,7 @@ RTIObjectClass::discoverInstance(RTIObjectInstance* objectInstance, const RTIDat
return;
}
hlaObjectClass->discoverInstance(objectInstance, tag);
objectInstance->requestObjectAttributeValueUpdate();
}
void

View File

@@ -50,9 +50,6 @@ public:
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;
@@ -63,20 +60,6 @@ public:
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)
@@ -136,6 +119,8 @@ public:
} else {
_attributeData[i].setUpdateEnabled(false);
_attributeData[i].setOwned(false);
if (getAttributeSubscribed(i))
_attributeData[i].setRequestUpdate(true);
}
}
_attributeData.resize(numAttributes);
@@ -143,9 +128,13 @@ public:
if (getAttributePublished(i)) {
_attributeData[i].setUpdateEnabled(true);
_attributeData[i].setOwned(owned);
if (!owned && getAttributeSubscribed(i))
_attributeData[i].setRequestUpdate(true);
} else {
_attributeData[i].setUpdateEnabled(false);
_attributeData[i].setOwned(false);
if (getAttributeSubscribed(i))
_attributeData[i].setRequestUpdate(true);
}
}
}
@@ -213,7 +202,6 @@ public:
if (request) {
if (!_pendingAttributeUpdateRequest) {
_pendingAttributeUpdateRequest = true;
addToRequestQueue();
}
}
}
@@ -239,80 +227,25 @@ protected:
// 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);
}
// Pool of update list entries
RTIIndexDataPairList _indexDataPairList;
// This adds raw storage for attribute index i to the end of the dataPairList.
void getDataFromPool(unsigned i, RTIIndexDataPairList& dataPairList)
void getDataFromPool(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()) {
if (_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());
dataPairList.splice(dataPairList.end(), _indexDataPairList, _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());
}
}
_indexDataPairList.splice(_indexDataPairList.begin(), dataPairList);
}
struct AttributeData {

View File

@@ -2,7 +2,7 @@
include (SimGearComponent)
set(HEADERS
set(HEADERS
iochannel.hxx
lowlevel.hxx
raw_socket.hxx
@@ -14,9 +14,11 @@ set(HEADERS
sg_serial.hxx
sg_socket.hxx
sg_socket_udp.hxx
HTTPClient.hxx
HTTPRequest.hxx
)
set(SOURCES
set(SOURCES
iochannel.cxx
lowlevel.cxx
raw_socket.cxx
@@ -28,6 +30,41 @@ set(SOURCES
sg_serial.cxx
sg_socket.cxx
sg_socket_udp.cxx
HTTPClient.cxx
HTTPRequest.cxx
)
simgear_component(io io "${SOURCES}" "${HEADERS}")
simgear_component(io io "${SOURCES}" "${HEADERS}")
if(ENABLE_TESTS)
if (SIMGEAR_SHARED)
set(TEST_LIBS SimGearCore)
else()
set(TEST_LIBS
sgio sgbucket sgstructure sgthreads sgtiming sgmisc sgdebug
${CMAKE_THREAD_LIBS_INIT}
${WINSOCK_LIBRARY}
${ZLIB_LIBRARY}
${RT_LIBRARY})
endif()
add_executable(test_sock socktest.cxx)
target_link_libraries(test_sock ${TEST_LIBS})
add_executable(test_http test_HTTP.cxx)
target_link_libraries(test_http ${TEST_LIBS})
add_test(http ${EXECUTABLE_OUTPUT_PATH}/test_http)
add_executable(httpget httpget.cxx)
target_link_libraries(httpget ${TEST_LIBS})
add_executable(decode_binobj decode_binobj.cxx)
target_link_libraries(decode_binobj ${TEST_LIBS})
add_executable(test_binobj test_binobj.cxx)
target_link_libraries(test_binobj ${TEST_LIBS})
add_test(binobj ${EXECUTABLE_OUTPUT_PATH}/test_binobj)
endif(ENABLE_TESTS)

450
simgear/io/HTTPClient.cxx Normal file
View File

@@ -0,0 +1,450 @@
#include "HTTPClient.hxx"
#include <sstream>
#include <cassert>
#include <list>
#include <boost/foreach.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <simgear/io/sg_netChat.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/timing/timestamp.hxx>
#if defined( HAVE_VERSION_H ) && HAVE_VERSION_H
#include "version.h"
#else
# if !defined(SIMGEAR_VERSION)
# define SIMGEAR_VERSION "simgear-development"
# endif
#endif
using std::string;
using std::stringstream;
using std::vector;
//#include <iostream>
//using namespace std;
namespace simgear
{
namespace HTTP
{
extern const int DEFAULT_HTTP_PORT = 80;
class Connection : public NetChat
{
public:
Connection(Client* pr) :
client(pr),
state(STATE_CLOSED),
port(DEFAULT_HTTP_PORT)
{
}
void setServer(const string& h, short p)
{
host = h;
port = p;
}
// socket-level errors
virtual void handleError(int error)
{
NetChat::handleError(error);
if (activeRequest) {
SG_LOG(SG_IO, SG_INFO, "HTTP socket error");
activeRequest->setFailure(error, "socket error");
activeRequest = NULL;
}
state = STATE_SOCKET_ERROR;
}
virtual void handleClose()
{
NetChat::handleClose();
if ((state == STATE_GETTING_BODY) && activeRequest) {
// force state here, so responseComplete can avoid closing the
// socket again
state = STATE_CLOSED;
responseComplete();
} else {
state = STATE_CLOSED;
}
}
void queueRequest(const Request_ptr& r)
{
if (!activeRequest) {
startRequest(r);
} else {
queuedRequests.push_back(r);
}
}
void startRequest(const Request_ptr& r)
{
if (state == STATE_CLOSED) {
if (!connectToHost()) {
return;
}
state = STATE_IDLE;
}
activeRequest = r;
state = STATE_SENT_REQUEST;
bodyTransferSize = -1;
chunkedTransfer = false;
setTerminator("\r\n");
stringstream headerData;
string path = r->path();
if (!client->proxyHost().empty()) {
path = r->url();
}
headerData << r->method() << " " << path << " HTTP/1.1\r\n";
headerData << "Host: " << r->hostAndPort() << "\r\n";
headerData << "User-Agent:" << client->userAgent() << "\r\n";
if (!client->proxyAuth().empty()) {
headerData << "Proxy-Authorization: " << client->proxyAuth() << "\r\n";
}
BOOST_FOREACH(string h, r->requestHeaders()) {
headerData << h << ": " << r->header(h) << "\r\n";
}
headerData << "\r\n"; // final CRLF to terminate the headers
// TODO - add request body support for PUT, etc operations
bool ok = push(headerData.str().c_str());
if (!ok) {
SG_LOG(SG_IO, SG_WARN, "HTTP writing to socket failed");
state = STATE_SOCKET_ERROR;
return;
}
}
virtual void collectIncomingData(const char* s, int n)
{
if ((state == STATE_GETTING_BODY) || (state == STATE_GETTING_CHUNKED_BYTES)) {
activeRequest->processBodyBytes(s, n);
} else {
buffer += string(s, n);
}
}
virtual void foundTerminator(void)
{
switch (state) {
case STATE_SENT_REQUEST:
activeRequest->responseStart(buffer);
state = STATE_GETTING_HEADERS;
buffer.clear();
break;
case STATE_GETTING_HEADERS:
processHeader();
buffer.clear();
break;
case STATE_GETTING_BODY:
responseComplete();
break;
case STATE_GETTING_CHUNKED:
processChunkHeader();
break;
case STATE_GETTING_CHUNKED_BYTES:
setTerminator("\r\n");
state = STATE_GETTING_CHUNKED;
break;
case STATE_GETTING_TRAILER:
processTrailer();
buffer.clear();
break;
default:
break;
}
}
bool hasIdleTimeout() const
{
if (state != STATE_IDLE) {
return false;
}
return idleTime.elapsedMSec() > 1000 * 10; // ten seconds
}
bool hasError() const
{
return (state == STATE_SOCKET_ERROR);
}
bool shouldStartNext() const
{
return !activeRequest && !queuedRequests.empty() &&
((state == STATE_CLOSED) || (state == STATE_IDLE));
}
void startNext()
{
Request_ptr next = queuedRequests.front();
queuedRequests.pop_front();
startRequest(next);
}
private:
bool connectToHost()
{
SG_LOG(SG_IO, SG_INFO, "HTTP connecting to " << host << ":" << port);
if (!open()) {
SG_LOG(SG_ALL, SG_WARN, "HTTP::Connection: connectToHost: open() failed");
return false;
}
if (connect(host.c_str(), port) != 0) {
return false;
}
return true;
}
void processHeader()
{
string h = strutils::simplify(buffer);
if (h.empty()) { // blank line terminates headers
headersComplete();
if (chunkedTransfer) {
state = STATE_GETTING_CHUNKED;
} else {
setByteCount(bodyTransferSize); // may be -1, that's fine
state = STATE_GETTING_BODY;
}
return;
}
int colonPos = buffer.find(':');
if (colonPos < 0) {
SG_LOG(SG_IO, SG_WARN, "malformed HTTP response header:" << h);
return;
}
string key = strutils::simplify(buffer.substr(0, colonPos));
string lkey = boost::to_lower_copy(key);
string value = strutils::strip(buffer.substr(colonPos + 1));
// only consider these if getting headers (as opposed to trailers
// of a chunked transfer)
if (state == STATE_GETTING_HEADERS) {
if (lkey == "content-length") {
int sz = strutils::to_int(value);
if (bodyTransferSize <= 0) {
bodyTransferSize = sz;
}
activeRequest->setResponseLength(sz);
} else if (lkey == "transfer-length") {
bodyTransferSize = strutils::to_int(value);
} else if (lkey == "transfer-encoding") {
processTransferEncoding(value);
}
}
activeRequest->responseHeader(lkey, value);
}
void processTransferEncoding(const string& te)
{
if (te == "chunked") {
chunkedTransfer = true;
} else {
SG_LOG(SG_IO, SG_WARN, "unsupported transfer encoding:" << te);
// failure
}
}
void processChunkHeader()
{
if (buffer.empty()) {
// blank line after chunk data
return;
}
int chunkSize = 0;
int semiPos = buffer.find(';');
if (semiPos >= 0) {
// extensions ignored for the moment
chunkSize = strutils::to_int(buffer.substr(0, semiPos), 16);
} else {
chunkSize = strutils::to_int(buffer, 16);
}
buffer.clear();
if (chunkSize == 0) { // trailer start
state = STATE_GETTING_TRAILER;
return;
}
state = STATE_GETTING_CHUNKED_BYTES;
setByteCount(chunkSize);
}
void processTrailer()
{
if (buffer.empty()) {
// end of trailers
responseComplete();
return;
}
// process as a normal header
processHeader();
}
void headersComplete()
{
activeRequest->responseHeadersComplete();
}
void responseComplete()
{
activeRequest->responseComplete();
client->requestFinished(this);
//cout << "response complete: " << activeRequest->url() << endl;
bool doClose = activeRequest->closeAfterComplete();
activeRequest = NULL;
if (state == STATE_GETTING_BODY) {
state = STATE_IDLE;
if (doClose) {
// this will bring us into handleClose() above, which updates
// state to STATE_CLOSED
close();
}
}
setTerminator("\r\n");
// if we have more requests, and we're idle, can start the next
// request immediately. Note we cannot do this if we're in STATE_CLOSED,
// since NetChannel::close cleans up state after calling handleClose;
// instead we pick up waiting requests in update()
if (!queuedRequests.empty() && (state == STATE_IDLE)) {
startNext();
} else {
idleTime.stamp();
}
}
enum ConnectionState {
STATE_IDLE = 0,
STATE_SENT_REQUEST,
STATE_GETTING_HEADERS,
STATE_GETTING_BODY,
STATE_GETTING_CHUNKED,
STATE_GETTING_CHUNKED_BYTES,
STATE_GETTING_TRAILER,
STATE_SOCKET_ERROR,
STATE_CLOSED ///< connection should be closed now
};
Client* client;
Request_ptr activeRequest;
ConnectionState state;
string host;
short port;
std::string buffer;
int bodyTransferSize;
SGTimeStamp idleTime;
bool chunkedTransfer;
std::list<Request_ptr> queuedRequests;
};
Client::Client()
{
setUserAgent("SimGear-" SG_STRINGIZE(SIMGEAR_VERSION));
}
void Client::update()
{
NetChannel::poll();
ConnectionDict::iterator it = _connections.begin();
for (; it != _connections.end(); ) {
if (it->second->hasIdleTimeout() || it->second->hasError()) {
// connection has been idle for a while, clean it up
// (or has an error condition, again clean it up)
SG_LOG(SG_IO, SG_INFO, "cleaning up " << it->second);
ConnectionDict::iterator del = it++;
delete del->second;
_connections.erase(del);
} else {
if (it->second->shouldStartNext()) {
it->second->startNext();
}
++it;
}
} // of connecion iteration
}
void Client::makeRequest(const Request_ptr& r)
{
string host = r->host();
int port = r->port();
if (!_proxy.empty()) {
host = _proxy;
port = _proxyPort;
}
stringstream ss;
ss << host << "-" << port;
string connectionId = ss.str();
if (_connections.find(connectionId) == _connections.end()) {
Connection* con = new Connection(this);
con->setServer(host, port);
_connections[connectionId] = con;
}
_connections[connectionId]->queueRequest(r);
}
void Client::requestFinished(Connection* con)
{
}
void Client::setUserAgent(const string& ua)
{
_userAgent = ua;
}
void Client::setProxy(const string& proxy, int port, const string& auth)
{
_proxy = proxy;
_proxyPort = port;
_proxyAuth = auth;
}
} // of namespace HTTP
} // of namespace simgear

56
simgear/io/HTTPClient.hxx Normal file
View File

@@ -0,0 +1,56 @@
#ifndef SG_HTTP_CLIENT_HXX
#define SG_HTTP_CLIENT_HXX
#include <map>
#include <simgear/io/HTTPRequest.hxx>
namespace simgear
{
namespace HTTP
{
class Connection;
class Client
{
public:
Client();
void update();
void makeRequest(const Request_ptr& r);
void setUserAgent(const std::string& ua);
void setProxy(const std::string& proxy, int port, const std::string& auth = "");
const std::string& userAgent() const
{ return _userAgent; }
const std::string& proxyHost() const
{ return _proxy; }
const std::string& proxyAuth() const
{ return _proxyAuth; }
private:
void requestFinished(Connection* con);
friend class Connection;
friend class Request;
std::string _userAgent;
std::string _proxy;
int _proxyPort;
std::string _proxyAuth;
// connections by host
typedef std::map<std::string, Connection*> ConnectionDict;
ConnectionDict _connections;
};
} // of namespace HTTP
} // of namespace simgear
#endif // of SG_HTTP_CLIENT_HXX

210
simgear/io/HTTPRequest.cxx Normal file
View File

@@ -0,0 +1,210 @@
#include "HTTPRequest.hxx"
#include <simgear/misc/strutils.hxx>
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
using std::string;
using std::map;
namespace simgear
{
namespace HTTP
{
extern const int DEFAULT_HTTP_PORT;
Request::Request(const string& url, const string method) :
_method(method),
_url(url),
_responseVersion(HTTP_VERSION_UNKNOWN),
_responseStatus(0),
_responseLength(0),
_receivedBodyBytes(0),
_willClose(false)
{
}
Request::~Request()
{
}
void Request::setUrl(const string& url)
{
_url = url;
}
string_list Request::requestHeaders() const
{
string_list r;
return r;
}
string Request::header(const std::string& name) const
{
return string();
}
void Request::responseStart(const string& r)
{
const int maxSplit = 2; // HTTP/1.1 nnn reason-string
string_list parts = strutils::split(r, NULL, maxSplit);
if (parts.size() != 3) {
SG_LOG(SG_IO, SG_WARN, "HTTP::Request: malformed response start:" << r);
setFailure(400, "malformed HTTP response header");
return;
}
_responseVersion = decodeVersion(parts[0]);
_responseStatus = strutils::to_int(parts[1]);
_responseReason = parts[2];
}
void Request::responseHeader(const string& key, const string& value)
{
if (key == "connection") {
_willClose = (value.find("close") != string::npos);
}
_responseHeaders[key] = value;
}
void Request::responseHeadersComplete()
{
// no op
}
void Request::processBodyBytes(const char* s, int n)
{
_receivedBodyBytes += n;
gotBodyData(s, n);
}
void Request::gotBodyData(const char* s, int n)
{
}
void Request::responseComplete()
{
}
string Request::scheme() const
{
int firstColon = url().find(":");
if (firstColon > 0) {
return url().substr(0, firstColon);
}
return ""; // couldn't parse scheme
}
string Request::path() const
{
string u(url());
int schemeEnd = u.find("://");
if (schemeEnd < 0) {
return ""; // couldn't parse scheme
}
int hostEnd = u.find('/', schemeEnd + 3);
if (hostEnd < 0) {
return ""; // couldn't parse host
}
int query = u.find('?', hostEnd + 1);
if (query < 0) {
// all remainder of URL is path
return u.substr(hostEnd);
}
return u.substr(hostEnd, query - hostEnd);
}
string Request::host() const
{
string hp(hostAndPort());
int colonPos = hp.find(':');
if (colonPos >= 0) {
return hp.substr(0, colonPos); // trim off the colon and port
} else {
return hp; // no port specifier
}
}
unsigned short Request::port() const
{
string hp(hostAndPort());
int colonPos = hp.find(':');
if (colonPos >= 0) {
return (unsigned short) strutils::to_int(hp.substr(colonPos + 1));
} else {
return DEFAULT_HTTP_PORT;
}
}
string Request::hostAndPort() const
{
string u(url());
int schemeEnd = u.find("://");
if (schemeEnd < 0) {
return ""; // couldn't parse scheme
}
int hostEnd = u.find('/', schemeEnd + 3);
if (hostEnd < 0) { // all remainder of URL is host
return u.substr(schemeEnd + 3);
}
return u.substr(schemeEnd + 3, hostEnd - (schemeEnd + 3));
}
void Request::setResponseLength(unsigned int l)
{
_responseLength = l;
}
unsigned int Request::responseLength() const
{
// if the server didn't supply a content length, use the number
// of bytes we actually received (so far)
if ((_responseLength == 0) && (_receivedBodyBytes > 0)) {
return _receivedBodyBytes;
}
return _responseLength;
}
void Request::setFailure(int code, const std::string& reason)
{
_responseStatus = code;
_responseReason = reason;
failed();
}
void Request::failed()
{
// no-op in base class
}
Request::HTTPVersion Request::decodeVersion(const string& v)
{
if (v == "HTTP/1.1") return HTTP_1_1;
if (v == "HTTP/1.0") return HTTP_1_0;
if (strutils::starts_with(v, "HTTP/0.")) return HTTP_0_x;
return HTTP_VERSION_UNKNOWN;
}
bool Request::closeAfterComplete() const
{
// for non HTTP/1.1 connections, assume server closes
return _willClose || (_responseVersion != HTTP_1_1);
}
} // of namespace HTTP
} // of namespace simgear

103
simgear/io/HTTPRequest.hxx Normal file
View File

@@ -0,0 +1,103 @@
#ifndef SG_HTTP_REQUEST_HXX
#define SG_HTTP_REQUEST_HXX
#include <map>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/math/sg_types.hxx>
namespace simgear
{
namespace HTTP
{
class Request : public SGReferenced
{
public:
virtual ~Request();
virtual void setUrl(const std::string& url);
virtual std::string method() const
{ return _method; }
virtual std::string url() const
{ return _url; }
virtual std::string scheme() const;
virtual std::string path() const;
virtual std::string host() const;
virtual std::string hostAndPort() const;
virtual unsigned short port() const;
virtual string_list requestHeaders() const;
virtual std::string header(const std::string& name) const;
virtual int responseCode() const
{ return _responseStatus; }
virtual std::string responseReason() const
{ return _responseReason; }
void setResponseLength(unsigned int l);
virtual unsigned int responseLength() const;
/**
* running total of body bytes received so far. Can be used
* to generate a completion percentage, if the response length is
* known.
*/
unsigned int responseBytesReceived() const
{ return _receivedBodyBytes; }
enum HTTPVersion {
HTTP_VERSION_UNKNOWN = 0,
HTTP_0_x, // 0.9 or similar
HTTP_1_0,
HTTP_1_1
};
HTTPVersion responseVersion() const
{ return _responseVersion; }
static HTTPVersion decodeVersion(const std::string& v);
bool closeAfterComplete() const;
protected:
Request(const std::string& url, const std::string method = "GET");
virtual void responseStart(const std::string& r);
virtual void responseHeader(const std::string& key, const std::string& value);
virtual void responseHeadersComplete();
virtual void responseComplete();
virtual void failed();
virtual void gotBodyData(const char* s, int n);
private:
friend class Client;
friend class Connection;
void processBodyBytes(const char* s, int n);
void setFailure(int code, const std::string& reason);
std::string _method;
std::string _url;
HTTPVersion _responseVersion;
int _responseStatus;
std::string _responseReason;
unsigned int _responseLength;
unsigned int _receivedBodyBytes;
bool _willClose;
typedef std::map<std::string, std::string> HeaderDict;
HeaderDict _responseHeaders;
};
typedef SGSharedPtr<Request> Request_ptr;
} // of namespace HTTP
} // of namespace simgear
#endif // of SG_HTTP_REQUEST_HXX

View File

@@ -1,88 +0,0 @@
includedir = @includedir@/io
lib_LIBRARIES = libsgio.a
include_HEADERS = \
iochannel.hxx \
lowlevel.hxx \
sg_binobj.hxx \
sg_file.hxx \
sg_serial.hxx \
sg_socket.hxx \
sg_socket_udp.hxx \
raw_socket.hxx \
sg_netBuffer.hxx \
sg_netChannel.hxx \
sg_netChat.hxx
libsgio_a_SOURCES = \
iochannel.cxx \
lowlevel.cxx \
sg_binobj.cxx \
sg_file.cxx \
sg_serial.cxx \
sg_socket.cxx \
sg_socket_udp.cxx \
raw_socket.cxx \
sg_netBuffer.cxx \
sg_netChannel.cxx \
sg_netChat.cxx
INCLUDES = -I$(top_srcdir)
noinst_PROGRAMS = decode_binobj socktest lowtest tcp_server tcp_client
tcp_server_SOURCES = tcp_server.cxx
tcp_server_LDADD = \
libsgio.a \
$(top_builddir)/simgear/structure/libsgstructure.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
-lz \
$(network_LIBS) \
$(base_LIBS)
tcp_client_SOURCES = tcp_client.cxx
tcp_client_LDADD = \
libsgio.a \
$(top_builddir)/simgear/structure/libsgstructure.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
-lz \
$(network_LIBS) \
$(base_LIBS)
socktest_SOURCES = socktest.cxx
socktest_LDADD = \
libsgio.a \
$(top_builddir)/simgear/structure/libsgstructure.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
-lz \
$(network_LIBS) \
$(base_LIBS)
lowtest_SOURCES = lowtest.cxx
lowtest_LDADD = \
libsgio.a \
$(top_builddir)/simgear/structure/libsgstructure.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(base_LIBS) -lz
decode_binobj_SOURCES = decode_binobj.cxx
decode_binobj_LDADD = \
libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(base_LIBS) -lz

View File

@@ -4,9 +4,13 @@
#include <simgear/compiler.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include "sg_binobj.hxx"

169
simgear/io/httpget.cxx Normal file
View File

@@ -0,0 +1,169 @@
#include <cstdio>
#include <cstring>
#include <signal.h>
#include <iostream>
#include <boost/foreach.hpp>
#include <simgear/io/sg_file.hxx>
#include <simgear/io/HTTPClient.hxx>
#include <simgear/io/HTTPRequest.hxx>
#include <simgear/io/sg_netChannel.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/timing/timestamp.hxx>
using namespace simgear;
using std::cout;
using std::endl;
using std::cerr;
using std::string;
class ARequest : public HTTP::Request
{
public:
ARequest(string& url) :
Request(url),
_complete(false),
_file(NULL)
{
}
void setFile(SGFile* f)
{
_file = f;
}
bool complete() const
{ return _complete; }
void addHeader(const string& h)
{
int colonPos = h.find(':');
if (colonPos < 0) {
cerr << "malformed header: " << h << endl;
return;
}
string key = h.substr(0, colonPos);
_headers[key] = h.substr(colonPos + 1);
}
virtual string_list requestHeaders() const
{
string_list r;
std::map<string, string>::const_iterator it;
for (it = _headers.begin(); it != _headers.end(); ++it) {
r.push_back(it->first);
}
return r;
}
virtual string header(const string& name) const
{
std::map<string, string>::const_iterator it = _headers.find(name);
if (it == _headers.end()) {
return string();
}
return it->second;
}
protected:
virtual void responseHeadersComplete()
{
}
virtual void responseComplete()
{
_complete = true;
}
virtual void gotBodyData(const char* s, int n)
{
_file->write(s, n);
}
private:
bool _complete;
SGFile* _file;
std::map<string, string> _headers;
};
int main(int argc, char* argv[])
{
HTTP::Client cl;
SGFile* outFile = 0;
string proxy, proxyAuth;
string_list headers;
string url;
for (int a=0; a<argc;++a) {
if (argv[a][0] == '-') {
if (!strcmp(argv[a], "--user-agent")) {
cl.setUserAgent(argv[++a]);
} else if (!strcmp(argv[a], "--proxy")) {
proxy = argv[++a];
} else if (!strcmp(argv[a], "--auth")) {
proxyAuth = argv[++a];
} else if (!strcmp(argv[a], "-f") || !strcmp(argv[a], "--file")) {
outFile = new SGFile(argv[++a]);
if (!outFile->open(SG_IO_OUT)) {
cerr << "failed to open output for writing:" << outFile->get_file_name() << endl;
return EXIT_FAILURE;
}
} else if (!strcmp(argv[a], "--header")) {
headers.push_back(argv[++a]);
}
} else { // of argument starts with a hyphen
url = argv[a];
}
} // of arguments iteration
if (!proxy.empty()) {
int colonPos = proxy.find(':');
string proxyHost = proxy;
int proxyPort = 8800;
if (colonPos >= 0) {
proxyHost = proxy.substr(0, colonPos);
proxyPort = strutils::to_int(proxy.substr(colonPos + 1));
}
cl.setProxy(proxyHost, proxyPort, proxyAuth);
}
#ifndef WIN32
signal(SIGPIPE, SIG_IGN);
#endif
if (!outFile) {
outFile = new SGFile(fileno(stdout));
}
if (url.empty()) {
cerr << "no URL argument specificed" << endl;
return EXIT_FAILURE;
}
ARequest* req = new ARequest(url);
BOOST_FOREACH(string h, headers) {
req->addHeader(h);
}
req->setFile(outFile);
cl.makeRequest(req);
while (!req->complete()) {
cl.update();
SGTimeStamp::sleepForMSec(100);
}
if (req->responseCode() != 200) {
cerr << "got response:" << req->responseCode() << endl;
cerr << "\treason:" << req->responseReason() << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View File

@@ -73,6 +73,6 @@ bool SGIOChannel::close() {
// dummy eof routine
bool SGIOChannel::eof() {
bool SGIOChannel::eof() const {
return false;
}

View File

@@ -30,15 +30,6 @@
#include <simgear/compiler.h>
// #include "protocol.hxx"
#include <string>
#include <vector>
using std::vector;
using std::string;
#define SG_IO_MAX_MSG_SIZE 16384
/**
@@ -158,7 +149,7 @@ public:
* false.
* @return result of eof check
*/
virtual bool eof();
virtual bool eof() const;
inline void set_type( SGChannelType t ) { type = t; }
inline SGChannelType get_type() const { return type; }

View File

@@ -1,20 +1,20 @@
/*
simgear::Socket, adapted from PLIB Socket by James Turner
Copyright (C) 2010 James Turner
PLIB - A Suite of Portable Game Libraries
Copyright (C) 1998,2002 Steve Baker
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 Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -25,8 +25,7 @@
#endif
#include <simgear/compiler.h>
#include "sg_socket.hxx"
#include "raw_socket.hxx"
#if defined(_WIN32) && !defined(__CYGWIN__)
# define WINSOCK // use winsock convetions, otherwise standard POSIX
@@ -37,16 +36,18 @@
#include <cstring>
#include <cassert>
#include <cstdio> // for snprintf
#include <errno.h>
#if defined(WINSOCK)
# include <winsock.h>
# include <winsock2.h>
# include <ws2tcpip.h>
# include <stdarg.h>
#else
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <sys/time.h>
# include <sys/time.h>
# include <unistd.h>
# include <netdb.h>
# include <fcntl.h>
@@ -56,55 +57,253 @@
#define socklen_t int
#endif
#include <map>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/threads/SGThread.hxx>
namespace {
class Resolver : public SGThread
{
public:
static Resolver* instance()
{
if (!static_instance) {
static_instance = new Resolver;
atexit(&Resolver::cleanup);
static_instance->start();
}
return static_instance;
}
static void cleanup()
{
static_instance->shutdown();
static_instance->join();
}
Resolver() :
_done(false)
{
}
void shutdown()
{
_lock.lock();
_done = true;
_wait.signal();
_lock.unlock();
}
simgear::IPAddress* lookup(const string& host)
{
simgear::IPAddress* result = NULL;
_lock.lock();
AddressCache::iterator it = _cache.find(host);
if (it == _cache.end()) {
_cache[host] = NULL; // mark as needing looked up
_wait.signal(); // if the thread was sleeping, poke it
} else {
result = it->second;
}
_lock.unlock();
return result;
}
simgear::IPAddress* lookupSync(const string& host)
{
simgear::IPAddress* result = NULL;
_lock.lock();
AddressCache::iterator it = _cache.find(host);
if (it == _cache.end()) {
_lock.unlock();
result = new simgear::IPAddress;
bool ok = lookupHost(host.c_str(), *result);
_lock.lock();
if (ok) {
_cache[host] = result; // mark as needing looked up
} else {
delete result;
result = NULL;
}
} else { // found in cache, easy
result = it->second;
}
_lock.unlock();
return result;
}
protected:
/**
* run method waits on a condition (_wait), and when awoken,
* finds any unresolved entries in _cache, resolves them, and goes
* back to sleep.
*/
virtual void run()
{
_lock.lock();
while (!_done) {
AddressCache::iterator it;
for (it = _cache.begin(); it != _cache.end(); ++it) {
if (it->second == NULL) {
string h = it->first;
_lock.unlock();
simgear::IPAddress* addr = new simgear::IPAddress;
// may take seconds or even minutes!
lookupHost(h.c_str(), *addr);
_lock.lock();
// cahce may have changed while we had the lock released -
// so iterators may be invalid: restart the traversal
it = _cache.begin();
_cache[h] = addr;
} // of found un-resolved entry
} // of un-resolved address iteration
_wait.wait(_lock);
} // of thread run loop
_lock.unlock();
}
private:
static Resolver* static_instance;
/**
* The actual synchronous, blocking host lookup function
* do *not* call this with any locks (mutexs) held, since depending
* on local system configuration / network availability, it
* may block for seconds or minutes.
*/
bool lookupHost(const char* host, simgear::IPAddress& addr)
{
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
bool ok = false;
struct addrinfo* result0 = NULL;
int err = getaddrinfo(host, NULL, &hints, &result0);
if (err) {
SG_LOG(SG_IO, SG_WARN, "getaddrinfo failed for '" << host << "' : " << gai_strerror(err));
return false;
} else {
struct addrinfo* result;
for (result = result0; result != NULL; result = result->ai_next) {
if (result->ai_family != AF_INET) { // only accept IP4 for the moment
continue;
}
if (result->ai_addrlen != addr.getAddrLen()) {
SG_LOG(SG_IO, SG_ALERT, "mismatch in socket address sizes: got " <<
result->ai_addrlen << ", expected " << addr.getAddrLen());
continue;
}
memcpy(addr.getAddr(), result->ai_addr, result->ai_addrlen);
ok = true;
break;
} // of getaddrinfo results iteration
} // of getaddrinfo succeeded
freeaddrinfo(result0);
return ok;
}
SGMutex _lock;
SGWaitCondition _wait;
typedef std::map<string, simgear::IPAddress*> AddressCache;
AddressCache _cache;
bool _done;
};
Resolver* Resolver::static_instance = NULL;
} // of anonymous namespace
namespace simgear
{
IPAddress::IPAddress ( const char* host, int port )
{
set ( host, port ) ;
}
IPAddress::IPAddress( const IPAddress& other ) :
addr(NULL)
{
if (other.addr) {
addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
memcpy(addr, other.addr, sizeof(struct sockaddr_in));
}
}
const IPAddress& IPAddress::operator=(const IPAddress& other)
{
if (addr) {
free(addr);
addr = NULL;
}
if (other.addr) {
addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
memcpy(addr, other.addr, sizeof(struct sockaddr_in));
}
return *this;
}
void IPAddress::set ( const char* host, int port )
{
memset(this, 0, sizeof(IPAddress));
addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
memset(addr, 0, sizeof(struct sockaddr_in));
sin_family = AF_INET ;
sin_port = htons (port);
addr->sin_family = AF_INET ;
addr->sin_port = htons (port);
/* Convert a string specifying a host name or one of a few symbolic
** names to a numeric IP address. This usually calls gethostbyname()
** names to a numeric IP address. This usually calls getaddrinfo()
** to do the work; the names "" and "<broadcast>" are special.
*/
if (!host || host[0] == '\0') {
sin_addr = INADDR_ANY;
addr->sin_addr.s_addr = INADDR_ANY;
return;
}
if (strcmp(host, "<broadcast>") == 0) {
sin_addr = INADDR_BROADCAST;
addr->sin_addr.s_addr = INADDR_BROADCAST;
return;
}
sin_addr = inet_addr ( host ) ;
if (sin_addr != INADDR_NONE) {
return;
// check the cache
IPAddress* cached = Resolver::instance()->lookupSync(host);
if (cached) {
memcpy(addr, cached->getAddr(), cached->getAddrLen());
}
// finally, try gethostbyname
struct hostent *hp = gethostbyname ( host ) ;
if (!hp) {
SG_LOG(SG_IO, SG_WARN, "gethostbyname failed for " << host);
sin_addr = INADDR_ANY ;
return;
}
memcpy ( (char *) &sin_addr, hp->h_addr, hp->h_length ) ;
addr->sin_port = htons (port); // fix up port after getaddrinfo
}
IPAddress::~IPAddress()
{
if (addr) {
free (addr);
}
}
bool IPAddress::lookupNonblocking(const char* host, IPAddress& addr)
{
IPAddress* cached = Resolver::instance()->lookup(host);
if (!cached) {
return false;
}
addr = *cached;
return true;
}
/* Create a string object representing an IP address.
This is always a string of the form 'dd.dd.dd.dd' (with variable
@@ -112,31 +311,52 @@ void IPAddress::set ( const char* host, int port )
const char* IPAddress::getHost () const
{
#if 0
const char* buf = inet_ntoa ( sin_addr ) ;
#else
if (!addr) {
return NULL;
}
static char buf [32];
long x = ntohl(sin_addr);
long x = ntohl(addr->sin_addr.s_addr);
sprintf(buf, "%d.%d.%d.%d",
(int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
(int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff );
#endif
return buf;
}
unsigned int IPAddress::getIP () const
{
return sin_addr;
unsigned int IPAddress::getIP () const
{
if (!addr) {
return 0;
}
return addr->sin_addr.s_addr;
}
unsigned int IPAddress::getPort() const
{
return ntohs(sin_port);
if (!addr) {
return 0;
}
return ntohs(addr->sin_port);
}
unsigned int IPAddress::getFamily () const
{
return sin_family;
void IPAddress::setPort(int port)
{
if (!addr) {
return;
}
addr->sin_port = htons(port);
}
unsigned int IPAddress::getFamily () const
{
if (!addr) {
return 0;
}
return addr->sin_family;
}
const char* IPAddress::getLocalHost ()
@@ -163,9 +383,32 @@ const char* IPAddress::getLocalHost ()
bool IPAddress::getBroadcast () const
{
return sin_addr == INADDR_BROADCAST;
if (!addr) {
return false;
}
return (addr->sin_addr.s_addr == INADDR_BROADCAST);
}
unsigned int IPAddress::getAddrLen() const
{
return sizeof(struct sockaddr_in);
}
struct sockaddr* IPAddress::getAddr() const
{
if (addr == NULL) {
addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
memset(addr, 0, sizeof(struct sockaddr_in));
}
return (struct sockaddr*) addr;
}
bool IPAddress::isValid() const
{
return (addr != NULL);
}
Socket::Socket ()
{
@@ -248,7 +491,7 @@ void Socket::setBroadcast ( bool broadcast )
} else {
result = ::setsockopt( handle, SOL_SOCKET, SO_BROADCAST, NULL, 0 );
}
if ( result < 0 ) {
throw sg_exception("Socket::setBroadcast failed");
}
@@ -262,13 +505,13 @@ int Socket::bind ( const char* host, int port )
IPAddress addr ( host, port ) ;
#if !defined(WINSOCK)
if( (result = ::bind(handle,(const sockaddr*)&addr,sizeof(IPAddress))) < 0 ) {
SG_LOG(SG_IO, SG_ALERT, "bind(" << host << ":" << port << ") failed. Errno " << errno << " (" << strerror(errno) << ")");
if( (result = ::bind(handle, addr.getAddr(), addr.getAddrLen() ) ) < 0 ) {
SG_LOG(SG_IO, SG_ALERT, "bind(" << addr.getHost() << ":" << addr.getPort() << ") failed. Errno " << errno << " (" << strerror(errno) << ")");
return result;
}
#endif
// 224.0.0.0 - 239.255.255.255 are multicast
// 224.0.0.0 - 239.255.255.255 are multicast
// Usage of 239.x.x.x is recommended for local scope
// Reference: http://tools.ietf.org/html/rfc5771
if( ntohl(addr.getIP()) >= 0xe0000000 && ntohl(addr.getIP()) <= 0xefffffff ) {
@@ -278,7 +521,7 @@ int Socket::bind ( const char* host, int port )
a.sin_addr.S_un.S_addr = INADDR_ANY;
a.sin_family = AF_INET;
a.sin_port = htons(port);
if( (result = ::bind(handle,(const sockaddr*)&a,sizeof(a))) < 0 ) {
SG_LOG(SG_IO, SG_ALERT, "bind(any:" << port << ") failed. Errno " << errno << " (" << strerror(errno) << ")");
return result;
@@ -294,7 +537,7 @@ int Socket::bind ( const char* host, int port )
}
}
#if defined(WINSOCK)
else if( (result = ::bind(handle,(const sockaddr*)&addr,sizeof(IPAddress))) < 0 ) {
else if( (result = ::bind(handle,addr.getAddr(), addr.getAddrLen())) < 0 ) {
SG_LOG(SG_IO, SG_ALERT, "bind(" << host << ":" << port << ") failed. Errno " << errno << " (" << strerror(errno) << ")");
return result;
}
@@ -321,20 +564,26 @@ int Socket::accept ( IPAddress* addr )
}
else
{
socklen_t addr_len = (socklen_t) sizeof(IPAddress) ;
return ::accept(handle,(sockaddr*)addr,&addr_len);
socklen_t addr_len = addr->getAddrLen(); ;
return ::accept(handle, addr->getAddr(), &addr_len);
}
}
int Socket::connect ( const char* host, int port )
{
assert ( handle != -1 ) ;
IPAddress addr ( host, port ) ;
if ( addr.getBroadcast() ) {
return connect ( &addr );
}
int Socket::connect ( IPAddress* addr )
{
assert ( handle != -1 ) ;
if ( addr->getBroadcast() ) {
setBroadcast( true );
}
return ::connect(handle,(const sockaddr*)&addr,sizeof(IPAddress));
return ::connect(handle, addr->getAddr(), addr->getAddrLen() );
}
@@ -350,7 +599,7 @@ int Socket::sendto ( const void * buffer, int size,
{
assert ( handle != -1 ) ;
return ::sendto(handle,(const char*)buffer,size,flags,
(const sockaddr*)to,sizeof(IPAddress));
(const sockaddr*) to->getAddr(), to->getAddrLen());
}
@@ -365,8 +614,8 @@ int Socket::recvfrom ( void * buffer, int size,
int flags, IPAddress* from )
{
assert ( handle != -1 ) ;
socklen_t fromlen = (socklen_t) sizeof(IPAddress) ;
return ::recvfrom(handle,(char*)buffer,size,flags,(sockaddr*)from,&fromlen);
socklen_t fromlen = (socklen_t) from->getAddrLen() ;
return ::recvfrom(handle,(char*)buffer,size,flags, from->getAddr(),&fromlen);
}
@@ -422,7 +671,7 @@ int Socket::select ( Socket** reads, Socket** writes, int timeout )
{
fd_set r,w;
int retval;
FD_ZERO (&r);
FD_ZERO (&w);
@@ -460,7 +709,7 @@ int Socket::select ( Socket** reads, Socket** writes, int timeout )
// It bothers me that select()'s first argument does not appear to
// work as advertised... [it hangs like this if called with
// anything less than FD_SETSIZE, which seems wasteful?]
// Note: we ignore the 'exception' fd_set - I have never had a
// need to use it. The name is somewhat misleading - the only
// thing I have ever seen it used for is to detect urgent data -
@@ -526,8 +775,6 @@ static void netExit ( void )
int Socket::initSockets()
{
assert ( sizeof(sockaddr_in) == sizeof(IPAddress) ) ;
#if defined(WINSOCK)
/* Start up the windows networking */
WORD version_wanted = MAKEWORD(1,1);

View File

@@ -23,12 +23,15 @@
#ifndef SG_IO_SOCKET_HXX
#define SG_IO_SOCKET_HXX
#include <errno.h>
//#include <errno.h>
#if defined(__APPLE__) || defined(__FreeBSD__)
# include <netinet/in.h>
#endif
//#if defined(__APPLE__) || defined(__FreeBSD__)
//# include <netinet/in.h>
//#endif
struct sockaddr_in;
struct sockaddr;
namespace simgear
{
@@ -37,32 +40,31 @@ namespace simgear
*/
class IPAddress
{
/* DANGER!!! This MUST match 'struct sockaddr_in' exactly! */
#if defined(__APPLE__) || defined(__FreeBSD__)
__uint8_t sin_len;
__uint8_t sin_family;
in_port_t sin_port;
in_addr_t sin_addr;
char sin_zero[8];
#else
short sin_family ;
unsigned short sin_port ;
unsigned int sin_addr ;
char sin_zero [ 8 ] ;
#endif
mutable struct sockaddr_in* addr;
public:
IPAddress () {}
IPAddress () : addr(0) {}
IPAddress ( const char* host, int port ) ;
~IPAddress();
static bool lookupNonblocking(const char* host, IPAddress& addr);
IPAddress( const IPAddress& other );
const IPAddress& operator=(const IPAddress& other);
bool isValid () const;
void set ( const char* host, int port ) ;
const char* getHost () const ;
unsigned int getPort() const ;
void setPort(int port);
unsigned int getIP () const ;
unsigned int getFamily () const ;
static const char* getLocalHost () ;
bool getBroadcast () const ;
unsigned int getAddrLen() const;
sockaddr* getAddr() const;
};
@@ -72,7 +74,7 @@ public:
class Socket
{
int handle ;
public:
Socket () ;
@@ -89,6 +91,7 @@ public:
int listen ( int backlog ) ;
int accept ( IPAddress* addr ) ;
int connect ( const char* host, int port ) ;
int connect ( IPAddress* addr ) ;
int send ( const void * buffer, int size, int flags = 0 ) ;
int sendto ( const void * buffer, int size, int flags, const IPAddress* to ) ;
int recv ( void * buffer, int size, int flags = 0 ) ;

File diff suppressed because it is too large Load Diff

View File

@@ -27,29 +27,24 @@
#ifndef _SG_BINOBJ_HXX
#define _SG_BINOBJ_HXX
#include <zlib.h> // for gzFile
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/math/sg_types.hxx>
#include <simgear/bucket/newbucket.hxx>
#include <simgear/math/SGMath.hxx>
#include <stdio.h>
#include <time.h>
#include <list>
#include <vector>
#include <string>
/** STL Structure used to store object information */
typedef std::vector < int_list > group_list;
typedef group_list::iterator group_list_iterator;
typedef group_list::const_iterator const_group_list_iterator;
/** Magic Number for our file format */
#define SG_FILE_MAGIC_NUMBER ( ('S'<<24) + ('G'<<16) + SG_BINOBJ_VERSION )
// forward decls
class SGBucket;
class SGPath;
/**
* A class to manipulate the simgear 3d object format.
@@ -85,6 +80,7 @@ typedef group_list::const_iterator const_group_list_iterator;
* - vertex: FLOAT, FLOAT, FLOAT
*/
class SGBinObject {
private:
unsigned short version;
SGVec3d gbs_center;
@@ -119,6 +115,24 @@ class SGBinObject {
group_list fans_tc; // fans texture coordinate index
string_list fan_materials; // fans materials
void read_properties(gzFile fp, int nproperties);
void read_object( gzFile fp,
int obj_type,
int nproperties,
int nelements,
group_list& vertices,
group_list& normals,
group_list& colors,
group_list& texCoords,
string_list& materials);
void write_header(gzFile fp, int type, int nProps, int nElements);
void write_objects(gzFile fp, int type, const group_list& verts,
const group_list& normals, const group_list& colors,
const group_list& texCoords, const string_list& materials);
unsigned int count_objects(const string_list& materials);
public:
inline unsigned short get_version() const { return version; }
@@ -207,6 +221,9 @@ public:
*/
bool write_bin( const std::string& base, const std::string& name, const SGBucket& b );
bool write_bin_file(const SGPath& file);
/**
* Write out the structures to an ASCII file. We assume that the
* groups come to us sorted by material property. If not, things

View File

@@ -31,6 +31,14 @@
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#if !defined(_MSC_VER)
# include <unistd.h>
#endif
#include <simgear/misc/stdint.hxx>
#include <simgear/debug/logstream.hxx>
@@ -38,13 +46,20 @@
using std::string;
SGFile::SGFile(const string &file, int repeat_)
: file_name(file), fp(-1), eof_flag(true), repeat(repeat_), iteration(0)
{
set_type( sgFileType );
}
SGFile::SGFile( int existingFd ) :
fp(existingFd),
eof_flag(false),
repeat(1),
iteration(0)
{
set_type( sgFileType );
}
SGFile::~SGFile() {
}

View File

@@ -26,33 +26,19 @@
#ifndef _SG_FILE_HXX
#define _SG_FILE_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include <string>
#include <sys/types.h> // for open(), read(), write(), close()
#include <sys/stat.h> // for open(), read(), write(), close()
#include <fcntl.h> // for open(), read(), write(), close()
#if !defined( _MSC_VER )
# include <unistd.h> // for open(), read(), write(), close()
#endif
#include "iochannel.hxx"
using std::string;
/**
* A file I/O class based on SGIOChannel.
*/
class SGFile : public SGIOChannel {
string file_name;
std::string file_name;
int fp;
bool eof_flag;
// Number of repetitions to play. -1 means loop infinitely.
@@ -70,7 +56,12 @@ public:
* @param file name of file to open
* @param repeat On eof restart at the beginning of the file
*/
SGFile( const string& file, int repeat_ = 1 );
SGFile( const std::string& file, int repeat_ = 1 );
/**
* Create an SGFile from an existing, open file-descriptor
*/
SGFile( int existingFd );
/** Destructor */
~SGFile();
@@ -94,10 +85,10 @@ public:
bool close();
/** @return the name of the file being manipulated. */
inline string get_file_name() const { return file_name; }
inline std::string get_file_name() const { return file_name; }
/** @return true of eof conditions exists */
inline bool eof() const { return eof_flag; };
virtual bool eof() const { return eof_flag; };
};

View File

@@ -34,9 +34,11 @@
#include <memory>
#include <cassert>
#include <cstring>
#include <errno.h>
#include <simgear/debug/logstream.hxx>
namespace simgear {
static NetChannel* channels = 0 ;
@@ -45,6 +47,7 @@ NetChannel::NetChannel ()
{
closed = true ;
connected = false ;
resolving_host = false;
accepting = false ;
write_blocked = false ;
should_delete = false ;
@@ -82,7 +85,6 @@ NetChannel::setHandle (int handle, bool is_connected)
close () ;
Socket::setHandle ( handle ) ;
connected = is_connected ;
//if ( connected ) this->handleConnect();
closed = false ;
}
@@ -106,21 +108,12 @@ NetChannel::listen ( int backlog )
}
int
NetChannel::connect ( const char* host, int port )
NetChannel::connect ( const char* h, int p )
{
int result = Socket::connect ( host, port ) ;
if (result == 0) {
connected = true ;
//this->handleConnect();
return 0;
} else if (isNonBlockingError ()) {
return 0;
} else {
// some other error condition
this->handleError (result);
close();
return -1;
}
host = h;
port = p;
resolving_host = true;
return handleResolve();
}
int
@@ -188,12 +181,10 @@ NetChannel::handleReadEvent (void)
if (accepting) {
if (!connected) {
connected = true ;
//this->handleConnect();
}
this->handleAccept();
} else if (!connected) {
connected = true ;
//this->handleConnect();
this->handleRead();
} else {
this->handleRead();
@@ -205,12 +196,42 @@ NetChannel::handleWriteEvent (void)
{
if (!connected) {
connected = true ;
//this->handleConnect();
}
write_blocked = false ;
this->handleWrite();
}
int
NetChannel::handleResolve()
{
IPAddress addr;
if (!IPAddress::lookupNonblocking(host.c_str(), addr)) {
return 0; // not looked up yet, wait longer
}
if (!addr.isValid()) {
SG_LOG(SG_IO, SG_WARN, "Network: host lookup failed:" << host);
handleError (0);
close();
return -1;
}
resolving_host = false;
addr.setPort(port);
int result = Socket::connect ( &addr ) ;
if (result == 0) {
connected = true ;
return 0;
} else if (isNonBlockingError ()) {
return 0;
} else {
// some other error condition
handleError (result);
close();
return -1;
}
}
bool
NetChannel::poll (unsigned int timeout)
{
@@ -235,6 +256,12 @@ NetChannel::poll (unsigned int timeout)
}
else if ( ! ch -> closed )
{
if (ch -> resolving_host )
{
ch -> handleResolve();
continue;
}
nopen++ ;
if (ch -> readable()) {
assert(nreads<MAX_SOCKETS);

View File

@@ -54,14 +54,17 @@
#define SG_NET_CHANNEL_H
#include <simgear/io/raw_socket.hxx>
#include <string>
namespace simgear
{
class NetChannel : public Socket
{
bool closed, connected, accepting, write_blocked, should_delete ;
bool closed, connected, accepting, write_blocked, should_delete, resolving_host ;
NetChannel* next_channel ;
std::string host;
int port;
friend bool netPoll (unsigned int timeout);
@@ -96,6 +99,7 @@ public:
void handleReadEvent (void);
void handleWriteEvent (void);
int handleResolve (void);
// These are meant to be overridden.
virtual void handleClose (void) {

View File

@@ -26,14 +26,16 @@
#include <simgear/io/sg_netChat.hxx>
#include <cstring> // for strdup
#include <cstdlib>
namespace simgear {
void
NetChat::setTerminator (const char* t)
{
if (terminator) delete[] terminator;
if (terminator) free(terminator);
terminator = strdup(t);
bytesToCollect = -1;
}
const char*
@@ -42,6 +44,15 @@ NetChat::getTerminator (void)
return terminator;
}
void
NetChat::setByteCount(int count)
{
if (terminator) free(terminator);
terminator = NULL;
bytesToCollect = count;
}
// return the size of the largest prefix of needle at the end
// of haystack
@@ -89,13 +100,23 @@ NetChat::handleBufferRead (NetBuffer& in_buffer)
// necessary because we might read several data+terminator combos
// with a single recv().
while (in_buffer.getLength()) {
while (in_buffer.getLength()) {
// special case where we're not using a terminator
if (terminator == 0 || *terminator == 0) {
collectIncomingData (in_buffer.getData(),in_buffer.getLength());
in_buffer.remove ();
return;
if (terminator == 0 || *terminator == 0) {
if ( bytesToCollect > 0) {
const int toRead = std::min(in_buffer.getLength(), bytesToCollect);
collectIncomingData(in_buffer.getData(), toRead);
in_buffer.remove(0, toRead);
bytesToCollect -= toRead;
if (bytesToCollect == 0) { // read all requested bytes
foundTerminator();
}
} else { // read the whole lot
collectIncomingData (in_buffer.getData(),in_buffer.getLength());
in_buffer.remove ();
}
continue;
}
int terminator_len = strlen(terminator);

View File

@@ -61,6 +61,8 @@
#ifndef SG_NET_CHAT_H
#define SG_NET_CHAT_H
#include <memory>
#include <cstdlib>
#include <simgear/io/sg_netBuffer.hxx>
namespace simgear
@@ -69,16 +71,25 @@ namespace simgear
class NetChat : public NetBufferChannel
{
char* terminator;
int bytesToCollect;
virtual void handleBufferRead (NetBuffer& buffer) ;
public:
NetChat () : terminator (0) {}
NetChat () :
terminator (NULL),
bytesToCollect(-1)
{}
void setTerminator (const char* t);
const char* getTerminator (void);
/**
* set byte count to collect - 'foundTerminator' will be called once
* this many bytes have been collected
*/
void setByteCount(int bytes);
bool push (const char* s);
virtual void collectIncomingData (const char* s, int n) {}

View File

@@ -36,6 +36,7 @@
#include "sg_socket.hxx"
bool SGSocket::init = false;
using std::string;
SGSocket::SGSocket( const string& host, const string& port_,
const string& style ) :

View File

@@ -33,6 +33,8 @@
#include <cstring>
#include <cstdlib> // for atoi
using std::string;
SGSocketUDP::SGSocketUDP( const string& host, const string& port ) :
hostname(host),
port_str(port),
@@ -160,11 +162,8 @@ int SGSocketUDP::write( const char *buf, const int length ) {
return 0;
}
bool error_condition = false;
if ( sock.send( buf, length, 0 ) < 0 ) {
SG_LOG( SG_IO, SG_WARN, "Error writing to socket: " << port );
error_condition = true;
return 0;
}

View File

@@ -89,7 +89,7 @@ public:
* @param host name of host if direction is SG_IO_OUT or SG_IO_BI
* @param port port number if we care to choose one.
* @param style specify "udp" or "tcp" */
SGSocketUDP( const string& host, const string& port );
SGSocketUDP( const std::string& host, const std::string& port );
/** Destructor */
~SGSocketUDP();

541
simgear/io/test_HTTP.cxx Normal file
View File

@@ -0,0 +1,541 @@
#include <cstdlib>
#include <iostream>
#include <map>
#include <sstream>
#include <boost/algorithm/string/case_conv.hpp>
#include "HTTPClient.hxx"
#include "HTTPRequest.hxx"
#include <simgear/io/sg_netChat.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/timing/timestamp.hxx>
using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::stringstream;
using namespace simgear;
const char* BODY1 = "The quick brown fox jumps over a lazy dog.";
const unsigned int body2Size = 8 * 1024;
char body2[body2Size];
#define COMPARE(a, b) \
if ((a) != (b)) { \
cerr << "failed:" << #a << " != " << #b << endl; \
cerr << "\tgot:" << a << endl; \
exit(1); \
}
#define VERIFY(a) \
if (!(a)) { \
cerr << "failed:" << #a << endl; \
exit(1); \
}
class TestRequest : public HTTP::Request
{
public:
bool complete;
bool failed;
string bodyData;
TestRequest(const std::string& url) :
HTTP::Request(url),
complete(false)
{
}
std::map<string, string> sendHeaders;
std::map<string, string> headers;
protected:
string_list requestHeaders() const
{
string_list r;
std::map<string, string>::const_iterator it;
for (it = sendHeaders.begin(); it != sendHeaders.end(); ++it) {
r.push_back(it->first);
}
return r;
}
string header(const string& name) const
{
std::map<string, string>::const_iterator it = sendHeaders.find(name);
if (it == sendHeaders.end()) {
return string();
}
return it->second;
}
virtual void responseHeadersComplete()
{
}
virtual void responseComplete()
{
complete = true;
}
virtual void failure()
{
failed = true;
}
virtual void gotBodyData(const char* s, int n)
{
bodyData += string(s, n);
}
virtual void responseHeader(const string& header, const string& value)
{
headers[header] = value;
}
};
class TestServerChannel : public NetChat
{
public:
enum State
{
STATE_IDLE = 0,
STATE_HEADERS,
STATE_REQUEST_BODY
};
TestServerChannel()
{
state = STATE_IDLE;
setTerminator("\r\n");
}
virtual void collectIncomingData(const char* s, int n)
{
buffer += string(s, n);
}
virtual void foundTerminator(void)
{
if (state == STATE_IDLE) {
state = STATE_HEADERS;
string_list line = strutils::split(buffer, NULL, 3);
if (line.size() < 3) {
cerr << "malformed request:" << buffer << endl;
exit(-1);
}
method = line[0];
path = line[1];
httpVersion = line[2];
requestHeaders.clear();
buffer.clear();
} else if (state == STATE_HEADERS) {
string s = strutils::simplify(buffer);
if (s.empty()) {
buffer.clear();
receivedRequestHeaders();
return;
}
int colonPos = buffer.find(':');
if (colonPos < 0) {
cerr << "malformed HTTP response header:" << buffer << endl;
buffer.clear();
return;
}
string key = strutils::simplify(buffer.substr(0, colonPos));
string value = strutils::strip(buffer.substr(colonPos + 1));
requestHeaders[key] = value;
buffer.clear();
} else if (state == STATE_REQUEST_BODY) {
}
}
void receivedRequestHeaders()
{
state = STATE_IDLE;
if (path == "/test1") {
string contentStr(BODY1);
stringstream d;
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
d << "Content-Length:" << contentStr.size() << "\r\n";
d << "\r\n"; // final CRLF to terminate the headers
d << contentStr;
push(d.str().c_str());
} else if (path == "/test_headers") {
COMPARE(requestHeaders["X-Foo"], string("Bar"));
COMPARE(requestHeaders["X-AnotherHeader"], string("A longer value"));
string contentStr(BODY1);
stringstream d;
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
d << "Content-Length:" << contentStr.size() << "\r\n";
d << "\r\n"; // final CRLF to terminate the headers
d << contentStr;
push(d.str().c_str());
} else if (path == "/test2") {
sendBody2();
} else if (path == "/testchunked") {
stringstream d;
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
d << "Transfer-Encoding:chunked\r\n";
d << "\r\n";
d << "8\r\n"; // first chunk
d << "ABCDEFGH\r\n";
d << "6\r\n"; // second chunk
d << "ABCDEF\r\n";
d << "10\r\n"; // third chunk
d << "ABCDSTUVABCDSTUV\r\n";
d << "0\r\n"; // start of trailer
d << "X-Foobar: wibble\r\n"; // trailer data
d << "\r\n";
push(d.str().c_str());
} else if (path == "http://www.google.com/test2") {
// proxy test
if (requestHeaders["Host"] != "www.google.com") {
sendErrorResponse(400, true, "bad destination");
}
if (requestHeaders["Proxy-Authorization"] != string()) {
sendErrorResponse(401, false, "bad auth"); // shouldn't supply auth
}
sendBody2();
} else if (path == "http://www.google.com/test3") {
// proxy test
if (requestHeaders["Host"] != "www.google.com") {
sendErrorResponse(400, true, "bad destination");
}
if (requestHeaders["Proxy-Authorization"] != "ABCDEF") {
sendErrorResponse(401, false, "bad auth"); // forbidden
}
sendBody2();
} else if (strutils::starts_with(path, "/test_1_0")) {
string contentStr(BODY1);
stringstream d;
d << "HTTP/1.0 " << 200 << " " << reasonForCode(200) << "\r\n";
d << "\r\n"; // final CRLF to terminate the headers
d << contentStr;
push(d.str().c_str());
closeWhenDone();
} else if (path == "/test_close") {
string contentStr(BODY1);
stringstream d;
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
d << "Connection: close\r\n";
d << "\r\n"; // final CRLF to terminate the headers
d << contentStr;
push(d.str().c_str());
closeWhenDone();
} else {
sendErrorResponse(404, true, "");
}
}
void sendBody2()
{
stringstream d;
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
d << "Content-Length:" << body2Size << "\r\n";
d << "\r\n"; // final CRLF to terminate the headers
push(d.str().c_str());
bufferSend(body2, body2Size);
}
void sendErrorResponse(int code, bool close, string content)
{
cerr << "sending error " << code << " for " << path << endl;
stringstream headerData;
headerData << "HTTP/1.1 " << code << " " << reasonForCode(code) << "\r\n";
headerData << "Content-Length:" << content.size() << "\r\n";
headerData << "\r\n"; // final CRLF to terminate the headers
push(headerData.str().c_str());
push(content.c_str());
if (close) {
closeWhenDone();
}
}
string reasonForCode(int code)
{
switch (code) {
case 200: return "OK";
case 404: return "not found";
default: return "unknown code";
}
}
State state;
string buffer;
string method;
string path;
string httpVersion;
std::map<string, string> requestHeaders;
};
class TestServer : public NetChannel
{
public:
TestServer()
{
open();
bind(NULL, 2000); // localhost, any port
listen(5);
}
virtual ~TestServer()
{
}
virtual bool writable (void) { return false ; }
virtual void handleAccept (void)
{
simgear::IPAddress addr ;
int handle = accept ( &addr ) ;
//cout << "did accept from " << addr.getHost() << ":" << addr.getPort() << endl;
TestServerChannel* chan = new TestServerChannel();
chan->setHandle(handle);
}
};
void waitForComplete(HTTP::Client* cl, TestRequest* tr)
{
SGTimeStamp start(SGTimeStamp::now());
while (start.elapsedMSec() < 1000) {
cl->update();
if (tr->complete) {
return;
}
SGTimeStamp::sleepForMSec(1);
}
cerr << "timed out" << endl;
}
void waitForFailed(HTTP::Client* cl, TestRequest* tr)
{
SGTimeStamp start(SGTimeStamp::now());
while (start.elapsedMSec() < 1000) {
cl->update();
if (tr->failed) {
return;
}
SGTimeStamp::sleepForMSec(1);
}
cerr << "timed out waiting for failure" << endl;
}
int main(int argc, char* argv[])
{
TestServer s;
HTTP::Client cl;
// test URL parsing
TestRequest* tr1 = new TestRequest("http://localhost.woo.zar:2000/test1?foo=bar");
COMPARE(tr1->scheme(), "http");
COMPARE(tr1->hostAndPort(), "localhost.woo.zar:2000");
COMPARE(tr1->host(), "localhost.woo.zar");
COMPARE(tr1->port(), 2000);
COMPARE(tr1->path(), "/test1");
TestRequest* tr2 = new TestRequest("http://192.168.1.1/test1/dir/thing/file.png");
COMPARE(tr2->scheme(), "http");
COMPARE(tr2->hostAndPort(), "192.168.1.1");
COMPARE(tr2->host(), "192.168.1.1");
COMPARE(tr2->port(), 80);
COMPARE(tr2->path(), "/test1/dir/thing/file.png");
// basic get request
{
TestRequest* tr = new TestRequest("http://localhost:2000/test1");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForComplete(&cl, tr);
COMPARE(tr->responseCode(), 200);
COMPARE(tr->responseReason(), string("OK"));
COMPARE(tr->responseLength(), strlen(BODY1));
COMPARE(tr->responseBytesReceived(), strlen(BODY1));
COMPARE(tr->bodyData, string(BODY1));
}
{
TestRequest* tr = new TestRequest("http://localhost:2000/test_headers");
HTTP::Request_ptr own(tr);
tr->sendHeaders["X-Foo"] = "Bar";
tr->sendHeaders["X-AnotherHeader"] = "A longer value";
cl.makeRequest(tr);
waitForComplete(&cl, tr);
COMPARE(tr->responseCode(), 200);
COMPARE(tr->responseReason(), string("OK"));
COMPARE(tr->responseLength(), strlen(BODY1));
COMPARE(tr->responseBytesReceived(), strlen(BODY1));
COMPARE(tr->bodyData, string(BODY1));
}
// larger get request
for (unsigned int i=0; i<body2Size; ++i) {
body2[i] = (i << 4) | (i >> 2);
}
{
TestRequest* tr = new TestRequest("http://localhost:2000/test2");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForComplete(&cl, tr);
COMPARE(tr->responseCode(), 200);
COMPARE(tr->responseBytesReceived(), body2Size);
COMPARE(tr->bodyData, string(body2, body2Size));
}
{
TestRequest* tr = new TestRequest("http://localhost:2000/testchunked");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForComplete(&cl, tr);
COMPARE(tr->responseCode(), 200);
COMPARE(tr->responseReason(), string("OK"));
COMPARE(tr->responseBytesReceived(), 30);
COMPARE(tr->bodyData, "ABCDEFGHABCDEFABCDSTUVABCDSTUV");
// check trailers made it too
COMPARE(tr->headers["x-foobar"], string("wibble"));
}
// test 404
{
TestRequest* tr = new TestRequest("http://localhost:2000/not-found");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForComplete(&cl, tr);
COMPARE(tr->responseCode(), 404);
COMPARE(tr->responseReason(), string("not found"));
COMPARE(tr->responseLength(), 0);
}
cout << "done1" << endl;
// test HTTP/1.0
{
TestRequest* tr = new TestRequest("http://localhost:2000/test_1_0");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForComplete(&cl, tr);
COMPARE(tr->responseCode(), 200);
COMPARE(tr->responseLength(), strlen(BODY1));
COMPARE(tr->bodyData, string(BODY1));
}
cout << "done2" << endl;
// test HTTP/1.1 Connection::close
{
TestRequest* tr = new TestRequest("http://localhost:2000/test_close");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForComplete(&cl, tr);
COMPARE(tr->responseCode(), 200);
COMPARE(tr->responseLength(), strlen(BODY1));
COMPARE(tr->bodyData, string(BODY1));
}
cout << "done3" << endl;
// test connectToHost failure
/*
{
TestRequest* tr = new TestRequest("http://not.found/something");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForFailed(tr);
COMPARE(tr->responseCode(), -1);
}
*/
// test proxy
{
cl.setProxy("localhost", 2000);
TestRequest* tr = new TestRequest("http://www.google.com/test2");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForComplete(&cl, tr);
COMPARE(tr->responseCode(), 200);
COMPARE(tr->responseLength(), body2Size);
COMPARE(tr->bodyData, string(body2, body2Size));
}
{
cl.setProxy("localhost", 2000, "ABCDEF");
TestRequest* tr = new TestRequest("http://www.google.com/test3");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForComplete(&cl, tr);
COMPARE(tr->responseCode(), 200);
COMPARE(tr->responseBytesReceived(), body2Size);
COMPARE(tr->bodyData, string(body2, body2Size));
}
// pipelining
{
cl.setProxy("", 80);
TestRequest* tr = new TestRequest("http://localhost:2000/test1");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
TestRequest* tr2 = new TestRequest("http://localhost:2000/test1");
HTTP::Request_ptr own2(tr2);
cl.makeRequest(tr2);
TestRequest* tr3 = new TestRequest("http://localhost:2000/test1");
HTTP::Request_ptr own3(tr3);
cl.makeRequest(tr3);
waitForComplete(&cl, tr3);
VERIFY(tr->complete);
VERIFY(tr2->complete);
COMPARE(tr->bodyData, string(BODY1));
COMPARE(tr2->bodyData, string(BODY1));
COMPARE(tr3->bodyData, string(BODY1));
}
// multiple requests with an HTTP 1.0 server
{
cout << "http 1.0 multiple requests" << endl;
cl.setProxy("", 80);
TestRequest* tr = new TestRequest("http://localhost:2000/test_1_0/A");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
TestRequest* tr2 = new TestRequest("http://localhost:2000/test_1_0/B");
HTTP::Request_ptr own2(tr2);
cl.makeRequest(tr2);
TestRequest* tr3 = new TestRequest("http://localhost:2000/test_1_0/C");
HTTP::Request_ptr own3(tr3);
cl.makeRequest(tr3);
waitForComplete(&cl, tr3);
VERIFY(tr->complete);
VERIFY(tr2->complete);
COMPARE(tr->bodyData, string(BODY1));
COMPARE(tr2->bodyData, string(BODY1));
COMPARE(tr3->bodyData, string(BODY1));
}
cout << "all tests passed ok" << endl;
return EXIT_SUCCESS;
}

261
simgear/io/test_binobj.cxx Normal file
View File

@@ -0,0 +1,261 @@
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#ifdef _MSC_VER
# define random rand
#endif
#include <simgear/misc/sg_dir.hxx>
#include "sg_binobj.hxx"
using std::cout;
using std::cerr;
using std::endl;
using std::string;
#define COMPARE(a, b) \
if ((a) != (b)) { \
cerr << "failed:" << #a << " != " << #b << endl; \
cerr << "\tgot:" << a << endl; \
exit(1); \
}
#define VERIFY(a) \
if (!(a)) { \
cerr << "failed:" << #a << endl; \
exit(1); \
}
void generate_points(int count, std::vector<SGVec3d>& vec)
{
for (int i=0; i<count; ++i) {
vec.push_back(SGVec3d(i * 0.5, i * i, i * 4));
}
}
void generate_normals(int count, std::vector<SGVec3f>& vec)
{
for (int i=0; i<count; ++i) {
vec.push_back(normalize(SGVec3f(i, i * 2, i * -4)));
}
}
void generate_tcs(int count, std::vector<SGVec2f>& vec)
{
for (int i=0; i<count; ++i) {
vec.push_back(SGVec2f(1.0 / i, 16.0 / i));
}
}
void test_empty()
{
SGBinObject empty;
SGPath path(simgear::Dir::current().file("empty.btg.gz"));
bool ok = empty.write_bin_file(path);
VERIFY( ok );
SGBinObject rd;
ok = rd.read_bin(path.str()) ;
VERIFY( ok);
COMPARE(rd.get_wgs84_nodes().size(), 0);
VERIFY(rd.get_pt_materials().empty());
}
void comparePoints(const SGBinObject& rd, const std::vector<SGVec3d>& b)
{
for (unsigned int i=1; i<b.size(); i += 10) {
SGVec3d pos = rd.get_wgs84_nodes()[i];
pos += rd.get_gbs_center();
if (!equivalent(pos, b[i], 0.1)) {
cout << "i=" << i << endl;
cout << b[i] << endl;
cout << pos << endl;
}
VERIFY(equivalent(pos, b[i], 0.1));
}
}
void compareTexCoords(const SGBinObject& rd, const std::vector<SGVec2f>& b)
{
for (unsigned int i=1; i<b.size(); i += 10) {
SGVec2f pos = rd.get_texcoords()[i];
VERIFY(equivalent(pos, b[i], 0.001f));
}
}
int_list make_tri(int maxIndex)
{
int_list r;
r.push_back(random() % maxIndex);
r.push_back(random() % maxIndex);
r.push_back(random() % maxIndex);
return r;
}
void compareTris(const SGBinObject& a, const SGBinObject& b)
{
unsigned int count = a.get_tri_materials().size();
for (unsigned int i=0; i<count; i += 39) {
const int_list& vA(a.get_tris_v()[i]);
const int_list& vB(b.get_tris_v()[i]);
VERIFY(vA == vB);
COMPARE(a.get_tri_materials()[i], b.get_tri_materials()[i]);
const int_list& tA(a.get_tris_tc()[i]);
const int_list& tB(b.get_tris_tc()[i]);
VERIFY(tA == tB);
}
}
void generate_tris(SGBinObject& b, int count)
{
group_list v, n, tc;
string_list materials;
int maxVertices = b.get_wgs84_nodes().size();
int maxNormals = b.get_normals().size();
int maxTCs = b.get_texcoords().size();
for (int t=0; t<count; ++t) {
v.push_back(make_tri(maxVertices));
n.push_back(make_tri(maxNormals));
tc.push_back(make_tri(maxTCs));
materials.push_back("material1");
}
b.set_tris_v(v);
b.set_tris_n(n);
b.set_tris_tc(tc);
b.set_tri_materials(materials);
}
void test_basic()
{
SGBinObject basic;
SGPath path(simgear::Dir::current().file("basic.btg.gz"));
SGVec3d center(1, 2, 3);
basic.set_gbs_center(center);
basic.set_gbs_radius(12345);
std::vector<SGVec3d> points;
generate_points(1024, points);
std::vector<SGVec3f> normals;
generate_normals(1024, normals);
std::vector<SGVec2f> texCoords;
generate_tcs(10000, texCoords);
basic.set_wgs84_nodes(points);
basic.set_normals(normals);
basic.set_texcoords(texCoords);
bool ok = basic.write_bin_file(path);
VERIFY( ok );
SGBinObject rd;
ok = rd.read_bin(path.str()) ;
VERIFY( ok);
COMPARE(rd.get_version(), 7); // should be version 7 since indices are < 2^16
COMPARE(rd.get_gbs_center(), center);
COMPARE(rd.get_gbs_radius(), 12345);
COMPARE(rd.get_wgs84_nodes().size(), points.size());
comparePoints(rd, points);
compareTexCoords(rd, texCoords);
}
void test_many_tcs()
{
SGBinObject basic;
SGPath path(simgear::Dir::current().file("many_tex.btg.gz"));
SGVec3d center(1, 2, 3);
basic.set_gbs_center(center);
basic.set_gbs_radius(12345);
std::vector<SGVec3d> points;
generate_points(10000, points);
std::vector<SGVec3f> normals;
generate_normals(1024, normals);
std::vector<SGVec2f> texCoords;
generate_tcs(100000, texCoords);
basic.set_wgs84_nodes(points);
basic.set_normals(normals);
basic.set_texcoords(texCoords);
generate_tris(basic, 20000);
bool ok = basic.write_bin_file(path);
VERIFY( ok );
SGBinObject rd;
ok = rd.read_bin(path.str()) ;
VERIFY( ok);
COMPARE(rd.get_version(), 10); // should be version 10 since indices are > 2^16
COMPARE(rd.get_wgs84_nodes().size(), points.size());
COMPARE(rd.get_texcoords().size(), texCoords.size());
comparePoints(rd, points);
compareTexCoords(rd, texCoords);
compareTris(basic, rd);
}
void test_big()
{
SGBinObject basic;
SGPath path(simgear::Dir::current().file("big.btg.gz"));
SGVec3d center(1, 2, 3);
basic.set_gbs_center(center);
basic.set_gbs_radius(12345);
std::vector<SGVec3d> points;
generate_points(200000, points);
std::vector<SGVec3f> normals;
generate_normals(1024, normals);
std::vector<SGVec2f> texCoords;
generate_tcs(300000, texCoords);
basic.set_wgs84_nodes(points);
basic.set_normals(normals);
basic.set_texcoords(texCoords);
generate_tris(basic, 200000);
bool ok = basic.write_bin_file(path);
VERIFY( ok );
SGBinObject rd;
ok = rd.read_bin(path.str()) ;
VERIFY( ok);
COMPARE(rd.get_version(), 10); // should be version 10 since indices are > 2^16
COMPARE(rd.get_wgs84_nodes().size(), points.size());
COMPARE(rd.get_texcoords().size(), texCoords.size());
comparePoints(rd, points);
compareTexCoords(rd, texCoords);
compareTris(basic, rd);
}
int main(int argc, char* argv[])
{
test_empty();
test_basic();
test_many_tcs();
test_big();
return 0;
}

View File

@@ -4,4 +4,15 @@ include (SimGearComponent)
set(HEADERS magvar.hxx coremag.hxx)
set(SOURCES magvar.cxx coremag.cxx)
simgear_component(magvar magvar "${SOURCES}" "${HEADERS}")
simgear_component(magvar magvar "${SOURCES}" "${HEADERS}")
if(ENABLE_TESTS)
add_executable(test_magvar testmagvar.cxx )
if (SIMGEAR_SHARED)
target_link_libraries(test_magvar SimGearCore)
else()
target_link_libraries(test_magvar sgmagvar)
endif()
endif(ENABLE_TESTS)

View File

@@ -1,17 +0,0 @@
includedir = @includedir@/magvar
lib_LIBRARIES = libsgmagvar.a
include_HEADERS = magvar.hxx coremag.hxx
libsgmagvar_a_SOURCES = coremag.cxx magvar.cxx
noinst_PROGRAMS = testmagvar
testmagvar_SOURCES = testmagvar.cxx
testmagvar_LDADD = \
libsgmagvar.a \
$(base_LIBS)
INCLUDES = -I$(top_srcdir)

View File

@@ -16,7 +16,7 @@ int main(int argc, char *argv[])
/* output N, E, down components of B (nTesla)
dip angle (down positive), variation (E positive) */
double lat_deg,lon_deg,h,var;
int model,yy,mm,dd;
int /* model,*/yy,mm,dd;
double field[6];
if ((argc != 8) && (argc !=7)) {
@@ -36,9 +36,9 @@ mm= (int)strtol(argv[4],NULL,10);
dd= (int)strtol(argv[5],NULL,10);
yy= (int)strtol(argv[6],NULL,10);
if (argc == 8){
model= (int)strtol(argv[7],NULL,10);
// model= (int)strtol(argv[7],NULL,10);
}else{
model=7;
// model=7;
}

View File

@@ -28,7 +28,6 @@ set(HEADERS
beziercurve.hxx
interpolater.hxx
leastsqs.hxx
project.hxx
sg_geodesy.hxx
sg_types.hxx
sg_random.h
@@ -39,9 +38,25 @@ set(SOURCES
SGGeodesy.cxx
interpolater.cxx
leastsqs.cxx
project.cxx
sg_random.c
)
simgear_component(math math "${SOURCES}" "${HEADERS}")
if(ENABLE_TESTS)
if (SIMGEAR_SHARED)
set(TEST_LIBS SimGearCore)
else()
set(TEST_LIBS sgmath sgstructure sgdebug)
endif()
add_executable(math_test SGMathTest.cxx)
target_link_libraries(math_test ${TEST_LIBS})
add_test(math ${EXECUTABLE_OUTPUT_PATH}/math_test)
add_executable(geometry_test SGGeometryTest.cxx)
target_link_libraries(geometry_test ${TEST_LIBS})
add_test(geometry ${EXECUTABLE_OUTPUT_PATH}/geometry_test)
endif(ENABLE_TESTS)

View File

@@ -1,64 +0,0 @@
includedir = @includedir@/math
check_PROGRAMS = SGMathTest SGGeometryTest
TESTS = $(check_PROGRAMS)
SGMathTest_SOURCES = SGMathTest.cxx
SGMathTest_LDADD = \
libsgmath.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/structure/libsgstructure.a \
$(base_LIBS)
SGGeometryTest_SOURCES = SGGeometryTest.cxx
SGGeometryTest_LDADD = \
libsgmath.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/structure/libsgstructure.a \
$(base_LIBS)
lib_LIBRARIES = libsgmath.a
include_HEADERS = \
interpolater.hxx \
leastsqs.hxx \
sg_geodesy.hxx \
sg_random.h \
sg_types.hxx \
Math.hxx \
SGBox.hxx \
SGCMath.hxx \
SGGeoc.hxx \
SGGeod.hxx \
SGGeodesy.hxx \
SGGeometry.hxx \
SGGeometryFwd.hxx \
SGIntersect.hxx \
SGLimits.hxx \
SGLineSegment.hxx \
SGMatrix.hxx \
SGMath.hxx \
SGMathFwd.hxx \
SGMisc.hxx \
SGPlane.hxx \
SGQuat.hxx \
SGRay.hxx \
SGSphere.hxx \
SGTriangle.hxx \
SGVec2.hxx \
SGVec3.hxx \
SGVec4.hxx \
beziercurve.hxx \
project.hxx
libsgmath_a_SOURCES = \
interpolater.cxx \
leastsqs.cxx \
sg_random.c \
SGGeod.cxx \
SGGeodesy.cxx \
project.cxx
INCLUDES = -I$(top_srcdir)

View File

@@ -97,7 +97,7 @@ public:
return (_max[0] - _min[0])*(_max[1] - _min[1])*(_max[2] - _min[2]);
}
const bool empty() const
bool empty() const
{ return !valid(); }
bool valid() const

View File

@@ -15,6 +15,10 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include "SGMath.hxx"
#ifndef NO_OPENSCENEGRAPH_INTERFACE

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