gosu 1.4.3 → 1.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e577795a3efb0fe3e5a207c81305191da2682fe06de1c58de7bb78fe2351fa54
4
- data.tar.gz: 9ba25d605fab3f9950c9d861fed9eed3f276ce3bb2316276426be2dd6d6a7626
3
+ metadata.gz: 5f95c74e52e49585949f9d7f5c0af95bbd09ddee0738492fe8973a74a2430137
4
+ data.tar.gz: 8fbf827e6d76e83c3e67c51767538ced99470f9d578b324a8f53f045af282927
5
5
  SHA512:
6
- metadata.gz: f24d89b6a88e3d1b5dd8e776bd93e2c5c338ca67b8f2d87b570caded06021ff7369a272e9771c5509dcbc9f0dae1fb303ac6541a6a65a9267393e3138be536d3
7
- data.tar.gz: e2d21e6b09442dcf5041e02725da89566bb151b9a3b9b2edb2f4b95a1efa99c7318dfdd7da6c287bf64f0e824e68f7684153be3c3d5b2b0781369c0c0e14cbd1
6
+ metadata.gz: a75b9ac5f9bf1df4eef813199b05bc99d8645d622cb13c985331a5da70106a83641a064c186aaf0b8755a326832cb8033c77533a5bae51d3443c7dfa30681a7e
7
+ data.tar.gz: 683f1785588d95076f5878b7e8bc778393a60fbc2ed3427684d1e4bd041e600498735a1d66dba5bc4acf756cffa6637bb2ff5e2177a22bd3c9d9a5092a995459
data/ext/gosu/extconf.rb CHANGED
@@ -74,9 +74,12 @@ elsif macos
74
74
  $LDFLAGS << " #{`sdl2-config --static-libs`.chomp} -framework OpenGL -framework Metal"
75
75
  # And yet another hack: `sdl2-config --static-libs` uses `-lSDL2` instead of linking to the static library,
76
76
  # even if it exists. -> Manually replace it. (Ugh!)
77
- %w(/usr/local/lib/libSDL2.a /opt/homebrew/opt/sdl2/lib/libSDL2.a).each do |static_lib|
78
- $LDFLAGS.sub! " -lSDL2 ", " #{static_lib} " if File.exist? static_lib
79
- end
77
+ static_lib = if RbConfig::CONFIG["target_cpu"] == "arm64"
78
+ "/opt/homebrew/opt/sdl2/lib/libSDL2.a"
79
+ else
80
+ "/usr/local/lib/libSDL2.a"
81
+ end
82
+ $LDFLAGS.sub! " -lSDL2 ", " #{static_lib} " if File.exist? static_lib
80
83
 
81
84
  # Disable building of 32-bit slices in Apple's Ruby.
82
85
  # (RbConfig::CONFIG['CXXFLAGS'] on 10.11: -arch x86_64 -arch i386 -g -Os -pipe)
@@ -24,7 +24,7 @@ namespace Gosu
24
24
 
25
25
  /// Manages initialization and shutdown of the input system.
26
26
  /// Only one Input instance can exist per application.
27
- class Input : Noncopyable
27
+ class Input : private Noncopyable
28
28
  {
29
29
  struct Impl;
30
30
  std::unique_ptr<Impl> pimpl;
@@ -107,5 +107,11 @@ namespace Gosu
107
107
  TextInput* text_input() const;
108
108
  //! Sets the currently active TextInput, or resets it to the nullptr.
109
109
  void set_text_input(TextInput* input);
110
+
111
+ /// Returns the contents of the clipboard as plain text, or an empty string if none is available.
112
+ static std::string clipboard();
113
+
114
+ /// Replaces the contents of the clipboard with the given string.
115
+ static void set_clipboard(const std::string& text);
110
116
  };
111
117
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include <Gosu/Fwd.hpp>
4
4
  #include <Gosu/Platform.hpp>
5
+ #include <Gosu/Utility.hpp>
5
6
  #include <memory>
6
7
  #include <string>
7
8
 
@@ -15,11 +16,10 @@ namespace Gosu
15
16
  /// build a text that can be accessed via TextInput::text().
16
17
  /// A TextInput object has no built-in UI. It is up to you to actually draw a text field.
17
18
  /// TextInput only provides a portable base for your own GUI to build upon.
18
- class TextInput
19
+ class TextInput : private Noncopyable
19
20
  {
20
21
  struct Impl;
21
- // Non-movable (const) to avoid dangling references to TextInput instances.
22
- const std::unique_ptr<Impl> m_impl;
22
+ std::unique_ptr<Impl> m_impl;
23
23
 
24
24
  public:
25
25
  TextInput();
@@ -2,6 +2,9 @@
2
2
 
3
3
  namespace Gosu
4
4
  {
5
+ /// Freezes the current thread for the given amount of milliseconds.
6
+ void sleep(unsigned milliseconds);
7
+
5
8
  /// Returns the milliseconds since first calling this function.
6
9
  /// Can wrap after running for a long time.
7
10
  unsigned long milliseconds();
@@ -4,7 +4,7 @@
4
4
 
5
5
  #define GOSU_MAJOR_VERSION 1
6
6
  #define GOSU_MINOR_VERSION 4
7
- #define GOSU_POINT_VERSION 3
7
+ #define GOSU_POINT_VERSION 4
8
8
 
9
9
  namespace Gosu
10
10
  {
@@ -3,6 +3,7 @@
3
3
  #include <Gosu/Fwd.hpp>
4
4
  #include <Gosu/Input.hpp>
5
5
  #include <Gosu/Platform.hpp>
6
+ #include <Gosu/Utility.hpp>
6
7
  #include <memory>
7
8
  #include <string>
8
9
 
@@ -19,10 +20,10 @@ namespace Gosu
19
20
  /// Convenient all-in-one class that serves as the foundation of a standard Gosu application.
20
21
  /// Manages initialization of all of Gosu's core components and provides timing functionality.
21
22
  /// Note that you can only use one instance of this class at the same time.
22
- class Window
23
+ class Window : private Noncopyable
23
24
  {
24
25
  struct Impl;
25
- const std::unique_ptr<Impl> m_impl;
26
+ std::unique_ptr<Impl> m_impl;
26
27
 
27
28
  public:
28
29
  /// Constructs a Window.
data/rdoc/gosu.rb CHANGED
@@ -272,6 +272,7 @@ module Gosu
272
272
  # @option options [bool] :bold (false)
273
273
  # @option options [bool] :italic (false)
274
274
  # @option options [bool] :underline (false)
275
+ # @option options [bool] :retro (false) see Gosu::Image
275
276
  #
276
277
  # @overload initialize(height, options = {})
277
278
  # @overload initialize(window, font_name, height)
@@ -1042,6 +1043,19 @@ module Gosu
1042
1043
  #
1043
1044
  def axis(id); end
1044
1045
 
1046
+ ##
1047
+ # Returns the contents of the clipboard as plain text, or an empty string if none is available.
1048
+ #
1049
+ # @return [String]
1050
+ def clipboard(); end
1051
+
1052
+ ##
1053
+ # Replaces the contents of the clipboard with the given string.
1054
+ #
1055
+ # @return [nil]
1056
+ def clipboard=(text); end
1057
+
1058
+
1045
1059
  # @!group Drawing primitives
1046
1060
 
1047
1061
  ##
@@ -1295,7 +1309,7 @@ module Gosu
1295
1309
  # @see char_to_button_id
1296
1310
  # @see Window#text_input
1297
1311
  # @see TextInput
1298
- def self.button_id_to_char(id); end
1312
+ def button_id_to_char(id); end
1299
1313
 
1300
1314
  ##
1301
1315
  # Returns the button that usually produces a character, if any.
@@ -1306,7 +1320,7 @@ module Gosu
1306
1320
  # @see button_id_to_char
1307
1321
  # @see Window#text_input
1308
1322
  # @see TextInput
1309
- def self.char_to_button_id(char); end
1323
+ def char_to_button_id(char); end
1310
1324
 
1311
1325
  ##
1312
1326
  # @return [Float] a random number in the range [min; max).
data/src/Audio.cpp CHANGED
@@ -13,7 +13,7 @@ static Gosu::Song* cur_song = nullptr;
13
13
  // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
14
14
  static bool cur_song_looping;
15
15
 
16
- struct Gosu::Sample::Impl : Gosu::Noncopyable
16
+ struct Gosu::Sample::Impl : private Gosu::Noncopyable
17
17
  {
18
18
  ALuint buffer;
19
19
 
@@ -76,7 +76,7 @@ Gosu::Channel Gosu::Sample::play_pan(double pan, double volume, double speed, bo
76
76
  }
77
77
 
78
78
  // AudioFile impl
79
- struct Gosu::Song::Impl : Gosu::Noncopyable
79
+ struct Gosu::Song::Impl : private Gosu::Noncopyable
80
80
  {
81
81
  private:
82
82
  double m_volume = 1.0;
@@ -35,7 +35,7 @@ static void throw_os_error(OSStatus status, unsigned line)
35
35
 
36
36
  #define CHECK_OS(status) do { if (status) throw_os_error(status, __LINE__); } while (0)
37
37
 
38
- struct Gosu::AudioFile::Impl : Gosu::Noncopyable
38
+ struct Gosu::AudioFile::Impl : private Gosu::Noncopyable
39
39
  {
40
40
  Buffer buffer;
41
41
  AudioFileID file_id;
@@ -14,7 +14,7 @@
14
14
  #include <mutex>
15
15
  #include <vector>
16
16
 
17
- struct Gosu::AudioFile::Impl : Gosu::Noncopyable
17
+ struct Gosu::AudioFile::Impl : private Gosu::Noncopyable
18
18
  {
19
19
  Buffer buffer;
20
20
 
@@ -4,7 +4,7 @@
4
4
  #include <vector>
5
5
  using namespace std;
6
6
 
7
- struct Gosu::BlockAllocator::Impl : Gosu::Noncopyable
7
+ struct Gosu::BlockAllocator::Impl : private Gosu::Noncopyable
8
8
  {
9
9
  unsigned width, height;
10
10
 
data/src/FileUnix.cpp CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
  using namespace std;
18
18
 
19
- struct Gosu::File::Impl : Gosu::Noncopyable
19
+ struct Gosu::File::Impl : private Gosu::Noncopyable
20
20
  {
21
21
  int fd = -1;
22
22
  void* mapping = MAP_FAILED;
data/src/FileWin.cpp CHANGED
@@ -9,7 +9,7 @@ using namespace std;
9
9
 
10
10
  // TODO: Error checking
11
11
 
12
- struct Gosu::File::Impl : Gosu::Noncopyable
12
+ struct Gosu::File::Impl : private Gosu::Noncopyable
13
13
  {
14
14
  HANDLE handle = INVALID_HANDLE_VALUE;
15
15
 
data/src/Font.cpp CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  static const int FONT_RENDER_SCALE = 2;
15
15
 
16
- struct Gosu::Font::Impl : Gosu::Noncopyable
16
+ struct Gosu::Font::Impl : private Gosu::Noncopyable
17
17
  {
18
18
  std::string name;
19
19
  int height;
data/src/Graphics.cpp CHANGED
@@ -42,7 +42,7 @@ namespace Gosu
42
42
  }
43
43
  }
44
44
 
45
- struct Gosu::Graphics::Impl : Gosu::Noncopyable
45
+ struct Gosu::Graphics::Impl : private Gosu::Noncopyable
46
46
  {
47
47
  unsigned virt_width = 0, virt_height = 0;
48
48
  unsigned phys_width = 0, phys_height = 0;
data/src/Input.cpp CHANGED
@@ -36,7 +36,7 @@ static vector<shared_ptr<SDL_GameController>> open_game_controllers;
36
36
  // Stores joystick instance id or -1 if empty
37
37
  static array<int, Gosu::NUM_GAMEPADS> gamepad_slots = {-1, -1, -1, -1};
38
38
 
39
- struct Gosu::Input::Impl : Gosu::Noncopyable
39
+ struct Gosu::Input::Impl : private Gosu::Noncopyable
40
40
  {
41
41
  struct InputEvent
42
42
  {
@@ -678,4 +678,19 @@ void Gosu::Input::set_text_input(TextInput* text_input)
678
678
  pimpl->text_input = text_input;
679
679
  }
680
680
 
681
+ std::string Gosu::Input::clipboard()
682
+ {
683
+ require_sdl_video();
684
+
685
+ std::shared_ptr<char> clipboard{SDL_GetClipboardText(), SDL_free};
686
+ return std::string{clipboard.get()};
687
+ }
688
+
689
+ void Gosu::Input::set_clipboard(const std::string& text)
690
+ {
691
+ require_sdl_video();
692
+
693
+ SDL_SetClipboardText(text.c_str());
694
+ }
695
+
681
696
  #endif
data/src/InputUIKit.cpp CHANGED
@@ -7,7 +7,7 @@
7
7
  #import <UIKit/UIKit.h>
8
8
  using namespace std;
9
9
 
10
- struct Gosu::Input::Impl : Gosu::Noncopyable
10
+ struct Gosu::Input::Impl : private Gosu::Noncopyable
11
11
  {
12
12
  UIView* view = nil;
13
13
  TextInput* text_input = nullptr;
data/src/Macro.cpp CHANGED
@@ -4,7 +4,7 @@
4
4
  #include "DrawOpQueue.hpp"
5
5
  #include <stdexcept>
6
6
 
7
- struct Gosu::Macro::Impl : Gosu::Noncopyable
7
+ struct Gosu::Macro::Impl : private Gosu::Noncopyable
8
8
  {
9
9
  VertexArrays vertex_arrays;
10
10
  int width, height;
data/src/RubyGosu.cxx CHANGED
@@ -2345,6 +2345,16 @@ namespace Gosu
2345
2345
  {
2346
2346
  return Gosu::Input::axis(btn);
2347
2347
  }
2348
+
2349
+ std::string clipboard()
2350
+ {
2351
+ return Gosu::Input::clipboard();
2352
+ }
2353
+
2354
+ void set_clipboard(const std::string& text)
2355
+ {
2356
+ return Gosu::Input::set_clipboard(text);
2357
+ }
2348
2358
  }
2349
2359
 
2350
2360
  // Global graphics functions
@@ -10918,6 +10928,64 @@ fail:
10918
10928
  }
10919
10929
 
10920
10930
 
10931
+ SWIGINTERN VALUE
10932
+ _wrap_clipboard(int argc, VALUE *argv, VALUE self) {
10933
+ std::string result;
10934
+ VALUE vresult = Qnil;
10935
+
10936
+ if ((argc < 0) || (argc > 0)) {
10937
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
10938
+ }
10939
+ {
10940
+ try {
10941
+ result = Gosu::clipboard();
10942
+ }
10943
+ catch (const std::exception& e) {
10944
+ SWIG_exception(SWIG_RuntimeError, e.what());
10945
+ }
10946
+ }
10947
+ vresult = SWIG_From_std_string(static_cast< std::string >(result));
10948
+ return vresult;
10949
+ fail:
10950
+ return Qnil;
10951
+ }
10952
+
10953
+
10954
+ SWIGINTERN VALUE
10955
+ _wrap_clipboarde___(int argc, VALUE *argv, VALUE self) {
10956
+ std::string *arg1 = 0 ;
10957
+ int res1 = SWIG_OLDOBJ ;
10958
+
10959
+ if ((argc < 1) || (argc > 1)) {
10960
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
10961
+ }
10962
+ {
10963
+ std::string *ptr = (std::string *)0;
10964
+ res1 = SWIG_AsPtr_std_string(argv[0], &ptr);
10965
+ if (!SWIG_IsOK(res1)) {
10966
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "std::string const &","Gosu::set_clipboard", 1, argv[0] ));
10967
+ }
10968
+ if (!ptr) {
10969
+ SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "std::string const &","Gosu::set_clipboard", 1, argv[0]));
10970
+ }
10971
+ arg1 = ptr;
10972
+ }
10973
+ {
10974
+ try {
10975
+ Gosu::set_clipboard((std::string const &)*arg1);
10976
+ }
10977
+ catch (const std::exception& e) {
10978
+ SWIG_exception(SWIG_RuntimeError, e.what());
10979
+ }
10980
+ }
10981
+ if (SWIG_IsNewObj(res1)) delete arg1;
10982
+ return Qnil;
10983
+ fail:
10984
+ if (SWIG_IsNewObj(res1)) delete arg1;
10985
+ return Qnil;
10986
+ }
10987
+
10988
+
10921
10989
  SWIGINTERN VALUE
10922
10990
  _wrap_draw_line(int argc, VALUE *argv, VALUE self) {
10923
10991
  double arg1 ;
@@ -12459,7 +12527,7 @@ SWIGEXPORT void Init_gosu(void) {
12459
12527
  rb_define_const(mGosu, "LICENSES", SWIG_From_std_string(static_cast< std::string >(Gosu::LICENSES)));
12460
12528
  rb_define_const(mGosu, "MAJOR_VERSION", SWIG_From_int(static_cast< int >(1)));
12461
12529
  rb_define_const(mGosu, "MINOR_VERSION", SWIG_From_int(static_cast< int >(4)));
12462
- rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(3)));
12530
+ rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(4)));
12463
12531
  rb_define_module_function(mGosu, "milliseconds", VALUEFUNC(_wrap_milliseconds), -1);
12464
12532
  rb_define_module_function(mGosu, "random", VALUEFUNC(_wrap_random), -1);
12465
12533
  rb_define_module_function(mGosu, "degrees_to_radians", VALUEFUNC(_wrap_degrees_to_radians), -1);
@@ -12960,6 +13028,8 @@ SWIGEXPORT void Init_gosu(void) {
12960
13028
  rb_define_module_function(mGosu, "button_name", VALUEFUNC(_wrap_button_name), -1);
12961
13029
  rb_define_module_function(mGosu, "gamepad_name", VALUEFUNC(_wrap_gamepad_name), -1);
12962
13030
  rb_define_module_function(mGosu, "axis", VALUEFUNC(_wrap_axis), -1);
13031
+ rb_define_module_function(mGosu, "clipboard", VALUEFUNC(_wrap_clipboard), -1);
13032
+ rb_define_module_function(mGosu, "clipboard=", VALUEFUNC(_wrap_clipboarde___), -1);
12963
13033
  rb_define_module_function(mGosu, "draw_line", VALUEFUNC(_wrap_draw_line), -1);
12964
13034
  rb_define_module_function(mGosu, "draw_triangle", VALUEFUNC(_wrap_draw_triangle), -1);
12965
13035
  rb_define_module_function(mGosu, "draw_quad", VALUEFUNC(_wrap_draw_quad), -1);
data/src/TextInput.cpp CHANGED
@@ -7,7 +7,7 @@
7
7
  #include <SDL.h>
8
8
  #endif
9
9
 
10
- struct Gosu::TextInput::Impl : Gosu::Noncopyable
10
+ struct Gosu::TextInput::Impl : private Gosu::Noncopyable
11
11
  {
12
12
  std::string text;
13
13
 
data/src/TimingApple.cpp CHANGED
@@ -2,6 +2,12 @@
2
2
  #if defined(GOSU_IS_MAC)
3
3
 
4
4
  #include <Gosu/Timing.hpp>
5
+ #include <unistd.h>
6
+
7
+ void Gosu::sleep(unsigned milliseconds)
8
+ {
9
+ usleep(milliseconds * 1000);
10
+ }
5
11
 
6
12
  // Thanks to this blog for the unconvoluted code example:
7
13
  // http://shiftedbits.org/2008/10/01/mach_absolute_time-on-the-iphone/
@@ -11,7 +17,7 @@
11
17
  unsigned long Gosu::milliseconds()
12
18
  {
13
19
  static mach_timebase_info_data_t info;
14
- static uint64_t first_tick = [] {
20
+ static const uint64_t first_tick = [] {
15
21
  mach_timebase_info(&info);
16
22
  return mach_absolute_time();
17
23
  }();
data/src/TimingUnix.cpp CHANGED
@@ -3,19 +3,21 @@
3
3
 
4
4
  #include <Gosu/Timing.hpp>
5
5
  #include <sys/time.h>
6
+ #include <unistd.h>
6
7
 
7
- unsigned long Gosu::milliseconds()
8
+ void Gosu::sleep(unsigned milliseconds)
8
9
  {
9
- static unsigned long start = 0;
10
+ usleep(milliseconds * 1000);
11
+ }
10
12
 
13
+ unsigned long Gosu::milliseconds()
14
+ {
11
15
  timeval tp;
12
16
  gettimeofday(&tp, nullptr);
17
+ unsigned long ms = tp.tv_usec / 1000UL + tp.tv_sec * 1000UL;
13
18
 
14
- if (start == 0) {
15
- start = tp.tv_usec / 1000UL + tp.tv_sec * 1000UL;
16
- }
17
-
18
- return tp.tv_usec / 1000UL + tp.tv_sec * 1000UL - start;
19
+ static unsigned long start = ms;
20
+ return ms - start;
19
21
  }
20
22
 
21
23
  #endif
data/src/TimingWin.cpp CHANGED
@@ -4,9 +4,14 @@
4
4
  #include <Gosu/Timing.hpp>
5
5
  #include <windows.h>
6
6
 
7
+ void Gosu::sleep(unsigned milliseconds)
8
+ {
9
+ Sleep(milliseconds);
10
+ }
11
+
7
12
  unsigned long Gosu::milliseconds()
8
13
  {
9
- static unsigned long start = [] {
14
+ static const unsigned long start = [] {
10
15
  timeBeginPeriod(1);
11
16
  return timeGetTime();
12
17
  }();
data/src/TrueTypeFont.cpp CHANGED
@@ -9,7 +9,7 @@
9
9
  #define STB_TRUETYPE_IMPLEMENTATION
10
10
  #include <stb_truetype.h>
11
11
 
12
- struct Gosu::TrueTypeFont::Impl : Gosu::Noncopyable
12
+ struct Gosu::TrueTypeFont::Impl : private Gosu::Noncopyable
13
13
  {
14
14
  stbtt_fontinfo info{};
15
15
  std::shared_ptr<TrueTypeFont> fallback;
data/src/Window.cpp CHANGED
@@ -71,7 +71,7 @@ namespace Gosu
71
71
  }
72
72
  }
73
73
 
74
- struct Gosu::Window::Impl : Gosu::Noncopyable
74
+ struct Gosu::Window::Impl : private Gosu::Noncopyable
75
75
  {
76
76
  bool fullscreen = false;
77
77
  double update_interval = 0;
data/src/WindowUIKit.cpp CHANGED
@@ -4,7 +4,7 @@
4
4
  #include "GosuViewController.hpp"
5
5
  #include <Gosu/Gosu.hpp>
6
6
 
7
- struct Gosu::Window::Impl : Gosu::Noncopyable
7
+ struct Gosu::Window::Impl : private Gosu::Noncopyable
8
8
  {
9
9
  UIWindow* window;
10
10
  GosuViewController* controller;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gosu
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3
4
+ version: 1.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Raschke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-27 00:00:00.000000000 Z
11
+ date: 2022-12-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
  2D game development library.
@@ -304,7 +304,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
304
304
  - !ruby/object:Gem::Version
305
305
  version: '0'
306
306
  requirements: []
307
- rubygems_version: 3.2.22
307
+ rubygems_version: 3.3.11
308
308
  signing_key:
309
309
  specification_version: 4
310
310
  summary: 2D game development library.