Missing closing brace in SFML program? - visual-c++

I made a program using C++ and SFML. The program is supposed to generate 20 circles that are either red or blue, and it did work. Yet, I made a few changes, saved, and came back to it on VS a few hours later to find that I keep getting an error:
'{': No matching token found (Line 9)
I keep scanning through the code and I can't seem to find the issue at all.
Code:
#include <SFML/Graphics.hpp>
#include <iostream>
#include <chrono>
#include <random>
using namespace std;
int main()
{ //Line 9
unsigned seed = chrono::system_clock::now().time_since_epoch().count();
default_random_engine generator(seed);
uniform_int_distribution<int> distribution1(0, 1024);
uniform_int_distribution<int> distribution2(1, 2);
sf::RenderWindow window(sf::VideoMode(1024, 1024), "Spooky Circle Box");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Red);
shape.setPosition(10, 10);
std::vector<sf::CircleShape> circles(20);
window.clear();
for (unsigned int i = 0; i < circles.size(); i++) {
int find = 0;
int find_color = 0;
while (find != 20) {
circles[i].setPosition(distribution1(generator), distribution1(generator));
for (unsigned int j = 0; j < circles.size(); j++) {
if (i == j || (circles[i].getPosition().x != circles[j].getPosition().x || circles[i].getPosition().y != circles[j].getPosition().y)) {
find++;
} else;
if (find != 20) {
find = 0;
} else;
}
find = 0;
find_color = distribution2(generator);
circles[i].setRadius(5.f);
if (find_color == 1) {
circles[i].setFillColor(sf::Color::Blue);
} else { circles[i].setFillColor(sf::Color::Red); }
window.draw(circles[i]);
}
window.display();
while (window.isOpen()) {
sf::sleep((sf::milliseconds(100)));
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
}
return 0;
}

I explain further my comments, but I'm not going to post any repaired code. I only suggest a way of doing things.
By the structure of you're code, it seems you're trying to generate some blue or red circles randomly distributed over the window, but, at the same time, you're trying to draw them.
You should differentiate your actual data from your drawing stuff. My suggested pseudo-code would be.
int main(){int main(){
// 1 . Declare your circle vector
// 2 . Populate that vector with random circles (random position, random color)
// Now draw those circles
// 3 . while(window.isOpen()) loop
// 3.1 Clear the window
// 3.2 Draw your circles
// 3.3 Display the stuff
}
That point 3 it's basically the way to draw stuff acording SFML tutorials.

Related

How to increase speed of large for loops

Right now i'm trying to run very large for loops for some task, nearly about 8e+12 iterations. I tried using c++11 threading, but it do not seems to be working that fast as required. I am using system with 8 gb ram, i5 cpu and intel graphics 4000 card. If i use openmp would it be better or i have to use nvidia gpu and use cuda for this task? My code is as below:
#include <ros/ros.h>
// PCL specific includes
#include <sensor_msgs/PointCloud2.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <visualization_msgs/Marker.h>
#include <rosbag/bag.h>
#include <std_msgs/Int32.h>
#include <rosbag/view.h>
#include <boost/foreach.hpp>
#define foreach BOOST_FOREACH
#include <fstream>
#include <pcl/point_cloud.h>
#include <pcl/octree/octree_pointcloud_changedetector.h>
#include <pcl/io/pcd_io.h>
#include <iostream>
#include <vector>
#include <ctime>
#include <thread>
ros::Publisher marker_publisher;
int frame_index = 0;
using namespace std;
int x[200000];
void thread_function(pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloudB,vector<int> v,int p0) {
for(size_t p1=0;p1<v.size() && ros::ok();++p1) {
int p0p1 = sqrt( pow(cloudB->points[v[p1]].x-cloudB->points[v[p0]].x,2)
+pow(cloudB->points[v[p1]].y-cloudB->points[v[p0]].y,2)
+pow(cloudB->points[v[p1]].z-cloudB->points[v[p0]].z,2) ) * 1000;
if(p0p1>10) {
for(size_t p2=0;p2<v.size() && ros::ok();++p2) {
int p0p2 = sqrt( pow(cloudB->points[v[p2]].x-cloudB->points[v[p0]].x,2)
+pow(cloudB->points[v[p2]].y-cloudB->points[v[p0]].y,2)
+pow(cloudB->points[v[p2]].z-cloudB->points[v[p0]].z,2) ) * 1000;
int p1p2 = sqrt( pow(cloudB->points[v[p2]].x-cloudB->points[v[p1]].x,2)
+pow(cloudB->points[v[p2]].y-cloudB->points[v[p1]].y,2)
+pow(cloudB->points[v[p2]].z-cloudB->points[v[p1]].z,2) ) * 1000;
if(p0p2>10 && p1p2>10) {
}
}
}
}
x[p0] = 3;
cout<<"ended thread="<<p0<<endl;
}
void cloud_cb (const sensor_msgs::PointCloud2ConstPtr& input)
{
frame_index++;
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudB (new pcl::PointCloud<pcl::PointXYZRGB> );
pcl::fromROSMsg(*input,*cloudB);
// Initializing Marker parameters which will be used in rviz
vector<visualization_msgs::Marker> line_list, marker, text_view_facing;
line_list.resize(4); marker.resize(4); text_view_facing.resize(4);
for(int i=0;i<line_list.size();i++) {
marker[i].header.frame_id = line_list[i].header.frame_id = text_view_facing[i].header.frame_id = "/X3/base_link";
marker[i].header.stamp = line_list[i].header.stamp = text_view_facing[i].header.stamp =ros::Time();
marker[i].ns = line_list[i].ns = text_view_facing[i].ns ="lines";
marker[i].action = line_list[i].action = text_view_facing[i].action = visualization_msgs::Marker::ADD;
marker[i].pose.orientation.w = line_list[i].pose.orientation.w = text_view_facing[i].pose.orientation.w = 1;
marker[i].id = i+4;
line_list[i].id = i;
marker[i].type = visualization_msgs::Marker::POINTS;
line_list[i].type = visualization_msgs::Marker::LINE_LIST;
line_list[i].color.r = 1; line_list[i].color.g = 1; line_list[i].color. b = 1; line_list[i].color.a = 1;
marker[i].scale.x = 0.003;
marker[i].scale.y = 0.003;
marker[i].scale.z = 0.003;
text_view_facing[i].id = i+8;
text_view_facing[i].type = visualization_msgs::Marker::TEXT_VIEW_FACING;
text_view_facing[i].color.b = 1; text_view_facing[i].color.a = 1.0; text_view_facing[i].color.g = 1.0; text_view_facing[i].color.r = 1.0;
text_view_facing[i].scale.z = 0.015;
}
marker[3].scale.x = 0.05;
marker[3].scale.y = 0.05;
marker[3].scale.z = 0.05;
if(frame_index==10) // Saving the point cloud for only one time to find moved object in it
{
pcl::io::savePCDFileASCII ("test_pcd.pcd", *cloudB);
}
if(frame_index>10) // Reading above point cloud file after saving for once to compare it with newly arriving point clouds
{
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB>);
if (pcl::io::loadPCDFile<pcl::PointXYZRGB> ("test_pcd.pcd", *cloud) == -1) //* load the file
{
PCL_ERROR ("Couldn't read file test_pcd.pcd \n");
}
else {
srand ((unsigned int) time (NULL));
// Octree resolution - side length of octree voxels
double resolution = 0.1;
// Instantiate octree-based point cloud change detection class
pcl::octree::OctreePointCloudChangeDetector<pcl::PointXYZRGB> octree (resolution);
// Add points from cloudA to octree
octree.setInputCloud (cloud);
octree.addPointsFromInputCloud ();
// Switch octree buffers: This resets octree but keeps previous tree structure in memory.
octree.switchBuffers ();
// Add points from cloudB to octree
octree.setInputCloud (cloudB);
octree.addPointsFromInputCloud ();
std::vector<int> newPointIdxVector;
// Get vector of point indices from octree voxels which did not exist in previous buffer
octree.getPointIndicesFromNewVoxels (newPointIdxVector);
geometry_msgs::Point p; std_msgs::ColorRGBA c;
for (size_t i = 0; i < newPointIdxVector.size (); ++i)
{
p.x = cloudB->points[newPointIdxVector[i]].x;
p.y = cloudB->points[newPointIdxVector[i]].y;
p.z = cloudB->points[newPointIdxVector[i]].z;
c.r = cloudB->points[newPointIdxVector[i]].r/255.0;
c.g = cloudB->points[newPointIdxVector[i]].g/255.0;
c.b = cloudB->points[newPointIdxVector[i]].b/255.0;
c.a = 1;
//cout<<newPointIdxVector.size()<<"\t"<<p.x<<"\t"<<p.y<<"\t"<<p.z<<endl;
if(!isnan(p.x) && !isnan(p.y) && !isnan(p.z)) {
marker[3].points.push_back(p);
marker[3].colors.push_back(c);
}
}
marker_publisher.publish(marker[3]);
pcl::PointCloud<pcl::PointXYZRGB> P;
thread t[newPointIdxVector.size()];
for(int p0=0;p0<newPointIdxVector.size();++p0) { // For each voxel in moved object
t[p0] = thread(thread_function,cloudB,newPointIdxVector,p0);
}
for(int p0=0;p0<newPointIdxVector.size();++p0) { // For each voxel in moved object
t[p0].join();
cout<<"joined"<<"\t"<<p0<<"\t"<<x[p0]<<endl;
}
}
}
}
int main (int argc, char** argv)
{
ros::init (argc, argv, "training");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe<sensor_msgs::PointCloud2> ("input", 1, cloud_cb);
marker_publisher = nh.advertise<visualization_msgs::Marker> ("visualization_marker",1);
// Spin
ros::spin ();
}
This task is really important for my algorithm to complete. I need a suggestion how to make this loops run very fast.
In above code the thread_function is the main function where i'm putting the for loops currentely. Is their any way to increase its performance in above code?
OpenMP is the easiest to implement and try. Just add a couple of lines at your CMakeLists.txt, an include and the famous #pragma omp parallel for line just before your for loop.
Threading itself is not necessarily a guarantee for speed. If your process is mostly linear, there is nothing to be done in parallel. In your case, it looks like you have a loop and each iteration might be able to be done independently in parallel, but because each loop is so small and mostly simple mathematical operations, the overhead for making each item its own thread might not save you much (if any) time. The algorithm itself might need an overhaul (i.e. doing this an entirely different way), but threading could potentially solve your issue if your loop is huge and you can break it into, say, 4 chunks and parallel process the 4 chunks (i.e. one thread does items 0-100, another 101-200, etc). Just be aware that one process might finish before another and if some other process is relying on the completion of the whole set of data, then you'll need to ensure that you're done with all 4 threads before continuing. And if you do any kind of manipulation of the data (i.e. shifting elements, adding, removing) in the parallel processes, then you could end up screwing up a parallel thread. Hope that helps!

My semaphore module is not working properly(Dining philosopher)

I'm implementing a semaphore methods to understand synchronization and thread things.
By using my semaphore, I tried to solve the Dining Philosophers problem.
My plan was making deadlock situation first.
But I found that just only one philosopher eat repeatedly.
And I checked that my semaphore is working quite good by using other synchronization problems. I think there is some problem with grammar.
please let me know what is the problem.
Here is my code.
dinig.c (including main function)
#include "sem.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static tsem_t *chopstick[5];
static tsem_t *updating;
static int update_status (int i, int eating)
{
static int status[5] = { 0, };
static int duplicated;
int idx;
int sum;
tsem_wait (updating);
status[i] = eating;
/* Check invalid state. */
duplicated = 0;
sum = 0;
for (idx = 0; idx < 5; idx++)
{
sum += status[idx];
if (status[idx] && status[(idx + 1) % 5])
duplicated++;
}
/* Avoid printing empty table. */
if (sum == 0)
{
tsem_signal (updating);
return 0;
}
for (idx = 0; idx < 5; idx++)
fprintf (stdout, "%3s ", status[idx] ? "EAT" : "...");
/* Stop on invalid state. */
if (sum > 2 || duplicated > 0)
{
fprintf (stdout, "invalid %d (duplicated:%d)!\n", sum, duplicated);
exit (1);
}
else
fprintf (stdout, "\n");
tsem_signal (updating);
return 0;
}
void *thread_func (void *arg)
{
int i = (int) (long) arg;
int k = (i + 1) % 5;
do
{
tsem_wait (chopstick[i]);
tsem_wait (chopstick[k]);
update_status (i, 1);
update_status (i, 0);
tsem_signal (chopstick[i]);
tsem_signal (chopstick[k]);
}
while (1);
return NULL;
}
int main (int argc,
char **argv)
{
int i;
for (i = 0; i < 5; i++)
chopstick[i] = tsem_new (1);
updating = tsem_new (1);
for (i = 0; i < 5; i++)
{
pthread_t tid;
pthread_create (&tid, NULL, thread_func, (void *) (long) i);
}
/* endless thinking and eating... */
while (1)
usleep (10000000);
return 0;
}
sem.c(including semaphore methods)
#include "sem.h"
.
sem.h(Header for sem.c)
#ifndef __SEM_H__
#define __SEM_H__
#include <pthread.h>
typedef struct test_semaphore tsem_t;
tsem_t *tsem_new (int value);
void tsem_free (tsem_t *sem);
void tsem_wait (tsem_t *sem);
int tsem_try_wait (tsem_t *sem);
void tsem_signal (tsem_t *sem);
#endif /* __SEM_H__ */
compile command
gcc sem.c dining.c -pthread -o dining
One problem is that in tsem_wait() you have the following code sequence outside of a lock:
while(sem->count <= 0)
continue;
There's no guarantee that the program will actually re-read sem->count - the compiler is free to produce machine code that does something like the following:
int temp = sem->count;
while(temp <= 0)
continue;
In fact, this will likely happen in an optimized build.
Try changing your busy wait loop to something like this so the count is checked while holding the lock:
void tsem_wait (tsem_t *sem)
{
pthread_mutex_lock(&(sem->mutexLock));
while (sem->count <= 0) {
pthread_mutex_unlock(&(sem->mutexLock));
usleep(1);
pthread_mutex_lock(&(sem->mutexLock));
}
// sem->mutexLock is still held here...
sem->count--;
pthread_mutex_unlock(&(sem->mutexLock));
}
Strictly speaking, you should do something similar for tsem_try_wait() (which you're not using yet).
Note that you might want to consider using a pthread_cond_t to make waiting on the counter changing more efficient.
Finally, your code to 'get' the chopsticks in thread_func() has the classic Dining Philosopher deadlock problem in the situation where each philosopher simultaneously acquires the 'left' chopstick (chopstick[i]) and ends up waiting forever to get the 'right' chopstick (chopstick[k]) since all the chopsticks are in some philosopher's left hand.

C++ First-chance exception

I have wrote a shape detection code with c++.
I am using Visual Studio 2013 Express Desktop Edition.
When I run the program it will give following error.
First-chance exception at 0x54EE3C77 (opencv_imgproc244d.dll) in Final.exe: 0xC0000005: Access violation reading location 0x05958000.
If there is a handler for this exception, the program may be safely continued.
Following is the code sample.
#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#include <cv.h>
#include <highgui.h>
#include <windows.h>
void shapeDetectionNew(IplImage* img)
{
try
{
//converting the original image into grayscale
IplImage* imgGrayScale = cvCreateImage(cvGetSize(img), 8, 1);
cvCvtColor(img, imgGrayScale, CV_BGR2GRAY);
//thresholding the grayscale image to get better results
cvThreshold(imgGrayScale, imgGrayScale, 128, 255, CV_THRESH_BINARY);
CvSeq* contour; //hold the pointer to a contour
CvSeq* result; //hold sequence of points of a contour
CvMemStorage *storage = cvCreateMemStorage(0); //storage area for all contours
//finding all contours in the image
cvFindContours(imgGrayScale, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));
//***********************************
cv::Mat img = cv::imread("F:\\My Works\\Opencv\\Shape_Detection_Images\\shape.jpg");
//convert IplImage to Mat
//cv::Mat img(iplImg);
cv::Mat gray;
cv::cvtColor(img, gray, CV_BGR2GRAY);
// Use Canny instead of threshold to catch squares with gradient shading
cv::Mat bw;
cv::Canny(gray, bw, 0, 50, 5);
// Find contours
std::vector<std::vector<cv::Point> > contours;
cv::findContours(bw.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
std::vector<cv::Point> approx;
cv::Mat dst = img.clone();
//***********************************
for (int i = 0; i < contours.size(); i++)
{
// Approximate contour with accuracy proportional
// to the contour perimeter
cv::approxPolyDP(cv::Mat(contours[i]), approx, cv::arcLength(cv::Mat(contours[i]), true)*0.02, true);
// Skip small or non-convex objects
if (std::fabs(cv::contourArea(contours[i])) < 100 || !cv::isContourConvex(approx))
continue;
if (approx.size() == 3)
{
setLabel(dst, "TRI", contours[i]); // Triangles
}
else if (approx.size() >= 4 && approx.size() <= 6)
{
// Number of vertices of polygonal curve
int vtc = approx.size();
// Get the cosines of all corners
std::vector<double> cos;
for (int j = 2; j < vtc + 1; j++)
cos.push_back(angle(approx[j%vtc], approx[j - 2], approx[j - 1]));
// Sort ascending the cosine values
std::sort(cos.begin(), cos.end());
// Get the lowest and the highest cosine
double mincos = cos.front();
double maxcos = cos.back();
// Use the degrees obtained above and the number of vertices
// to determine the shape of the contour
if (vtc == 4 && mincos >= -0.1 && maxcos <= 0.3)
setLabel(dst, "RECT", contours[i]);
else if (vtc == 5 && mincos >= -0.34 && maxcos <= -0.27)
setLabel(dst, "PENTA", contours[i]);
else if (vtc == 6 && mincos >= -0.55 && maxcos <= -0.45)
setLabel(dst, "HEXA", contours[i]);
}
else
{
// Detect and label circles
double area = cv::contourArea(contours[i]);
cv::Rect r = cv::boundingRect(contours[i]);
int radius = r.width / 2;
if (std::abs(1 - ((double)r.width / r.height)) <= 0.2 &&
std::abs(1 - (area / (CV_PI * std::pow((double)radius, 2)))) <= 0.2)
setLabel(dst, "CIR", contours[i]);
}
}
cv::imshow("Shape_Detection", dst);
}
catch (int e)
{
throw e;
}
}
int main()
{
try
{
// Create CvCapture object to grab data from the webcam
CvCapture* pCapture;
// Start capturing data from the webcam
pCapture = cvCaptureFromCAM(1);
// Define the IplImage pointers we're going to use as globals
IplImage* pFrame;
IplImage* pProcessedFrame;
IplImage* tempFrame;
pFrame = cvQueryFrame(pCapture);
//Create the low threshold slider
// Format: Slider name, window name, reference to variable for slider, max value of slider, callback function
cvCreateTrackbar("Low Threshold", "Edge_Detection", &lowSliderPosition, maxLowThreshold, onLowThresholdSlide);
// Create the high threshold slider
cvCreateTrackbar("High Threshold", "Edge_Detection", &highSliderPosition, maxHighThreshold, onHighThresholdSlide);
// Create a greyscale image which is the size of our captured image
pProcessedFrame = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1);
// Create a frame to use as our temporary copy of the current frame but in grayscale mode
tempFrame = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1);
char keypress;
bool quit = false;
int counterCheck = 1;
while (quit == false)
{
// Make an image from the raw capture data
// Note: cvQueryFrame is a combination of cvGrabFrame and cvRetrieveFrame
pFrame = cvQueryFrame(pCapture);
// Draw the original frame in our window
cvShowImage("Live_Cam", pFrame);
shapeDetectionNew(pFrame);
} // End of while loop
cvDestroyAllWindows();
}
catch (Exception ex)
{
}
return 1;
}
You are not checking that the result of
pFrame = cvQueryFrame(pCapture);
is not null. If it is, eventuallu this will get passed to cvCvtColor() and hence the exception.
Completely separate problem:imshow() will not display anything without a subsequent call to waitKey()

SDL2/SDL.h causing undefined references in Non-SDL code

I've been having an awfully strange problem that I cannot seem to grasp. I'm almost convinced that this is a compiler bug.
xTech : xIncludes.hh
#ifndef _xIncludes_
#define _xIncludes_
#define SDL_MAIN_HANDLED
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <vector>
#include <SDL2/SDL.h>
#if defined _WIN32
#include <winsock.h>
#endif
#endif
xTech : xSound.cc
#include "xSound.hh"
int xOGGStreamSource::_stream(ALuint Buffer) {
char data[BufferSize];
int size = 0;
int section;
int result;
while (size < BufferSize) {
result = ov_read(&_oggstream, data + size, BufferSize - size, 0, 2, 1, &section);
if (result > 0)
size += result;
else
if (result < 0)
return result;
else
break; //This seems a little redundant.... deal with it after it works.
}
if (size == 0) return 0;
alBufferData(Buffer, _format, data, size, _vorbisinfo->rate);
return 1;
}
void xOGGStreamSource::_empty() {
int queued;
alGetSourcei(_source, AL_BUFFERS_QUEUED, &queued);
while (queued--) {
ALuint Buffer;
alSourceUnqueueBuffers(_source, 1, &Buffer);
}
}
int xOGGStreamSource::Open(xString path) {
int result;
_oggfile = xOpenFile(path, "rb");
if (_oggfile.Buffer == NULL) {
xLogf("Audio", "Error in OGG File '%s', file does not exist.", path);
return -3;
}
if (result = ov_open(_oggfile.Buffer, &_oggstream, NULL, 0) < 0) {
xLogf("Audio", "Error in OGG File '%s', file is non-OGG.", path);
xCloseFile(_oggfile);
return -2;
}
_vorbisinfo = ov_info(&_oggstream, -1);
_vorbiscomment = ov_comment(&_oggstream, -1);
if (_vorbisinfo->channels == 1)
_format = AL_FORMAT_MONO16;
else
_format = AL_FORMAT_STEREO16;
alGenBuffers(2, _buffers);
alGenSources(1, &_source);
return 1;
}
void xOGGStreamSource::Close() {
alSourceStop(_source);
_empty();
alDeleteSources(1, &_source);
alDeleteBuffers(1, _buffers);
ov_clear(&_oggstream);
}
int xOGGStreamSource::Playback() {
if (Playing()) return 1;
if (!_stream(_buffers[0])) return 0;
if (!_stream(_buffers[1])) return 0;
alSourceQueueBuffers(_source, 2, _buffers);
alSourcePlay(_source);
return 1;
}
int xOGGStreamSource::Playing() {
ALenum state;
alGetSourcei(_source, AL_SOURCE_STATE, &state);
return (state == AL_PLAYING);
}
int xOGGStreamSource::Update(xVec3f_t Pos, xVec3f_t Vloc, xVec3f_t Dir, float Vol) {
int processed;
int active = 1;
alSource3f(_source, AL_POSITION, Pos.X, Pos.Y, Pos.Z);
alSource3f(_source, AL_VELOCITY, Vloc.X, Vloc.Y, Vloc.Z);
alSource3f(_source, AL_DIRECTION, Dir.X, Dir.Y, Dir.Z);
alSourcef (_source, AL_GAIN, Vol);
alSourcei (_source, AL_SOURCE_RELATIVE, AL_TRUE);
alGetSourcei(_source, AL_BUFFERS_PROCESSED, &processed);
while(processed--) {
ALuint Buffer;
alSourceUnqueueBuffers(_source, 1, &Buffer);
active = _stream(Buffer);
alSourceQueueBuffers(_source, 1, &Buffer);
}
return active;
}
xSound::xSound(xOGGStreamSource xss) { _source = xss; }
int xSound::PlaySound(float Volume, xVec3f_t Location) {
if (!_source.Playback()) return -3;
while(_source.Update(Location, xVec3f_t(0,0,0), xVec3f_t(0,0,0), Volume)) {
if (!_source.Playing()) {
if (!_source.Playback()) return -2;
else return -1;
}
}
_source.Close();
return 1;
}
xSoundManager::xSoundManager(){}
int xSoundManager::Init() {
_device = alcOpenDevice(NULL);
if (!_device) return -2;
_context = alcCreateContext(_device, NULL);
if (alcMakeContextCurrent(_context) == ALC_FALSE || !_context) return -1;
if (!Volume) {
xLogf("Error", "Volume in Audio is not set properly. Setting to default");
Volume = DEFAULT_VOLUME;
}
alListenerf(AL_GAIN, Volume);
if (!BufferSize) {
xLogf("Error", "Buffer size in Audio is not set properly. Setting to default");
BufferSize = DEFAULT_BUFFER_SIZE;
}
return 0;
}
xSound* xSoundManager::LoadOGG(xString file) {
xOGGStreamSource ogg;
if (ogg.Open(file) < 0) return NULL;
return new xSound(ogg);
}
xTechLibTest : main.cc
int main() {
xSetLogFile("xTechLibTest.log");
xSoundManager* audio = new xSoundManager();
if (audio->Init() < 0) return -1;
xSound* testsound1 = audio->LoadOGG("testsound.ogg");
if (testsound1 == NULL) return -2;
testsound1->PlaySound(1.0, xVec3f_t(1.0,0.5,0.3));
}
The above code and everything associated with it (string implementations, etc) work fine, no problems at all. That is until I include SDL.h; I get undefined references for every function I defined, when the compiler could find them with no problem before. It seems that the mere inclusion of SDL.h completely nullifies any definition I make. Any ideas what's going on here?
Have you properly included the linkage to the SDL libraries?
If you have built the binaries yourself, you need to include the path and library. On a linux system, if you have built the static libraries yourself, you will have a binary called libSDL2.a, however to link you need to specify SDL2 as your linked library.
Also as a side note, do you have a redundant include guard on your xsound.h file( via #ifdef _xsound_ ... ) ?
p.s. It will help the other users if you specify what how your environment is setup; compiler, system os, IDE.
It would be useful to see the output from your compiler/linker.
I've had similar problems with network related code when using Cygwin on a windows machine. I've had sockets working fine without SDL, as soon as I include SDL, the whole lot breaks with messages saying that certain header files and references can't be found.
I'm not certain, but I think it has something to do with the way that SDL has it's own main macros (here is a post about it here - simple tcp echo program not working when SDL included?).
I may be wrong, but is this similar to what you are seeing?

Multithreading in C++ using reference classes - ThreadStart constructor issues?

I appreciate any help, and would like to thank you in advance. I'm working on a project for one of my classes. Essentially performing merge sort using multithreading and reference classes. In main I'm just trying to create an initial thread that will begin the recursive mergesort. Each time the array is split a new thread is spawned to handle that subroutine. I don't need all of it done, i just don't under stand why my Thread constructor and ThreadStart delegate are not working. Thanks again!!
#include <iostream>
#include <vector>
#include <string>
#include <time.h>
#include <cstdlib>
using namespace System;
using namespace System::Threading;
public ref class MergeSort
{
private: int cnt;
public: MergeSort()
{
cnt = 0;
}
public: void mergeSort(char a[], int from, int to)
{
Thread^ current = Thread::CurrentThread;
if(from == to)
return;
int mid = (from + to)/2;
//Sort the first and the second half
//addThread(a, from, mid);
//addThread(a, mid+1, to);
//threads[0]->Join();
//threads[1]->Join();
merge(a, from, mid, to);
}
public: void merge(char a[], int from, int mid, int to)
{
Thread^ current = Thread::CurrentThread;
while (current ->ThreadState == ThreadState::Running)
{
int n = to-from + 1; // Size of range to be merged
std::vector<char> b(n);
int i1 = from; //Next element to consider in the first half
int i2 = mid + 1; //Next element to consider in the second half
int j = 0; //Next open position in b
//As long as neight i1 or i2 is past the end, move the smaller element into b
while(i1 <= mid && i2 <= to)
{
if(a[i1] < a[i2])
{
b[j] = a[i1];
i1++;
}
else
{
b[j] = a[i2];
i2++;
}
j++;
}
//Copy any remaining entries of the first half
while(i1 <= mid)
{
b[j] = a[i1];
i1++;
j++;
}
while(i2 <= to)
{
b[j] = a[i2];
i2++;
j++;
}
//Copy back from temporary vector
for(j = 0; j < n; j++)
a[from+j] = b[j];
}
}
};
void main()
{
char A[10];
for(int i = 0; i < 10; i++)
{
A[i] = ((char) ((rand() % (122-65)) + 65));
}
array<Thread^>^ tr = gcnew array<Thread^>(10);
MergeSort^ ms1 = gcnew MergeSort();
ThreadStart^ TS = gcnew ThreadStart(ms1, &MergeSort::mergeSort(A, 0, 10));
tr[0] = gcnew Thread(TS);
tr[0] -> Start();
system("pause");
}
The issue you are facing here is how to construct a ThreadStart delegate. You are trying to do too many things in the ThreadStart constructor. You cannot pass in arguments at this point because all it is looking for is a start location for the thread.
The delegate should be:
ThreadStart^ TS = gcnew ThreadStart(ms1, &MergeSort::mergeSort);
Since however you are passing in some state, I would recommend doing a bit more research on how that is done using C++\CLI. This MSDN topic should give you a start.
Edit:
Never mind, the problem was that I had to change the parameter of the method I tried to pass from Int32 to Object^.
I´m having a similar issue, though i think my problem are not the arguments. I´m passing those through during thread->Start().
I think my problem is rather that I´m trying to start the thread using a method of a ref class.
invalid delegate initializer -- function does not match the delegate type
Is the error I´m getting. Any Ideas?
void AddForcesAll() {
for (int index = 0; index < n; index++) {
Thread^ thread = gcnew Thread (gcnew ParameterizedThreadStart(this, &Bodies::AddForces));
thread->Start(index);
}
The Syntax worked fine for me for non referenced classes.

Resources