leaderboard 3.0.0.rc2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## leaderboard 3.0.0 (2012-12-03)
4
+
5
+ * Added `rank_member_if` and `rank_member_if_in` methods that allow you to rank a member in the leaderboard based on execution of a lambda.
6
+
3
7
  ## leaderboard 3.0.0.rc2 (2012-11-27)
4
8
 
5
9
  * No longer cast scores to a floating point automatically. If requesting a score for an unknown member in the leaderboard, return `nil`. Under the old behavior, a `nil` score gets returned as 0.0. This is misleading as 0.0 is a valid score.
@@ -119,7 +119,7 @@ Get some information about your leaderboard:
119
119
  => 1
120
120
  ```
121
121
 
122
- The `rank_member` call will also accept an optional string member data that could
122
+ The `rank_member` call will also accept an optional parameter, `member_data` that could
123
123
  be used to store other information about a given member in the leaderboard. This
124
124
  may be useful in situations where you are storing member IDs in the leaderboard and
125
125
  you want to be able to store a member name for display. You could use JSON to
@@ -236,6 +236,36 @@ friends = highscore_lb.ranked_in_list(['member_6', 'member_1', 'member_10'], :so
236
236
  => [{:member=>"member_1", :rank=>56, :score=>1.0}, {:member=>"member_6", :rank=>51, :score=>6.0}, {:member=>"member_10", :rank=>47, :score=>10.0}]
237
237
  ```
238
238
 
239
+ ### Conditionally rank a member in the leaderboard
240
+
241
+ You can pass a lambda to the `rank_member_if` method to conditionally rank a member in the leaderboard. The lambda is passed the following 5 parameters:
242
+
243
+ * `member`: Member name.
244
+ * `current_score`: Current score for the member in the leaderboard. May be `nil` if the member is not currently ranked in the leaderboard.
245
+ * `score`: Member score.
246
+ * `member_data`: Optional member data.
247
+ * `leaderboard_options`: Leaderboard options, e.g. :reverse => Value of reverse option
248
+
249
+ ```ruby
250
+ highscore_check = lambda do |member, current_score, score, member_data, leaderboard_options|
251
+ return true if current_score.nil?
252
+ return true if score > current_score
253
+ false
254
+ end
255
+
256
+ highscore_lb.rank_member_if(highscore_check, 'david', 1337)
257
+ highscore_lb.score_for('david')
258
+ => 1337.0
259
+ highscore_lb.rank_member_if(highscore_check, 'david', 1336)
260
+ highscore_lb.score_for('david')
261
+ => 1337.0
262
+ highscore_lb.rank_member_if(highscore_check, 'david', 1338)
263
+ highscore_lb.score_for('david')
264
+ => 1338.0
265
+ ```
266
+
267
+ NOTE: Use a lambda and not a proc, otherwise you will get a `LocalJumpError` as a return statement in the proc will return from the method enclosing the proc.
268
+
239
269
  ### Ranking multiple members in a leaderboard at once
240
270
 
241
271
  Insert multiple data items for members and their associated scores:
@@ -280,7 +310,7 @@ Use this method to do bulk insert of data, but be mindful of the amount of data
280
310
  intersect_leaderboards(destination, keys, options = {:aggregate => :min}): Intersect leaderboards given by keys with this leaderboard into destination
281
311
  ```
282
312
 
283
- Check the [online documentation](http://rubydoc.info/github/agoragames/leaderboard/master/frames) for more detail on each method.
313
+ Check the [online documentation](http://rubydoc.info/gems/leaderboard/frames) for more detail on each method.
284
314
 
285
315
  ## Performance Metrics
286
316
 
@@ -127,6 +127,46 @@ class Leaderboard
127
127
  end
128
128
  end
129
129
 
130
+ # Rank a member in the leaderboard based on execution of the +rank_conditional+.
131
+ #
132
+ # The +rank_conditional+ is passed the following parameters:
133
+ # member: Member name.
134
+ # current_score: Current score for the member in the leaderboard.
135
+ # score: Member score.
136
+ # member_data: Optional member data.
137
+ # leaderboard_options: Leaderboard options, e.g. :reverse => Value of reverse option
138
+ #
139
+ # @param rank_conditional [lambda] Lambda which must return +true+ or +false+ that controls whether or not the member is ranked in the leaderboard.
140
+ # @param member [String] Member name.
141
+ # @param score [String] Member score.
142
+ # @param member_data [Hash] Optional member_data.
143
+ def rank_member_if(rank_conditional, member, score, member_data = nil)
144
+ rank_member_if_in(@leaderboard_name, rank_conditional, member, score, member_data)
145
+ end
146
+
147
+ # Rank a member in the named leaderboard based on execution of the +rank_conditional+.
148
+ #
149
+ # The +rank_conditional+ is passed the following parameters:
150
+ # member: Member name.
151
+ # current_score: Current score for the member in the leaderboard.
152
+ # score: Member score.
153
+ # member_data: Optional member data.
154
+ # leaderboard_options: Leaderboard options, e.g. :reverse => Value of reverse option
155
+ #
156
+ # @param leaderboard_name [String] Name of the leaderboard.
157
+ # @param rank_conditional [lambda] Lambda which must return +true+ or +false+ that controls whether or not the member is ranked in the leaderboard.
158
+ # @param member [String] Member name.
159
+ # @param score [String] Member score.
160
+ # @param member_data [Hash] Optional member_data.
161
+ def rank_member_if_in(leaderboard_name, rank_conditional, member, score, member_data = nil)
162
+ current_score = @redis_connection.zscore(leaderboard_name, member)
163
+ current_score = current_score.to_f if current_score
164
+
165
+ if rank_conditional.call(member, current_score, score, member_data, {:reverse => @reverse})
166
+ rank_member_in(leaderboard_name, member, score, member_data)
167
+ end
168
+ end
169
+
130
170
  # Retrieve the optional member data for a given member in the leaderboard.
131
171
  #
132
172
  # @param member [String] Member name.
@@ -1,4 +1,4 @@
1
1
  class Leaderboard
2
2
  # Leaderboard version
3
- VERSION = '3.0.0.rc2'.freeze
3
+ VERSION = '3.0.0'.freeze
4
4
  end
@@ -642,4 +642,21 @@ describe 'Leaderboard' do
642
642
  ranked_members[0][:score].should be_nil
643
643
  ranked_members[0][:rank].should be_nil
644
644
  end
645
+
646
+ it 'should rank a member in the leaderboard with conditional execution' do
647
+ highscore_check = lambda do |member, current_score, score, member_data, leaderboard_options|
648
+ return true if current_score.nil?
649
+ return true if score > current_score
650
+ false
651
+ end
652
+
653
+ @leaderboard.total_members.should be(0)
654
+ @leaderboard.rank_member_if(highscore_check, 'david', 1337)
655
+ @leaderboard.total_members.should be(1)
656
+ @leaderboard.score_for('david').should eql(1337.0)
657
+ @leaderboard.rank_member_if(highscore_check, 'david', 1336)
658
+ @leaderboard.score_for('david').should eql(1337.0)
659
+ @leaderboard.rank_member_if(highscore_check, 'david', 1338)
660
+ @leaderboard.score_for('david').should eql(1338.0)
661
+ end
645
662
  end
@@ -2,6 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe 'Leaderboard::VERSION' do
4
4
  it 'should be the correct version' do
5
- Leaderboard::VERSION.should == '3.0.0.rc2'
5
+ Leaderboard::VERSION.should == '3.0.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leaderboard
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.rc2
5
- prerelease: 6
4
+ version: 3.0.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - David Czarnecki
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-27 00:00:00.000000000 Z
12
+ date: 2012-12-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
@@ -96,9 +96,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
96
96
  required_rubygems_version: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
- - - ! '>'
99
+ - - ! '>='
100
100
  - !ruby/object:Gem::Version
101
- version: 1.3.1
101
+ version: '0'
102
102
  requirements: []
103
103
  rubyforge_project: leaderboard
104
104
  rubygems_version: 1.8.24