How to get the number of current UObjects in scene UE4? - c++

How do I get the number of UObjects in the scene using TObjectIterator?
I tried the following , but I get an unresolved external error for Count++.
float Count = 0;
for(TObjectIterator<UObject> UObjectIt; UObjectIt; ++UObjectIt)
{
if(UObjectIt->GetWorld() == currentGameWorld)
{
UObject* ObjectModel = *UObjectIt;
Count++;
}
}

Related

How to know file is from internal or external storage in android?

I want to know how to figure out file path is from internal or external storage.
I want to delete a file. Before deleting it i want to check whether it is from internal memory or external.
if file is from internal storage then i can simply delete it like this
file.delete();
But if file is from external storage (sdcard). Then i would first check permission then delete it through storage access framework.
I'm currently doing like this.
File selectedFile = Constant.allMemoryVideoList.get(fPosition).getFile().getAbsoluteFile();
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (???????????? check if file is not from internal storage ???????????) {
List<UriPermission> permissions = getContentResolver().getPersistedUriPermissions();
if (permissions != null && permissions.size() > 0) {
sdCardUri = permissions.get(0).getUri();
deleteFileWithSAF();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Please select external storage directory (e.g SDCard)")
.setMessage("Due to change in android security policy it is not possible to delete or rename file in external storage without granting permission")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// call document tree dialog
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
}
})
.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
}
} else {
deleteFile();
}
} else {
deleteFile();
}
deleteFileWithSAF()
private void deleteFileWithSAF() {
//First we get `DocumentFile` from the `TreeUri` which in our case is `sdCardUri`.
DocumentFile documentFile = DocumentFile.fromTreeUri(this, sdCardUri);
//Then we split file path into array of strings.
//ex: parts:{"", "storage", "extSdCard", "MyFolder", "MyFolder", "myImage.jpg"}
// There is a reason for having two similar names "MyFolder" in
//my exmple file path to show you similarity in names in a path will not
//distract our hiarchy search that is provided below.
String[] parts = (selectedFile.getPath()).split("\\/");
// findFile method will search documentFile for the first file
// with the expected `DisplayName`
// We skip first three items because we are already on it.(sdCardUri = /storage/extSdCard)
for (int i = 3; i < parts.length; i++) {
if (documentFile != null) {
documentFile = documentFile.findFile(parts[i]);
}
}
if (documentFile == null) {
// File not found on tree search
// User selected a wrong directory as the sd-card
// Here must inform user about how to get the correct sd-card
// and invoke file chooser dialog again.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Please select root of external storage directory (click SELECT button at bottom)")
.setMessage("Due to change in android security policy it is not possible to delete or rename file in external storage without granting permission")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// call for document tree dialog
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
}
})
.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
} else {
// File found on sd-card and it is a correct sd-card directory
// save this path as a root for sd-card on your database(SQLite, XML, txt,...)
// Now do whatever you like to do with documentFile.
// Here I do deletion to provide an example.
if (documentFile.delete()) {// if delete file succeed
// Remove information related to your media from ContentResolver,
// which documentFile.delete() didn't do the trick for me.
// Must do it otherwise you will end up with showing an empty
// ImageView if you are getting your URLs from MediaStore.
getApplicationContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(selectedFile)));
// Methods.removeMedia(this,selectedFile.getPath());
if (deleteSingleFileCall){
Constant.allMemoryVideoList.remove(videoPosition);
adapter.notifyItemRemoved(videoPosition);
deleteSingleFileCall = false;
}
/*update the playback record to
* getFileName() contain file.getName()*/
for (int i = 0; i < Constant.filesPlaybackHistory.size(); i++) {
if ((selectedFile.getName()).equals(Constant.filesPlaybackHistory.get(i).getFileName())) {
Constant.filesPlaybackHistory.remove(i);
break;
}
}
//save the playback history
Paper.book().write("playbackHistory", Constant.filesPlaybackHistory);
}
}
}
This is how i load files of both internal and external storage.
StorageUtil is library https://github.com/hendrawd/StorageUtil
String[] allPath = StorageUtil.getStorageDirectories(this);
private File directory;
for (String path: allPath){
directory = new File(path);
Methods.load_Directory_Files(directory);
}
All Loaded files in following arraylist.
//all the directory that contains files
public static ArrayList<File> directoryList = null;
//list of all files (internal and external)
public static ArrayList<FilesInfo> allMemoryVideoList = new ArrayList<>();
FilesInfo: Contain all info about file like thumbnail, duration, directory, new or played before, if played then last playback position etc
LoadDirectoryFiles()
public static void load_Directory_Files(File directory) {
//Get all file in storage
File[] fileList = directory.listFiles();
//check storage is empty or not
if(fileList != null && fileList.length > 0)
{
for (int i=0; i<fileList.length; i++)
{
boolean restricted_directory = false;
//check file is directory or other file
if(fileList[i].isDirectory())
{
for (String path : Constant.removePath){
if (path.equals(fileList[i].getPath())) {
restricted_directory = true;
break;
}
}
if (!restricted_directory)
load_Directory_Files(fileList[i]);
}
else
{
String name = fileList[i].getName().toLowerCase();
for (String ext : Constant.videoExtensions){
//Check the type of file
if(name.endsWith(ext))
{
//first getVideoDuration
String videoDuration = Methods.getVideoDuration(fileList[i]);
long playbackPosition;
long percentage = C.TIME_UNSET;
FilesInfo.fileState state;
/*First check video already played or not. If not then state is NEW
* else load playback position and calculate percentage of it and assign it*/
//check it if already exist or not if yes then start from there else start from start position
int existIndex = -1;
for (int j = 0; j < Constant.filesPlaybackHistory.size(); j++) {
String fListName = fileList[i].getName();
String fPlaybackHisName = Constant.filesPlaybackHistory.get(j).getFileName();
if (fListName.equals(fPlaybackHisName)) {
existIndex = j;
break;
}
}
try {
if (existIndex != -1) {
//if true that means file is not new
state = FilesInfo.fileState.NOT_NEW;
//set playbackPercentage not playbackPosition
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(fileList[i].getPath());
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
retriever.release();
int duration = Integer.parseInt(time);
playbackPosition = Constant.filesPlaybackHistory.get(existIndex).getPlaybackPosition();
if (duration > 0)
percentage = 1000L * playbackPosition / duration;
else
percentage = C.TIME_UNSET;
}
else
state = FilesInfo.fileState.NEW;
//playbackPosition have value in percentage
Constant.allMemoryVideoList.add(new FilesInfo(fileList[i],
directory,videoDuration, state, percentage, storageType));
//directory portion
currentDirectory = directory.getPath();
unique_directory = true;
for(int j=0; j<directoryList.size(); j++)
{
if((directoryList.get(j).toString()).equals(currentDirectory)){
unique_directory = false;
}
}
if(unique_directory){
directoryList.add(directory);
}
//When we found extension from videoExtension array we will break it.
break;
}catch (Exception e){
e.printStackTrace();
Constant.allMemoryVideoList.add(new FilesInfo(fileList[i],
directory,videoDuration, FilesInfo.fileState.NOT_NEW, C.TIME_UNSET, storageType));
}
}
}
}
}
}
Constant.directoryList = directoryList;
}
Image So reader could easily understand what is going on.

Unknown reason for "ArgumentOutOfRangeException: Argument is out of range. Parameter name: index" exception

I am making a Unity game where the player is collecting data about aliens.
Therefor the player points on the alien and uses something like a camera.
Camera --> shoots Ray --> Ray returns all needed data attached to the script on the alien-gameobject
void ShootRay()
{
RaycastHit hitInfo; // stores information about hitted object
if (Physics.Raycast (transform.position, transform.forward, out hitInfo, maxRaycastRange, 1 << LayerMask.NameToLayer("creature"))) // out hitInfo = Unity puts information in the variable hitInfo
{
// UI alerts and collecting dna
if (hitInfo.distance <= photoRaycastRange)
{
distanceInfo.text = "scanning_genome";
if (hitInfo.collider.gameObject.GetComponent<EnemyAI> ().dna_collected == false) {
if (dna_percent_0_to_1 < 1)
{
calming_dna_scan_circle = false;
distanceInfo.text = "scanning_genome";
dna_percent_0_to_1 += Time.deltaTime * dna_scanSpeed;
dna_collect_circle.fillAmount = dna_percent_0_to_1;
}
else if (dna_percent_0_to_1 >= 1)
{
// adding info of creature to database
if (hitInfo.collider.gameObject.GetComponent<EnemyAI> ().raceIndex == 1)
{
if (!raceOneWasAdded)
{
BestiariumData.scannedSpecies.Add (hitInfo.collider.gameObject);
raceOneWasAdded = true;
}
BestiariumData.dnaBar_1 += 0.25f;
The mentioned database is simply a class called BestiariumData with:
public static List<GameObject> scannedSpecies = new List<GameObject> ();
public static List<float> savedDNAFillRates = new List<float> ();
public static float dnaBar_1 = 0;
public static float dnaBar_2 = 0;
public static float dnaBar_3 = 0;
public static float dnaBar_4 = 0;
public static float dnaBar_5 = 0;
public static float dnaBar_6 = 0;
public static float dnaBar_7 = 0;
public static float dnaBar_8 = 0;
}
I'm having a menu where the player can check which aliens he/she already has collected data. The name of the alien is displayed (Monster One, ...) and a progress bar for how many alien individuals the player has scanned.
THE PROBLEM:
if I try to assign the NAME of the status bar if throws the ArgumentOutOfRangeException: Argument is out of range. Parameter name: index exception. I am doing this by setting a bool in another script to true.
public List<GameObject> monsterButtons = new List<GameObject>();
public static bool nameButtons = false;
// Update is called once per frame
void LateUpdate ()
{
if (nameButtons)
{
for (int buttonIndex = monsterButtons.Count; buttonIndex > 0; buttonIndex--)
{
monsterButtons [buttonIndex].GetComponentInChildren<Text> ().text = BestiariumData.scannedSpecies [buttonIndex].name;
}
}
}
Thank you for your help.
Button index gives the count of your list. So say your list contains 10 items, count will be 10.
However a list's index starts at 0, not 1.
So when you try to access monsterButtons [buttonIndex] for the first time, you are calling index 10, which means item 11. This does not exist so throws your error.
To fix, add "-1" to your index asigning:
for (int buttonIndex = monsterButtons.Count -1; buttonIndex >= 0; buttonIndex--)
{
monsterButtons [buttonIndex].GetComponentInChildren<Text> ().text = BestiariumData.scannedSpecies [buttonIndex].name;
}

Pops / clicks when stopping and starting DirectX sound synth in C++ / MFC

I have made a soft synthesizer in Visual Studio 2012 with C++, MFC and DirectX. Despite having added code to rapidly fade out the sound I am experiencing popping / clicking when stopping playback (also when starting).
I copied the DirectX code from this project: http://www.codeproject.com/Articles/7474/Sound-Generator-How-to-create-alien-sounds-using-m
I'm not sure if I'm allowed to cut and paste all the code from the Code Project. Basically I use the Player class from that project as is, the instance of this class is called m_player in my code. The Stop member function in that class calls the Stop function of LPDIRECTSOUNDBUFFER:
void Player::Stop()
{
DWORD status;
if (m_lpDSBuffer == NULL)
return;
HRESULT hres = m_lpDSBuffer->GetStatus(&status);
if (FAILED(hres))
EXCEP(DirectSoundErr::GetErrDesc(hres), "Player::Stop GetStatus");
if ((status & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
{
hres = m_lpDSBuffer->Stop();
if (FAILED(hres))
EXCEP(DirectSoundErr::GetErrDesc(hres), "Player::Stop Stop");
}
}
Here is the notification code (with some supporting code) in my project that fills the sound buffer. Note that the rend function always returns a double between -1 to 1, m_ev_smps = 441, m_n_evs = 3 and m_ev_sz = 882. subInit is called from OnInitDialog:
#define FD_STEP 0.0005
#define SC_NOT_PLYD 0
#define SC_PLYNG 1
#define SC_FD_OUT 2
#define SC_FD_IN 3
#define SC_STPNG 4
#define SC_STPD 5
bool CMainDlg::subInit()
// initialises various variables and the sound player
{
Player *pPlayer;
SOUNDFORMAT format;
std::vector<DWORD> events;
int t, buf_sz;
try
{
pPlayer = new Player();
pPlayer->SetHWnd(m_hWnd);
m_player = pPlayer;
m_player->Init();
format.NbBitsPerSample = 16;
format.NbChannels = 1;
format.SamplingRate = 44100;
m_ev_smps = 441;
m_n_evs = 3;
m_smps = new short[m_ev_smps];
m_smp_scale = (int)pow(2, format.NbBitsPerSample - 1);
m_max_tm = (int)((double)m_ev_smps / (double)(format.SamplingRate * 1000));
m_ev_sz = m_ev_smps * format.NbBitsPerSample/8;
buf_sz = m_ev_sz * m_n_evs;
m_player->CreateSoundBuffer(format, buf_sz, 0);
m_player->SetSoundEventListener(this);
for(t = 0; t < m_n_evs; t++)
events.push_back((int)((t + 1)*m_ev_sz - m_ev_sz * 0.95));
m_player->CreateEventReadNotification(events);
m_status = SC_NOT_PLYD;
}
catch(MATExceptions &e)
{
MessageBox(e.getAllExceptionStr().c_str(), "Error initializing the sound player");
EndDialog(IDCANCEL);
return FALSE;
}
return TRUE;
}
void CMainDlg::Stop()
// stop playing
{
m_player->Stop();
m_status = SC_STPD;
}
void CMainDlg::OnBnClickedStop()
// causes fade out
{
m_status = SC_FD_OUT;
}
void CMainDlg::OnSoundPlayerNotify(int ev_num)
// render some sound samples and check for errors
{
ScopeGuardMutex guard(&m_mutex);
int s, end, begin, elapsed;
if (m_status != SC_STPNG)
{
begin = GetTickCount();
try
{
for(s = 0; s < m_ev_smps; s++)
{
m_smps[s] = (int)(m_synth->rend() * 32768 * m_fade);
if (m_status == SC_FD_IN)
{
m_fade += FD_STEP;
if (m_fade > 1)
{
m_fade = 1;
m_status = SC_PLYNG;
}
}
else if (m_status == SC_FD_OUT)
{
m_fade -= FD_STEP;
if (m_fade < 0)
{
m_fade = 0;
m_status = SC_STPNG;
}
}
}
}
catch(MATExceptions &e)
{
OutputDebugString(e.getAllExceptionStr().c_str());
}
try
{
m_player->Write(((ev_num + 1) % m_n_evs)*m_ev_sz, (unsigned char*)m_smps, m_ev_sz);
}
catch(MATExceptions &e)
{
OutputDebugString(e.getAllExceptionStr().c_str());
}
end = GetTickCount();
elapsed = end - begin;
if(elapsed > m_max_tm)
m_warn_msg.Format(_T("Warning! compute time: %dms"), elapsed);
else
m_warn_msg.Format(_T("compute time: %dms"), elapsed);
}
if (m_status == SC_STPNG)
Stop();
}
It seems like the buffer is not always sounding out when the stop button is clicked. I don't have any specific code for waiting for the sound buffer to finish playing before the DirectX Stop is called. Other than that the sound playback is working just fine, so at least I am initialising the player correctly and notification code is working in that respect.
Try replacing 32768 with 32767. Not by any means sure this is your issue, but it could overflow the positive short int range (assuming your audio is 16-bit) and cause a "pop".
I got rid of the pops / clicks when stopping playback, by filling the buffer with zeros after the fade out. However I still get pops when re-starting playback, despite filling with zeros and then fading back in (it is frustrating).

Creating new objects in C++ function causes program to crash

I have a program which allows the user to play Dominoes against 3 CPU players, with varying difficulty. Each CPU player can be either Beginner, Intermediate or Expert, and each difficulty has it's own class. If I initiate my 3 CPU players at the beginning of my 'Window' class (below), the program runs fine.
In Window.h
public:
Window(QWidget *parent = 0);
Intermediate *cpu1;
Beginner *cpu2;
Intermediate *cpu3;
In Window.cpp
Window::Window(QWidget *parent):QDialog(parent) {
cpu1 = new Intermediate;
cpu2 = new Beginner;
cpu3 = new Intermediate;
}
However I want the user to be able to select the CPU difficulties at the beginning of the game, so I now have a function within 'Window' that creates the objects. As soon as I call this function the game freezes and I get an error message pop up saying telling me the program has ended unexpectedly.
void Window:: startGame(){
cpu1 = new Intermediate;
cpu2 = new Beginner;
cpu3 = new Intermediate;
}
If anyone would be able to explain to me what is going on and what I can do to get around this that would be great.
Intermediate.cpp (Beginner.cpp is almost identical)
#include "intermediate.h"
Intermediate::Intermediate()
{
tilePlaced = false;
skipGo = false;
}
void Intermediate::findDoubles(int a[7][2]){
for(int i = 0; i < 7; i++){ // Creates new doubles list after each go.
doublesList[i] = 0;
}
for(int i = 0; i < 7; i++){ // Creates a list of doubles
if ((a[i][0] == a[i][1]) && (a[i][0] != 7)){
doublesList[a[i][0]] = 1;
}
}
}
bool Intermediate::addDomino(){} // Function that finds best domino to replace and returns bool
if(tilePlaced == false){
pass++;
text += "\nPassed turn";
return false;
}
else{
pass = 0;
text += QString("\nPlaced [%1 : %2]").arg(a).arg(b);
return true;
}
}
One way to start would be to narrow down which class is causing the fault. Does it work if they are all Beginner, or if they are all Intermediate? If so then the other one is causing the problem.

invalid operands to binary expression - when removing object

I want to remove an object from an array.
The problem is that i don't know the index, so i try the remove method.
The method is definded like this:
void ofxDTangibleManager::updateList(vector<ofxDTangible> &oldList, vector<ofxDTangible> &newList) {
Here is the part where it goes wrong:
for(int i = 0; i < oldList.size(); i++) {
if(newList.size() == 0) {
break;
}
ofxDTangible &t = oldList[i];
ofxDTangible &closest = getClosestTangible(t, newList, false);
float d = distSquared(t, closest);
if(d < maxMoveDistSquared) {
refound[i] = true;
// copy values of new one over
// todo
// set as target so we can interpoplate if required
// remove it so we make sure we don't assign it to multiple tangibles
remove(newList.begin(), newList.end(), closest);
}
}
This are the errors:
How can i get around this problem?