Welcome to CountryBit. We're exploring making things ourselves. We explore new technology in software, woodworking, home improvement and even cooking as to do not only challenges us, but improves us.
Right now I'm building OverSATX - a SAT Solver for Windows 10. A SAT solver is our take on a fundamental problem of computer science. Given a set of boolean expressions, figure out the variable assignment that makes them all true. There's a lot of interest in this problem because we can make software much more powerful as we get better at solving these problems. Some day, a general solution, could even give us the computing power we need to cure most diseases, and perhaps even achieve immortality. It's a good hobby to work on.
Originally OverSAT was a console application, but, I'm interested in Windows 10 and have it mind to write for it, so I figured I'd start with migrating OverSAT to Windows 10. Then, I can put it into the Windows store, but its open source and you can have a look here. It may not be much, but, the sales pitch is for immortality. Maybe I'll get some gas money for this or enough to get the Mrs. some new dishes.
The challenge today, is changing from a command line C++ application to a Windows Universal wrapper around a C++ program. That part actually proved not to be too bad. I recommend letting the wizard generate the vanilla application and then move C++ code into it. Working with C++ style pointers versus Windows runtime references poses a few minor conversion challenges but ultimately comes out ok.
Some things I have learned:
How to convert a C++ string to a Windows Runtime string.My file_data class is created by a Platform string. The Data() member str gets you a wide string, and then you have to convert it to UTF8, if that's what you want:
file_data(Platform::String^ str) { auto wdata = str->Data(); using convert_type = std::codecvt_utf8How to do a file picker in Windows Runtime C++; std::wstring_convert converter; converted_str = converter.to_bytes(wdata); length = converted_str.size(); }
The file picker is a bit of a head turner for those not used to Windows Universals asynchronous ways. Ironically, JavaScript people will find this familiar. You have to chain a lot of async callbacks but it turns out Microsoft provides a C++ library to do this.
Your .pch file might wind up like this:
#includeThe key thing is to include ppltasks.h. Now we can write our handler for a button clicked event. When the button is clicked, we will load up a new CNF file. Namespaces in our Windows main.xaml.cpp file:#include #include "App.xaml.h"
using namespace OverSatX; using namespace concurrency; using namespace Platform; using namespace Windows::Storage; using namespace Windows::Storage::Pickers; using namespace Windows::Storage::Streams; using namespace Windows::Foundation; using namespace Windows::Foundation::Collections; using namespace Windows::System::Threading; using namespace Windows::UI::Xaml; using namespace Windows::UI::Xaml::Controls; using namespace Windows::UI::Xaml::Controls::Primitives; using namespace Windows::UI::Xaml::Data; using namespace Windows::UI::Xaml::Input; using namespace Windows::UI::Xaml::Media; using namespace Windows::UI::Xaml::Navigation;And finally, our open handler. We open up a file open picker, which, when the user clicks on something, will hand us a StorageFile. We open that async as well. Once opened, we can then use
void OverSatX::MainPage::btnCnfLoad_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { FileOpenPicker^ openPicker = ref new FileOpenPicker(); openPicker->ViewMode = PickerViewMode::List; openPicker->SuggestedStartLocation = PickerLocationId::DocumentsLibrary; openPicker->FileTypeFilter->Append(".cnf"); auto dataReader = std::make_sharedHope this helps! A few noteworthy things are - it seems to be relatively ok to call UI objects on these async threads. I'm not sure if the traditional Windows UI must be managed on the STA thread remains in effective, or, if something evil is going behind the scenes. We shall see when we start running long runn calculation threads in the background. I don't trust it!(nullptr); create_task(openPicker->PickSingleFileAsync()) .then([this](StorageFile^ file) { if (file) { SetStatus(L"FOUND"); return file->OpenAsync(FileAccessMode::Read); } else { SetStatus(L"CANCELLED"); throw task_canceled(); } }) .then([this,dataReader](IRandomAccessStream^ stream)-> IAsyncOperation ^ { SetStatus(L"READING"); *dataReader = ref new DataReader(stream->GetInputStreamAt(0)); return (*dataReader)->LoadAsync(stream->Size); }) .then([this, dataReader](unsigned int nbytes) { SetStatus(L"READ"); textFileContent = (*dataReader)->ReadString(nbytes); solver::file_data fd(textFileContent); SetStatus(L"PARSE"); sat_solver = sat_solver_factory.create_problem(fd); spDecisionString->Children->Clear(); spRootConflicts->Children->Clear(); spNewSimplifiedConflicts->Children->Clear(); spAllSimplifiedConflicts->Children->Clear(); DrawProblem(); this->btnSATStep->IsEnabled = true; this->btnSATCalc->IsEnabled = true; this->btnSATStop->IsEnabled = false; SetStatus(L"LOADED"); }); }
No comments:
Post a Comment