setTimer() to generate WM_TIMER message only once - visual-c++

I am using timers with resource ID added and based on WM_TIMER message.
I would like to call a routine like DrunkenDragon() on OnTimer() but for only once after SetTimer(id,10sec,NULL) was called. We know that Call to KillTimer() inside DrunkenDragon() routine would fix the solution. Is it okay to go with this, or am I missing out something great with timers.

(Only answering this in case someone else comes across it like I did and was unsatisfied with the answers available)
So, in WindowClass.h, what you can do is an enumeration of the timer identifiers you want to use. While you certainly can use raw numeric values, using symbols is probably easier to work with in the long run.
class WindowClass : CWnd
{
// other parts of the interface...
protected:
enum
{
TIMER_MAIN_UPDATE = 1,
TIMER_PLASTERED_DRAGON
};
};
Meanwhile, back at in WindowClass.cpp,
int WindowClass::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
// { ... other initialization code }
// In case you want to do other types of updates at regular intervals.
SetTimer(TIMER_MAIN_UPDATE, 1000, NULL);
// Note the symbolic identifiers.
SetTimer(TIMER_PLASTERED_DRAGON, 10000, NULL);
return 0;
}
That's only any good if you want to do it 10 seconds after the window's been created, though. You can also just call SetTimer() in some other event handler whenever you'd like:
void WindowClass::OnJustGotPaid()
{
// { ... other handling }
// Since our dragon is a real lightweight, it apparently only takes
// 10 seconds to get him puking up flaming vomit.
SetTimer(TIMER_PLASTERED_DRAGON, 10000, NULL);
}
When it comes time for the actual event to be handled, it is typically handled in the Windows OnTimer() callback. A timer event can be directed to a different (custom) callback, if desired, by specifying a valid function pointer in SetTimer()'s third parameter instead of NULL.
void WindowClass::OnTimer(UINT_PTR p_timer_id)
{
switch(p_timer_id)
{
default:
break;
case TIMER_MAIN_UPDATE:
// { ... main update code }
break;
case TIMER_PLASTERED_DRAGON:
// Killing the timer first in case DrunkenDragon() takes a good
// long while for whatever reason.
KillTimer(TIMER_PLASTERED_DRAGON);
DrunkenDragon();
break;
}
}

int CYourDialog::OnInitDialog()
{
__super::OnInitDialog();
SetTimer(0x10, 10000, NULL);
return true;
}
void CYourDialog::OnTimer(UINT_PTR ignore)
{
DrunkenDragon();
}
And ensure you have ON_WM_TIMER in message-map.

You are not missing anything and you would have to use KillTimer for system to stop generating WM_TIMER messages.
You can also use CreateTimerQueueTimer and set parameters the way a callback is called only once.
See this for more details.

Related

CAPL code, putting delay in the code

I have a CAPL test code that controls the start of CAN signal sending. My goal is to delay the start of the sending process.
My idea to do this is via a setTimer() function in combination with isTimerActive().
In general my code looks the following:
main() {
CANstart();
function_2();
function_3();
}
CANstart() {
SetTimer(Delay, 5000); //Timer initialization, set to be 5000ms
while (isTimerActive()==1) {
// this while loop avoids that the code is proceding while the settimer exception is being called and executed
}
StartCANTransmitting(); // After this function, jump back to main and proceed with function_2
}
on timer Delay {
// Do nothing, just wait
}
The program code above lead to being stuck at that point, CANoe does not response and the only way I can end the simulation is via taskmanager.
Further examination from my side lead to the conclusion that the timer need more time to process and is not executed at all.
Without the isTimerActive() function, the program code does not wait for the timer to finish and there is no delay at all. Seems like the code runs through without waiting for the exception.
Seems like CAPL handles loops very bad.
I check out stackoverflow and the following forum posts talk about very similar issues that I have without offering any working solutions:
CAPL Programming usage of Timer as a delay
Are timers running, while loops are active?
Delay function in CAPL apart from testwaitfortimeout()
I see a great deal of issues with your code. It actually does not feel like code at all, but more like pseudo-code. Does it compile on your CAPL browser?
main() {
CANstart();
function_2();
function_3();
}
If this is a function declaration, then it is missing both a type and a return value. In addition, when are you expecting main() to be executed?
The same applies to:
CANstart()
Let us make a step back. You need to delay the beginning of can transmitting. If you need to do so because you have code outside CANalyzer/CANoe running, then I suggest you call the application via command line (refer to the guide for more help).
If you need, however, to have blocks running in your setup configuration, like a Replay block, a Loggin block or whatever, I suggest you to do the following:
variables {
/* define your variables here. You need to define all messages you want to send and respective signal values if not defaulted */
message 0x12345678 msg1; // refer to CAPL guide on how to define message type variables
msTimer delay;
msTimer msgClock1;
}
on start {
/* when you hit the start measurements button (default F9) */
setTimer(delay, 5000); // also note your syntax is wrong in the example
}
on timer delay {
/* when timer expires, start sending messages */
output(msg1); // send your message
setTimer(msgClock1,250); // set timer for cyclic message sending
}
on timer msgClock1 {
/* this mimicks the behaviour of a IG block */
setTimer(msgClock1,250); // keep sending message
output(msg1)
}
Does this achieve your goal? Please feel free to ask for more details.
It appears that you have a problem with the while (isTimerActive()==1) { statement.
CAPL function int isTimerActive requires the parameters timer or mstimer variable and return values
1, if the timer is active otherwise 0.
You can check if the timer is active and the time to elapse in the following way.
timer t;
write("Active? %d", isTimerActive(t)); // writes 0
setTimer(t, 5);
write("Active? %d", isTimerActive(t)); // writes 1
write("Time to elapse: %d",timeToElapse(t)); // Writes 5
try adding the parameter timer at while (isTimerActive(Delay)==1) {
I would not suggest using the while statement instead you can use the timer directly to call the function StartCANTransmitting() and your Main() should be MainTest()
void MainTest()
{
TestModuleTitle("Sample Tests");
TestModuleDescription("This test module calls some test cases to demonstrate ");
CANstart();
if (TestGetVerdictLastTestCase() == 1)
Write("CANstart failed.");
else
Write("CANstart passed.");
}
testcase CANstart() {
// add info block to test case in report
TestReportAddMiscInfoBlock("Used Test Parameters");
TestReportAddMiscInfo("Max. voltage", "19.5 V");
TestReportAddMiscInfo("Max. current", "560 mA");
TestReportAddMiscInfo("StartCANTransmitting");
SetTimer(Delay, 5000); //Timer initialization, set to be 5000ms
}
on timer Delay {
StartCANTransmitting();
}

Skipping threads based on parameter, then returning to them later

I have a method that takes in a value and if a condition is met the action shouldn't run for 24 hours. But when it stops I want to run other threads that don't met that condition.
In this example I have 30 threads made at the beginning of the program. Once I make 5 pieces of cheese I need to stop because that's too much cheese. What would be great is if there was a place to send threads that can't be acted on until time is run out while the others are running. Task.Delay even with Wait does not seem to be effective here.
Here's me code sample:
//Stop making cheese when you have enough for the day but continue making others
public void madeEnoughToday(string cheese)
{
//Find how much cheese is made based on cheese type.
DataGridViewRow row = cheeseGV.Rows
.Cast<DataGridViewRow>()
.Where(r =>
r.Cells["Cheese"].Value.ToString().Equals(cheese))
.First();
if (row.Cells["MadeToday"].Value.Equals(row.Cells["Perday"].Value))
{
Task.Delay(30000).Wait();
}
}
When I need to pause thread execution, I use another thread (global variable, or another implementation) - call Thread.Join() method for the second instance of the thread.
Thread tPause; // global var
private void MyThreadFunc()
{
// do something
if (pauseCondition)
{
tPause=new Thread(PauseThread);
tPause.Start();
tPause.Join(); // You can specify needed milliseconds, or TimeSpan
// the subsequent code will not be executed until tPause.IsAlive == true
// IMPORTANT: if tPause == null during Join() - an exception occurs
}
}
private void PauseThread()
{
Thread.Sleep(Timeout.Infinite); // You can specify needed milliseconds, or TimeSpan
}
private void Main()
{
// any actions
Thread myThread=new Thread(MyThreadFunc);
myThread.Start();
// any actions
}
There are many ways of this realization.
If you want to continue the thread execution, you can call the Thread.Abort() method for the pause thread instance, or use the sophisticated construction of function for the pause thread.

SAPI 5 TTS Events

I'm writing to ask you some advices for a particular problem regarding SAPI engine. I have an application that can speak both to the speakers and to a WAV file. I also need some events to be aware, i.e. word boundary and end input.
m_cpVoice->SetNotifyWindowMessage(m_hWnd, TTS_MSG, 0, 0);
hr = m_cpVoice->SetInterest(SPFEI_ALL_EVENTS, SPFEI_ALL_EVENTS);
Just for test I added all events! When the engine speaks to speakers all events are triggered and sent to the m_hWnd window, but when I set output to the WAV file, none of them are sent
CSpStreamFormat fmt;
CComPtr<ISpStreamFormat> pOld;
m_cpVoice->GetOutputStream(&pOld);
fmt.AssignFormat(pOld);
SPBindToFile(file, SPFM_CREATE_ALWAYS, &m_wavStream, &fmt.FormatId(), fmt.WaveFormatExPtr());
m_cpVoice->SetOutput(m_wavStream, false);
m_cpVoice->Speak(L"Test", SPF_ASYNC, 0);
Where file is a path passed as argument.
Really this code is taken from the TTS samples found on the SAPI SDK. It seems a little bit obscure the part setting the format...
Can you help me in finding the problem? Or does anyone of you know a better way to write TTS to WAV? I can not use manager code, it should be better to use the C++ version...
Thank you very much for help
EDIT 1
This seems to be a thread problem and searching in the spuihelp.h file, that contains the SPBindToFile helper I found that it uses the CoCreateInstance() function to create the stream. Maybe this is where the ISpVoice object looses its ability to send event in its creation thread.
What do you think about that?
I adopted an on-the-fly solution that I think should be acceptable in most of the cases, In fact when you write speech on files, the major event you would be aware is the "stop" event.
So... take a look a the class definition:
#define TTS_WAV_SAVED_MSG 5000
#define TTS_WAV_ERROR_MSG 5001
class CSpeech {
public:
CSpeech(HWND); // needed for the notifications
...
private:
HWND m_hWnd;
CComPtr<ISpVoice> m_cpVoice;
...
std::thread* m_thread;
void WriteToWave();
void SpeakToWave(LPCWSTR, LPCWSTR);
};
I implemented the method SpeakToWav as follows
// Global variables (***)
LPCWSTR tMsg;
LPCWSTR tFile;
long tRate;
HWND tHwnd;
ISpObjectToken* pToken;
void CSpeech::SpeakToWave(LPCWSTR file, LPCWSTR msg) {
// Using, for example wcscpy_s:
// tMsg <- msg;
// tFile <- file;
tHwnd = m_hWnd;
m_cpVoice->GetRate(&tRate);
m_cpVoice->GetVoice(&pToken);
if(m_thread == NULL)
m_thread = new std::thread(&CSpeech::WriteToWave, this);
}
And now... take a look at the WriteToWave() method:
void CSpeech::WriteToWav() {
// create a new ISpVoice that exists only in this
// new thread, so we need to
//
// CoInitialize(...) and...
// CoCreateInstance(...)
// Now set the voice, i.e.
// rate with global tRate,
// voice token with global pToken
// output format and...
// bind the stream using tFile as I did in the
// code listed in my question
cpVoice->Speak(tMsg, SPF_PURGEBEFORESPEAK, 0);
...
Now, because we did not used the SPF_ASYNC flag the call is blocking, but because we are on a separate thread the main thread can continue. After the Speak() method finished the new thread can continue as follow:
...
if(/* Speak is went ok */)
::PostMessage(tHwn, TTS_WAV_SAVED_MSG, 0, 0);
else
::PostMessage(tHwnd, TTS_WAV_ERROR_MSG, 0, 0);
}
(***) OK! using global variables is not quite cool :) but I was going fast. Maybe using a thread with the std::reference_wrapper to pass parameters would be more elegant!
Obviously, when receiving the TTS messages you need to clean the thread for a next time call! This can be done using a CSpeech::CleanThread() method like this:
void CSpeech::CleanThread() {
m_thread->join(); // I prefer to be sure the thread has finished!
delete m_thread;
m_thread = NULL;
}
What do you think about this solution? Too complex?

can Multiple threads depend on a single manual Kill-event?

I have a MFC code with multiple threads that all make recursive calls to a subroutine, with different parameters.
In the beginning of the subroutine, I make a call to function CheckKillEvent():
bool CTestShellDlg::CheckKillEvent()
{
DWORD waitS;
waitS = WaitForSingleObject(h_KillEvent, 0);
switch (waitS)
{
case WAIT_OBJECT_0:
return true;
break;
case WAIT_TIMEOUT:
return false;
break;
default:
IERROR
break;
}
}
and return() immediately if CheckKillEvent returns true.
fyi, h_killEvent is initialized as:
h_KillEvent = CreateEvent(NULL, true, false, NULL);
ie, it has a manual reset.
However, these threads seem to take (literally) forever to finish after I set the Kill-event as below:
bool CTestShellDlg::KillThreads()
{
//Signall the killing event
SetEvent(h_KillEvent);
if (WaitForMultipleObjects(,,true,)==...)
{
ResetEvent(h_KillEvent);
return true; //Killing successful
}
else
return false; //Killing failed
}
The question is, is there an issue with calling CheckKillEvent() from multiple threads? Should the WaitForSingleObject() be done inside a critical section or something? Or is it simply my recursive code being bad at recursing back to a point where it no longer calls itself?
As Hans suggested in the comment, the problem was in fact with the message pump being blocked. Always best to assign separate threads for tasks that might take long or might themselves need access to the message pump.

How to asynchronously read to std::string using Boost::asio?

I'm learning Boost::asio and all that async stuff. How can I asynchronously read to variable user_ of type std::string? Boost::asio::buffer(user_) works only with async_write(), but not with async_read(). It works with vector, so what is the reason for it not to work with string? Is there another way to do that besides declaring char user_[max_len] and using Boost::asio::buffer(user_, max_len)?
Also, what's the point of inheriting from boost::enable_shared_from_this<Connection> and using shared_from_this() instead of this in async_read() and async_write()? I've seen that a lot in the examples.
Here is a part of my code:
class Connection
{
public:
Connection(tcp::acceptor &acceptor) :
acceptor_(acceptor),
socket_(acceptor.get_io_service(), tcp::v4())
{ }
void start()
{
acceptor_.get_io_service().post(
boost::bind(&Connection::start_accept, this));
}
private:
void start_accept()
{
acceptor_.async_accept(socket_,
boost::bind(&Connection::handle_accept, this,
placeholders::error));
}
void handle_accept(const boost::system::error_code& err)
{
if (err)
{
disconnect();
}
else
{
async_read(socket_, boost::asio::buffer(user_),
boost::bind(&Connection::handle_user_read, this,
placeholders::error, placeholders::bytes_transferred));
}
}
void handle_user_read(const boost::system::error_code& err,
std::size_t bytes_transferred)
{
if (err)
{
disconnect();
}
else
{
...
}
}
...
void disconnect()
{
socket_.shutdown(tcp::socket::shutdown_both);
socket_.close();
socket_.open(tcp::v4());
start_accept();
}
tcp::acceptor &acceptor_;
tcp::socket socket_;
std::string user_;
std::string pass_;
...
};
The Boost.Asio documentation states:
A buffer object represents a contiguous region of memory as a 2-tuple consisting of a pointer and size in bytes. A tuple of the form {void*, size_t} specifies a mutable (modifiable) region of memory.
This means that in order for a call to async_read to write data to a buffer, it must be (in the underlying buffer object) a contiguous block of memory. Additionally, the buffer object must be able to write to that block of memory.
std::string does not allow arbitrary writes into its buffer, so async_read cannot write chunks of memory into a string's buffer (note that std::string does give the caller read-only access to the underlying buffer via the data() method, which guarantees that the returned pointer will be valid until the next call to a non-const member function. For this reason, Asio can easily create a const_buffer wrapping an std::string, and you can use it with async_write).
The Asio documentation has example code for a simple "chat" program (see http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/examples.html#boost_asio.examples.chat) that has a good method of overcoming this problem. Basically, you need to have the sending TCP send along the size of a message first, in a "header" of sorts, and your read handler must interpret the header to allocate a buffer of a fixed size suitable for reading the actual data.
As far as the need for using shared_from_this() in async_read and async_write, the reason is that it guarantees that the method wrapped by boost::bind will always refer to a live object. Consider the following situation:
Your handle_accept method calls async_read and sends a handler "into the reactor" - basically you've asked the io_service to invoke Connection::handle_user_read when it finishes reading data from the socket. The io_service stores this functor and continues its loop, waiting for the asynchronous read operation to complete.
After your call to async_read, the Connection object is deallocated for some reason (program termination, an error condition, etc.)
Suppose the io_service now determines that the asynchronous read is complete, after the Connection object has been deallocated but before the io_service is destroyed (this can occur, for example, if io_service::run is running in a separate thread, as is typical). Now, the io_service attempts to invoke the handler, and it has an invalid reference to a Connection object.
The solution is to allocate Connection via a shared_ptr and use shared_from_this() instead of this when sending a handler "into the reactor" - this allows io_service to store a shared reference to the object, and shared_ptr guarantees that it won't be deallocated until the last reference expires.
So, your code should probably look something like:
class Connection : public boost::enable_shared_from_this<Connection>
{
public:
Connection(tcp::acceptor &acceptor) :
acceptor_(acceptor),
socket_(acceptor.get_io_service(), tcp::v4())
{ }
void start()
{
acceptor_.get_io_service().post(
boost::bind(&Connection::start_accept, shared_from_this()));
}
private:
void start_accept()
{
acceptor_.async_accept(socket_,
boost::bind(&Connection::handle_accept, shared_from_this(),
placeholders::error));
}
void handle_accept(const boost::system::error_code& err)
{
if (err)
{
disconnect();
}
else
{
async_read(socket_, boost::asio::buffer(user_),
boost::bind(&Connection::handle_user_read, shared_from_this(),
placeholders::error, placeholders::bytes_transferred));
}
}
//...
};
Note that you now must make sure that each Connection object is allocated via a shared_ptr, e.g.:
boost::shared_ptr<Connection> new_conn(new Connection(...));
Hope this helps!
This isn't intended to be an answer per se, but just a lengthy comment: a very simple way to convert from an ASIO buffer to a string is to stream from it:
asio::streambuf buff;
asio::read_until(source, buff, '\r'); // for example
istream is(&buff);
is >> targetstring;
This is a data copy, of course, but that's what you need to do if you want it in a string.
You can use a std:string with async\_read() like this:
async_read(socket_, boost::asio::buffer(&user_[0], user_.size()),
boost::bind(&Connection::handle_user_read, this,
placeholders::error, placeholders::bytes_transferred));
However, you'd better make sure that the std::string is big enough to accept the packet that you're expecting and padded with zeros before calling async\_read().
And as for why you should NEVER bind a member function callback to a this pointer if the object can be deleted, a more complete description and a more robust method can be found here: Boost async_* functions and shared_ptr's.
Boost Asio has two styles of buffers. There's boost::asio::buffer(your_data_structure), which cannot grow, and is therefore generally useless for unknown input, and there's boost::asio::streambuf which can grow.
Given a boost::asio::streambuf buf, you turn it into a string with std::string(std::istreambuf_iterator<char>(&buf), {});.
This is not efficient as you end up copying data once more, but that would require making boost::asio::buffer aware of growable containers, i.e. containers that have a .resize(N) method. You can't make it efficient without touching Boost code.

Resources