Added new module extension

This commit is contained in:
Robert Vokac 2024-09-28 17:53:22 +02:00
parent f2525489bb
commit 1b5e436d09
Signed by: robertvokac
GPG Key ID: FB9CE8E20AADA55F
4 changed files with 208 additions and 9 deletions

View File

@ -28,6 +28,7 @@ import com.pixelgamelibrary.api.interfaces.Internal;
import com.pixelgamelibrary.api.interfaces.Net;
import com.pixelgamelibrary.api.interfaces.Utils;
import com.pixelgamelibrary.api.interfaces.App;
import com.pixelgamelibrary.api.interfaces.Extension;
/**
*
@ -47,38 +48,46 @@ public class Pixel {
////
public static App app() {
return get().app();
return extension().getOrDefault(App.class, get().app());
}
public static Graphics graphics() {
return get().graphics();
return extension().getOrDefault(Graphics.class, get().graphics());
}
public static Audio audio() {
return get().audio();
return extension().getOrDefault(Audio.class, get().audio());
}
public static Input input() {
return get().input();
return extension().getOrDefault(Input.class, get().input());
}
public static Net net() {
return get().net();
return extension().getOrDefault(Net.class, get().net());
}
public static Files files() {
return get().files();
return extension().getOrDefault(Files.class, get().files());
}
public static Utils utils() {
return get().utils();
return extension().getOrDefault(Utils.class, get().utils());
}
public static Internal internal() {
return get().internal();
return extension().getOrDefault(Internal.class, get().internal());
}
////
public static Extension extension() {
return get().extension();
}
public static <T> T get(Class<T> clazz) {
return get().get(clazz);
}
////
public static void initBackend(PixelBackend pixelBackend) {
if (isBackendSet()) {
throw new PixelException("Pixel Backend was already set");

View File

@ -0,0 +1,77 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Pixel: Game library.
// Copyright (C) 2024 the original author or authors.
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.extension;
import com.pixelgamelibrary.api.PixelException;
import com.pixelgamelibrary.api.interfaces.Extension;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
* @author robertvokac
*/
public class ExtensionImpl implements Extension {
private static final ExtensionImpl INSTANCE = new ExtensionImpl();
public static Extension getInstance() {
return INSTANCE;
}
public ExtensionImpl() {
}
// Map to hold registered implementations
private final Map<Class<?>, Object> implementations = new HashMap<>();
// Implement the method for registering implementations
@Override
public <T> void register(Class<T> interfaceClass, T implementation) {
if(interfaceClass == Extension.class) {
throw new PixelException("Custom implementation of interface Extension cannot be registred.");
}
implementations.put(interfaceClass, implementation);
System.out.println("Registered implementation for: " + interfaceClass.getName());
}
// Implementation of the generic method getImplementation \
@Override
public <T> T get(Class<T> clazz) {
T implementation = (T) implementations.get(clazz);
if (implementation == null) {
throw new IllegalArgumentException("No implementation registered for: " + clazz.getName());
}
return implementation;
}
@Override
public <T> boolean has(Class<T> clazz) {
return implementations.containsKey(clazz);
}
@Override
public List<Class<?>> list() {
return implementations.keySet().stream().collect(Collectors.toList());
}
}

View File

@ -0,0 +1,90 @@
////////////////////////////////////////////////////////////////////////////////////////////////
// Pixel: Game Library - Extension Module
// Copyright (C) 2024 the original author or authors.
//
// This program is free software: you can redistribute it and/or modify it under the terms of
// the GNU General Public License as published by the Free Software Foundation, either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program.
// If not, see <https://www.gnu.org/licenses/> or write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
////////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.interfaces;
import java.util.List;
/**
* The Extension interface allows the registration and retrieval of various
* implementations for specific interfaces. It acts as a flexible extension
* module, enabling dynamic modularization and adding extensibility to the
* Pixel Game Library.
*
* This interface provides generic methods to register, retrieve, and check
* the availability of registered implementations, offering a loosely coupled
* and highly flexible way to extend the game library.
*
* @author robertvokac
*/
public interface Extension {
/**
* Registers an implementation for a given interface class.
*
* This method allows you to register an implementation for a specific
* interface, enabling the extension mechanism to return the appropriate
* implementation when requested.
*
* @param <T> the type of the interface to be registered
* @param interfaceClass the Class object of the interface to be implemented
* @param implementation the instance of the implementation that corresponds to the interface
*/
<T> void register(Class<T> interfaceClass, T implementation);
/**
* Retrieves the registered implementation for a given interface.
*
* This method returns the implementation instance that was previously
* registered for the provided interface class.
*
* @param <T> the type of the interface
* @param clazz the Class object of the interface for which the implementation is requested
* @return the registered implementation of the interface, or null if no implementation is registered
*/
<T> T get(Class<T> clazz);
default <T> T getOrDefault(Class<T> clazz, T defaultInstance) {
if(has(clazz)) {
return get(clazz);
} else {
return defaultInstance;
}
}
/**
* Checks if an implementation is registered for a specific interface class.
*
* This method verifies whether there is an implementation registered for
* the given interface class.
*
* @param <T> the type of the interface
* @param clazz the Class object of the interface to be checked
* @return true if an implementation is registered, false otherwise
*/
<T> boolean has(Class<T> clazz);
/**
* Lists all the registered interface classes.
*
* This method provides a list of all the interface classes for which
* implementations have been registered. It can be useful for debugging or
* introspection purposes.
*
* @return a List of Class objects representing the registered interfaces
*/
List<Class<?>> list();
}

View File

@ -19,6 +19,9 @@
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.interfaces;
import com.pixelgamelibrary.api.PixelException;
import com.pixelgamelibrary.api.extension.ExtensionImpl;
/**
*
* @author robertvokac
@ -29,9 +32,29 @@ public interface PixelBackend {
Graphics graphics();
Audio audio();
Input input();
//
Net net();
Files files();
Utils utils();
Internal internal();
//
default Extension extension() {
return ExtensionImpl.getInstance();
}
default <T> T get(Class<T> clazz) {
if(clazz.equals(App.class)) {return (T) app();}
if(clazz.equals(Graphics.class)) {return (T) graphics();}
if(clazz.equals(Audio.class)) {return (T) audio();}
if(clazz.equals(Input.class)) {return (T) input();}
//
if(clazz.equals(Net.class)) {return (T) net();}
if(clazz.equals(Files.class)) {return (T) files();}
if(clazz.equals(Utils.class)) {return (T) utils();}
if(clazz.equals(Internal.class)) {return (T) internal();}
//
if(clazz.equals(Extension.class)) {return (T) extension();}
throw new PixelException("Unsupported interface: " + clazz.getName());
}
}