Commit graph

810 commits

Author SHA1 Message Date
Chris Beams
84c7de24aa Revert "Add java home path"
This reverts commit 02d3dd2258.
2014-11-22 08:40:32 +01:00
Manfred Karrer
dca19708b6 Make amount tx field selectable 2014-11-21 20:07:31 +01:00
Chris Beams
30c0ade5f9
Merge branch 'cbeams'
Significant changes in the way that controllers and models interact with
backend services. Most important is the introduction of RxJava's
Observable. See individual commit comments for details.

Conflicts were minor, mainly dealing with the fact that MainPM had been
modified in master, but removed completely on the 'cbeams' branch. All
changes have been preserved by carrying them over to MainModel.

* cbeams:
  Improve service initialization coordination using rx.Observable
  Redesign controller/model types and apply to gui.main.Main*

Conflicts:
	build.gradle
	src/main/java/io/bitsquare/btc/WalletService.java
	src/main/java/io/bitsquare/gui/main/MainPM.java
	src/main/java/io/bitsquare/msg/tomp2p/TomP2PNode.java
2014-11-21 10:37:05 +01:00
Chris Beams
67295aea55
Improve service initialization coordination using rx.Observable
This change introduces the use of RxJava's Observable [1] to redesign
how we work with non-deterministic and/or event-based information, such
as: connecting to peer-to-peer infrastructure, synchronizing the bitcoin
blockchain, and so on.

Prior to this commit, these activities were initiated in methods like
WalletService#initialize and TomP2PMessageService#init. These methods
accepted 'listener' interfaces, and these listeners' callback methods
would be invoked whenever work progressed, completed, or failed.

This approach required significant coordination logic, which, prior to
this commit, was found primarily in MainModel#initBackend. A primary
goal of the logic found here was to determine when the backend was
"ready". This state was represented in MainModel's `backendReady` field,
which would be set to true once the following three conditions were
satisfied:

 1. the message service had finished initialization
 2. the wallet service had finished initialization, and
 3. the blockchain synchronization had reached 100%

Monitoring these three states was complex, and required hard-to-follow
conditional logic spread across a number of locations in the code. In
any case, however, once these three conditions were satisfied and
backendReady's value was set to true, a listener on the backendReady
field (in MainViewCB#doInitialize) would then populate combo boxes and
pending trade counts in the main view and cause the splash screen to
fade out, rendering the application ready for user interaction.

The introduction of rx.Observable is designed to achieve the same
show-the-splash-screen-until-everything-is-ready functionality described
above, without the complex monitoring, conditional logic and nested
callbacks. This is achieved by modeling each process as an Observable
stream of events. Observables in RxJava can emit any number of events,
and can complete either normally or with an error.

These observables may be 'subscribed' to by any number of subscribers,
and events emitted can be acted upon by instructing the subscriber what
to do `onNext`, `onCompleted`, and `onError`. So for example
WalletService now exposes an Observable<Double> called bootstrapState.
This Observable is subscribed to in MainModel#initBackend in such a way
that every time it emits a new double value (i.e. a new percentage), the
various bootstrap state text labels and progress indicators are updated
accordingly.

Where it gets really interesting, however, is when Observables are
combined. The primary complexity described above is coordinating the
fading out of the splash screen with the completed initialization of all
backend services. As can now be seen in MainModel#initBackend, the
wallet service and message service Observables are simply "merged" into
a single observable and returned. From the MainViewCB side, this "single
backend observable" is subscribed to and, when it completes (i.e. when
all the underlying Observables complete), then combo boxes and pending
trade counts are populated and the splash screen is faded out.

Understanding RxJava, Observables, and the principles of "Functional
Reactive Programming" takes time. It is a paradigm shift in dealing with
concurrency and non-determinism, but one that ultimately rewards those
who take the time. In the end, I believe it's use will result in a
significantly more concise and robust internal architecture for
Bitsquare, and using RxJava's lightweight, well-adopted and
infrastructure-agnostic API leaves us open to using Akka or other more
sophisticated infrastructure later without tying ourselves to those
specific APIs (because virtually anything can be modeled as an
Observable). Achieve these benifits means that core committers will need
to understand how RxJava works, how to think about it, and how to design
using it. I have spent the better part of the last week getting to know
it, and I am certainly still learning. I can recommend many resources to
aid in this process, but having gone through it myself, I recommend that
everyone read at least [1] and [2] first.

[1]: https://github.com/ReactiveX/RxJava/wiki/Observable
[2]: [The introduction to Reactive Programming you've been
missing](https://gist.github.com/staltz/868e7e9bc2a7b8c1f754)
2014-11-21 10:34:35 +01:00
Chris Beams
3c3d3a507c
Redesign controller/model types and apply to gui.main.Main*
Major changes:

 - Introduce Controller base class and FxmlController subclass. The
   latter has awareness of an @FXML "root" Node. Together, these classes
   functionally replace the ViewCB class, however ViewCB has been left
   in place so as to avoid the need to refactor all controllers at once.
   In this commit, the new Controller hierarchy has been applied only to
   the gui.main.MainViewCB controller.

 - Eliminate MainPM in favor of placing all logic in MainModel. This is
   potentially temporary, i.e. the distinction between data model and
   presentation model may be reintroduced in later commits, but for the
   purposes of this change, the goal was to simplify and remove as many
   layers as possible. The precise arrangement of controller and model
   classes is a topic to be discussed when reviewing this change.

Minor changes:

 - Inject model objects into MainModel instead of MainViewCB.
   Previously, model objects such as WalletService were injected into
   both MainModel and MainViewCB. Now this intended separation is more
   strictly observed.

 - Remove comment section markers and empty methods from MainModel and
   MainViewCB

 - Use public constructors in MainModel and elsewhere. This avoids
   unnecessary IDE warnings, allows the possibility of unit testing, and
   generally avoids surprise for the reader.

 - Eliminate Profiler statements in MainModel and elsewhere. These
   statements are fine during debugging or optimization sessions, but
   should otherwise be removed so as not to fill the logs with
   unimportant information.

 - Change signature of User#getCurrentBankAccount to return
   ObjectProperty. Previously, this method returned the underlying
   BankAccount; now returning ObjectProperty allows other components to
   add listeners (such as for user persistence when changing accounts in
   the UI).

 - Handle user persistence on account change elsewhere; namely add a
   listener for it in the MainModel constructor. Previously this was
   done in MainModel#setCurrentBankAccount, which amounts to a side
   effect in a setter method--something to avoid if possible.

 - Expose MainModel#getUser, and eliminate delegate methods previously
   in place that mediated access to the User object. This is mainly for
   consistency and concision.
2014-11-21 10:34:35 +01:00
Manfred Karrer
4fdc4366a1 Cleanup 2014-11-21 01:55:49 +01:00
Manfred Karrer
c3f87609a8 Throw exception if address storage fails 2014-11-21 01:21:45 +01:00
Manfred Karrer
ef7c2305fc Fix bug with states 2014-11-21 01:18:55 +01:00
Manfred Karrer
58d81c2c51 Fix bug with unsupported case 2014-11-21 00:34:22 +01:00
Manfred Karrer
52bdb78990 Add java home path 2014-11-20 23:33:08 +01:00
Manfred Karrer
02d3dd2258 Add java home path 2014-11-20 23:02:29 +01:00
Manfred Karrer
1d24a2aa38 Change discover handling 2014-11-20 22:59:24 +01:00
Chris Beams
356b76a21a
Configure shadowJar classifier in time for packageNative config
This change avoids the "Main application jar is missing" error described
in the comments on issue #243.
2014-11-20 18:52:46 +01:00
Manfred Karrer
351feae334 Add path to javapackager 2014-11-20 18:41:08 +01:00
Manfred Karrer
15854bdf06 Restrict non Desktop API for linux only (Win7 cause problems) 2014-11-20 00:58:26 +01:00
Manfred Karrer
5b5bacc397 Cleanup, improve logging 2014-11-20 00:09:27 +01:00
Manfred Karrer
a23277a527 Use Utilities when accessing the default currency 2014-11-19 20:50:33 +01:00
Manfred Karrer
c57aba7992 Fix tradestate problem 2014-11-19 20:36:03 +01:00
Manfred Karrer
c9bed48a53 Change back fee to new standard 2014-11-19 20:35:08 +01:00
Manfred Karrer
82325f615f Fix missing update for trade state (#285) 2014-11-19 18:03:26 +01:00
Manfred Karrer
b9b50da190 Cleanup 2014-11-19 17:17:07 +01:00
Manfred Karrer
d482798024 Change open URI support 2014-11-19 17:04:19 +01:00
Manfred Karrer
279145a5ca Add support if desktop.browse(uri) is not supported 2014-11-19 16:10:26 +01:00
Manfred Karrer
b7d6c5195e Add support if desktop.browse(uri) is not supported (Ubuntu with latest java version) 2014-11-19 16:10:03 +01:00
Manfred Karrer
107731b884 Use biteasy testnet as link for tx explorer 2014-11-19 15:07:17 +01:00
Manfred Karrer
aff235dbb0 Add null check 2014-11-19 14:33:39 +01:00
Manfred Karrer
3c6f31a421 Revert fee to old 0.0001 BTC to avoid problems with not accepted tx 2014-11-19 14:33:25 +01:00
Manfred Karrer
bc39d4d315 Deactivate relay mode 2014-11-19 13:16:52 +01:00
Manfred Karrer
74bedff837 Scroll down to important content #226 2014-11-19 02:25:46 +01:00
Manfred Karrer
bd8b39b996 Show busy spinner at pay reg. fee #284 2014-11-19 01:48:17 +01:00
Manfred Karrer
2b4e7528c4 Add behindFirewall 2014-11-19 00:29:49 +01:00
Manfred Karrer
b85317c8f3 Shutdown peer in BootstrappedPeerFactory in case of bootstrap is still in progress (#270)\n\n Te other shutdown call in TomP2PNode would not trigger a shutdown as the peer is null during bootstrap 2014-11-18 23:44:41 +01:00
Manfred Karrer
9517c7ee6d Show busy spinner at create and take offer #281 2014-11-18 23:25:21 +01:00
Manfred Karrer
f92104f4e2 Close trade after withdrawal #283 2014-11-18 20:19:30 +01:00
Manfred Karrer
f8e4d1a41d Allow only EUR for the moment (#282) 2014-11-18 20:04:28 +01:00
Manfred Karrer
f9859b3a13 Fix trade state update bug 2014-11-18 19:52:46 +01:00
Manfred Karrer
b87a27922a Fix missing remove listener (Should fix #280 - not reproducible yet) 2014-11-18 19:08:02 +01:00
Manfred Karrer
ee310fc4ae Reduce security deposit to make testing cheaper on IRC accountmodel 2014-11-18 17:11:10 +01:00
Manfred Karrer
cbcab9e5aa Cleanup 2014-11-18 16:13:06 +01:00
Manfred Karrer
e4a54c47f8 Reduce security deposit to make testing cheaper 2014-11-18 16:12:53 +01:00
Manfred Karrer
3234df4484 Change log level 2014-11-18 16:08:00 +01:00
Manfred Karrer
976a76411f Update formatter to new lower reg. fee (miner fee dropped 10 fold) 2014-11-17 20:26:20 +01:00
Manfred Karrer
46a56e4e4f Update to BitcoinJ 0.12.2 2014-11-17 18:57:58 +01:00
Manfred Karrer
29cfdd2301 Update for lastest TomP2P master 2014-11-17 18:04:52 +01:00
Manfred Karrer
f6d6f80a64 Update to lastest TomP2P master 2014-11-17 17:40:22 +01:00
Chris Beams
b9a1095578
Merge branch 'cbeams'
Changes made during the effort to decouple "backend initialization" for
the purpose of developing and testing the GUI while offline and/or
without having to actually connect to the bitcoin / tomp2p networks.
This decoupling is not yet possible--these changes just prepare for it.
These changes also represent the first steps in streamlining controller
archictecture toward maximum maintainability. See individual commit
comments for details.

* cbeams:
  Polish MainViewCB
  Refactor ViewLoader for proper injection
  Refactor MainViewCB and Navigation.Item
2014-11-17 11:47:27 +01:00
Chris Beams
70d6be1aef
Polish MainViewCB
Complete the MainViewCB refactoring process described earlier now that
ViewLoader is properly injected (see previous commit). Also, rearrange
the few private methods that remain to align with their order of
invocation.
2014-11-17 11:29:33 +01:00
Chris Beams
f6f97d55ed
Avoid use of JOpt's #defaultsTo method
Providing an explicit default using the #defaultsTo method ends up
short-circuiting the Spring Environment's hierarchical property resolution
process. for example, if --port.useManualPortForwarding has a default
value of `false`, then the command line property source always returns a
value when its #getProperty method is invoked by the Environment. This
means that a lower-precedence property source never has the opportunity
to return its value. For example, if port.useManualPortForwarding had
been set to true in the filesystem property source
(at ${user.data.dir}/bitsquare.properties), this property value would
never be resolved because the default command line property source always
overrides it (thus the notion of "short circuiting" above).

This change eliminates the use of JOpt's #defaultsTo method in favor of
a simple approach to advertising default values (if any) in the option's
description string. The result is --help output that reads exactly the
same as it did before, but no actual default value is set at the command
line property source level.

Note that the default property source is still created, and default
values are still assigned in BitsquareEnvironment#defaultPropertySource.
This property source has the lowest precedence, and this means that any
and all other property sources have the opportunity to provide a value
and override the default.
2014-11-17 11:18:21 +01:00
Manfred Karrer
97fc4a728e Remove PeerConnection for sendDirect 2014-11-17 02:30:47 +01:00
Chris Beams
a4d3fab462
Refactor ViewLoader for proper injection
ViewLoader is now modeled as a stateless singleton and injected into all
components (usually controllers) that need it. This is as opposed to the
prior situation in which a ViewLoader was instatiated every time view
loading was required. This was an understerstandable approach, given
that FXMLLoader (which ViewLoader wraps) assumes the same
construction-per-use approach, but it is nevertheless problematic.

 - Return Item tuple from ViewLoader#load.

   This avoids the need to call ViewLoader#load followed by individual
   calls to get the view and then the controller, as this requires
   mutable state to be held in the ViewLoader (which is now a shared
   singleton injected throughout the application). The previous approach
   is (a) confusing and (b) could create problems in a multithreaded
   environment. While (b) is unlikely in our case, the new approach is
   still clearer anyway.

 - Refactor ViewLoader#load to accept URL vs FxmlResource.

   This decouples the ViewLoader abstraction away from the
   Navigation.Item / FxmlResource abstraction completely.
2014-11-16 16:51:10 +01:00