• S'inscrire
    • Se connecter
    • Recherche
    • Récent
    • Mots-clés
    • Populaire
    • Utilisateurs
    • Groupes

    Créer une API (ajout de recette)

    Archives
    1.8.x
    2
    6
    2750
    Charger plus de messages
    • Du plus ancien au plus récent
    • Du plus récent au plus ancien
    • Les plus votés
    Répondre
    • Répondre à l'aide d'un nouveau sujet
    Se connecter pour répondre
    Ce sujet a été supprimé. Seuls les utilisateurs avec les droits d'administration peuvent le voir.
    • BrokenSwing
      BrokenSwing Moddeurs confirmés Rédacteurs dernière édition par BrokenSwing

      Sommaire

      • Introduction

      • Pré-requis

      • Code

        • Création de toute les packages et toutes les classes
        • L’enum TutoApi
        • Les interfaces de l’Api
        • Les classes de l’Api
        • Utilisation de l’Api

        Introduction

        Aujourd’hui nous allons apprendre à créer une API (Application Programming Interface) ou Interface de programmation en français (source).
        La problématique est la suivante, imaginez que vous aillez un mod, il contient une machine quelconque possédant des recettes que vous avez préalablement établie dans
        votre code source. Mais vous aimeriez qu’un autre moddeur puisse ajouter lui aussi des recettes à votre machine sans modifier votre mod.
        La solution, vous la devinez et de créer une API afin qu’il puisse ajouter des recettes.

        Pré-requis

        • Avoir un mod fonctionnel
        • Avoir une bloc de type four

        Code

        Création de toute les packages et toutes les classes

        Dans un premier temps nous allons créer un enum nommée TutoApi qui se trouvera dans le dossier src/api/java
        Pour ce faire sélectionnez votre projet Eclipse contenant votre mod, clique droit -> New -> Source Folder
        Dans folder name tapez : src/api/java, validez. Créez maintenant un package avec le nom que vous voulez.
        Clique droit -> New -> Package et entrez le nom, validez.
        Dans ce package créez un enum appelé TutoApi. Dans le même package créez une interface que vous appelerez ITutoApi.
        Créez un sous-package nommé “features” dans lequel vous créez 3 interfaces :

        • IMachineTutoRecipe
        • IMachineTutoRegistry
        • IRegistryRecipes

        Ensuite dans le package “common” de votre mod (dans le dossier “src/main/java”) créez un package “core”.
        Dans “core” créez une classe ‘Api’ et un package ‘features’.
        Dans “features” créez une classe ‘MachineTutoRecipe’ et un package ‘registries’
        Dans “registries” créez une classe ‘RegistryRecipes’ et une classe ‘RegistryMachineTuto’

        Vous devriez avoir créé 9 fichier java.

        L’enum TutoApi

        Nom du fichier : TutoApi
        Ce fichier dans le dossier : src/api/java/
        Dans le package : modid.api
        Nous avons créer un enum car nous n’avons pas besoin d’instance.

        
        public enum TutoApi {
        
        	; //Aucun champs, il FAUT mettre le point-virgule
        
        	/** Chemin vers la classe Api */
        	private static final String API_CLASS_PATH = "prefix.common.core.Api";
        	/** Nom du champ contenant l'instance de la classe Api */
        	private static final String INSTANCE_FIELD = "INSTANCE";
        	/** //Instance de la classe Api */
        	private static ITutoApi API;
        
        	/**
        	*	Utilisation de la réflection pour récupérer l'instance de la classe Api
        	*/
        	static {
        		try {
        			final Class apiClass = Class.forName(API_CLASS_PATH);
        			final Field instanceField = apiClass.getDeclaredField(INSTANCE_FIELD);
        			API = (ITutoApi)(instanceField.get(apiClass));
        		} catch (final ClassNotFoundException e) {
        			e.printStackTrace();
        		} catch (final NoSuchFieldException e) {
        			e.printStackTrace();
        		} catch (final IllegalAccessException e) {
        			e.printStackTrace();
        		}
        	}
        
        	/**
        	*	@return L'instance de la classe Api
        	*/
        	public static ITutoApi instance() {
        		return API;
        	}
        }
        
        

        Voilà, il n’y a pas grand-chose à expliquer, on utilise la réflection pour obtenir l’instance de la classe Api

        Les interfaces de l’Api

        ITutoApi
        Dossier : src/api/java
        Package : modid.api

        Cette interface permet de récupérer le registre contenant toutes les recettes que nous mettons à disposition via l’API

        
        public interface ITutoApi {
        
        	/**
        	 * @return Le registre contenant toute les recettes
        	 */
        	public IRegistryRecipes recipes();
        
        }
        
        

        IRegistryRecipes
        Dossier : src/api/java
        Package : modid.api.features

        Cette interface permet de récupérer le registre contenant toute les recettes d’une certaines machine

        
        public interface IRegistryRecipes {
        
        	/**
        	* @return Le registre des recettes du bloc MachineTuto
        	*/
        	public IMachineTutoRegistry machineTuto();
        
        }
        
        

        IMachineTutoRegistry
        Dossier : src/api/java
        Package : modid.api.features

        Cette interface permet de récupérer de manipuler les recettes et le carburant du bloc MachineTuto

        
        public interface IMachineTutoRegistry {
        
        	/**
        	 * @return Une liste contenant les recettes du bloc MachineTuto
        	 */
        	public List <imachinetutorecipe>getRecipes();
        
        	/**
        	 * Permet d'ajouter une recette à la liste de recette
        	 * @param ItemStacks d'inputs
        	 * @param ItemStacks d'output
        	 */
        	public void addRecipe(ItemStack[] in, ItemStack[] out);
        
        	/**
        	 * Permet de récupérer la recette pour un input donné
        	 * @param ItemStacks d'input de la recette cherchée
        	 * @return
        	 */
        	public IMachineTutoRecipe getRecipeForInput(ItemStack[] in);
        
        	/**
        	 * Permet d'ajouter un carburant à la machine
        	 * @param Le carburant
        	 * @param La durée du carburant
        	 */
        	public void addFuel(ItemStack stack, Integer duration);
        
        	/**
        	 * @param Un carburant
        	 * @return La durée du carburant
        	 */
        	public int getFuelDuration(ItemStack stack);
        
        }
        
        

        IMachineTutoRecipe
        Dossier : src/api/java
        Package : modid.api.features

        Cette interface représente une recette du bloc MachineTuto

        
        public interface IMachineTutoRecipe {
        
        	/**
        	 * @return ItemStacks d'input de la recette
        	 */
        	public ItemStack[] getInput();
        
        	/**
        	 * Permet de modifier les ItemStacks d'input de la recette
        	 * @param ItemStacks d'input de la recette
        	 */
        	public void setInput(ItemStack[] input);
        
        	/**
        	 * @return ItemStacks d'output de la recette
        	 */
        	public ItemStack[] getOutput();
        
        	/**
        	 * Permet de modifier les ItemStacks d'output de la recette
        	 * @param ItemStacks d'output de la recette
        	 */
        	public void setOutput(ItemStack[] output);
        
        }
        
        

        Comme vous pouvez le voir grâce à ces interfaces le moddeur peut facilement ajouter ou modifier une recette sans réécrire le mod.

        Les classes de l’Api

        Api
        Dossier : src/main/java
        Package : prefix.common.core

        Cette classe est celle dont on a spécifié le chemin dans l’interface TutoApi, elle implémente l’interface ITutoApi

        
        public class Api implements ITutoApi {
        
        	/**
        	 * Instance de l'Api qui est récupéré par réflexion par l'enum TutoApi
        	 * "INSTANCE" est le champs qui est renseigné dans le second champs de la classe TutoApi
        	 */
        	public static final Api INSTANCE = new Api();
        
        	/**
        	 * Instance privé de l'interface IRegistryRecipes
        	 */
        	private IRegistryRecipes registryRecipes;
        
        	/**
        	 * Instanciation de l'interface IRegistryRecipes via la classe RegistryRecipes
        	 */
        	private Api() {
        		registryRecipes = new RegistryRecipes();
        	}
        
        	@Override
        	public IRegistryRecipes recipes() {
        		return registryRecipes;
        	}
        
        }
        
        

        RegistryRecipes
        Dossier : src/main/java
        Package : prefix.common.core.features.registries

        Cette classe implemente l’interface IRegistryRecipes

        
        public class RegistryRecipes implements IRegistryRecipes {
        
        	/**
        	 * Instance du registre du bloc MachineTuto
        	 */
        	private IMachineTutoRegistry machineTuto;;
        
        	/**
        	* Instanciation de la variable dans le constructeur
        	*/
        	public RegistryRecipes() {
        		machineTuto = new RegistryMachineTuto();
        	}
        
        	@Override
        	public IMachineTutoRegistry machineTuto() {
        		return machineTuto;
        	}
        
        }
        
        

        RegistryMachineTuto
        Dossier : src/main/java
        Package : prefix.common.core.features.registries

        Cette classe contient les recettes du bloc MachineTuto et la liste des fuels, elle implémente l’interface IMachineTutoRegistry

        
        public class RegistryMachineTuto implements IMachineTutoRegistry {
        
        	/** Mapping des carburant avec leur durée */
        	private Map <itemstack, integer="">fuelToTime = new HashMap<itemstack, integer="">();
        	/** List de recettes */
        	private List <imachinetutorecipe>recipes;
        
        	/**
        	 * Ajout des recettes et des carburants de base
        	 */
        	public RegistryMachineTuto()
        	{
        		this.recipes = new ArrayList<imachinetutorecipe>();
        		this.addFuel(new ItemStack(Items.blaze_powder), 5000);
        		this.addRecipe(new ItemStack[] {
        				new ItemStack(Items.apple),
        				new ItemStack(Items.apple),
        				new ItemStack(Items.apple),
        				new ItemStack(Items.apple)
        		}, new ItemStack[] {
        				new ItemStack(Items.apple),
        				new ItemStack(Items.apple)
        		});
        	}
        
        	@Override
        	public int getFuelDuration(ItemStack fuel)
        	{
        		Iterator<entry<itemstack, integer="">> iterator = this.fuelToTime.entrySet().iterator();
        		Entry <itemstack, integer="">entry;
        		do
        		{
        			if(!iterator.hasNext())
        			{
        				return 0;
        			}
        			entry = iterator.next();
        		}
        		while(fuel.getItem() != entry.getKey().getItem() || fuel.getItemDamage() != entry.getKey().getItemDamage() );
        
        		return entry.getValue();
        	}
        
        	@Override
        	public void addFuel(ItemStack fuel, Integer time)
        	{
        		fuelToTime.put(fuel, time);
        	}
        
        	@Override
        	public void addRecipe(ItemStack[] input, ItemStack[] output)
        	{
        		if(this.getRecipeForInput(input) == null);
        		recipes.add(new MachineTutoRecipe(input, output));
        	}
        
        	@Override
        	public List <imachinetutorecipe>getRecipes() {
        		return recipes;
        	}
        
        	@Override
        	public IMachineTutoRecipe getRecipeForInput(ItemStack[] in) {
        		if(in == null) return null;
        		if(in.length != TileEntityMachineTuto.INPUTS_SLOTS) return null;
        		for(IMachineTutoRecipe recipe : recipes) {
        			boolean recipeOK = true;
        			ItemStack[] inputs = recipe.getInput();
        			for(int i = 0; i < in.length; i++) {
        				if(!ItemStack.areItemsEqual(in*, inputs*)) recipeOK = false;
        			}
        			if(recipeOK) return recipe;
        		}
        		return null;
        	}
        }
        
        

        MachineTutoRecipe
        Dossier : src/main/java
        Package : prefix.common.core.features

        Cette classe est la classe d’une recette elle implémente l’interface IMachineTutoRecipe

        
        public class MachineTutoRecipe implements IMachineTutoRecipe {
        
        	/** ItemStacks d'input */
        	private ItemStack[] inputs;
        	/** ItemStacks d'ouput */
        	private ItemStack[] outputs;
        
        	public MachineTutoRecipe(ItemStack[] in, ItemStack[] out) {
        		inputs = in;
        		outputs = out;
        	}
        
        	@Override
        	public ItemStack[] getInput() {
        		return inputs;
        	}
        
        	@Override
        	public void setInput(ItemStack[] input) {
        		inputs = input;
        	}
        
        	@Override
        	public ItemStack[] getOutput() {
        		return outputs;
        	}
        
        	@Override
        	public void setOutput(ItemStack[] output) {
        		outputs = output;
        	}
        
        }
        
        

        Et voilà, c’est tout.

        Utilisation de l’Api

        Maintenant que tout est bon, il ne reste plus qu’à savoir s’en servir.
        Premièrement, lorsqu’un mod veut utiliser votre API il lui suffit d’ajouter à son buildpath tout ce qui se trouve dans src/api/java
        Ensuite quand il veut utiliser votre API il faut qu’il vérifie si votre mod est bien load

        
        Loader.isModLoaded(modid de votre mod) {
        	//Utilisation de votre API
        }
        
        

        Exemple de d’utilisation :

        
        Loader.isModLoaded(modid de votre mod) {
        	TutoApi.instance().recipes().machineTuto().addFuel(new ItemStack(Items.bone), 50);
        }
        
        

        Ce code ajoute comme carburant une os avec comme durée 50.
        C’est aussi simple que cela.

      1 réponse Dernière réponse Répondre Citer 0
      • SCAREX
        SCAREX dernière édition par

        Créer une API est une bonne idée pour organiser son mod !

        En revanche précise que c’est une API pour les recettes car une API c’est très général.

        Site web contenant mes scripts : http://SCAREXgaming.github.io

        Pas de demandes de support par MP ni par skype SVP.
        Je n'accepte sur skype que l…

        1 réponse Dernière réponse Répondre Citer 0
        • BrokenSwing
          BrokenSwing Moddeurs confirmés Rédacteurs dernière édition par

          Ici s’en est une pour les recettes parce qu’il fallait un exemple mais si comme tu le dit c’est général une API si on a compris le principe c’est simple de faire autre chose que rajouter des recettes. J’avoue que je ne suis pas encore super bon pour les API j’ai fait ça aujourd’hui en essayant de voir comment ça marche avec Applied donc si il y a des erreurs où autres n’hésite vraiment pas

          1 réponse Dernière réponse Répondre Citer 0
          • SCAREX
            SCAREX dernière édition par

            A vrai dire, une API est différente selon les personnes, chez certains c’est plus complet, chez d’autres c’est plus simple, mais le principal c’est de tout expliquer pour que tout le monde le change un peu à sa manière et de ce que je vois (j’ai pas tout lu) c’est bien commenté

            Site web contenant mes scripts : http://SCAREXgaming.github.io

            Pas de demandes de support par MP ni par skype SVP.
            Je n'accepte sur skype que l…

            1 réponse Dernière réponse Répondre Citer 0
            • BrokenSwing
              BrokenSwing Moddeurs confirmés Rédacteurs dernière édition par

              Ce qui fait bizarre, selon moi c’est que je me suis inspiré de l’API d’Applied qui est complète alors que dans le tutoriel je ne rajoute que le fait d’ajouter des recettes à un bloc ce qui fait qu’on a l’impression de brasser de l’air pour pas grand-chose

              1 réponse Dernière réponse Répondre Citer 0
              • SCAREX
                SCAREX dernière édition par

                L’organisation c’est bien, dans mon mod CSP j’ai fait une bonne API pour mes blocks ce qui me permet de créer un block avec model et système d’énergie integré avec seulement quelques lignes : https://github.com/SCAREXgaming/CSP/blob/master/src/main/java/fr/scarex/csp/block/SolarPanelFrame.java

                Site web contenant mes scripts : http://SCAREXgaming.github.io

                Pas de demandes de support par MP ni par skype SVP.
                Je n'accepte sur skype que l…

                1 réponse Dernière réponse Répondre Citer 0
                • 1 / 1
                • Premier message
                  Dernier message
                Design by Woryk
                Contact / Mentions Légales

                MINECRAFT FORGE FRANCE © 2018

                Powered by NodeBB