-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathClojureAtom.java
More file actions
115 lines (99 loc) · 3.56 KB
/
ClojureAtom.java
File metadata and controls
115 lines (99 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package org.jruby.clojure;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyClass;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.Block;
import clojure.lang.Atom;
import clojure.lang.ArraySeq;
import static org.jruby.runtime.Visibility.*;
@JRubyClass(name = "Atom")
public class ClojureAtom extends RubyObject {
public static RubyClass createAtomClass(final Ruby runtime) {
RubyClass atomc = runtime.defineClass("Atom", runtime.getObject(), ATOM_ALLOCATOR);
atomc.setReifiedClass(ClojureAtom.class);
atomc.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
return obj instanceof ClojureAtom;
}
};
atomc.defineAnnotatedMethods(ClojureAtom.class);
return atomc;
}
Atom atom;
private static ObjectAllocator ATOM_ALLOCATOR = new ObjectAllocator() {
public IRubyObject allocate(final Ruby runtime, final RubyClass klass) {
return new ClojureAtom(runtime, klass);
}
};
public ClojureAtom(final Ruby runtime, final RubyClass klass) {
super(runtime, klass);
atom = null;
}
@JRubyMethod(visibility = PRIVATE)
public IRubyObject initialize(final ThreadContext context, final IRubyObject state) {
try {
atom = new Atom(state);
} catch (Exception e) {
throw context.getRuntime().newConcurrencyError(e.getLocalizedMessage());
}
return this;
}
@JRubyMethod
public Object swap(final ThreadContext context, final Block block) {
try {
return atom.swap(new ClojureFunction(context, block));
} catch (Exception e) {
throw context.getRuntime().newConcurrencyError(e.getLocalizedMessage());
}
}
@JRubyMethod
public Object swap(final ThreadContext context, final IRubyObject arg0, final Block block) {
try {
return atom.swap(new ClojureFunction(context, block), arg0);
} catch (Exception e) {
throw context.getRuntime().newConcurrencyError(e.getLocalizedMessage());
}
}
@JRubyMethod
public Object swap(final ThreadContext context, final IRubyObject arg0, final IRubyObject arg1, final Block block) {
try {
return atom.swap(new ClojureFunction(context, block), arg0, arg1);
} catch (Exception e) {
throw context.getRuntime().newConcurrencyError(e.getLocalizedMessage());
}
}
@JRubyMethod(rest = true)
public Object swap(final ThreadContext context, final IRubyObject[] args, final Block block) {
ArraySeq seq = ArraySeq.create((Object[])args);
Object arg0 = seq.get(0);
Object arg1 = seq.get(1);
try {
return atom.swap(new ClojureFunction(context, block), arg0, arg1, seq.next().next());
} catch (Exception e) {
throw context.getRuntime().newConcurrencyError(e.getLocalizedMessage());
}
}
@JRubyMethod(name = "compare_and_set")
public IRubyObject compareAndSet(ThreadContext context, IRubyObject oldv, IRubyObject newv){
return atom.compareAndSet(oldv, newv) ? context.getRuntime().getTrue() : context.getRuntime().getFalse();
}
@JRubyMethod
public Object reset(final ThreadContext context, final IRubyObject newVal) {
return atom.reset(newVal);
}
@JRubyMethod
public Object deref(final ThreadContext context) {
try {
return atom.deref();
} catch (Exception e) {
throw context.getRuntime().newConcurrencyError(e.getLocalizedMessage());
}
}
}