robobuilder 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +1 -0
- data/COPYING +680 -0
- data/README.md +44 -0
- data/Rakefile +176 -0
- data/ext/robobuilder.cc +341 -0
- data/lib/robobuilder_ext.rb +378 -0
- metadata +70 -0
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
robobuilder
|
2
|
+
======
|
3
|
+
|
4
|
+
**Author**: Jan Wedekind
|
5
|
+
**Copyright**: 2011
|
6
|
+
**License**: GPL
|
7
|
+
|
8
|
+
Synopsis
|
9
|
+
--------
|
10
|
+
|
11
|
+
This Ruby extension defines the class {Robobuilder} for communicating with a Robobuilder robot via serial port or Bluetooth serial.
|
12
|
+
|
13
|
+
Installation
|
14
|
+
------------
|
15
|
+
|
16
|
+
To install this Ruby extension, use the following command:
|
17
|
+
|
18
|
+
$ sudo gem install robobuilder
|
19
|
+
|
20
|
+
Alternatively you can build and install the Ruby extension from source as follows:
|
21
|
+
|
22
|
+
$ rake
|
23
|
+
$ sudo rake install
|
24
|
+
|
25
|
+
Usage
|
26
|
+
-----
|
27
|
+
|
28
|
+
Simply run Interactive Ruby:
|
29
|
+
|
30
|
+
$ irb
|
31
|
+
|
32
|
+
You can load the Ruby extension like this:
|
33
|
+
|
34
|
+
require 'rubygems'
|
35
|
+
require 'robobuilder'
|
36
|
+
|
37
|
+
See documentation of {Robobuilder} on how to use this Ruby extension.
|
38
|
+
|
39
|
+
External Links
|
40
|
+
--------------
|
41
|
+
|
42
|
+
* [Robobuilder](http://www.robobuilder.net/eng/)
|
43
|
+
* [Page at Robosavvy](http://robosavvy.com/site/index.php?task=view&Itemid=128)
|
44
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'date'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/loaders/makefile'
|
7
|
+
require 'rbconfig'
|
8
|
+
|
9
|
+
PKG_NAME = 'robobuilder'
|
10
|
+
PKG_VERSION = '0.3.0'
|
11
|
+
CFG = RbConfig::CONFIG
|
12
|
+
CXX = ENV[ 'CXX' ] || 'g++'
|
13
|
+
RB_FILES = FileList[ 'lib/**/*.rb' ]
|
14
|
+
CC_FILES = FileList[ 'ext/*.cc' ]
|
15
|
+
HH_FILES = FileList[ 'ext/*.hh' ] + FileList[ 'ext/*.tcc' ]
|
16
|
+
TC_FILES = FileList[ 'test/tc_*.rb' ]
|
17
|
+
TS_FILES = FileList[ 'test/ts_*.rb' ]
|
18
|
+
SO_FILE = "ext/#{PKG_NAME.tr '\-', '_'}.#{CFG[ 'DLEXT' ]}"
|
19
|
+
PKG_FILES = [ 'Rakefile', 'README.md', 'COPYING', '.document' ] +
|
20
|
+
RB_FILES + CC_FILES + HH_FILES + TS_FILES + TC_FILES
|
21
|
+
BIN_FILES = [ 'README.md', 'COPYING', '.document', SO_FILE ] +
|
22
|
+
RB_FILES + TS_FILES + TC_FILES
|
23
|
+
SUMMARY = %q{Ruby extension for controlling a Robobuilder}
|
24
|
+
DESCRIPTION = %q{This Ruby extension defines the Robobuilder class for communicating a Robobuilder via the serial port or a Bluetooth serial connection.}
|
25
|
+
AUTHOR = %q{Jan Wedekind}
|
26
|
+
EMAIL = %q{jan@wedesoft.de}
|
27
|
+
HOMEPAGE = %q{http://wedesoft.github.com/robobuilder/}
|
28
|
+
|
29
|
+
OBJ = CC_FILES.ext 'o'
|
30
|
+
$CXXFLAGS = "-DNDEBUG #{CFG[ 'CPPFLAGS' ]} #{CFG[ 'CFLAGS' ]}"
|
31
|
+
if CFG[ 'rubyhdrdir' ]
|
32
|
+
$CXXFLAGS = "#{$CXXFLAGS} -I#{CFG[ 'rubyhdrdir' ]} " +
|
33
|
+
"-I#{CFG[ 'rubyhdrdir' ]}/#{CFG[ 'arch' ]}"
|
34
|
+
else
|
35
|
+
$CXXFLAGS = "#{$CXXFLAGS} -I#{CFG[ 'archdir' ]}"
|
36
|
+
end
|
37
|
+
$LIBRUBYARG = "-L#{CFG[ 'libdir' ]} #{CFG[ 'LIBRUBYARG' ]} #{CFG[ 'LDFLAGS' ]} " +
|
38
|
+
"#{CFG[ 'SOLIBS' ]} #{CFG[ 'DLDLIBS' ]}"
|
39
|
+
$SITELIBDIR = CFG[ 'sitelibdir' ]
|
40
|
+
$SITEARCHDIR = CFG[ 'sitearchdir' ]
|
41
|
+
$LDSHARED = CFG[ 'LDSHARED' ][ CFG[ 'LDSHARED' ].index( ' ' ) .. -1 ]
|
42
|
+
|
43
|
+
task :default => :all
|
44
|
+
|
45
|
+
desc 'Compile Ruby extension (default)'
|
46
|
+
task :all => [ SO_FILE ]
|
47
|
+
|
48
|
+
file SO_FILE => OBJ do |t|
|
49
|
+
sh "#{CXX} #{$LDSHARED} -o #{t.name} #{OBJ} #{$LIBRUBYARG}"
|
50
|
+
end
|
51
|
+
|
52
|
+
task :test => [ SO_FILE ]
|
53
|
+
|
54
|
+
desc 'Install Ruby extension'
|
55
|
+
task :install => :all do
|
56
|
+
verbose true do
|
57
|
+
for f in RB_FILES do
|
58
|
+
FileUtils.mkdir_p "#{$SITELIBDIR}/#{File.dirname f.gsub( /^lib\//, '' )}"
|
59
|
+
FileUtils.cp_r f, "#{$SITELIBDIR}/#{f.gsub( /^lib\//, '' )}"
|
60
|
+
end
|
61
|
+
FileUtils.mkdir_p $SITEARCHDIR
|
62
|
+
FileUtils.cp SO_FILE, "#{$SITEARCHDIR}/#{File.basename SO_FILE}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
desc 'Uninstall Ruby extension'
|
67
|
+
task :uninstall do
|
68
|
+
verbose true do
|
69
|
+
for f in RB_FILES do
|
70
|
+
FileUtils.rm_f "#{$SITELIBDIR}/#{f.gsub /^lib\//, ''}"
|
71
|
+
end
|
72
|
+
FileUtils.rm_f "#{$SITEARCHDIR}/#{File.basename SO_FILE}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
Rake::TestTask.new do |t|
|
77
|
+
t.libs << 'ext'
|
78
|
+
t.test_files = TC_FILES
|
79
|
+
end
|
80
|
+
|
81
|
+
begin
|
82
|
+
require 'yard'
|
83
|
+
YARD::Rake::YardocTask.new :yard do |y|
|
84
|
+
y.files << RB_FILES
|
85
|
+
end
|
86
|
+
rescue LoadError
|
87
|
+
STDERR.puts 'Please install \'yard\' if you want to generate documentation'
|
88
|
+
end
|
89
|
+
|
90
|
+
Rake::PackageTask.new PKG_NAME, PKG_VERSION do |p|
|
91
|
+
p.need_tar = true
|
92
|
+
p.package_files = PKG_FILES
|
93
|
+
end
|
94
|
+
|
95
|
+
begin
|
96
|
+
require 'rubygems'
|
97
|
+
require 'rubygems/builder'
|
98
|
+
$SPEC = Gem::Specification.new do |s|
|
99
|
+
s.name = PKG_NAME
|
100
|
+
s.version = PKG_VERSION
|
101
|
+
s.platform = Gem::Platform::RUBY
|
102
|
+
s.date = Date.today.to_s
|
103
|
+
s.summary = SUMMARY
|
104
|
+
s.description = DESCRIPTION
|
105
|
+
s.author = AUTHOR
|
106
|
+
s.email = EMAIL
|
107
|
+
s.homepage = HOMEPAGE
|
108
|
+
s.files = PKG_FILES
|
109
|
+
s.test_files = TC_FILES
|
110
|
+
s.require_paths = [ 'lib', 'ext' ]
|
111
|
+
# s.rubyforge_project = %q{}
|
112
|
+
s.extensions = %w{Rakefile}
|
113
|
+
s.has_rdoc = 'yard'
|
114
|
+
s.extra_rdoc_files = []
|
115
|
+
s.add_development_dependency %q{rake}
|
116
|
+
end
|
117
|
+
GEM_SOURCE = "#{PKG_NAME}-#{PKG_VERSION}.gem"
|
118
|
+
$BINSPEC = Gem::Specification.new do |s|
|
119
|
+
s.name = PKG_NAME
|
120
|
+
s.version = PKG_VERSION
|
121
|
+
s.platform = Gem::Platform::CURRENT
|
122
|
+
s.date = Date.today.to_s
|
123
|
+
s.summary = SUMMARY
|
124
|
+
s.description = DESCRIPTION
|
125
|
+
s.author = AUTHOR
|
126
|
+
s.email = EMAIL
|
127
|
+
s.homepage = HOMEPAGE
|
128
|
+
s.files = BIN_FILES
|
129
|
+
s.test_files = TC_FILES
|
130
|
+
s.require_paths = [ 'lib', 'ext' ]
|
131
|
+
# s.rubyforge_project = %q{}
|
132
|
+
s.has_rdoc = 'yard'
|
133
|
+
s.extra_rdoc_files = []
|
134
|
+
end
|
135
|
+
GEM_BINARY = "#{PKG_NAME}-#{PKG_VERSION}-#{$BINSPEC.platform}.gem"
|
136
|
+
desc "Build the gem file #{GEM_SOURCE}"
|
137
|
+
task :gem => [ "pkg/#{GEM_SOURCE}" ]
|
138
|
+
file "pkg/#{GEM_SOURCE}" => [ 'pkg' ] + $SPEC.files do
|
139
|
+
when_writing 'Creating GEM' do
|
140
|
+
Gem::Builder.new( $SPEC ).build
|
141
|
+
verbose true do
|
142
|
+
FileUtils.mv GEM_SOURCE, "pkg/#{GEM_SOURCE}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
desc "Build the gem file #{GEM_BINARY}"
|
147
|
+
task :gem_binary => [ "pkg/#{GEM_BINARY}" ]
|
148
|
+
file "pkg/#{GEM_BINARY}" => [ 'pkg' ] + $BINSPEC.files do
|
149
|
+
when_writing 'Creating binary GEM' do
|
150
|
+
Gem::Builder.new( $BINSPEC ).build
|
151
|
+
verbose true do
|
152
|
+
FileUtils.mv GEM_BINARY, "pkg/#{GEM_BINARY}"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
rescue LoadError
|
157
|
+
STDERR.puts 'Please install \'rubygems\' if you want to create Gem packages'
|
158
|
+
end
|
159
|
+
|
160
|
+
rule '.o' => '.cc' do |t|
|
161
|
+
sh "#{CXX} #{$CXXFLAGS} -c -o #{t.name} #{t.source}"
|
162
|
+
end
|
163
|
+
|
164
|
+
file ".depends.mf" do |t|
|
165
|
+
sh "g++ -MM #{CC_FILES.join ' '} | " +
|
166
|
+
"sed -e :a -e N -e 's/\\n/\\$/g' -e ta | " +
|
167
|
+
"sed -e 's/ *\\\\\\$ */ /g' -e 's/\\$/\\n/g' | sed -e 's/^/ext\\//' > #{t.name}"
|
168
|
+
end
|
169
|
+
CC_FILES.each do |t|
|
170
|
+
file t.ext(".o") => t
|
171
|
+
end
|
172
|
+
import ".depends.mf"
|
173
|
+
|
174
|
+
CLEAN.include 'ext/*.o'
|
175
|
+
CLOBBER.include SO_FILE, 'doc', '.yardoc', '.depends.mf'
|
176
|
+
|
data/ext/robobuilder.cc
ADDED
@@ -0,0 +1,341 @@
|
|
1
|
+
/* Robobuilder - Ruby-extension to control Robobuilder
|
2
|
+
Copyright (C) 2009 Jan Wedekind
|
3
|
+
|
4
|
+
This program is free software: you can redistribute it and/or modify
|
5
|
+
it under the terms of the GNU General Public License as published by
|
6
|
+
the Free Software Foundation, either version 3 of the License, or
|
7
|
+
(at your option) any later version.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it will be useful,
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
GNU General Public License for more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License
|
15
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
16
|
+
#ifndef NDEBUG
|
17
|
+
#include <iostream>
|
18
|
+
#endif
|
19
|
+
#include <boost/shared_array.hpp>
|
20
|
+
#include <boost/smart_ptr.hpp>
|
21
|
+
#include <ruby.h>
|
22
|
+
#include <errno.h>
|
23
|
+
#include <sys/stat.h>
|
24
|
+
#include <sys/types.h>
|
25
|
+
#include <termios.h>
|
26
|
+
#include <fcntl.h>
|
27
|
+
#include <string>
|
28
|
+
#include <sstream>
|
29
|
+
|
30
|
+
class Error: public std::exception
|
31
|
+
{
|
32
|
+
public:
|
33
|
+
Error(void) {}
|
34
|
+
Error( Error &e ): std::exception( e )
|
35
|
+
{ m_message << e.m_message.str(); }
|
36
|
+
virtual ~Error(void) throw() {}
|
37
|
+
template< typename T >
|
38
|
+
std::ostream &operator<<( const T &t )
|
39
|
+
{ m_message << t; return m_message; }
|
40
|
+
std::ostream &operator<<( std::ostream& (*__pf)( std::ostream&) )
|
41
|
+
{ (*__pf)( m_message ); return m_message; }
|
42
|
+
virtual const char* what(void) const throw() {
|
43
|
+
temp = m_message.str();
|
44
|
+
return temp.c_str();
|
45
|
+
return NULL;
|
46
|
+
}
|
47
|
+
protected:
|
48
|
+
std::ostringstream m_message;
|
49
|
+
static std::string temp;
|
50
|
+
};
|
51
|
+
|
52
|
+
class Robobuilder
|
53
|
+
{
|
54
|
+
public:
|
55
|
+
Robobuilder( const std::string &device = "/dev/ttyS0" ) throw (Error);
|
56
|
+
virtual ~Robobuilder(void);
|
57
|
+
std::string inspect(void) const;
|
58
|
+
void close(void);
|
59
|
+
int write( const char *data, int length ) throw (Error);
|
60
|
+
std::string read( int num ) throw (Error);
|
61
|
+
void flush(void) throw (Error);
|
62
|
+
int timeout(void);
|
63
|
+
void setTimeout( int value ) throw (Error);
|
64
|
+
static VALUE cRubyClass;
|
65
|
+
static VALUE registerRubyClass(void);
|
66
|
+
static void deleteRubyObject( void *ptr );
|
67
|
+
static VALUE wrapNew( VALUE rbClass, VALUE rbDevice );
|
68
|
+
static VALUE wrapInspect( VALUE rbSelf );
|
69
|
+
static VALUE wrapClose( VALUE rbSelf );
|
70
|
+
static VALUE wrapWrite( VALUE rbSelf, VALUE rbData );
|
71
|
+
static VALUE wrapRead( VALUE rbSelf, VALUE rbNum );
|
72
|
+
static VALUE wrapFlush( VALUE rbSelf );
|
73
|
+
static VALUE wrapTimeout( VALUE rbSelf );
|
74
|
+
static VALUE wrapSetTimeout( VALUE rbSelf, VALUE rbValue );
|
75
|
+
protected:
|
76
|
+
std::string m_device;
|
77
|
+
int m_fd;
|
78
|
+
struct termios m_tio;
|
79
|
+
};
|
80
|
+
|
81
|
+
typedef boost::shared_ptr< Robobuilder > RobobuilderPtr;
|
82
|
+
|
83
|
+
using namespace boost;
|
84
|
+
using namespace std;
|
85
|
+
|
86
|
+
string Error::temp;
|
87
|
+
|
88
|
+
#define ERRORMACRO( condition, class, params, message ) \
|
89
|
+
if ( !( condition ) ) { \
|
90
|
+
class _e params; \
|
91
|
+
_e << message; \
|
92
|
+
throw _e; \
|
93
|
+
};
|
94
|
+
|
95
|
+
VALUE Robobuilder::cRubyClass = Qnil;
|
96
|
+
|
97
|
+
#undef SW_FLOW_CONTROL
|
98
|
+
#undef HW_FLOW_CONTROL
|
99
|
+
|
100
|
+
Robobuilder::Robobuilder( const string &device ) throw (Error):
|
101
|
+
m_device(device), m_fd(-1)
|
102
|
+
{
|
103
|
+
try {
|
104
|
+
m_fd = open( device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY );
|
105
|
+
ERRORMACRO( m_fd != -1, Error, ,
|
106
|
+
"Error opening serial port: " << strerror( errno ) );
|
107
|
+
int flags = fcntl( m_fd, F_GETFL, 0 );
|
108
|
+
ERRORMACRO( fcntl( m_fd, F_SETFL, flags | O_NONBLOCK ) != -1, Error, ,
|
109
|
+
"Error switching to non-blocking mode: "
|
110
|
+
<< strerror( errno ) );
|
111
|
+
tcflush( m_fd, TCIOFLUSH );
|
112
|
+
bzero( &m_tio, sizeof( m_tio ) );
|
113
|
+
#ifdef SW_FLOW_CONTROL
|
114
|
+
m_tio.c_iflag = IXON |IXOFF;
|
115
|
+
#else
|
116
|
+
m_tio.c_iflag = 0;
|
117
|
+
#endif
|
118
|
+
m_tio.c_oflag = 0;
|
119
|
+
m_tio.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
|
120
|
+
#ifdef HW_FLOW_CONTROL
|
121
|
+
m_tio.c_cflag |= CRTSCTS;
|
122
|
+
#endif
|
123
|
+
m_tio.c_lflag = 0;
|
124
|
+
#ifdef SW_FLOW_CONTROL
|
125
|
+
m_tio.c_cc[ VSTART ] = 0x11;
|
126
|
+
m_tio.c_cc[ VSTOP ] = 0x13;
|
127
|
+
#endif
|
128
|
+
#ifdef HW_FLOW_CONTROL
|
129
|
+
m_tio.c_cc[ VSTART ] = _POSIX_VDISABLE;
|
130
|
+
m_tio.c_cc[ VSTOP ] = _POSIX_VDISABLE;
|
131
|
+
#endif
|
132
|
+
m_tio.c_cc[ VTIME ] = 1;// * 1/10 second
|
133
|
+
m_tio.c_cc[ VMIN ] = 0;// bytes
|
134
|
+
ERRORMACRO( tcsetattr( m_fd, TCSANOW, &m_tio ) != -1, Error, ,
|
135
|
+
"Error configuring serial port: " << strerror( errno ) );
|
136
|
+
ERRORMACRO( fcntl( m_fd, F_SETFL, flags & ~O_NONBLOCK ) != -1, Error, ,
|
137
|
+
"Error switching to blocking mode" );
|
138
|
+
} catch ( Error &e ) {
|
139
|
+
close();
|
140
|
+
throw e;
|
141
|
+
};
|
142
|
+
}
|
143
|
+
|
144
|
+
Robobuilder::~Robobuilder(void)
|
145
|
+
{
|
146
|
+
close();
|
147
|
+
}
|
148
|
+
|
149
|
+
string Robobuilder::inspect(void) const
|
150
|
+
{
|
151
|
+
ostringstream s;
|
152
|
+
s << "Robobuilder( \"" << m_device << "\" )";
|
153
|
+
return s.str();
|
154
|
+
}
|
155
|
+
|
156
|
+
void Robobuilder::close(void)
|
157
|
+
{
|
158
|
+
if ( m_fd != -1 ) {
|
159
|
+
::close( m_fd );
|
160
|
+
m_fd = -1;
|
161
|
+
};
|
162
|
+
}
|
163
|
+
|
164
|
+
int Robobuilder::write( const char *data, int length ) throw (Error)
|
165
|
+
{
|
166
|
+
ERRORMACRO( m_fd != -1, Error, , "Serial connection is closed" );
|
167
|
+
int n = ::write( m_fd, data, length );
|
168
|
+
ERRORMACRO( n != -1, Error, , "Error writing to serial device: "
|
169
|
+
<< strerror( errno ) );
|
170
|
+
return n;
|
171
|
+
}
|
172
|
+
|
173
|
+
void Robobuilder::flush(void) throw (Error)
|
174
|
+
{
|
175
|
+
ERRORMACRO( m_fd != -1, Error, , "Serial connection is closed" );
|
176
|
+
ERRORMACRO( tcflush( m_fd, TCIOFLUSH ) != -1, Error, ,
|
177
|
+
"Error flushing serial I/O: "
|
178
|
+
<< strerror( errno ) );
|
179
|
+
}
|
180
|
+
|
181
|
+
int Robobuilder::timeout(void)
|
182
|
+
{
|
183
|
+
ERRORMACRO( m_fd != -1, Error, , "Serial connection is closed" );
|
184
|
+
int retVal;
|
185
|
+
if ( m_tio.c_cc[ VMIN ] == 0 )
|
186
|
+
retVal = m_tio.c_cc[ VTIME ];
|
187
|
+
else
|
188
|
+
retVal = INT_MAX;
|
189
|
+
return retVal;
|
190
|
+
}
|
191
|
+
|
192
|
+
void Robobuilder::setTimeout( int value ) throw (Error)
|
193
|
+
{
|
194
|
+
ERRORMACRO( m_fd != -1, Error, , "Serial connection is closed" );
|
195
|
+
if ( value == INT_MAX ) {
|
196
|
+
m_tio.c_cc[ VMIN ] = 1;
|
197
|
+
m_tio.c_cc[ VTIME ] = 0;
|
198
|
+
} else {
|
199
|
+
m_tio.c_cc[ VMIN ] = 0;
|
200
|
+
m_tio.c_cc[ VTIME ] = value;
|
201
|
+
};
|
202
|
+
ERRORMACRO( tcsetattr( m_fd, TCSANOW, &m_tio ) != -1, Error, ,
|
203
|
+
"Error configuring serial port: " << strerror( errno ) );
|
204
|
+
}
|
205
|
+
|
206
|
+
std::string Robobuilder::read( int num ) throw (Error)
|
207
|
+
{
|
208
|
+
ERRORMACRO( m_fd != -1, Error, , "Serial connection is closed" );
|
209
|
+
shared_array< char > buffer( new char[ num ] );
|
210
|
+
int n = ::read( m_fd, buffer.get(), num );
|
211
|
+
ERRORMACRO( n != -1, Error, , "Error reading from serial device: "
|
212
|
+
<< strerror( errno ) );
|
213
|
+
return string( buffer.get(), n );
|
214
|
+
}
|
215
|
+
|
216
|
+
VALUE Robobuilder::registerRubyClass(void)
|
217
|
+
{
|
218
|
+
cRubyClass = rb_define_class( "Robobuilder", rb_cObject );
|
219
|
+
rb_define_const( cRubyClass, "INFINITE", INT2NUM(INT_MAX) );
|
220
|
+
rb_define_singleton_method( cRubyClass, "new",
|
221
|
+
RUBY_METHOD_FUNC( wrapNew ), 1 );
|
222
|
+
rb_define_method( cRubyClass, "inspect",
|
223
|
+
RUBY_METHOD_FUNC( wrapInspect ), 0 );
|
224
|
+
rb_define_method( cRubyClass, "close",
|
225
|
+
RUBY_METHOD_FUNC( wrapClose ), 0 );
|
226
|
+
rb_define_method( cRubyClass, "write",
|
227
|
+
RUBY_METHOD_FUNC( wrapWrite ), 1 );
|
228
|
+
rb_define_method( cRubyClass, "read",
|
229
|
+
RUBY_METHOD_FUNC( wrapRead ), 1 );
|
230
|
+
rb_define_method( cRubyClass, "flush",
|
231
|
+
RUBY_METHOD_FUNC( wrapFlush ), 0 );
|
232
|
+
rb_define_method( cRubyClass, "timeout",
|
233
|
+
RUBY_METHOD_FUNC( wrapTimeout ), 0 );
|
234
|
+
rb_define_method( cRubyClass, "timeout=",
|
235
|
+
RUBY_METHOD_FUNC( wrapSetTimeout ), 1 );
|
236
|
+
return cRubyClass;
|
237
|
+
}
|
238
|
+
|
239
|
+
void Robobuilder::deleteRubyObject( void *ptr )
|
240
|
+
{
|
241
|
+
delete (RobobuilderPtr *)ptr;
|
242
|
+
}
|
243
|
+
|
244
|
+
|
245
|
+
VALUE Robobuilder::wrapNew( VALUE rbClass, VALUE rbDevice )
|
246
|
+
{
|
247
|
+
VALUE retVal = Qnil;
|
248
|
+
try {
|
249
|
+
rb_check_type( rbDevice, T_STRING );
|
250
|
+
RobobuilderPtr ptr( new Robobuilder( StringValuePtr( rbDevice ) ) );
|
251
|
+
retVal = Data_Wrap_Struct( rbClass, 0, deleteRubyObject,
|
252
|
+
new RobobuilderPtr( ptr ) );
|
253
|
+
} catch ( std::exception &e ) {
|
254
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
255
|
+
};
|
256
|
+
return retVal;
|
257
|
+
}
|
258
|
+
|
259
|
+
VALUE Robobuilder::wrapInspect( VALUE rbSelf )
|
260
|
+
{
|
261
|
+
RobobuilderPtr *self; Data_Get_Struct( rbSelf, RobobuilderPtr, self );
|
262
|
+
string retVal( (*self)->inspect() );
|
263
|
+
return rb_str_new( retVal.c_str(), retVal.length() );
|
264
|
+
}
|
265
|
+
|
266
|
+
VALUE Robobuilder::wrapClose( VALUE rbSelf )
|
267
|
+
{
|
268
|
+
RobobuilderPtr *self; Data_Get_Struct( rbSelf, RobobuilderPtr, self );
|
269
|
+
(*self)->close();
|
270
|
+
return rbSelf;
|
271
|
+
}
|
272
|
+
|
273
|
+
VALUE Robobuilder::wrapWrite( VALUE rbSelf, VALUE rbData )
|
274
|
+
{
|
275
|
+
VALUE rbRetVal = Qnil;
|
276
|
+
try {
|
277
|
+
RobobuilderPtr *self; Data_Get_Struct( rbSelf, RobobuilderPtr, self );
|
278
|
+
rbRetVal = INT2NUM( (*self)->write( StringValuePtr( rbData ),
|
279
|
+
RSTRING_LEN( rbData ) ) );
|
280
|
+
} catch ( std::exception &e ) {
|
281
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
282
|
+
};
|
283
|
+
return rbRetVal;
|
284
|
+
}
|
285
|
+
|
286
|
+
VALUE Robobuilder::wrapRead( VALUE rbSelf, VALUE rbNum )
|
287
|
+
{
|
288
|
+
VALUE rbRetVal = Qnil;
|
289
|
+
try {
|
290
|
+
RobobuilderPtr *self; Data_Get_Struct( rbSelf, RobobuilderPtr, self );
|
291
|
+
string retVal( (*self)->read( NUM2INT( rbNum ) ) );
|
292
|
+
rbRetVal = rb_str_new( retVal.c_str(), retVal.length() );
|
293
|
+
} catch ( std::exception &e ) {
|
294
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
295
|
+
};
|
296
|
+
return rbRetVal;
|
297
|
+
}
|
298
|
+
|
299
|
+
VALUE Robobuilder::wrapFlush( VALUE rbSelf )
|
300
|
+
{
|
301
|
+
try {
|
302
|
+
RobobuilderPtr *self; Data_Get_Struct( rbSelf, RobobuilderPtr, self );
|
303
|
+
(*self)->flush();
|
304
|
+
} catch ( std::exception &e ) {
|
305
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
306
|
+
};
|
307
|
+
return Qnil;
|
308
|
+
}
|
309
|
+
|
310
|
+
VALUE Robobuilder::wrapTimeout( VALUE rbSelf )
|
311
|
+
{
|
312
|
+
VALUE rbRetVal = Qnil;
|
313
|
+
try {
|
314
|
+
RobobuilderPtr *self; Data_Get_Struct( rbSelf, RobobuilderPtr, self );
|
315
|
+
rbRetVal = INT2NUM( (*self)->timeout() );
|
316
|
+
} catch ( std::exception &e ) {
|
317
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
318
|
+
};
|
319
|
+
return rbRetVal;
|
320
|
+
}
|
321
|
+
|
322
|
+
VALUE Robobuilder::wrapSetTimeout( VALUE rbSelf, VALUE rbValue )
|
323
|
+
{
|
324
|
+
try {
|
325
|
+
RobobuilderPtr *self; Data_Get_Struct( rbSelf, RobobuilderPtr, self );
|
326
|
+
(*self)->setTimeout( NUM2INT( rbValue ) );
|
327
|
+
} catch ( std::exception &e ) {
|
328
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
329
|
+
};
|
330
|
+
return rbValue;
|
331
|
+
}
|
332
|
+
|
333
|
+
extern "C" {
|
334
|
+
|
335
|
+
void Init_robobuilder(void)
|
336
|
+
{
|
337
|
+
Robobuilder::registerRubyClass();
|
338
|
+
rb_require( "robobuilder_ext.rb" );
|
339
|
+
}
|
340
|
+
|
341
|
+
}
|