Skip to content

Commit

Permalink
refactor multimode wait and play process
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack-Chagarr committed Oct 31, 2023
1 parent 0267380 commit 0f65e95
Show file tree
Hide file tree
Showing 17 changed files with 643 additions and 127 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Queue;

public class MultiModeRoom implements Serializable {


private static final long serialVersionUID = 1L;
private final int GAME_STARTED = 1;
private final int GAME_NOT_STARTED = 0;
private final transient List<ObjectOutputStream> clientOutputStreams = new ArrayList<>();
private final HashSet<Integer> finishedUserSet = new HashSet<>();
private int status = GAME_NOT_STARTED;
private int finishCount = 0;
private int id; // 룸 ID
private List<MultiModeUser> userList; //유저 정보
private MultiModeUser roomOwner; // 방장
Expand All @@ -29,6 +33,7 @@ public class MultiModeRoom implements Serializable {

private Queue<UserDistance> updateQueue;


public MultiModeRoom(int roomId, RoomCreateInfo roomCreateInfo) { // 유저가 방을 만들때
userList = new ArrayList<MultiModeUser>();
this.id = roomId;
Expand Down Expand Up @@ -226,6 +231,21 @@ public int compare(UserDistance user1, UserDistance user2) {
return null;
}

public void addFinishCount(MultiModeUser user) {
if (!finishedUserSet.contains(user.getId())) {
finishCount++;
}
}

public boolean checkGameFinished() {
return finishCount == userList.size();
}

public void startGame() {
status = GAME_STARTED;
}


@Override
public int hashCode() {
return id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ public class Protocol {
public static final int UPDATE_USER_DISTANCE = 7;
public static final int UPDATE_TOP3_STATES = 8;
public static final int START_GAME = 9;
public static final int EXIT_GAME = 10;
public static final int FINISH_GAME = 11;
public static final int CLOSE_GAME = 12;
}

Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,8 @@
import MultiMode.Protocol;

public class MultiModeAdapter extends RecyclerView.Adapter<MultiModeAdapter.ViewHolder> {

//MultiModeUser user = new MultiModeUser(3, "apple");
private final SocketManager socketManager = SocketManager.getInstance(); // SocketManager 인스턴스를 가져옴
MultiModeUser user = new MultiModeUser(2, "berry"); // 유저 정보 임시로 더미데이터 활용
//MultiModeUser user = new MultiModeUser(1, "choco"); // 유저 정보 임시로 더미데이터 활용
MultiModeUser user = MultiModeFragment.user;
MultiModeRoom selectedRoom;
//MultiMode List 화면에서 각 Room Button과 관련된 Adapter
private List<MultiModeRoom> roomList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
public class MultiModeFragment extends Fragment {


//MultiModeUser user = new MultiModeUser(3, "apple");
public static MultiModeUser user = new MultiModeUser(1, "choco");
//public static MultiModeUser user = new MultiModeUser(2, "berry"); // 유저 정보 임시로 더미데이터 활용
//public static MultiModeUser user = new MultiModeUser(3, "apple");
private final SocketManager socketManager = SocketManager.getInstance(); // SocketManager 인스턴스를 가져옴
MultiModeUser user = new MultiModeUser(2, "berry"); // 유저 정보 임시로 더미데이터 활용
//MultiModeUser user = new MultiModeUser(1, "choco");
Dialog dialog;
private Button createRoomButton;
private RecyclerView recyclerView;
Expand Down Expand Up @@ -114,8 +114,8 @@ public void onClick(View v) {
if (startTime.isBefore(now)) {
startTime = startTime.plusDays(1);
}
//RoomCreateInfo roomInfo = new RoomCreateInfo(groupName, distance, LocalDateTime.now().plusSeconds(5), numRunners, duration);
RoomCreateInfo roomInfo = new RoomCreateInfo(groupName, 0, startTime, numRunners, duration);
RoomCreateInfo roomInfo = new RoomCreateInfo(groupName, 0, LocalDateTime.now().plusSeconds(5), numRunners, duration);
//RoomCreateInfo roomInfo = new RoomCreateInfo(groupName, 0, startTime, numRunners, duration);
new SendRoomInfoTask().execute(roomInfo); //소켓에 연결하여 패킷 전송

}
Expand Down Expand Up @@ -276,4 +276,6 @@ protected void onPostExecute(Boolean success) {

}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;

import com.example.runusandroid.MainActivity2;
import com.example.runusandroid.R;
Expand Down Expand Up @@ -47,9 +49,9 @@
public class MultiModePlayFragment extends Fragment {

private final List<LatLng> pathPoints = new ArrayList<>();

MultiModeUser user = MultiModeFragment.user;
//MultiModeUser user = new MultiModeUser(1, "choco");
MultiModeUser user = new MultiModeUser(2, "berry"); // 유저 정보 임시로 더미데이터 활용
//MultiModeUser user = new MultiModeUser(2, "berry"); // 유저 정보 임시로 더미데이터 활용
//MultiModeUser user = new MultiModeUser(3, "apple");

SocketManager socketManager = SocketManager.getInstance();
Expand All @@ -69,24 +71,12 @@ public class MultiModePlayFragment extends Fragment {
TextView bronzeDistanceTextView;
TextView bronzeNickNameTextView;
ProgressBar progressBar;
private final Handler top3UpdateHandler = new Handler(Looper.getMainLooper()) {//탑3 유저 업데이트. 아마 handleMessage 코드가 실제로 실행되는지는 모르겟음
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);

if (msg.obj instanceof Packet) {
Packet receivedPacket = (Packet) msg.obj;
if (receivedPacket.getProtocol() == Protocol.UPDATE_TOP3_STATES) {
UserDistance[] top3UserDistance = receivedPacket.getTop3UserDistance();
updateTop3UserDistance(top3UserDistance);

}
}
}
};
LocalDateTime gameStartTime;
TextView distancePresentContentTextView; //API 사용해서 구한 나의 현재 이동 거리
TextView pacePresentContentTextView; //API 사용해서 구한 나의 현재 페이스

Button playLeaveButton;
SocketListenerThread socketListenerThread = null;
private TextView timePresentContentTextView;
private Handler timeHandler;
Expand All @@ -103,14 +93,6 @@ public void handleMessage(Message msg) {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

selectedRoom = (MultiModeRoom) getArguments().getSerializable("room");
//socketListenerThread = (SocketListenerThread) getArguments().getSerializable("socketListenerThread"); //waitFragment의 socketListenrThread객체 가져와서 이어서 사용
//socketListenerThread.addPlayFragment(this);
//socketListenerThread.resumeListening();
// try {
// socketManager.openSocket();
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
gameStartTime = LocalDateTime.now();

mainActivity = (MainActivity2) getActivity();
Expand All @@ -132,7 +114,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c
distancePresentContentTextView = view.findViewById(R.id.distance_present_content);
pacePresentContentTextView = view.findViewById(R.id.pace_present_content);
progressBar = view.findViewById(R.id.linear_progress_bar);

playLeaveButton = view.findViewById(R.id.play_leaveButton);
//목표 시간 계산하기 위한 코드
long secondsRemaining = selectedRoom.getDuration().getSeconds();

Expand All @@ -147,6 +129,15 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c

}

playLeaveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new ExitGameTask().execute();
NavController navController = Navigation.findNavController(v);
navController.navigate(R.id.navigation_multi_mode);
}
});

//TODO: only draw lines if running is started
//TODO: doesn't update location when app is in background -> straight lines are drawn from the last location when app is opened again
//TODO: lines are ugly and noisy -> need to filter out some points or smoothed
Expand Down Expand Up @@ -215,6 +206,8 @@ public void run() {
if (isFinished == 0) {
// 1초마다 Runnable 실행
timeHandler.postDelayed(this, 1000);
} else {
new SendFinishedTask().execute();
}
}
};
Expand All @@ -227,7 +220,7 @@ public void run() {
public void run() {
Packet requestPacket = new Packet(Protocol.UPDATE_USER_DISTANCE, user, distance);
//distance += 1;
new SendPacketTask().execute(requestPacket);
new SendDistanceTask().execute(requestPacket);
if (isFinished == 0) {
// 1초마다 Runnable 실행
sendDataHandler.postDelayed(this, 5000); // 5초마다 전송. 처음에 socketlistnerthread 설정 때문에 약간의 딜레이가 필요할 듯 함
Expand Down Expand Up @@ -263,6 +256,12 @@ public void updateTop3UserDistance(UserDistance[] userDistances) { // 화면에
goldDistance = top3UserDistance[0].getDistance();
String goldDistanceString = String.format("%.3fkm", goldDistance);
goldDistanceTextView.setText(goldDistanceString);

silverNickNameTextView.setText("-");
silverDistanceTextView.setText("-");

bronzeNickNameTextView.setText("-");
bronzeDistanceTextView.setText("-");
} else if (top3UserDistance.length == 2) {
goldNickNameTextView.setText(top3UserDistance[0].getUser().getNickName());
goldDistance = top3UserDistance[0].getDistance();
Expand All @@ -274,7 +273,8 @@ public void updateTop3UserDistance(UserDistance[] userDistances) { // 화면에
String silverDistanceString = String.format("%.3fkm", silverDistance);
silverDistanceTextView.setText(silverDistanceString);


bronzeNickNameTextView.setText("-");
bronzeDistanceTextView.setText("-");
} else {
goldNickNameTextView.setText(top3UserDistance[0].getUser().getNickName());
goldDistance = top3UserDistance[0].getDistance();
Expand All @@ -289,7 +289,7 @@ public void updateTop3UserDistance(UserDistance[] userDistances) { // 화면에
bronzeNickNameTextView.setText(top3UserDistance[2].getUser().getNickName());
double bronzeDistance = top3UserDistance[2].getDistance();
String bronzeDistanceString = String.format("%.3fkm", bronzeDistance);
silverDistanceTextView.setText(bronzeDistanceString);
bronzeDistanceTextView.setText(bronzeDistanceString);
}

int progress = 0;
Expand Down Expand Up @@ -339,7 +339,7 @@ public void onDestroyView() {
timeHandler.removeCallbacks(timeRunnable);
}

private class SendPacketTask extends AsyncTask<Packet, Void, Boolean> { // 서버에 업데이트할 거리 정보 전송
private class SendDistanceTask extends AsyncTask<Packet, Void, Boolean> { // 서버에 업데이트할 거리 정보 전송
@Override
protected Boolean doInBackground(Packet... packets) {
boolean success = true;
Expand Down Expand Up @@ -376,4 +376,87 @@ protected void onPostExecute(Boolean success) {
}
}
}


//경기 시간이 종료되었을 경우 해당 유저의 레이스가 종료되었다는 패킷을 보냄
private class SendFinishedTask extends AsyncTask<Void, Void, Boolean> {
Packet packet;

@Override
protected Boolean doInBackground(Void... voids) {
boolean success = true;
try {
ObjectOutputStream oos = socketManager.getOOS();
Packet requestPacket = new Packet(Protocol.FINISH_GAME, user, selectedRoom);
oos.writeObject(requestPacket);
oos.flush();
} catch (IOException e) {
e.printStackTrace();
success = false;
} finally {
timeHandler.removeCallbacks(timeRunnable);
sendDataHandler.removeCallbacks(sendDataRunnable);
Log.d("response", "socket closed");
}
return success;
}

//ExitGameTask 실행 결과에 따라 수행
@Override
protected void onPostExecute(Boolean success) {
super.onPostExecute(success);
if (success) {
Log.d("SendPacket", "Packet sent successfully!");

} else {
Log.d("ExitSendPacket", "Failed to send packet!");
}
}

}

private class ExitGameTask extends AsyncTask<Void, Void, Boolean> {
Packet packet;

@Override
protected Boolean doInBackground(Void... voids) {
boolean success = true;
try {
ObjectOutputStream oos = socketManager.getOOS();
Packet requestPacket = new Packet(Protocol.EXIT_GAME, user, selectedRoom);
oos.writeObject(requestPacket);
oos.flush();
} catch (IOException e) {
e.printStackTrace();
success = false;
} finally {
try {
socketManager.closeSocket();
timeHandler.removeCallbacks(timeRunnable);
sendDataHandler.removeCallbacks(sendDataRunnable);
Log.d("response", "socket closed");


} catch (IOException e) {
Log.d("response", "socket close error");
success = false;
}

}
return success;
}

//ExitGameTask 실행 결과에 따라 수행
@Override
protected void onPostExecute(Boolean success) {
super.onPostExecute(success);
if (success) {
Log.d("SendPacket", "Packet sent successfully!");

} else {
Log.d("ExitSendPacket", "Failed to send packet!");
}
}

}
}
Loading

0 comments on commit 0f65e95

Please sign in to comment.