Mercurial > lasercutter
view src/clojure/lang/ARef.java @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
line wrap: on
line source
1 /**2 * Copyright (c) Rich Hickey. All rights reserved.3 * The use and distribution terms for this software are covered by the4 * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)5 * which can be found in the file epl-v10.html at the root of this distribution.6 * By using this software in any fashion, you are agreeing to be bound by7 * the terms of this license.8 * You must not remove this notice, or any other, from this software.9 **/11 /* rich Jan 1, 2009 */13 package clojure.lang;15 import java.util.Map;17 public abstract class ARef extends AReference implements IRef{18 protected volatile IFn validator = null;19 private volatile IPersistentMap watches = PersistentHashMap.EMPTY;21 public ARef(){22 super();23 }25 public ARef(IPersistentMap meta){26 super(meta);27 }29 void validate(IFn vf, Object val){30 try31 {32 if(vf != null && !RT.booleanCast(vf.invoke(val)))33 throw new IllegalStateException("Invalid reference state");34 }35 catch(RuntimeException re)36 {37 throw re;38 }39 catch(Exception e)40 {41 throw new IllegalStateException("Invalid reference state", e);42 }43 }45 void validate(Object val){46 validate(validator, val);47 }49 public void setValidator(IFn vf){50 try51 {52 validate(vf, deref());53 }54 catch(Exception e)55 {56 throw new RuntimeException(e);57 }58 validator = vf;59 }61 public IFn getValidator(){62 return validator;63 }65 public IPersistentMap getWatches(){66 return watches;67 }69 synchronized public IRef addWatch(Object key, IFn callback){70 watches = watches.assoc(key, callback);71 return this;72 }74 synchronized public IRef removeWatch(Object key){75 try76 {77 watches = watches.without(key);78 }79 catch(Exception e)80 {81 throw new RuntimeException(e);82 }84 return this;85 }87 public void notifyWatches(Object oldval, Object newval){88 IPersistentMap ws = watches;89 if(ws.count() > 0)90 {91 for(ISeq s = ws.seq(); s != null; s = s.next())92 {93 Map.Entry e = (Map.Entry) s.first();94 IFn fn = (IFn) e.getValue();95 try96 {97 if(fn != null)98 fn.invoke(e.getKey(), this, oldval, newval);99 }100 catch(Exception e1)101 {102 throw new RuntimeException(e1);103 }104 }105 }106 }107 }