/** * Copyright (c) 2009-2011, The HATS Consortium. All rights reserved. * This file is licensed under the terms of the Modified BSD License. */ package abs.backend.java.lib.runtime; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import abs.backend.java.lib.types.ABSBool; import abs.backend.java.lib.types.ABSValue; import abs.backend.java.observing.COGView; import abs.backend.java.observing.ObjectCreationObserver; import abs.backend.java.observing.TaskSchedulerView; import abs.backend.java.scheduling.DefaultTaskScheduler; import abs.backend.java.scheduling.SimpleTaskScheduler; import abs.backend.java.scheduling.TaskScheduler; import abs.backend.java.scheduling.TaskSchedulingStrategy; public class COG implements ABSValue { private final TaskScheduler scheduler; private final Class<?> initialClass; private final int id; private final ABSRuntime runtime; private abs.backend.java.lib.types.ABSInterface dc; public COG(ABSRuntime runtime, Class<?> clazz, abs.backend.java.lib.types.ABSInterface dc) { initialClass = clazz; this.runtime = runtime; scheduler = runtime.createTaskScheduler(this); id = runtime.freshCOGID(); this.dc = dc; } public COG(ABSRuntime runtime, Class<?> clazz, abs.backend.java.lib.types.ABSInterface dc, TaskSchedulingStrategy schedulingStrategy) { initialClass = clazz; this.runtime = runtime; scheduler = runtime.createUserTaskScheduler(this, schedulingStrategy); id = runtime.freshCOGID(); this.dc = dc; } public ABSRuntime getRuntime() { return runtime; } public Class<?> getInitialClass() { return initialClass; } public TaskScheduler getScheduler() { return scheduler; } public abs.backend.java.lib.types.ABSInterface getDC() { return dc; } public void addTask(Task<?> task) { scheduler.addTask(task); } public int getID() { return id; } public String toString() { return "COG [" + initialClass.getSimpleName() + "] (" + getID() + ")"; } public void objectCreated(ABSObject absObject) { if (view != null) view.objectCreated(absObject); } public void objectInitialized(ABSObject absObject) { if (view != null) view.objectInitialized(absObject); } private View view; public synchronized COGView getView() { if (view == null) { view = new View(); } return view; } private class View implements COGView { private List<ObjectCreationObserver> creationListeners; private Map<String, List<ObjectCreationObserver>> creationClassListeners; synchronized void notifyListeners(ABSObject absObject, boolean created) { if (creationListeners != null) { for (ObjectCreationObserver l : creationListeners) { if (created) l.objectCreated(absObject.getView()); else l.objectInitialized(absObject.getView()); } } if (creationClassListeners != null) { List<ObjectCreationObserver> list = creationClassListeners.get(absObject.getClassName()); if (list != null) { for (ObjectCreationObserver l : list) { if (created) l.objectCreated(absObject.getView()); else l.objectInitialized(absObject.getView()); } } } } synchronized void objectCreated(ABSObject absObject) { notifyListeners(absObject, true); } synchronized void objectInitialized(ABSObject absObject) { notifyListeners(absObject, false); } @Override public synchronized void registerObjectCreationListener(ObjectCreationObserver listener) { if (creationListeners == null) { creationListeners = new ArrayList<ObjectCreationObserver>(1); } creationListeners.add(listener); } @Override public synchronized void registerObjectCreationListener(String className, ObjectCreationObserver e) { if (creationClassListeners == null) { creationClassListeners = new HashMap<String, List<ObjectCreationObserver>>(); } List<ObjectCreationObserver> list = creationClassListeners.get(className); if (list == null) { list = new ArrayList<ObjectCreationObserver>(1); creationClassListeners.put(className, list); } list.add(e); } @Override public TaskSchedulerView getScheduler() { return scheduler.getView(); } @Override public int getID() { return id; } } public void register(ABSObject absObject) { // nothing to do } @Override public ABSBool eq(ABSValue o) { return ABSBool.fromBoolean(this.equals(o)); } @Override public ABSBool notEq(ABSValue o) { return eq(o).negate(); } @Override public ABSBool gt(ABSValue other) { if (other.getClass() == COG.class) { return ABSBool.fromBoolean(this.id > ((COG)other).getID()); } else { // type error, not reached return ABSBool.FALSE; } } @Override public ABSBool lt(ABSValue other) { if (other.getClass() == COG.class) { return ABSBool.fromBoolean(this.id < ((COG)other).getID()); } else { // type error, not reached return ABSBool.FALSE; } } @Override public ABSBool gtEq(ABSValue other) { if (other.getClass() == COG.class) { return eq(other).or(gt(other)); } else { // type error, not reached return ABSBool.FALSE; } } @Override public ABSBool ltEq(ABSValue other) { if (other.getClass() == COG.class) { return eq(other).or(lt(other)); } else { // type error, not reached return ABSBool.FALSE; } } @Override public boolean isDataType() { return false; } @Override public boolean isReference() { return true; } }