Effective December 13, Adobe disabled the activation server for CS2 products and Acrobat 7 because of a technical glitch. These products were released over 7 years ago and do not run on many modern operating systems. But to ensure that any customers activating those old versions can continue to use their software, we issued a serial number directly to those customers. While this might be interpreted as Adobe giving away software for free, we did it to help our customers.
So yes you can, but the intent was not to give it away for free. I was one of the people who it did affect (owned CS2 package).
I've done something similar recently (not the priority side).
I actually made an atomic enum that tracked the state of the worker thread.
enum class WorkerThreadState : int
I could then use the atomic compare_exchange commands to test the state to see if it was safe to change or if it had changed to a terminating state, leave it alone.
And since I had a reference to the state outside of the thread, I could query what the thread was doing at the moment.
Thread would start as CheckingForJob. It would atomically check if the State was still CheckingForJob before checking the queue. If it wasn't, then it was likely triggered to shutdown (Terminating). This could have happened while processing a previous job. Once a job was retrieved, it was set to RunningJob. If no jobs were available, it would be set to Sleeping and wait for a condition variable to be triggered to check again. The controlling thread would set the variable to Terminating when it was ready for it to shut down. When set to Terminating, once whatever job it was working on was complete, it would stop the loop and set itself as ReadyToJoin. A function outside the WorkerThread would check the vector of worker threads for threads that were ReadyToJoin and call join on them, then remove them from the vector.
I can't stand warnings either. Currently the ones that have driven me the most mad are Intellisense warnings in VS 2015. The code is right and works, but I think the templated nature of the code is a little too much for Intellisense. It reports that a function doesn't exist, despite compiling and executing just fine.
I remember doing something similar. I started writing a forum post so some other eyes could look at some code I couldn't get to compile and looked right to me. As I was writing the post, I was actually writing out a list of expected responses, which then led me to realize what was actually wrong with the code.
Thought I'd add that the upcoming Windows 10 Anniversary update will be adding some "native" Linux support. While you might not be able to test the program itself (not sure how much will or won't work), you will be able to run GCC from bash directly from Windows.
This one is a long shot, but have you tried throwing a breakpoint on the non-ref AddRef and check to see if anything looks weird about the template parameter or the function parameters when it gets called?
And I definately get not being able to share everything, I'm just trying to fill in the gaps where I can
I see what your saying about the non-reffed version. I tried stripping it down some (replaced ai:BehaviorTree with an empty class Test2 since I don't have all your headers), Both calls ended up calling the first version of the function, which would seem to be the correct behavior, since it should only be the wrapper Asset getting manipulated. Now something I notice (and am guessing this is just a bad cut and paste or just not a complete code), is that
shouldn't work in your posted code, since in your example I don't see any kind of constructor of Asset that would pass along the parameter into the ai:BehaviorTree constructor.
It looks like it revolves around your decltype for the returns. When I comment them out, it works fine. I'm guess it has to do with trying to set the return type to void using the decltype (since the function doesn't have a return call). So it is defaulting to the version that already has void as a return type. long and int are effectively the same type in VS, so I don't think that would stop anything.
And thinking about it more (without further testing), void() might be making a return type of a function pointer with a return type of void, not the actual void type.
template <typename ObjectType>
static auto AddRef(ObjectType* pObject)/* -> decltype(AddRef(pObject, 0))*/
return AddRef<ObjectType>(pObject, 0);
template <typename ObjectType>
static auto AddRef(ObjectType* pObject, int)/* -> decltype(pObject->AddRef(), void())*/
static void AddRef(ObjectType* pObject, long)
int main(int argc, char* argv)
Test* test = new Test();
At that moment, you wish you had never heard of constexpr (at least that's what I felt like!). Because if you had been told ahead of time that the function would be evaluated at runtime anyway, you would have used a better algorithm.
I feel the same way. I love the concept, but it can be annoying sometimes. I had a bit counting function implemented that called the Microsoft intrinsic version when it was available. When VS2015 was released, I thought I was being clever and had implemented the fallback as a constexpr function. Only to get smacked in the face by the fact that the intrinsic specializations couldn't coexist with the constexpr version. They had to be named separate, which defeats what I was hoping for (not really thinking about how it would really work)... If it can be at compile-time, do it at compile-time. If it can't be, use the intrinsic version if available, else the fallback.