- Timestamp:
- 07/10/13 22:41:02 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
java/main/src/main/java/com/framsticks/remote/RemoteTree.java
r98 r99 7 7 import com.framsticks.communication.queries.SetRequest; 8 8 import com.framsticks.core.AbstractTree; 9 import com.framsticks.core.Mode;10 import com.framsticks.core.ListChange;11 9 import com.framsticks.core.Path; 12 10 import com.framsticks.params.*; 11 import com.framsticks.params.EventListener; 13 12 import com.framsticks.params.annotations.AutoAppendAnnotation; 14 13 import com.framsticks.params.annotations.FramsClassAnnotation; … … 28 27 import com.framsticks.util.dispatching.ThrowExceptionHandler; 29 28 import com.framsticks.util.lang.Casting; 30 import com.framsticks.util.lang.Pair;31 29 import com.framsticks.util.dispatching.RunAt; 32 30 import static com.framsticks.core.TreeOperations.*; … … 42 40 */ 43 41 @FramsClassAnnotation 44 public class RemoteTree extends AbstractTree implements JoinableParent {42 public final class RemoteTree extends AbstractTree implements JoinableParent { 45 43 46 44 private final static Logger log = Logger.getLogger(RemoteTree.class); 47 45 48 46 protected ClientSideManagedConnection connection; 49 50 protected final Set<Pair<Path, Subscription<?>>> subscriptions = new HashSet<>();51 52 public Pair<Path, Subscription<?>> getSubscription(Path path) {53 for (Pair<Path, Subscription<?>> s : subscriptions) {54 if (s.first.isTheSameObjects(path)) {55 return s;56 }57 }58 return null;59 }60 47 61 48 public RemoteTree() { … … 88 75 89 76 @Override 90 public void get(final Path path, final ValueParam param, Mode mode,final Future<Object> future) {77 public void get(final Path path, final ValueParam param, final Future<Object> future) { 91 78 assert isActive(); 92 79 assert param != null; … … 166 153 167 154 @Override 168 public void get(final Path path, final Mode mode, finalFuture<Path> future) {155 public void get(final Path path, final Future<Path> future) { 169 156 assert isActive(); 170 157 … … 187 174 } 188 175 189 190 @Override191 protected void tryRegisterOnChangeEvents(final Path path) {192 assert isActive();193 AccessInterface access = bindAccess(path);194 if (!(access instanceof ListAccess)) {195 return;196 }197 198 assert path.size() >= 2;199 FramsClass underFramsClass = getInfoFromCache(path.getUnder().getParam().getContainedTypeName());200 201 EventParam changedEvent;202 try {203 changedEvent = underFramsClass.getParamEntry(path.getTop().getParam().getId() + "_changed", EventParam.class);204 } catch (FramsticksException e) {205 return;206 }207 208 log.debug("registering for " + changedEvent);209 if (getSubscription(path) != null) {210 return;211 }212 213 final Pair<Path, Subscription<?>> temporary = new Pair<>(path, null);214 subscriptions.add(temporary);215 216 connection.subscribe(path.getTextual() + "_changed", this, new SubscriptionCallback<Tree>() {217 @Override218 public EventCallback subscribed(final Subscription<? super Tree> subscription) {219 if (subscription == null) {220 log.error("failed to subscribe for change event for " + path);221 return null;222 }223 log.debug("subscribed for change event for " + path);224 // subscription.setDispatcher(RemoteInstance.this);225 RemoteTree.this.dispatch(new RunAt<Tree>(this) {226 @Override227 protected void runAt() {228 subscriptions.remove(temporary);229 subscriptions.add(new Pair<Path, Subscription<?>>(path, subscription));230 }231 });232 return new EventCallback() {233 @Override234 public void call(List<File> files) {235 assert isActive();236 assert files.size() == 1;237 final MultiParamLoader loader = new MultiParamLoader();238 loader.setNewSource(files.get(0).getContent());239 loader.addBreakCondition(MultiParamLoader.Status.AfterObject);240 loader.addListener(MultiParamLoader.Status.OnComment, new MultiParamLoader.StatusListener() {241 242 @Override243 public void onStatusChange() {244 throw new FramsticksException().msg("multi param loader error").arg("line", loader.getCurrentLine());245 }246 });247 ReflectionAccess access = new ReflectionAccess(ListChange.class, FramsClass.build().forClass(ListChange.class));248 loader.addAccessInterface(access);249 250 MultiParamLoader.Status status;251 while ((status = loader.go()) != MultiParamLoader.Status.Finished) {252 if (status == MultiParamLoader.Status.AfterObject) {253 AccessInterface accessInterface = loader.getLastAccessInterface();254 reactToChange(path, (ListChange) accessInterface.getSelected());255 }256 }257 }258 };259 }260 });261 }262 263 protected Future<Path> futureListChanger(final ListChange listChange, final String path) {264 return new FutureHandler<Path>(Logging.logger(log, "failed to " + listChange, path)) {265 @Override266 protected void result(Path result) {267 log.debug(listChange + ": " + result);268 }269 };270 }271 272 protected void reactToChange(final Path path, final ListChange listChange) {273 assert isActive();274 log.debug("reacting to change " + listChange + " in " + path);275 AccessInterface access = bindAccess(path);276 assert access != null;277 278 if ((listChange.getAction() == ListChange.Action.Modify) && (listChange.getPosition() == -1)) {279 final String p = path.getTextual();280 tryGet(this, p, futureListChanger(listChange, p));281 return;282 }283 284 CompositeParam childParam = Casting.tryCast(CompositeParam.class, access.getParam(listChange.getBestIdentifier()));285 assert childParam != null;286 switch (listChange.getAction()) {287 case Add: {288 final String p = path.getTextual() + "/" + childParam.getId();289 tryGet(this, p, futureListChanger(listChange, p));290 break;291 }292 case Remove: {293 access.set(childParam, null);294 break;295 }296 case Modify: {297 final String p = path.getTextual() + "/" + childParam.getId();298 tryGet(this, p, futureListChanger(listChange, p));299 break;300 }301 }302 }303 304 176 @Override 305 177 public void set(final Path path, final PrimitiveParam<?> param, final Object value, final Future<Integer> future) { … … 380 252 } 381 253 382 // @Override 383 // public Path create(Path path) { 384 // assert isActive(); 385 // assert !path.isResolved(); 386 // Path resolved = path.tryFindResolution(); 387 // if (!resolved.isResolved()) { 388 // log.debug("creating: " + path); 389 // //TODO: access parent here, check if it is valid, only then create 390 // AccessInterface access = registry.prepareAccess(path.getTop().getParam()); 391 // assert access != null; 392 // Object child = access.createAccessee(); 393 // assert child != null; 394 // if (path.size() == 1) { 395 // setRoot(new Node(getRoot().getParam(), child)); 396 // } else { 397 // bindAccess(this, path.getUnder()).set(path.getTop().getParam(), child); 398 // } 399 // resolved = path.appendResolution(child); 400 // } 401 // tryRegisterOnChangeEvents(resolved); 402 // return resolved; 403 // } 254 protected final Map<EventListener<?>, EventListener<File>> proxyListeners = new IdentityHashMap<>(); 255 256 public <A> void addListener(Path path, EventParam param, final EventListener<A> listener, final Class<A> argumentType, final Future<Void> future) { 257 assert isActive(); 258 assert path.isResolved(); 259 if ((!argumentType.equals(Object.class)) && (null == registry.getFramsClassForJavaClass(argumentType))) { 260 registry.registerAndBuild(argumentType); 261 } 262 263 final EventListener<File> proxyListener = new EventListener<File>() { 264 265 @Override 266 public void action(final File file) { 267 Dispatching.dispatchIfNotActive(RemoteTree.this, new RunAt<RemoteTree>(RemoteTree.this) { 268 269 @Override 270 protected void runAt() { 271 assert isActive(); 272 if (argumentType.equals(Object.class)) { 273 listener.action(Casting.tryCast(argumentType, file)); 274 return; 275 } 276 AccessInterface access = registry.createAccess(argumentType); 277 Object argument = access.createAccessee(); 278 access.select(argument); 279 if (!argumentType.isInstance(argument)) { 280 throw new FramsticksException().msg("created argument is of wrond type").arg("expected", argumentType).arg("created", argument.getClass()); 281 } 282 A typedArgument = argumentType.cast(argument); 283 284 // log.info("executing event with argument " + argumentType); 285 MultiParamLoader loader = new MultiParamLoader(); 286 loader.setNewSource(file.getContent()); 287 loader.addBreakCondition(MultiParamLoader.Status.AfterObject); 288 loader.addAccessInterface(access); 289 loader.go(); 290 291 listener.action(typedArgument); 292 } 293 }); 294 } 295 }; 296 297 proxyListeners.put(listener, proxyListener); 298 299 connection.addListener(Path.appendString(path.getTextual(), param.getId()), proxyListener, this, future); 300 } 301 302 public void removeListener(Path path, EventParam param, EventListener<?> listener, Future<Void> future) { 303 assert isActive(); 304 EventListener<File> proxyListener = proxyListeners.get(listener); 305 connection.removeListener(proxyListener, this, future); 306 } 404 307 405 308 }
Note: See TracChangeset
for help on using the changeset viewer.