View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0002196 | NoesisGUI | C++ SDK | public | 2021-11-18 14:42 | 2022-03-04 12:05 |
| Reporter | lowprofile | Assigned To | jsantos | ||
| Priority | normal | Severity | feature | ||
| Status | assigned | Resolution | open | ||
| Product Version | 3.1 | ||||
| Summary | 0002196: Create a callback allows loading UserControl xamls when the Control type is not found while parsing xamls hierarchy | ||||
| Description | Currently we need to create C++ class for all UserControls that we use in the hierarchy. And usually that C++ class only do loading the corresponding UserControl xaml. Details are described in this forum thread. | ||||
| Attached Files | |||||
| Platform | Any | ||||
|
Thanks for the report, you have access to the source code right? I mean, I can send you a patch for testing things. |
|
|
Yes, we have the source code. We could test if you send a patch. |
|
|
Something as simple as the attached patch should work. Right now, there is a bit of inefficiency because for the implementation of Factory::IsComponentRegistered we need to also invoke the custom callback just for checking the returned object and then just discard. I think we could get rid of IsComponentRegistered. But let's experiment with this first. Factory.patch (2,230 bytes)
Index: Include/NsCore/Factory.h
===================================================================
--- Include/NsCore/Factory.h (revision 10984)
+++ Include/NsCore/Factory.h (working copy)
@@ -35,6 +35,9 @@
/// Creates an instance of the specified component
NS_CORE_KERNEL_API Ptr<BaseComponent> CreateComponent(Symbol name);
+typedef Ptr<BaseComponent> (*FallbackHandler)(Symbol name);
+NS_CORE_KERNEL_API void SetFallbackHandler(FallbackHandler handler);
+
/// Registers a component
typedef BaseComponent* (*CreatorFn)(Symbol name);
NS_CORE_KERNEL_API void RegisterComponent(Symbol name, Symbol category, CreatorFn func);
Index: Src/Factory.cpp
===================================================================
--- Src/Factory.cpp (revision 10984)
+++ Src/Factory.cpp (working copy)
@@ -27,7 +27,9 @@
typedef HashMap<Symbol, Vector<Symbol>> CategoryMap;
static CategoryMap gCategories;
+static Factory::FallbackHandler gFallbackHandler;
+
////////////////////////////////////////////////////////////////////////////////////////////////////
static ComponentMap::ConstIterator FallbackFind(Symbol name)
{
@@ -44,7 +46,7 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
bool Factory::IsComponentRegistered(Symbol name)
{
- return FallbackFind(name) != gComponents.End();
+ return FallbackFind(name) != gComponents.End() || (gFallbackHandler && gFallbackHandler(name));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -64,10 +66,21 @@
return *(it->value(name));
}
+ if (gFallbackHandler != nullptr)
+ {
+ return gFallbackHandler(name);
+ }
+
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
+void Factory::SetFallbackHandler(FallbackHandler handler)
+{
+ gFallbackHandler = handler;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
void Factory::RegisterComponent(Symbol name, Symbol category, Factory::CreatorFn func)
{
NS_ASSERT(!name.IsNull());
|
|
|
After applying the patch, I noticed that the callback is not called. I investigated the source code and saw that there is an early return if Reflection::GetType(typeId) returns nullptr in XmlContext.cpp line 823. I fixed this part by adding if IsComponentRegistered. Then the callback was called properly. I was using Noesis::GUI::LoadXaml in the callback. But it wasn't showing the loaded xaml in the hierarchy. Would be great if you could test it. I think we should have 2 callbacks. One is for to be used in the IsComponentRegistered that checks if view xaml could be loaded (without loading it). And the second callback from Factory::CreateComponent to load the xaml. |
|
|
I have changed the source code in XamlContext.cpp and It works now. I will send the solution to you. You might want to check it if it has any side effects. |
|
|
We want to remove all kind of "IsComponentRegistered" or "IsTypeRegistered" API to simplify everything a bit but I still didn't have time to think about it. Yes, please, if you could attach a patch with the changes in all your files, that will definitely help toward having this feature officially supported. Thank you! |
|
|
I made very minimal changes and it works. noesis.diff.txt (1,908 bytes)
==== //Noesis/NoesisSDK/Native/Src/Packages/Core/Kernel/Include/NsCore/Factory.h#2 (text) - //Noesis/NoesisSDK/Native/Src/Packages/Core/Kernel/Include/NsCore/Factory.h#1 (text) ==== content
13c13
< #include <functional>
---
>
38,43d37
< // Set create component callback
< using FallbackHandler = std::function<Ptr<BaseComponent>(Symbol const name)>;
< NS_CORE_KERNEL_API void SetFallbackHandler(FallbackHandler handler);
<
==== //Noesis/NoesisSDK/Native/Src/Packages/Core/Kernel/Src/Factory.cpp#2 (text) - //Noesis/NoesisSDK/Native/Src/Packages/Core/Kernel/Src/Factory.cpp#1 (text) ==== content
30,32d29
< static Factory::FallbackHandler gFallbackHandler;
70,77d66
< // Call callback to create component
< if (gFallbackHandler != nullptr)
< {
< return gFallbackHandler(name);
< }
<
82,88d70
< void Factory::SetFallbackHandler(FallbackHandler handler)
< {
< gFallbackHandler = handler;
< }
< ////////////////////////////////////////////////////////////////////////////////////////////////////
==== //Noesis/NoesisSDK/Native/Src/Packages/Gui/Core/Src/XamlContext.cpp#2 (text) - //Noesis/NoesisSDK/Native/Src/Packages/Gui/Core/Src/XamlContext.cpp#1 (text) ==== content
822,841c822
< const Type* type = Reflection::GetType(typeId);
< Ptr<BaseComponent> instance;
<
< // Call the factory create component that contains a fallback. This way we can load xamls
< // without having corresponding c++ classes (without registered symbols)
< if (type == 0)
< {
< instance = Factory::CreateComponent(typeId);
<
< if (instance != nullptr)
< {
< type = Reflection::GetType(instance->GetClassType()->GetTypeId());
< NS_ASSERT(instance->GetClassType()->GetTypeId() == typeId);
<
< CheckTemplateOpen(instance, mAmbient);
< }
< }
<
---
> const Type* type = Reflection::GetType(typeId);
856a838,839
> Ptr<BaseComponent> instance;
>
|
|
|
Thanks for the patch, I will review it as soon as possible. |
|
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2021-11-18 14:42 | lowprofile | New Issue | |
| 2021-11-18 14:42 | lowprofile | Tag Attached: C# | |
| 2021-11-18 14:42 | lowprofile | Tag Attached: C++ | |
| 2021-11-18 14:42 | lowprofile | Tag Attached: xaml | |
| 2021-11-19 11:00 | jsantos | Assigned To | => jsantos |
| 2021-11-19 11:00 | jsantos | Status | new => assigned |
| 2021-11-19 11:00 | jsantos | Target Version | => 3.1.2 |
| 2021-11-19 11:04 | jsantos | Note Added: 0007591 | |
| 2021-11-19 11:04 | jsantos | Status | assigned => feedback |
| 2021-11-19 12:27 | lowprofile | Note Added: 0007592 | |
| 2021-11-19 12:27 | lowprofile | Status | feedback => assigned |
| 2021-12-06 17:24 | jsantos | Target Version | 3.1.2 => |
| 2021-12-06 17:24 | jsantos | View Status | public => private |
| 2021-12-06 17:26 | jsantos | File Added: Factory.patch | |
| 2021-12-06 17:27 | jsantos | Status | assigned => feedback |
| 2021-12-06 17:29 | jsantos | File Deleted: Factory.patch | |
| 2021-12-06 17:30 | jsantos | File Added: Factory.patch | |
| 2021-12-06 17:30 | jsantos | Note Added: 0007656 | |
| 2022-01-05 15:52 | jsantos | View Status | private => public |
| 2022-01-05 15:52 | jsantos | Note View State: 0007592: public | |
| 2022-01-05 15:52 | jsantos | Note Edited: 0007656 | |
| 2022-01-11 14:27 | lowprofile | Note Added: 0007724 | |
| 2022-01-11 14:27 | lowprofile | Status | feedback => assigned |
| 2022-01-11 14:28 | lowprofile | Note Edited: 0007724 | |
| 2022-01-13 13:45 | lowprofile | Note Added: 0007731 | |
| 2022-01-13 17:23 | jsantos | Note Added: 0007732 | |
| 2022-01-13 17:23 | jsantos | Status | assigned => feedback |
| 2022-01-13 17:24 | jsantos | Note Edited: 0007732 | |
| 2022-01-13 17:24 | jsantos | Note Edited: 0007732 | |
| 2022-01-17 18:16 | lowprofile | File Added: noesis.diff.txt | |
| 2022-01-17 18:16 | lowprofile | Note Added: 0007741 | |
| 2022-01-17 18:16 | lowprofile | Status | feedback => assigned |
| 2022-01-21 14:22 | lowprofile | Note Edited: 0007741 | |
| 2022-01-31 16:07 | jsantos | Note Added: 0007759 |