// Path: src/main/java/com/kasirgalabs/etumulator/util/BaseDispatcher.java
// public class BaseDispatcher implements Dispatcher {
//     private final List<Observer> observers;
// 
//     public BaseDispatcher() {
//         observers = new ArrayList<>(10);
//     }
// 
//     @Override
//     public void addObserver(Observer observer) {
//         observers.add(observer);
//     }
// 
//     @Override
//     public void notifyObservers(Class<?> clazz, Object arg) {
//         for(int i = 0; i < observers.size(); i++) {
//             observers.get(i).update(clazz, arg);
//         }
//     }
// 
//     @Override
//     public void notifyObservers(Class<?> clazz) {
//         notifyObservers(clazz, null);
//     }
// }
// 
// Path: src/main/java/com/kasirgalabs/etumulator/util/Dispatcher.java
// public interface Dispatcher {
//     void addObserver(Observer observer);
// 
//     void notifyObservers(Class<?> clazz, Object arg);
// 
//     void notifyObservers(Class<?> clazz);
// }
// 
// Path: src/main/java/com/kasirgalabs/etumulator/util/Observable.java
// public interface Observable {
//     void addObserver(Observer observer);
// }
// 
// Path: src/main/java/com/kasirgalabs/etumulator/util/Observer.java
// public interface Observer {
//     void update(Class<?> clazz, Object arg);
// }


import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.kasirgalabs.etumulator.util.BaseDispatcher;
import com.kasirgalabs.etumulator.util.Dispatcher;
import com.kasirgalabs.etumulator.util.Observable;
import com.kasirgalabs.etumulator.util.Observer;
package com.kasirgalabs.etumulator.processor;


/**
 * A program counter is a register in a that contains the address (location) of the instruction
 * being executed at the current time. As each instruction gets executed, the program counter
 * increases its stored value by 1. After each instruction is executed, the program counter
 * points to the next instruction in the sequence. When the processor restarts, the program counter
 * reverts to 0.
 * <p>
 * This class represents an observable object. After a state change on PC value, all of it's
 * observers will be notified through default {@link BaseDispatcher} or the Dispatcher initialized
 * during construction.
 *
 * @author Görkem Mülayim
 */
@Singleton
public class PC implements Observable {
    private int pc;
    private final Dispatcher dispatcher;

    /**
     * Construct a PC with {@link BaseDispatcher}.
     *
     * @see BaseDispatcher
     */
    public PC() {
        dispatcher = new BaseDispatcher();
    }

    /**
     * Construct a PC with the given dispatcher as parameter.
     *
     * @param dispatcher The dispatcher which will be used to notify observers.
     *
     * @see Dispatcher
     */
    @Inject
    public PC(Dispatcher dispatcher) {
        this.dispatcher = dispatcher;
    }

    /**
     * Adds an observer to the list of observers for this object.
     *
     * @param observer The observer to be deleted.
     *
     * @see Observer
     */
    @Override
// Path: src/main/java/com/kasirgalabs/etumulator/util/BaseDispatcher.java
// public class BaseDispatcher implements Dispatcher {
//     private final List<Observer> observers;
// 
//     public BaseDispatcher() {
//         observers = new ArrayList<>(10);
//     }
// 
//     @Override
//     public void addObserver(Observer observer) {
//         observers.add(observer);
//     }
// 
//     @Override
//     public void notifyObservers(Class<?> clazz, Object arg) {
//         for(int i = 0; i < observers.size(); i++) {
//             observers.get(i).update(clazz, arg);
//         }
//     }
// 
//     @Override
//     public void notifyObservers(Class<?> clazz) {
//         notifyObservers(clazz, null);
//     }
// }
// 
// Path: src/main/java/com/kasirgalabs/etumulator/util/Dispatcher.java
// public interface Dispatcher {
//     void addObserver(Observer observer);
// 
//     void notifyObservers(Class<?> clazz, Object arg);
// 
//     void notifyObservers(Class<?> clazz);
// }
// 
// Path: src/main/java/com/kasirgalabs/etumulator/util/Observable.java
// public interface Observable {
//     void addObserver(Observer observer);
// }
// 
// Path: src/main/java/com/kasirgalabs/etumulator/util/Observer.java
// public interface Observer {
//     void update(Class<?> clazz, Object arg);
// }


// Path: src/main/java/com/kasirgalabs/etumulator/processor/PC.java
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.kasirgalabs.etumulator.util.BaseDispatcher;
import com.kasirgalabs.etumulator.util.Dispatcher;
import com.kasirgalabs.etumulator.util.Observable;
import com.kasirgalabs.etumulator.util.Observer;

package com.kasirgalabs.etumulator.processor;


/**
 * A program counter is a register in a that contains the address (location) of the instruction
 * being executed at the current time. As each instruction gets executed, the program counter
 * increases its stored value by 1. After each instruction is executed, the program counter
 * points to the next instruction in the sequence. When the processor restarts, the program counter
 * reverts to 0.
 * <p>
 * This class represents an observable object. After a state change on PC value, all of it's
 * observers will be notified through default {@link BaseDispatcher} or the Dispatcher initialized
 * during construction.
 *
 * @author Görkem Mülayim
 */
@Singleton
public class PC implements Observable {
    private int pc;
    private final Dispatcher dispatcher;

    /**
     * Construct a PC with {@link BaseDispatcher}.
     *
     * @see BaseDispatcher
     */
    public PC() {
        dispatcher = new BaseDispatcher();
    }

    /**
     * Construct a PC with the given dispatcher as parameter.
     *
     * @param dispatcher The dispatcher which will be used to notify observers.
     *
     * @see Dispatcher
     */
    @Inject
    public PC(Dispatcher dispatcher) {
        this.dispatcher = dispatcher;
    }

    /**
     * Adds an observer to the list of observers for this object.
     *
     * @param observer The observer to be deleted.
     *
     * @see Observer
     */
    @Override
    public void addObserver(Observer observer) {