Create ControlProperty for custom UIControl - swift

Is it possible to make extension of structure Reactive, where base class is my custom control inherited from UIControl?
When I'm trying following code:
extension Reactive where Base: CustomControl {
public var value: ControlProperty<CGFloat> {
return CustomControl.rx.value(
self.base,
getter: { customControl in
customControl.customProperty
},
setter: { customControl, value in
customControl.customProperty = value
}
)
}
}
I'm getting following error:
Instance member "value" cannot be used on type 'Reactive<CustomControl>'
I will be grateful if you provide me any explanation.

You can check this link: https://github.com/ReactiveX/RxSwift/issues/991
The method value isn't public so you need to create an public version of that. After that, it'll be possible create the extension for your custom control.

Related

Shopware 6: sw-inherit-wrapper property currentValue does not update on select

I've a custom entity enterprise, which is assigned to product.extensions.myPlugin.enterpriseId.
Now i want to select the enterprise within Shopware Vue-Component sw-entity-single-select wrapped by sw-inherit-wrapper:
<sw-inherit-wrapper
v-model="product.extensions.myPlugin.enterpriseId"
:has-parent="false"
:inherited-value="null">
<template #content="{currentValue, updateCurrentValue, isInherited}">
<sw-entity-single-select
class="enterprise-name"
:key="isInherited"
:value="currentValue"
entity="enterprise"
:placeholder="$tc('inputEnterprise.placeholder')"
show-clearable-button
allow-entity-creation
:entity-creation-label="$tc('inputEnterprise.labelCreation')"
#change="updateCurrentValue"></sw-entity-single-select>
</template>
</sw-inherit-wrapper>
This template ist part of a modal.
On select a enterprise from given list, the <sw-entity-single-select__selection-text> does not update.
Step out step in into the template (close and reopen the parent modal), the enterprise is set and printed out on the <sw-entity-single-select__selection-text>.
So the entity extension was updated but not the property currentValue in <sw-entity-single-select__selection-text>
As example i follow the sw_product_basic_form_manufacturer_field
Question: Why property currentValue does not update in <sw-entity-single-select> on select from its list?
EDIT #1
The extension is set in overridden component sw-product-detail like this:
// sw-product-detail/index.js
...
Component.override('sw-product-detail', {
...
computed: {
myPluginRepository() {
return this.repositoryFactory.create('my_plugin');
},
}
watch: {
product() {
if(this.product.id) {
this.__setMyPluginExtension()
}
}
},
methods: {
...
__setMyPluginExtension() {
let extension = this.product.extensions.myPlugin ?? null;
if(null === extension) {
extension =
this.myPluginRepository.create(Shopware.Context.api);
extension.enterpriseId = null
}
this.product.extensions.myPlugin = extension;
},
}
}
Inside the overridden child component sw-product-detail-base the modal is loaded.
I think, the extension is known when the component is loaded and rendered. I've check it with a debug breakpoint inside the created() in the custom component, the extension is known like defined in parent component.
Even more, if i set extension.enterpriseId a real default value instead null then the enterprise is printed out in <sw-entity-single-select__selection-text>, what me indicate, the extension is known.
Btw, i used the change method, but i'm looking for my error...
Best guess without knowing more of the stack would be that this.product.extensions.myPlugin.enterpriseId isn't reactive. That would be the case if the property doesn't exists when the product is originally set and it is declared like this:
this.product.extensions.myPlugin = {
enterpriseId: 'asdf'
};
Any further changes to enterpriseId would then not be reactive and the view would subsequently not be updated when it changes.
To be safe you could add a #change listener to sw-inherit-wrapper and update the property reactively:
onEnterpriseIdChange(enterpriseId) {
if (!this.product.extensions.myPlugin) {
this.$set(this.product.extensions, 'myPlugin', {});
}
if (!this.product.extensions.myPlugin.enterpriseId) {
this.$set(this.product.extensions.myPlugin, 'enterpriseId', enterpriseId);
}
}
As addition of #dneustadt answers:
...
const extension = this.myPluginRepository.create(Shopware.Context.api);
extension.enterpriseId= null
this.$set(this.product.extensions, 'myPlugin', extension)
...
Use the repository create() method instead create a simple object because of required method entity.getEntityName() in changeset-generator.data.js

Objects with application-wide scope in Swift Vapor

How can I create objects within a Vapor-Applicaton that are instantiated when the app starts and are acessible from within my controllers?
I would like to use Dictionary to store some of my models across multiple requests and assign them to a user via hidden fields.
Unfortunately SessionData only accepts Strings.
Many thanks in advance
Michael
The obvious way is to extend Application. I used the documentation for Repositories as inspiration. First, create a structure to hold your properties:
struct AppConfig {
var emailStatus: EmailStatus
static var environment: AppConfig {
return .init(emailStatus: .unknown)
}
}
Then extend:
extension Application {
struct AppConfigKey: StorageKey {
typealias Value = AppConfig
}
var config: AppConfig {
get {
storage[AppConfigKey.self] ?? .environment
}
set {
storage[AppConfigKey.self] = newValue
}
}
}
Finally, initialise in configure.swift:
app.config.emailStatus = .unknown
I’ve used an enumeration as an example but it can be whatever you want.
Edit: Addressing OP's issues and concerns
I put the above code in a separate source file, so you need:
import Vapor
To gain access to StorageKey, etc.
Accessing the running application instance in a controller is easy, it's available from the request as in request.application.

How to write C# implementation for a Q# operation with intrinsic body?

I have created a library in C# to be used in Q# programs. The library has two scripts, a C# class library called "Class1.cs" and a matching Q# script called "Util.qs", I share the code snippet of each here:
Class1.cs:
using System;
using Microsoft.Quantum.Simulation.Common;
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
namespace MyLibrary {
class Class1 : QuantumSimulator {
static void Method_1 (string str) { ... }
.
.
.
}
}
Util.qs:
namespace MyLibrary {
operation Op_1 (str : String) : Unit { body intrinsic; }
}
There is another Q# program in a different namespace that uses the namespace "MyLibrary" so after adding reference, in this Q# program I have:
namespace QSharp
{
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open MyLibrary;
operation TestMyLibrary() : Unit {
Op_1("some string");
}
}
When I execute "dotnet run" in the terminal I receive this message:
Unhandled Exception: System.AggregateException: One or more errors
occurred. (Cannot create an instance of MyLibrary.Op_1 because it is
an abstract class.) ---> System.MemberAccessException: Cannot create
an instance of MyLibrary.Op_1 because it is an abstract class.
How can I fix it?
Thanks.
UPDATE:
Following Mariia' answer and also checking Quantum.Kata.Utils, I changed my code as following:
So, I changed Class1 script to:
using System;
using Microsoft.Quantum.Simulation.Common;
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
namespace MyLibrary {
class Class1 : QuantumSimulator {
private string classString = "";
public Class1() { }
public class Op_1_Impl : Op_1{
string cl_1;
public Op_1_Impl (Class1 c) : base (c) {
cl_1 = c.classString;
}
public override Func<string, QVoid> Body => (__in) => {
return cl1;
};
}
}
Now the error messages are:
error CS0029: Cannot implicitly convert type 'string' to 'Microsoft.Quantum.Simulation.Core.QVoid'
error CS1662: Cannot convert lambda expression to intended delegate type because some of the return types
in the block are not implicitly convertible to the delegate return type
Having checked Quantum.Kata.Utils, I realised I need to create a field and a constructor for Class1 which is a base class and also I should override Func<string, QVoid> as the Op_1 parameter is string type. But I am not sure if each of these steps individually is done properly?
Second Update:
I have changed the previous c# code in first update to the following one:
using System;
using Microsoft.Quantum.Simulation.Common;
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
namespace MyLibrary {
class Class1 : QuantumSimulator {
public Class1() { }
public class Op_1_Impl : Op_1{
Class1 cl_1;
public Op_1_Impl (Class1 c) : base (c) {
cl_1 = c;
}
public override Func<string, QVoid> Body => (__in) => {
return QVoid.Instance;
};
}
}
Now the error message is the same as the very first one:
Unhandled Exception: System.AggregateException: One or more errors
occurred. (Cannot create an instance of MyLibrary.Op_1 because it is
an abstract class.) ---> System.MemberAccessException: Cannot create
an instance of MyLibrary.Op_1 because it is an abstract class.
And also in this new code shouldn't the constructor public Class1() { } have a parameter? if so what datatype?
In your code, there is nothing connecting the Q# operation Op_1 and the C# code that you intend to implement it in Method_1.
Q# operations are compiled into classes. To define a C# implementation for a Q# operation with the intrinsic body, you have to define a class that implements the abstract class into which your Q# operation gets compiled; so you would have something like public class Op_1_Impl : Op_1.
Getting all the piping right can be a bit tricky (it's a hack, after all!) I would recommend looking at the operation GetOracleCallsCount and its C# implementation to see the exact pieces that have to be in place for it to work.
For the updated question, the signature of your method says that it takes string as an input and returns nothing (QVoid), but the implementation tries to return a string cl_1, so you get a Cannot implicitly convert type 'string' to 'Microsoft.Quantum.Simulation.Core.QVoid'.
To provide a custom C# emulation for your Op_1 Q# operation, you'll need to replace your Class1.cs with something like this:
using System;
using Microsoft.Quantum.Simulation.Core;
namespace MyLibrary
{
public partial class Op_1
{
public class Native : Op_1
{
public Native(IOperationFactory m) : base(m) { }
public override Func<String, QVoid> Body => (str) =>
{
// put your implementation here.
Console.WriteLine(str);
return QVoid.Instance;
};
}
}
}
You can then run the Test1Library using the QuantumSimulator.
That being said, as Mariia said, this is kind of hacky, undocumented functionality that might change in the future, may I ask why you need this?

PostSharp C# - How to Implement All Fields Required

PostSharp contracts make it easy to label individual fields as Required. But I want a class attribute that makes all of the class fields required. I'm guessing I would have to implement a custom aspect to support this.
It seems like it would be a common need for anyone passing around data containers. Can anyone direct me to some code that implements a custom "AllFieldsRequired" aspect in PostSharp?
You can implement PostSharp.Aspects.IAspectProvider:
public class AllFieldsRequiredAttribute : TypeLevelAspect, IAspectProvider
{
IEnumerable<AspectInstance> IAspectProvider.ProvideAspects(object targetElement)
{
Type type = (Type)targetElement;
return type.GetFields().Select(
m => new AspectInstance(m, new ObjectConstruction(typeof(RequiredAttribute))));
}
}
[AllFieldsRequired]
public class Foo
{
public string Bar;
public object Baz;
}

Is there a way to have a get only (no set) in a typescript interface?

I have a case where I want to have just a get in the interface, no set. Is there a way to do that?
If not, we can implement a set and throw an exception if it is called. But it's cleaner if we can have just a get.
At present I have:
export interface IElement {
type : TYPE;
}
export class Element implements IElement {
public get type () : TYPE {
return TYPE.UNDEFINED;
}
public set type (type : TYPE) {
this.type = type;
}
}
I would like to have my interface & class be:
export class Element implements IElement {
public get type () : TYPE {
return TYPE.UNDEFINED;
}
}
TypeScript interfaces cannot currently define a property as read-only. If it's important to prevent, you'll need to throw an exception/error at runtime to prevent sets within the setter for the property.
The compiler doesn't require that you implement the get and a set though. You can just implement the get for example. However, at runtime, it won't be caught.