How to get back the name passed to ID3D12Object::SetName()? - directx-12

There's a setter, but no getter. The doc doesn't give any information other than that this name will be used in debug diagnostics and tools.

This works:
wchar_t name[128] = {};
UINT size = sizeof(name);
object->GetPrivateData(WKPDID_D3DDebugObjectNameW, &size, name);
In DX11 the SetName API didn't exist, but SetPrivateData(WKPDID_D3DDebugObjectName, ...) was used for the same purpose. And GetPrivateData could be used to retrieve the string.
DX12 actually uses the same system, just with a different GUID because the name is in unicode (note the W at the end of WKPDID_D3DDebugObjectNameW), and SetName is just a shortcut for it.

Related

Missing Xerces C++ class to copy attributes of element for use after SAX2 parsing

The documentation of xerces anticipates the need to make a copy of attributes, but the AttributesImpl class doesn't seem to exist. Neither does the facility seem to exist in other associated classes in either the current 3.2.3 version of xerces or previous 2.X
Xerces documentation in the file itself src/xercesc/sax2/Attributes.hpp says:
"The instance provided will return valid results only during the scope of the startElement invocation (to save it for future use, the application must make a copy: the AttributesImpl helper class provides a convenient constructor for doing so)."
See also I've left issue here as a bug in xerces
https://issues.apache.org/jira/browse/XERCESC-2238
Appears I will be stuck instead creating my own version of attributes in which to copy or clone, and not overwritten each new line. Not saving whole document (which would defeat purpose of SAX streaming parse), but the existing framework populating Attributes is pretty convoluted and undocumented. Obviously the library and docs are designed to use the api, not to hack or extend the application.
Is this really correct, AttributesImpl is helper class in the documentation that doesn't actually exist? Neither is there a different class with this functionality to save an element's attributes for later use (outside the handler)?
Below is a working version of an Attributes deep copy utility function. It may be missing a few includes which I'm getting from other includes of my larger file. When I get the chance, I'll try making this a stand alone and update this answer. It still falls short of the Java version utility, due to inaccessible members of RefVectorOf class, because the wrapping class, the Attributes interface and VecAttributesImpl interface, do not provide access to them. https://xerces.apache.org/xerces-j/apiDocs/org/xml/sax/helpers/AttributesImpl.html
Last release of Xerces C/C++ is from 2016, so although marked status active, https://projects.apache.org/project.html?xerces-for_c++_xml_parser , really not so much. Can't vouch for libhunt site, but came up in quick google just now https://cpp.libhunt.com/xerces-c++-alternatives . One can see latest comment here, note use of the phrase "unless a security issue pops up or new committers appear to revive the project" https://issues.apache.org/jira/browse/XERCESC-2238?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel&focusedCommentId=17571942#comment-17571942
Leaving the status of Xerces C/C++ as active is either a lie or a gross and negligent oversight. This page shows no major release since 2010. https://xerces.apache.org/news.html (C++ is listed below the Java project updates)
#include <xercesc/validators/common/GrammarResolver.hpp>
#include <xercesc/framework/XMLGrammarPool.hpp>
#include <xercesc/sax2/Attributes.hpp>
#include <xercesc/util/RefVectorOf.hpp>
#include "spdlog/spdlog.h"
#define tr XMLString::transcode
static spdlog::logger logger = getLog();
/*
* cloneAttributes
* Uses LocalName as key instead of QName and ignores URI and URI id, id inside RefVectorOf
* but inaccessible to wrapper VecAttributesImpl, and type defaults to CDATA
*/
VecAttributesImpl* cloneAttributes(VecAttributesImpl& attrs, bool useScanner=false){
// from XMLReaderFactory::CreateXMLReader line 49
MemoryManager* const memManager = XMLPlatformUtils::fgMemoryManager;
XMLScanner* scanner;
if(useScanner){
// from void SAX2XMLReaderImpl::initialize() line 124
GrammarResolver* grammarResolver = new (memManager) GrammarResolver(0, memManager); // line 127
// use of 0 from SAX2XMLReaderImpl.hpp line 74 default constructor, XMLGrammarPool* const gramPool = 0
XMLStringPool* URIStringPool = grammarResolver->getStringPool(); // line 128
scanner = XMLScannerResolver::getDefaultScanner(0, grammarResolver, memManager);
// line 42 of XMLScannerResolver::getDefaultScanner uses return new (manager) IGXMLScanner(valToAdopt, grammarResolver, manager);
scanner->setURIStringPool(URIStringPool);
}else{
scanner = NULL;
}
VecAttributesImpl* newAttrs = new VecAttributesImpl(); //VecAttributesImpl is not a vector, it's a wrapper around RefVectorOf
RefVectorOf<XMLAttr> * newRefVectorOf = new (memManager) RefVectorOf<XMLAttr> (32, false, memManager) ;
XMLSize_t atLen = attrs.getLength();
XMLSize_t i;
std::stringstream bruce;
XMLAttr* cpXMLAttr;
for(i = 0;i<atLen;i++){
//Ever QName != LocalName? when URI != ""? logger.debug(format("{}. QName LocalName URI type: {}, {}, {}, {}", i, tr(attrs.getQName(i)), tr(attrs.getLocalName(i)), tr(attrs.getURI(i)),tr(attrs.getType(i)))); // #suppress("Invalid arguments")
cpXMLAttr = new (memManager) XMLAttr
(
0, //URIId, 0 if reading file, but int is inaccessible from attrs, inside RefVectorOf XMLAttr, and getURI(i) returns an XMLCh*
attrs.getLocalName(i),
attrs.getValue(i)
);
if(logger.level() == spdlog::level::debug){
bruce << tr(attrs.getLocalName(i))<<" : "<<tr(attrs.getValue(i))<< " | ";
}
newRefVectorOf->addElement(cpXMLAttr);
}
logger.debug(bruce.str());
newRefVectorOf->size();
logger.debug(newRefVectorOf->size());
//The scanner can actually be set to NULL and the above scanner construction skipped if the VecAttributesImpl isn't scanning.
newAttrs->setVector(newRefVectorOf, newRefVectorOf->size(), scanner, false);
return newAttrs;
}

Extract/Identify NodeType by Name (or string - identifier)

Hi!
I'm writing a "simple" Maya command in C++, in witch I need to select from the scene (like the ls command in MEL).
But I don't know how to identify an MFn::Type data based on a string name like "gpuCache".
Actually my (very stupid) parser does a simple if that identify the MFn::Type based on two options: if the node name is "gpuCache" sets the filter using MFn::Type::kPluginShape, otherwise use kDagNode (or kShape, or whatever fits my needs for a broad identification for as many nodes as possible, for a later use of the typeName() of the MFnDagNode class).
This is the "filterByType" function, that I want to use to convert a type defined by String in a type defined by MFn::Type.
MFn::Type Switch::filterByType( MString type )
{
MFn::Type object_type;
object_type = MFn::Type::kDagNode;
MNodeClass node_class( type );
MGlobal::displayInfo( MString("Type Name: " + node_class.typeName()) );
return object_type;
}
Can someone help me, or I need to call a MEL/Python command from C++ (a thing that I really don't want to do) to get this thing done?
Thanks!

Get Document Class Name

How can I get class name of a document in my program. I mean, I have done this:
pDocTemplate = new CMultiDocTemplate(
IDR_FRAMETYPE,
RUNTIME_CLASS(CFrameDoc2D),
RUNTIME_CLASS(CEditorChildFrame),
RUNTIME_CLASS(CFrameView));
gl_pDocTemplateManager->AddTemplateInfo("CMyDoc", eStructure);
AddDocTemplate(pDocTemplate);
I want to get CMyDoc string in another project (.dll) of my MSVC solution via CDocument class. I can't cast to a specific document class due to cyclic dependencies.
I'm not sure what AddTemplateInfo() does, it does not seem to be a standard MFC function.
To get the name of the class, you could use something like:
CRuntimeClass *pClass = pDoc->GetRuntimeClass();
if (pClass != NULL)
TRACE(_T("Document class = %S\n"), pClass->m_lpszClassName);
NOTE: m_lpszClassName is ASCII (LPCSTR) and the code above assumes your project is based on Unicode -- otherwise, change %S to %s.

How to properly use %USERPROFILE% inside code?

Is my code correct? It seems can compile but does not work properly..
CString testing = _T(" --url=") + cstring + _T(" --out=%USERPROFILE%\\snapshot.png");
I want to point it to user's folder..but still cannot work.
The answer is that you don't use environment variables at all. Rather, you use the shell functions specifically designed to retrieve the path of special folders.
On Windows Vista and later, that function is SHGetKnownFolderPath. It takes KNOWNFOLDERID values to identify the folder whose path you wish to retrieve. In your case, that would be FOLDERID_Profile.
If you need to target earlier versions of Windows (such as XP), you will need to use the SHGetSpecialFolderPath function, instead. It takes a CSIDL value identifying the folder whose path you wish to retrieve. Again, in your case, that would be CSIDL_PROFILE.
Of course, you should never store data directly in the user's profile folder. So hopefully the bit of code that you've shown is for demonstration purposes only. Applications should only create files in the specific locations under the user profile folder, designed for application data storage.
These locations are CSIDL_APPDATA or CSIDL_LOCAL_APPDATA. If you are creating data that the user should be able to modify and should treat as his/her own, then it would be appropriate to store that data in the user's documents folder (CSIDL_MYDOCUMENTS).
More usage information is available in my answer here.
Sample code:
TCHAR szFolderPath[MAX_PATH];
if (!SHGetSpecialFolderPath(NULL, szFolderPath, CSIDL_APPDATA, FALSE))
{
// Uh-oh! An error occurred; handle it.
}
Or, using MFC's CString class:
CString buffer;
BOOL bRet = SHGetSpecialFolderPath(NULL, buffer.GetBuffer(MAX_PATH), CSIDL_APPDATA, FALSE);
buffer.ReleaseBuffer();
if (!bRet)
{
// Uh-oh! An error occurred; handle it.
}
As Cody suggested, it's better to use the SHGetSpecialFolderPath function. However, you could use the GetEnvironmentVariable function to get that and other variables set in the system.
TCHAR szBuf[MAX_PATH] = {0};
::GetEnvironmentVariable(_T( "USERPROFILE" ), szBuf, MAX_PATH);

How to set text in Carbon textfield on OSX?

I'm trying to set the text of a textfield using the Carbon API like this:
ControlID editId = {'EDIT', 3};
ControlRef ctrl;
GetControlByID(GetWindowRef(), &editId, &ctrl);
CFStringRef title = CFSTR("Test");
OSErr er = SetControlData(ctrl, kControlEntireControl, kControlEditTextTextTag, CFStringGetLength(title), title);
CFRelease(title);
I'm using the C++ code template of XCode, so GetWindowRef() is a call to the predefined TWindow class. The OSErr return value gives me noErr, but my textfield only contains garbage.
It doesn't matter if I set the attribute of my textfield to Unicode or not.
Any ideas what is wrong here?
What does the GetControlID(...) return? Is it noErr?
As a ControlRef is also a HIViewRef, you can also use the function:
HIViewSetText to set the text. This is documented to work with functions that accept kControlEditTextCFStringTag.
By the way, the line you wrote:
CFRelease(title);
Will cause problems. One should only release objects that have been made using functions that have Create or Copy in the API name. You'll want to read: "Introduction to Memory Management Programming Guide for Core Foundation" -- search in the Xcode documentation.
Finally this did the trick:
SetControlData(ctrl, kControlEditTextPart, kControlStaticTextCFStringTag, sizeof(title), &title);
Since this seems to be very old API, a better way seems to be:
HIViewSetText(ctrl, title);
Thx to Lyndsey for the hints.