vendredi 12 mars 2021

Passing View elements as parameters without specifying a specific implementation

I want to implement Gamepad and Touchpad controllers for my app.

But idk how to implement passing MotionEvent from GenericMotionEvent to Gamepad class and UI controls to Tochpad class. P.S For Tocuhpad class i need some abstract UIController that will not depend to concrete implementation (button or seekbar or something). How to do it?

I tried to implement it something like this:

public class MainActivity extends AppCompatActivity {

    String settingsPath = Environment.getExternalStorageDirectory() + File.separator + "VehicleController" + File.separator;
    String settingsFilename = "newdata.json";
    Settings appSettings = null;

    ControllerFactory controllerFactory = new ControllerFactory();

    ControllerType controllerType;

    Controller userInputController;

    ControllerEventManager eventManager = new ControllerEventManager();

    public ArrayList<Integer> getGameControllerIds() {
        ArrayList<Integer> gameControllerDeviceIds = new ArrayList<Integer>();
        int[] deviceIds = InputDevice.getDeviceIds();
        for (int deviceId : deviceIds) {
            InputDevice dev = InputDevice.getDevice(deviceId);
            int sources = dev.getSources();

            // Verify that the device has gamepad buttons, control sticks, or both.
            if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD)
                    || ((sources & InputDevice.SOURCE_JOYSTICK)
                    == InputDevice.SOURCE_JOYSTICK)) {
                // This device is a game controller. Store its device ID.
                if (!gameControllerDeviceIds.contains(deviceId)) {
                    gameControllerDeviceIds.add(deviceId);
                }
            }
        }
        return gameControllerDeviceIds;
    }

    @Override
    public boolean onGenericMotionEvent(MotionEvent event) {
        eventManager.notify(event);
        return super.onGenericMotionEvent(event);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        LocalSettingsSaver settingsSaver = new LocalSettingsSaver(new FileManager(settingsPath, settingsFilename));

        VehicleController controller;

        appSettings = settingsSaver.load();

        if (getGameControllerIds().size() > 0){
            controllerType = ControllerType.GAMEPAD;
        }else{
            controllerType = ControllerType.TOUCHPAD;
        }

        userInputController = controllerFactory.createController(controllerType);


        eventManager.subscribe(userInputController);

    }
}

But i got an error in

eventManager.subscribe(userInputController);

because class Controller has not implementation of IMotionEventListener.

What can i do? Not all controllers need implementation of IMotionEventListener.

public abstract class Controller {

    protected ControllerMessage message = new ControllerMessage();
    protected ControllerInfo controllerInfo = new ControllerInfo();

    public ControllerMessage getControllerMessage(){
        return this.message;
    }
    public ControllerInfo getControllerInfo(){
        return this.controllerInfo;
    }
}

public class ControllerMessage {
    private float throttle = 0.0f;
    private float steering = 90.0f;

    public float getThrottle() {
        return throttle;
    }

    public void setThrottle(float throttle) {
        this.throttle = throttle;
    }

    public float getSteering() {
        return steering;
    }

    public void setSteering(float steering) {
        this.steering = steering;
    }

    public boolean getIsReverse() {
        return isReverse;
    }

    public void setReverse(boolean reverse) {
        isReverse = reverse;
    }

    private boolean isReverse = false;
}

public class ControllerEventManager {

    private List<MotionEventListener> listeners = new ArrayList<>();

    public void subscribe(MotionEventListener listener){
        listeners.add(listener);
    }

    public void unsubscribe(MotionEventListener listener){
        listeners.remove(listener);
    }

    public void notify(MotionEvent event){
        for (MotionEventListener listener : listeners){
            listener.onMotionEvent(event);
        }
    }

}

public interface MotionEventListener {
    void onMotionEvent(MotionEvent event);
}

public class ControllerFactory {
    public Controller createController(ControllerType type){

        Controller controller = null;

        if (type == ControllerType.GAMEPAD){
            controller = new Gamepad();
        }
        if (type == ControllerType.TOUCHPAD){
            controller = new TouchPad();
        }

        return controller;
    }
}

public enum ControllerType {
    GAMEPAD, TOUCHPAD
}

Aucun commentaire:

Enregistrer un commentaire