How to store System.currentTimeMillis() in an array with a park time simulator - latency

I'm trying to store the time in milliseconds for every time this time park is executed. And then I would like to use HdrHistogram to represent the latency.
However, i can't store the times in my array. Please, could you provide any help?
public class PracticeLatency1
{
public static void main(String [] args)
{
int[] startTimes;
long startTime;
int index=0;
startTimes = new int[10000];
startTime = System.currentTimeMillis();
runCalculations();
startTimes[index++] = (int) (System.currentTimeMillis() - startTime);
System.out.println(startTimes);
}
/**
* Run the practice calculations
*/
// System.currentTimeMillis()
private static void runCalculations()
{
// Create a random park time simulator
BaseSyncOpSimulator syncOpSimulator = new SyncOpSimulRndPark(TimeUnit.NANOSECONDS.toNanos(100),
TimeUnit.MICROSECONDS.toNanos(100));
// Execute the operation lot of times
for(int i = 0; i < 10000; i++)
{
syncOpSimulator.executeOp();
}
// TODO Show the percentile distribution of the latency calculation of each executeOp call
}
}

Related

day/night cycle and also track days?

I'm trying to make a day and night cycle that also keeps track of how many days passed. I watched a tutorial to start and for this post, I removed all the unnecessary stuff like rotating the sun and changing colors.
public class TimeController : MonoBehaviour
{
[SerializeField]
private float timeMultiplier;
[SerializeField]
private float startHour;
private DateTime currentTime;
void Start()
{
currentTime = DateTime.Now.Date + TimeSpan.FromHours(startHour);
}
void Update()
{
UpdateTimeOfDay();
}
private void UpdateTimeOfDay()
{
currentTime = currentTime.AddSeconds(Time.deltaTime * timeMultiplier);
}
}
The biggest issue I have with this is instead of timeMultiplier I'd rather have like a dayLength variable which represents how long a day should last in minutes so one day is 10minutes int dayLength = 600; or something like that, but I'm not sure how I'd implement that.
Also, I tried adding a method for checking if a day has passed, but the code ended up running like 20 times.
public int currentDay = 1;
private void HasDayPassed()
{
if (currentTime.Hour == 0)
{
Debug.Log("New day");
currentDay++;
}
}
Try this code
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TimeController : MonoBehaviour
{
public const float SecondsInDay = 86400f;
[SerializeField] [Range(0, SecondsInDay)] private float _realtimeDayLength = 60;
[SerializeField] private float _startHour;
private DateTime _currentTime;
private DateTime _lastDayTime;
private int _currentDay = 1;
private void Start()
{
_currentTime = DateTime.Now + TimeSpan.FromHours(_startHour);
_lastDayTime = _currentTime;
}
private void Update()
{
// Calculate a seconds step that we need to add to the current time
float secondsStep = SecondsInDay / _realtimeDayLength * Time.deltaTime;
_currentTime = _currentTime.AddSeconds(secondsStep);
// Check and increment the days passed
TimeSpan difference = _currentTime - _lastDayTime;
if(difference.TotalSeconds >= SecondsInDay)
{
_lastDayTime = _currentTime;
_currentDay++;
}
// Next do your animation stuff
AnimateSun();
}
private void AnimateSun()
{
// Animate sun however you want
}
}
Also you can remove the range attribute to specify more slower day than the realtime day.

C# byte [ ] operations - shall I use ArrayPool or MemoryPool?

I am writing a server application. It accepts thousands of incoming socket connections, each sending and receiving messages.
Every time a message is received or sent over the socket, I used to allocate new byte[] buffers, then they are garbage collected:
byte[] receivingBuffer = new byte[bufferSize];
To improve the performance, I want to reuse the byte[] buffers. Shall I use ArrayPool or MemoryPool?
Or shall I create an ObjectPool of fixed-length byte[] buffers? For example, if the messages I send and receive never exceed 100 KB, then I create an ObjectPool of 100 KB byte[] buffers. Every time I need to send or receive a message, I get one of these buffers.
Did some research and testing. ArrayPool is the right thing to use and will dramatically increase performance.
class Program
{
private static ManualResetEvent m_event = new ManualResetEvent(false);
private static DateTime m_dtStart;
private static int m_iNumOfIterations = 0;
private static int m_iNumOfExceptions = 0;
private static double m_dAvgSizeRatio = 0;
private static object m_lock = new object();
private static void ReportSizeRatio(double dRatio)
{
lock (m_lock)
{
m_dAvgSizeRatio = (m_dAvgSizeRatio * m_iNumOfIterations + dRatio) / (m_iNumOfIterations + 1);
m_iNumOfIterations++;
}
}
/// <summary>
/// When using ArrayPool:
/// - CPU: 1 ~ 1.5%
/// - Memory: 67 MB
/// - Speed: 9130 runs/sec
/// - Given buffer is 1.56 times bigger than asked for.
///
/// When NOT using ArrayPool:
/// - CPU: 20 ~ 25%
/// - Memory: 500 ~ 1000 MB
/// - Speed: 5300 runs/sec
///
/// Conclusion: huge improvement in performance.
/// </summary>
/// <param name="obj"></param>
private static void Test(object obj)
{
TrueRandom random = new TrueRandom(500, 800);
m_event.WaitOne();
while (true)
{
int iDesiredSize = random.GetRandomInteger() * 1000;
byte[] buffer = null;
try
{
//buffer = ArrayPool<byte>.Shared.Rent(iDesiredSize);
buffer = new byte[iDesiredSize];
ReportSizeRatio((double)buffer.Length / (double)iDesiredSize);
}
catch
{
Interlocked.Increment(ref m_iNumOfExceptions);
}
Thread.Sleep(100);
//ArrayPool<byte>.Shared.Return(buffer);
}
}
static void Main(string[] args)
{
for (int i = 0; i < 1000; i++)
{
Thread thread = new Thread(Test);
thread.Start();
}
Console.WriteLine("All threads fired.");
m_dtStart = DateTime.Now;
m_event.Set();
while (true)
{
Thread.Sleep(1000);
Console.Clear();
Console.WriteLine($"Iterations/sec: { (int)(m_iNumOfIterations / (DateTime.Now - m_dtStart).TotalSeconds) }, Ave rented size: { (m_dAvgSizeRatio * 100d).ToString("0.0") }%, exceptions: { m_iNumOfExceptions }.");
}
}
}

How to send a value from from one script to another on Unity

I am having an issue with dealing with some values that I want to send to.
The thing is that I want the total value of the time transcurred after quitting the game. When the player logs in, that value is multiplied with the money. So if the player connects after 30 minutes, the player will earn the value of 30 minutes multiplied with the money. Worked with JSON Serialization, public static, and PlayerPrefs but nothing.
PlayerPrefs and Serialization seem working but it only records the time stored before storing. For example, if the player connects after 5 seconds then 20 seconds, the second time it gets the value of 5 seconds and not 20 seconds.
Script A:
public SaveManager save_manager;
public DateTime new_time, old_time;
public TimeSpan gold_reward_time;
public float current_boostValue_gameplay;
private float minutes_booster_gameplay;
private float seconds_booster_gameplay;
private bool is_stopped_booster_gameplay;
private void Start()
{
new_time = DateTime.Now;
old_time = DateTime.Parse(PlayerPrefs.GetString("timeData"));
gold_reward_time = new_time - old_time;
Get_sum_of_time_reward();
}
private void OnApplicationQuit()
{
Application.Quit();
Sum_of_time_passed();
PlayerPrefs.SetString("timeData", DateTime.Now.ToString());
}
public void Get_sum_of_time_reward()
{
double time_hour = Convert.ToDouble(gold_reward_time.Hours);
double time_minutes = Convert.ToDouble(gold_reward_time.Minutes);
double time_seconds = Convert.ToDouble(gold_reward_time.Seconds);
double sum_of_time_values = time_hour + time_minutes + time_seconds;
PlayerPrefs.SetString("totalRewardTime",sum_of_time_values.ToString());
}
Script B:
public void Calculate_time_as_gold()
{
string load_resident_menu_data = File.ReadAllText(Application.persistentDataPath + "/resident_menu_data.json");
resident_data = Json_helper.FromJson<Resident_menu_data>(load_resident_menu_data);
string load_automation_menu_data = File.ReadAllText(Application.persistentDataPath + "/automation_menu_data.json");
automation_data = Json_helper.FromJson<Automation_menu_data>(load_automation_menu_data);
sum_of_all_per_sec = resident_data[0].resident_gold_per_sec + automation_data[0].automation_gold_per_sec;
sum_of_time_passed = double.Parse(PlayerPrefs.GetString("totalRewardTime"));
result_reward_after_time = sum_of_all_per_sec * sum_of_time_passed;
Debug.Log("total value 1 = " + double.Parse(PlayerPrefs.GetString("RewardTimeValue")));
reward_gold_text.text = Math.Truncate(result_reward_after_time).ToString();
}
PlayerPrefs.Save says you don't need to call it manually in OnApplicationQuit. Good.
Call Application.Quit(); at last in OnApplicationQuit. Otherwise your changes may not be saved I guess.
If you save the time like this: double sum_of_time_values = time_hour + time_minutes + time_seconds; wouldn't 20 minutes look the same as 20 seconds?
Why not simply add the Time.deltaTime in Update() to a variable? Time will be in seconds.

Unity timer count down not working when app killed android

I'm new to unity and c#, I have a code to increase energy after 10m, I have used PlayerPrefs to do so it is working in unity but not working on mobile please help.
I'm unable to understand what exactly is causing problem in phone. Also the timer pauses when the app is not killed but just minimized on mobile. I want the timer countdown to keep going game minimized and also if killed.
using System;
using UnityEngine;
using UnityEngine.UI;
public class EnergyAdder : MonoBehaviour
{
// Start is called before the first frame update
public float waitTime = 600;
Timer timer;
public GameRoot gameRoot;
public int count;
DateTime currentDate;
DateTime oldDate;
void Start()
{
//timer = new Timer(waitTime);
float remainingTime = PlayerPrefs.GetFloat("TimeOnExit");
timer = new Timer(remainingTime);
if (PlayerPrefs.HasKey("sysString"))
{
currentDate = DateTime.Now;
long temp = Convert.ToInt64(PlayerPrefs.GetString("sysString"));
oldDate = DateTime.FromBinary(temp);
TimeSpan difference = currentDate.Subtract(oldDate);
count = (int)(difference.TotalSeconds / waitTime);
Debug.Log("time remaining " + count);
gameRoot.AddEnergy(count);
timer = new Timer(remainingTime - (float)difference.TotalSeconds);
//PlayerPrefs.DeleteKey("TimeOnExit");
//PlayerPrefs.DeleteKey("sysString");
}
}
// Update is called once per frame
void Update()
{
if (Gameroot.isFull)
{
GetComponent<Text>().text = "Full";
count = 0;
timer.refresh();
}
else
{
//Debug.Log("deltatime ************************"+ secondstime);
timer.countDown();
if (timer.isFinished())
{
timer = new Timer(waitTime);
timer.refresh();
gameRoot.AddEnergy(1);
}
UpdateClock();
}
}
void UpdateClock()
{
int seconds = ((int)timer.timeLeft) % 60;
int minutes = (int)(timer.timeLeft / 60);
GetComponent<Text>().text = minutes.ToString() + ":" + seconds.ToString("00");
}
void OnApplicationQuit()
{
PlayerPrefs.SetFloat("TimeOnExit", timer.timeLeft);
var today = DateTime.Now;
PlayerPrefs.SetString("sysString", today.ToBinary().ToString());
PlayerPrefs.Save();
}
}
Please help what is wrong in above code or what is missing.
From OnApplicationQuit
Note: iOS applications are usually suspended and do not quit. You should tick "Exit on Suspend" in Player settings for iOS builds to cause the game to quit and not suspend, otherwise you may not see this call. If "Exit on Suspend" is not ticked then you will see calls to OnApplicationPause instead.
I suspect it is just the same with modern Android where your app is also not really closed but hibernate.
So I think you could use OnApplicationPause and OnApplicationFocus
On Android, when the on-screen keyboard is enabled, it causes a OnApplicationFocus(false) event. Additionally, if you press "Home" at the moment the keyboard is enabled, the OnApplicationFocus() event is not called, but OnApplicationPause() is called instead.
and just do the same as you do in OnApplicationQuit also for OnApplicationPause(true) and OnApplicationFocus(false)
and do the same as you do in Start also in OnApplicationPause(false) and OnApplictionFocus(true) like
public class EnergyAdder : MonoBehaviour
{
public float waitTime = 600;
public GameRoot gameRoot;
public int count;
// already reference this in the Inspector
[SerializeField] private Text timerText;
private Timer timer;
private DateTime currentDate;
private DateTime oldDate;
private void Awake()
{
// store this reference ONCE
if(!timerText) timerText = GetComponent<Text>();
}
private void Start()
{
GetTime();
}
private void Update()
{
// Note: probably a typo? shouldn't it be "gameRoot" ?
if (Gameroot.isFull)
{
timerText.text = "Full";
count = 0;
timer.refresh();
}
else
{
//Debug.Log("deltatime ************************"+ secondstime);
timer.countDown();
if (timer.isFinished())
{
timer = new Timer(waitTime);
timer.refresh();
gameRoot.AddEnergy(1);
}
UpdateClock();
}
}
private void UpdateClock()
{
int seconds = ((int)timer.timeLeft) % 60;
int minutes = (int)(timer.timeLeft / 60);
timerText.text = $"{minutes}:{seconds:00}";
}
private void OnApplicationQuit()
{
StoreTime();
}
// pauseStatus is True if the application is paused, else False.
private void OnApplicationPause(bool pauseStatus)
{
if(pauseStatus)
{
StoreTime();
}
else
{
GetTime();
}
}
// hasFocus is True if the GameObjects have focus, else False.
private void OnApplicationFocus(bool hasFocus)
{
if(hasFocus)
{
GetTime();
}
else
{
StoreTime();
}
}
private void StoreTime()
{
PlayerPrefs.SetFloat("TimeOnExit", timer.timeLeft);
var today = DateTime.Now;
PlayerPrefs.SetString("sysString", today.ToBinary().ToString());
PlayerPrefs.Save();
}
private void GetTime()
{
// NOTE: You should consider to pass a default value like
//float remainingTime = PlayerPrefs.GetFloat("TimeOnExit", 15);
float remainingTime = PlayerPrefs.GetFloat("TimeOnExit");
timer = new Timer(remainingTime);
if (PlayerPrefs.HasKey("sysString"))
{
currentDate = DateTime.Now;
long temp = Convert.ToInt64(PlayerPrefs.GetString("sysString"));
oldDate = DateTime.FromBinary(temp);
TimeSpan difference = currentDate.Subtract(oldDate);
count = (int)(difference.TotalSeconds / waitTime);
Debug.Log("time remaining " + count);
gameRoot.AddEnergy(count);
timer = new Timer(remainingTime - (float)difference.TotalSeconds);
}
}
}
Note: Typed on smartphone so I can't test it but I hope it goes into the right direction

SharedPreferences in public class - can't find value

I've been struggling to find the solution to loading some SharedPreferences values into SensorEventListener. I keep on getting blank values, null or it just crashes from example code that I found on Stackoverflow.
Here are a few of my references:
Android - How to use SharedPreferences in non-Activity class?
Android: Using SharedPreferences in a Shake Listener Class
Here is the Shake Detection code from below:
Android: I want to shake it
I'm getting these values not from a different activity, and I'd like to load them from SharedPreferences into the public class ShakeEventListener and change the static values for MIN_FORCE, MIN_DIRECTION_CHANGE and MAX_TOTAL_DURATION_OF_SHAKE to the SharedPreferences values based on the stored values.
Example of my SharedPerferences code from Motion.java:
SharedPerferences for value: MIN_FORCE
SharedPreferences spa = getSharedPreferences("ForceStore", Activity.MODE_PRIVATE);
int ValueForce = spa.getInt("Force", 15);
SharedPerferences for value: MIN_DIRECTION_CHANGE
SharedPreferences spb = getSharedPreferences("DirectionStore", MODE_PRIVATE);
int ValueDirection = spb.getInt("Direction", 2);
SharedPerferences for value: MAX_TOTAL_DURATION_OF_SHAKE
SharedPreferences spc = getSharedPreferences("ShakeStore", MODE_PRIVATE);
int ValueShake = spc.getInt("Shake", 200);
Example code from MainActivity.java:
((ShakeEventListener) mSensorListener).setOnShakeListener(new ShakeEventListener.OnShakeListener() {
public void onShake() {
// My code here to react to the Motion detected
}
}
});
}
Example code of public class ShakeEventListener:
public class ShakeEventListener implements SensorEventListener {
private static final int MIN_FORCE = 15;
private static final int MIN_DIRECTION_CHANGE = 2;
/** Maximum pause between movements. */
private static final int MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE = 200;
/** Maximum allowed time for shake gesture. */
private static final int MAX_TOTAL_DURATION_OF_SHAKE = 200;
/** Time when the gesture started. */
private long mFirstDirectionChangeTime = 0;
/** Time when the last movement started. */
private long mLastDirectionChangeTime;
/** How many movements are considered so far. */
private int mDirectionChangeCount = 0;
/** The last x position. */
private float lastX = 0;
/** The last y position. */
private float lastY = 0;
/** The last z position. */
private float lastZ = 0;
/** OnShakeListener that is called when shake is detected. */
private OnShakeListener mShakeListener;
public interface OnShakeListener {
void onShake();
}
public void setOnShakeListener(OnShakeListener listener) {
mShakeListener = listener;
}
#Override
public void onSensorChanged(SensorEvent se) {
// get sensor data
//float x = se.values[0];
//float y = se.values[1];
float z = se.values[2];
// calculate movement
//float totalMovement = Math.abs(x + y + z - lastX - lastY - lastZ);
float totalMovement = Math.abs(z - lastZ);
if (totalMovement > MIN_FORCE) {
// get time
long now = System.currentTimeMillis();
// store first movement time
if (mFirstDirectionChangeTime == 0) {
mFirstDirectionChangeTime = now;
mLastDirectionChangeTime = now;
}
// check if the last movement was not long ago
long lastChangeWasAgo = now - mLastDirectionChangeTime;
if (lastChangeWasAgo < MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE) {
// store movement data
mLastDirectionChangeTime = now;
mDirectionChangeCount++;
// store last sensor data
//lastX = x;
//lastY = y;
lastZ = z;
// check how many movements are so far
if (mDirectionChangeCount >= MIN_DIRECTION_CHANGE) {
// check total duration
long totalDuration = now - mFirstDirectionChangeTime;
if (totalDuration < MAX_TOTAL_DURATION_OF_SHAKE) {
mShakeListener.onShake();
resetShakeParameters();
}
}
} else {
resetShakeParameters();
}
}
}
private void resetShakeParameters() {
mFirstDirectionChangeTime = 0;
mDirectionChangeCount = 0;
mLastDirectionChangeTime = 0;
// lastX = 0;
// lastY = 0;
lastZ = 0;
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}