001package org.intellimate.izou.sdk.frameworks.permanentSoundOutput.output; 002 003import org.intellimate.izou.events.EventModel; 004import org.intellimate.izou.identification.Identification; 005import org.intellimate.izou.resource.ResourceModel; 006import org.intellimate.izou.sdk.Context; 007import org.intellimate.izou.sdk.frameworks.common.resources.SelectorResource; 008import org.intellimate.izou.sdk.frameworks.permanentSoundOutput.events.MuteEvent; 009import org.intellimate.izou.sdk.frameworks.permanentSoundOutput.events.StopEvent; 010import org.intellimate.izou.sdk.frameworks.permanentSoundOutput.events.UnMuteEvent; 011import org.intellimate.izou.sdk.output.OutputPlugin; 012 013import java.util.List; 014import java.util.Objects; 015import java.util.Optional; 016import java.util.concurrent.CompletableFuture; 017 018/** 019 * extend this class to use the framework 020 * @author LeanderK 021 * @version 1.0 022 */ 023public abstract class SimplePermanentSoundOutputPlugin<T> extends OutputPlugin<T> implements PermanentSoundUsed, 024 PermanentSoundHelper, PermanentSoundResources { 025 private boolean isCurrentlyPlayingSound = false; 026 public final boolean isUsingJava; 027 028 /** 029 * creates a new output-plugin with a new id 030 * 031 * @param context context 032 * @param id the id of the new output-plugin 033 */ 034 public SimplePermanentSoundOutputPlugin(Context context, String id, boolean isUsingJava) { 035 super(context, id); 036 resourcesInit(context); 037 this.isUsingJava = isUsingJava; 038 } 039 040 /** 041 * Default implementation waits until a new Event has been received and then processes it. 042 * <p> 043 * This method is made to be overwritten as seen fit by the developer 044 * 045 * @return the recently added Event-instance to be processed by the outputPlugin 046 * @throws InterruptedException if interrupted while waiting 047 */ 048 @Override 049 public EventModel blockingQueueHandling() throws InterruptedException { 050 EventModel eventModel = super.blockingQueueHandling(); 051 if (eventModel.containsDescriptor(MuteEvent.ID)) { 052 List<ResourceModel> resourceModels = 053 eventModel.getListResourceContainer().provideResource(SelectorResource.RESOURCE_ID); 054 if (resourceModels.isEmpty()) { 055 mute(); 056 } else { 057 resourceModels.stream() 058 .map(resourceModel -> resourceModel.getResource() instanceof Identification ? 059 ((Identification) resourceModel.getResource()) : null) 060 .filter(Objects::nonNull) 061 .filter(this::isOwner) 062 .findAny() 063 .ifPresent(id -> mute()); 064 } 065 } 066 if (eventModel.containsDescriptor(UnMuteEvent.ID)) { 067 List<ResourceModel> resourceModels = 068 eventModel.getListResourceContainer().provideResource(SelectorResource.RESOURCE_ID); 069 if (resourceModels.isEmpty()) { 070 unMute(); 071 } else { 072 resourceModels.stream() 073 .map(resourceModel -> resourceModel.getResource() instanceof Identification ? 074 ((Identification) resourceModel.getResource()) : null) 075 .filter(Objects::nonNull) 076 .filter(this::isOwner) 077 .findAny() 078 .ifPresent(id -> unMute()); 079 } 080 } 081 if (eventModel.containsDescriptor(StopEvent.ID)) { 082 List<ResourceModel> resourceModels = 083 eventModel.getListResourceContainer().provideResource(SelectorResource.RESOURCE_ID); 084 if (resourceModels.isEmpty()) { 085 stopSound(); 086 } else { 087 resourceModels.stream() 088 .map(resourceModel -> resourceModel.getResource() instanceof Identification ? 089 ((Identification) resourceModel.getResource()) : null) 090 .filter(Objects::nonNull) 091 .filter(this::isOwner) 092 .findAny() 093 .ifPresent(id -> stopSound()); 094 } 095 } 096 return eventModel; 097 } 098 099 100 101 /** 102 * retruns true if playing and false if not 103 * 104 * @return tre if playing 105 */ 106 @Override 107 public boolean isOutputRunning() { 108 return isCurrentlyPlayingSound; 109 } 110 111 /** 112 * true if using java, false if not (and for example a C-library) 113 * 114 * @return true if using java 115 */ 116 @Override 117 public boolean isUsingJava() { 118 return isUsingJava; 119 } 120 121 /** 122 * use this method to start playing sound (only plays sound if it is not already playing) 123 * @param function the function which plays the sound 124 * @return the Future 125 */ 126 public Optional<CompletableFuture<Void>> startPlaying(Runnable function) { 127 if (isCurrentlyPlayingSound) 128 return Optional.empty(); 129 CompletableFuture<Void> voidCompletableFuture = submit((Runnable) () -> startedSound(isUsingJava)) 130 .thenRun(() -> { 131 try { 132 isCurrentlyPlayingSound = true; 133 function.run(); 134 } finally { 135 submit((Runnable) this::endedSound); 136 isCurrentlyPlayingSound = false; 137 } 138 }); 139 return Optional.of(voidCompletableFuture); 140 } 141 142 /** 143 * this method call must mute the plugin 144 */ 145 public abstract void mute(); 146 147 /** 148 * this method call must un-mute the plugin 149 */ 150 public abstract void unMute(); 151 152 /** 153 * this method call must stop the sound 154 */ 155 public abstract void stopSound(); 156}