Commit 47f4ca69 authored by Martin LOISEAU's avatar Martin LOISEAU 🎄
Browse files

Clean code and add a lot of comments

parent f390ef27
......@@ -7,14 +7,14 @@ import android.util.Log;
import java.util.ArrayList;
class listener implements RecognitionListener
class Listener implements RecognitionListener
{
boolean result_available;
public boolean already_gave_results;
ArrayList<String> result_strings; // ordered by likeliness
MainActivity mainActivity;
public listener(MainActivity mainActivity)
public Listener(MainActivity mainActivity)
{
result_available = false;
result_strings = null;
......@@ -46,38 +46,21 @@ class listener implements RecognitionListener
}
public void onResults(Bundle results)
{
if(already_gave_results) return; // this is because of an oppen issue on google's end https://issuetracker.google.com/issues/152628934'
if(already_gave_results) return; // this is a fix of an open issue on google's end https://issuetracker.google.com/issues/152628934'
else already_gave_results = true;
if (results == null) {
Log.d("Debug", "no speech detected " + results);
return;
}
Log.d("Debug", "onResults " + results);
/* useless because apparently max confidence index is always 0*/
/*ArrayList ConfidenceScores = results.getStringArrayList(SpeechRecognizer.CONFIDENCE_SCORES);
float MaxConfidence = 0;
int IndexOfMax = 0;
for(int i = 0; i < ConfidenceScores.size(); i++)
{
if((float)ConfidenceScores.get(i) > MaxConfidence)
{
MaxConfidence = (float)ConfidenceScores.get(i);
IndexOfMax = i;
}
}*/
result_strings = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
// results are ordered by likeliness/confidence
Log.d("Debug", "Best confidence result: " + (String)result_strings.get(0));
result_available = true;
mainActivity.SetListeningResults((String)result_strings.get(0));
/*
for (int i = 0; i < data.size(); i++)
{
Log.d("Debug", "result " + data.get(i));
str += data.get(i);
}*/
//mText.setText("results: "+String.valueOf(data.size()));
}
public void onPartialResults(Bundle partialResults)
{
Log.d("Debug", "onPartialResults");
......
......@@ -44,9 +44,9 @@ public class MainActivity extends AppCompatActivity {
private CaptureQR QRActionRequesting;
private CaptureSpeech SpeechRequest;
private Intent recognizerIntent;
private listener listener;
private Listener listener;
//game logic
// logic
public ArrayList<Atom> Atoms;
public ArrayList<Node> OpenNodes, EveryNode, NodesToRemove, NodesToAdd;
......@@ -93,6 +93,11 @@ public class MainActivity extends AppCompatActivity {
}
public void CheckOpenNodes() {
/*
* Enter point of the logic.
* This function is called at the beginning of the game, and by running nodes when they
* finished their actions
*/
// this supposedly prevents java.util.ConcurrentModificationException
if(NodesToAdd.size()>0) {
......@@ -104,6 +109,8 @@ public class MainActivity extends AppCompatActivity {
NodesToRemove.clear();
}
// mainThread contains the rest of the logic
// threading should prevent blocking of use but as it is user input seems still locked for some actions (TTS)
if(OpenNodes.size()>0) mainThread.run();
else Log.d("Debug2", "NO OPEN NODE - GAME OVER");
}
......@@ -122,6 +129,7 @@ public class MainActivity extends AppCompatActivity {
}
private void initializeListeners() {
// initialisation of button, unused in the game but usefull for testing input
FloatingActionButton photo = findViewById(R.id.photo);
// Should open camera to take a picture of a QR code
......@@ -169,7 +177,7 @@ public class MainActivity extends AppCompatActivity {
});
}
public void LaunchGame(View v) throws InterruptedException // called when the "play" button is pressed on title screen
public void LaunchGame(View v) // called when the "play" button is pressed on title screen
{
CheckOpenNodes();
......@@ -240,7 +248,7 @@ public class MainActivity extends AppCompatActivity {
@Override
protected void onPostResume() {
super.onPostResume();
// Trigger the end of QRActionRequesting only onPostResume() to avoid a weird crash
if(QRActionRequesting != null) QRActionRequesting.TriggerEnd();
}
......@@ -275,14 +283,12 @@ public class MainActivity extends AppCompatActivity {
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,"voice.recognition.test");
recognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,2);
}
public void GetSpeech(CaptureSpeech calling_action) {
this.SpeechRequest = calling_action;
listener = new listener(this);
listener = new Listener(this);
sr = SpeechRecognizer.createSpeechRecognizer(this);
sr.setRecognitionListener(listener);
......
......@@ -3,15 +3,10 @@ package com.example.qrquest;
import android.util.Log;
import com.example.qrquest.atom.Atom;
import com.example.qrquest.atom.QRAtom;
import com.example.qrquest.atom.SpeechAtom;
import com.example.qrquest.node.Node;
import java.util.ArrayList;
public class MainThread implements Runnable {
private MainActivity mainActivity;
public Thread NodeThread;
public MainThread(MainActivity mainActivity)
{
......@@ -22,6 +17,7 @@ public class MainThread implements Runnable {
public void CheckOpenNodes() {
Log.d("Debug2", "CheckOpenNodes called");
Log.d("Debug2", "Open Nodes:");
// First we display every open node and every atom (useful for debug)
for (Node n : mainActivity.OpenNodes)
{
String node_info = "ID: " + n.ID + " requires ";
......@@ -37,19 +33,14 @@ public class MainThread implements Runnable {
Log.d("Debug2", a.displayType() + a.GetStringValue());
}
// Then we check every node and trigger the first one twhere the conditions are satisfied (every required atom present)
for (Node n : mainActivity.OpenNodes)
{
if (n.CheckConditions(mainActivity.Atoms))
{
Log.d("Debug2", "Triggering node " + Integer.toString(n.ID));
//NodeThread = new Thread(n);
// n.Trigger();
//NodeThread.run();
//NodeThread.join();
n.Trigger(); // Triggers only the first node
n.Trigger();
break;
//while(NodeThread.isAlive()) {};
//this.CheckOpenNodes();
}
}
}
......
......@@ -18,16 +18,12 @@ import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.util.ArrayList;
/*
* Created by Martin Loiseau on 06/2020
* Heavily inspired by MainActivity of QRLudo https://github.com/univ-angers/QRLudo
*/
public class QRCaptureActivity extends AppCompatActivity {
// attributes from QRLudo:
CameraSource m_cameraSource;
SurfaceView m_cameraView;
private int cameraState;
......@@ -42,8 +38,6 @@ public class QRCaptureActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
Log.d("Debug2", "Created QR activity");
setContentView(R.layout.photo_activity);
// Toolbar toolbar = findViewById(R.id.toolbar);
//setSupportActionBar(toolbar);
initializeAttributes();
setUpDetector();
......@@ -55,10 +49,6 @@ public class QRCaptureActivity extends AppCompatActivity {
protected void onDestroy() {
super.onDestroy();
// probably need to unbind service here to prevent leaked ServiceConnection warning
// However I can't identify the service used in this activity
//unbindService(something?);
}
/**
......
......@@ -29,7 +29,7 @@ import java.util.ArrayList;
public class ScenarioLoader {
/*
* The goal of the com.example.qrquest.ScenarioLoader is to get the list of every node from a scenario xml file
* The goal of the ScenarioLoader is to get the list of every node from the scenario.xml file in res/raw
*/
ArrayList<Node> ScenarioNodes;
MainActivity mainActivity;
......@@ -47,7 +47,7 @@ public class ScenarioLoader {
*/
InputStream in = mainActivity.getResources().openRawResource(
mainActivity.getResources().getIdentifier("scenario_kouzou",
mainActivity.getResources().getIdentifier("scenario_kouzou", // specify the file name here
"raw", mainActivity.getPackageName()));
try {
......@@ -302,26 +302,11 @@ public class ScenarioLoader {
return result;
}
/*
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}*/
private ArrayList<Node> HardCodedScenario(MainActivity mainActivity)
/*
* Another option is to directly load the scenario in the code
* This is useful to debug
*/
{
ArrayList<Action> A1 = new ArrayList<Action>();
A1.add(new TTSReading(mainActivity, 1, "Bonjour"));
......@@ -386,6 +371,6 @@ public class ScenarioLoader {
public ArrayList<Node> GetNodes() throws IOException, XmlPullParserException {
return XMLScenario(mainActivity);
//return HardCodedScenario(mainActivity);
//return HardCodedScenario(mainActivity); // Uncomment to get the hardcoded scenario
}
}
......@@ -15,7 +15,7 @@ public abstract class Action {
this.nodeID = nodeID;
}
public void Do()
public void Do() // every action should override this method, call super.Do() at the beginning and End() at the End.
{
this.node = mainActivity.GetNode(nodeID); // getting the node in order to call the next action when action is over
}
......
......@@ -8,7 +8,7 @@ import com.example.qrquest.atom.QRAtom;
public class CaptureQR extends Action {
/*
* This action will open the camera to let the user scan a QR code
* It will add the scanned QR code as a new atom
* It will add the scanned QR code as a new QRAtom
*/
public CaptureQR(MainActivity mainActivity, int nodeID) {
super(mainActivity, nodeID);
......
......@@ -6,6 +6,10 @@ import com.example.qrquest.MainActivity;
import com.example.qrquest.atom.SpeechAtom;
public class CaptureSpeech extends Action {
/*
* This action will listen for the player voice
* And add the word said by the player as a SpeechAtom
*/
public CaptureSpeech(MainActivity mainActivity, int nodeID) {
super(mainActivity, nodeID);
}
......
......@@ -6,6 +6,10 @@ import com.example.qrquest.atom.Atom;
import java.util.ArrayList;
public class ClearAtoms extends Action {
/*
* This action remove every atom of a specified class
* It is useful for player created atoms like QRAtom or SpeechAtom
*/
private Class atom_class;
public ClearAtoms(MainActivity mainActivity, int nodeID, Class atom_class) {
......
......@@ -6,6 +6,9 @@ import com.example.qrquest.MainActivity;
import com.example.qrquest.node.Node;
public class ClearNodes extends Action {
/*
* This action removes every OpenNode
*/
public ClearNodes(MainActivity mainActivity, int nodeID) {
super(mainActivity, nodeID);
......
......@@ -6,12 +6,12 @@ import com.example.qrquest.MainActivity;
import com.example.qrquest.atom.Atom;
public class RemoveAtom extends Action {
/*
* Remove a specific atom
*/
Atom _atom;
public RemoveAtom(MainActivity mainActivity, int nodeID, Atom atom) {
/*
* Remove a specific atom
*/
super(mainActivity, nodeID);
_atom = atom;
}
......
......@@ -3,9 +3,11 @@ package com.example.qrquest.actions;
import android.util.Log;
import com.example.qrquest.MainActivity;
import com.example.qrquest.node.Node;
public class RemoveNode extends Action {
/*
* Remove a specific node
*/
private int _nodeToRemoveID;
public RemoveNode(MainActivity mainActivity, int nodeID, int nodeToRemoveID) {
......@@ -18,7 +20,6 @@ public class RemoveNode extends Action {
super.Do();
if(!mainActivity.OpenNodes.contains(mainActivity.GetNode(_nodeToRemoveID))) throw new Error("Tried to remove a node that wasn't open");
Log.d("Debug2", "Removed node " + _nodeToRemoveID);
// mainActivity.OpenNodes.remove(mainActivity.GetNode(_nodeToRemoveID));
mainActivity.NodesToRemove.add(mainActivity.GetNode(_nodeToRemoveID));
End();
}
......
......@@ -5,7 +5,9 @@ import com.example.qrquest.MainActivity;
import com.example.qrquest.TTSReader;
public class TTSReading extends Action {
// TextToSpeech tts;
/*
* Say out lout a string of text using text-to-speech
*/
private String TextToRead;
......@@ -21,6 +23,7 @@ public class TTSReading extends Action {
// read TextToRead
mainActivity.ttsreader.PlayTTS(TextToRead);
while(!mainActivity.ttsreader.isOver()) {} // block while speaking
// This seems to blocks other inputs from the player such as changing volume
End();
}
......
......@@ -3,14 +3,18 @@ package com.example.qrquest.atom;
public class Any extends Atom {
/*
* This atom will be considered as the same as any other atom of class WantedClass
* It is used to catch unwanted values such as QRatoms or Speechatoms that doesn't trigger
* any node
* It is used to catch unwanted values such as QRAtoms or SpeechAtoms that doesn't trigger
* any previous node (like an else case)
* Note: an Any atom CANNOT be obtained by the player and will crash the game if in mainActivity.Atoms.
*
* This detection could have been done by creating a special Node that triggers whenever an Atom of
* a waited class is present
*/
public Class WantedClass;
public Any(String WantedClass)
{
// takes as only parameter the class of atom we want to detect as a string
this.WantedClass = getClassFromName(WantedClass);
}
......@@ -21,11 +25,11 @@ public class Any extends Atom {
@Override
public String GetStringValue() {
return null;
return WantedClass.toString();
}
@Override
public String displayType() {
return null;
return "[Any] ";
}
}
......@@ -2,13 +2,16 @@ package com.example.qrquest.atom;
public abstract class Atom {
/*
* Représente un item débloqué par le joueur
* Une certaine combinaison d'atome peut permettre de déclencher les actions d'un noeud ouvert
* An atom is an item created or gathered by the player
* Atoms will trigger a node if they match its Conditions list
*/
public boolean isSame(Atom atom)
{
if(this.getClass() == Any.class) throw new Error("Applied is same to Any atom (should be called in parameter)");
/*
* Comparison method
*/
if(this.getClass() == Any.class) throw new Error("Applied isSame() to \"Any\" atom (should be called in parameter)");
if(atom.getClass() == Any.class)
{
Any _Any = (Any)atom;
......@@ -22,6 +25,7 @@ public abstract class Atom {
}
else
{
// if both atom in the comparison are from the same class, call the comparison method of said class
return (hasSameValue(atom));
}
}
......@@ -33,6 +37,7 @@ public abstract class Atom {
public abstract String displayType();
protected Class getClassFromName(String checkedClassString) {
// this can probably get automated
if(checkedClassString.equals("QRAtom")) return QRAtom.class;
else if(checkedClassString.equals("SpeechAtom")) return SpeechAtom.class;
else if(checkedClassString.equals("Any")) return Any.class;
......
package com.example.qrquest.atom;
public final class ItemAtom extends Atom {
/*
* ItemAtom is typically used for unlockable items
*/
int ID;
public ItemAtom(int ID)
......
package com.example.qrquest.atom;
public final class QRAtom extends Atom {
/*
* Content from a QR code stored as a string
*/
public String AtomContent;
public QRAtom(String AtomContent)
......
package com.example.qrquest.atom;
public final class SpeechAtom extends Atom {
/*
* Contains a string of text said by the player
*/
String AtomContent;
public SpeechAtom(String AtomContent)
......
package com.example.qrquest.exceptions;
/**
* Created by Jules Leguy on 20/01/18.
*/
/**
* Thrown when a QRCode object cannot be built from a XML object
*/
public class UnhandledQRException extends Exception {
public UnhandledQRException(String message){
super(message);
}
}
package com.example.qrquest.exceptions;
/**
* Valentine Rahier
* Classe permettant de vérifier la version du QRCode scanné
*/
public class UnsupportedQRException extends Exception {
public UnsupportedQRException(String message){
super(message);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment