How to create a proxy class that inherits SourceProxy, bundles ConeSource, and exposes ConeSource properties using VTK.js? - oop

Note: This question is a bit arcane, if you don't have experience with The Visualization Toolkit (VTK.js) you may want to skip it (on the other hand, if you are a master of OOP and proxies...).
I'm attempting to build a "Hello World" implementation of VTK.js' proxies. This involves:
Creating a proxyManager that manages the proxies.
Creating a custom proxy that inherits from the SourceProxy.
This proxy should bundle ConeSource (non-proxy) and expose ConeSource's properties.
Creating a representation of the resulting geometric proxy.
Passing this representation to a view that displays inside a container on a page.
I used some code from VTK.js' documentation to create a basic geometric cone (not proxied):
import '#kitware/vtk.js/Rendering/Profiles/Geometry';
import vtkFullScreenRenderWindow from '#kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';
import vtkActor from '#kitware/vtk.js/Rendering/Core/Actor';
import vtkMapper from '#kitware/vtk.js/Rendering/Core/Mapper';
import vtkConeSource from '#kitware/vtk.js/Filters/Sources/ConeSource';
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance();
const renderer = fullScreenRenderer.getRenderer();
const renderWindow = fullScreenRenderer.getRenderWindow();
// Create our cone
const coneSource = vtkConeSource.newInstance({ height: 1.0 });
const mapper = vtkMapper.newInstance();
mapper.setInputConnection(coneSource.getOutputPort());
const actor = vtkActor.newInstance();
actor.setMapper(mapper);
renderer.addActor(actor);
renderer.resetCamera();
renderWindow.render();
This works fine, it's moving to proxies that I'm struggling with.
I've been looking at a few successful implementations of VTK.js proxies:
Example included with VTK.js source code.
Medical Image Visualization in MIQA.
Another Medical Image Visualization application called VolView
Of these the example included in the VTK.js source code should be the simplest but it is an animation proxy so the principles don't quite translate (at least I haven't been able to get similar code working for a geometry proxy).
The example I've worked with the most is that found in MIQA. Most of the code is found inside a src/vtk folder but some important calls are made in the Vuex store (src/store/index.ts, especially shrinkProxyManager, prepareProxyManager, and swapToFrame), utils ([src/utils][9] folder (crosshairs.js and fill2DView.js), and the Vue components VtkViewer (src/components/VtkViewer.vue) and DecisionButtons (src/components/DecisionButtons.vue).
I've tried a bunch of different approaches (e.g. using the animation example, the miqa source, the volview source) including those outlined in this VTK.js Proxies thread.
In the VTK.js proxies there is a minimal implementation that looks like this:
source = proxyManager.createProxy('Sources', 'TrivialProducer', { name: 'myImage' });
source.setInputData(myImageData);
view = proxyManager.createProxy('Views', 'View3D', { name: 'my3DView' });
view.setContainer(someHTMLElement);
rep = proxyManager.getRepresentation(source, view);
view.addRepresentation(rep);
But I'm unsure how to make the source proxy something like GeometryProducer? Any help is appreciated.

Related

Python architecture, correct way to pass configurable initialization object to project modules

I have a big architecture question about how to pass set of configurable / replaceable objects to modules of my project?
For example the set may be a bot, logger, database, etc.
Currently I'm just importing they, it make a big problem when you want to replace them during a tests.
Lets' say import app.bot will hard to test and patch
I had tried a multiple solutions but failed with them:
Option 1:
Create some base class with which will accepts set of such objects (db, bot, etc).
Every logic class (who need this set) will inherit this class.
AFAIK the similar approach there in SqlAlchemy ORM.
So the code will looks like:
app.config.py:
Class Config:
db: DB
...
tests.py:
import app.config
Config.db = Mock()
create_app.py:
import app.config
def create_app(db):
app.config.Config.db = db
logic.py
import app.config
User(app.config.Config):
def handle_text(text):
self.db.save_text(text=text)
...
The problem with this case is that most likely you can't importing as from app.config import Config
because it will lead to wrong behavior and this is implicit restriction.
Option 2
Pass this set in __init__ arguments to every instance.
(It's ma be a problem if app has many classes, > 20 like in my app).
User:
def __init__(..., config: ProductionConfig):
...
Option 3
In many backend frameworks (flask for example) there are context object.
Well we can inject our config into this context during initialization.
usage.py:
my_handler(update, context):
context.user.handle_text(text=update.text, db=context.db)
The problem with this approach is that every time we need to pass context to access a database in our logic.
Option 4
Create config by condition and import it directly.
This solution may be bad because conditions increases code complexity.
I'm following rule "namespace preferable over conditions".
app.config.py:
db = get_test_db() if DEBUG else get_production_db()
bot = Mock() if DEBUG else get_production_bot()
P.S. this question isn't "opinion based" because in some point the wrong solutions will leads to bad design and bugs therefore.

ACE editor - allow custom modes and themes in Angular/TypeScript

Introduction:
I've an Angular application where custom SQL statements can be written by using the ACE editor (https://ace.c9.io/). Even though there are modes and themes for SQL, I wanted to create a custom mode and a custom theme for my requirements.
Setup:
I followed this tutorial: https://blog.shhdharmen.me/how-to-setup-ace-editor-in-angular
ng new ace-app (Angular 13.3.2)
npm install ace-builds (ACE-Builds 1.4.14)
component.ts
import * as ace from 'ace-builds';
...
public aceEditor: ace.Ace.Editor;
#ViewChild('editor') private editor!: ElementRef<HTMLElement>;
...
ngAfterViewInit(): void {
// I don't understand why we don't set the "basePath" to our installed package
ace.config.set('basePath', 'https://unpkg.com/ace-builds#1.4.12/src-noconflict');
this.aceEditor = ace.edit(this.editor.nativeElement);
if (this.aceEditor) {
this.aceEditor.setOptions({
mode: 'ace/mode/sql',
theme: 'ace/theme/sqlserver',
});
}
component.html
<div #editor></div>
Result:
The editor is working, but now I need to somehow add a custom mode and theme.
Problems and Questions:
Is it correct to set the basePath to an external URL if I've the package already installed (obsolete due to Edit 1)?
How and where would I add the custom mode.js and theme.js?
How can I direct ace to the custom mode.js and theme.js?
Edit 1:
I managed to get rid of this line of code:
ace.config.set('basePath', 'https://unpkg.com/ace-builds#1.4.12/src-noconflict');
by directly importing the theme and mode with:
import 'ace-builds/src-noconflict/mode-sql';
import 'ace-builds/src-noconflict/theme-sqlserver';
the rest of the code did not have to be changed.
After looking through several projects and issues, I figured out that the best way to implement custom themes and modes for the ACE editor is to copy existing ones from ./node-modules/ace-builds/src-conflict and paste them to ./src/assets/ace.
Example:
Copy an existing mode (and optionally the theme) that represents your required syntax highlighting the most, in my case it was mode-sql.js. I copied the files to ./src/assets/ace and changed the import in my component.ts from:
import 'ace-builds/src-noconflict/mode-sql';
import 'ace-builds/src-noconflict/theme-sqlserver';
To:
import '../../../../assets/ace/mode-sql.js';
import '../../../../assets/ace/theme-sqlserver.js';
Everything else was kept exactly as described in the initial question. From there you can start to change the name of mode and theme, update the rules as well as the styling according to your requirements.

system_cpu_usage is Nan when compiled in native

In my quarkus application i'm using micrometer to retrieve metrics (like in this guide : https://quarkus.io/guides/micrometer).
In JVM mode everything works fine, but in native mode system_cpu_usage is "Nan".
I tried bumping micrometer to 1.8.4 and adding :
{
"name":"com.sun.management.OperatingSystemMXBean", "allPublicMethods": true
},
to my reflect-config.json but no luck. I also tried generating the reflect-config (and other native configuration files) with the graalvm tracing agent but still no luck.
This may be a bug.
Micrometer is looking for a few known implementations of the MXBean:
https://github.com/micrometer-metrics/micrometer/blob/b087856355667abf9bf2386265edef8642e0e077/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/system/ProcessorMetrics.java#L55
private static final List<String> OPERATING_SYSTEM_BEAN_CLASS_NAMES = Arrays.asList(
"com.ibm.lang.management.OperatingSystemMXBean", // J9
"com.sun.management.OperatingSystemMXBean" // HotSpot
);
so that it can find the methods that it should be invoking...
https://github.com/micrometer-metrics/micrometer/blob/b087856355667abf9bf2386265edef8642e0e077/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/system/ProcessorMetrics.java#L80
this.operatingSystemBean = ManagementFactory.getOperatingSystemMXBean();
this.operatingSystemBeanClass = getFirstClassFound(OPERATING_SYSTEM_BEAN_CLASS_NAMES);
Method getCpuLoad = detectMethod("getCpuLoad");
this.systemCpuUsage = getCpuLoad != null ? getCpuLoad : detectMethod("getSystemCpuLoad");
this.processCpuUsage = detectMethod("getProcessCpuLoad");
(Note specifically "getFirstClassFound", which is constrained against the first list).
Speculation on my part, but I suspect Graal is returning a different type, which is possible from here:
https://github.com/oracle/graal/blob/6ba65dad76a4f54fa59e1ed2a62dedd3afe39928/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/ManagementSupport.java#L166
would take some digging to know which, but I would open an issue with Micrometer so we can sort it out.

Recommended dynamic runtime configuration technique on nuxtjs (other than dotenv)

I have been trying to use publicRuntimeConfig / privateRuntimeConfig
On nuxt 2.4.1, I have defined my runtime config as follows on nuxt.config.js
publicRuntimeConfig: {
DATA_API_HOST_URL: process.env.VUE_APP_DATA_API_HOST_URL,
},
privateRuntimeConfig: {
AUTH_APP_CLIENT_SECRET: process.env.VUE_APP_AUTH_APP_CLIENT_SECRET,
},
and calling it as follows on my login.vue
asyncData( ctx ) {
console.log(ctx.$config.DATA_API_HOST_URL)
//some activity
}
The keys are showing up on $config inside asyncData. I debugged on chrome dev tools. But value is not read from process.env.VUE_APP_DATA_API_HOST_URL. The value is showing up as undefined. However, process.env.VUE_APP_DATA_API_HOST_URL is showing the value OK. The whole point is to move away from process.env.
this.$config.DATA_API_HOST_URL also does not access the values.
'${DATA_API_HOST_URL}' is shown in examples but I believe it is only for explicit param declarations at asyncData like asyncData( { $config : {DATA_API_HOST_URL}).
When I pass values as it is using DATA_API_HOST_URL: process.env.VUE_APP_DATA_API_HOST_URL || 'https://test.api.com', it seems to copy the value fine using ctx.$config.DATA_API_HOST_URL!
Looking to me like copying process.env to *RuntimeConfig has a problem!
What is the recommended way of importing and using runtime configurations?
As per documentation in the Nuxt blog post you marked, the feature your are trying to use is released in 2.13 (you´re using 2.4 if i not misunderstood). That could be the reason behind the behaviour you're seeing.
I'd recommend update your project dependencies or trying another approach.
I think you should use Docker to set dynamic runtime config like link below:
https://dev.to/frontendfoxes/dockerise-your-nuxt-ssr-app-like-a-boss-a-true-vue-vixens-story-4mm6

JayData oData request with custom headers - ROUND 2

Few month back I was working on some Odata WCF project and I had some problems with parsing custom headers for token auth (apiKey).
At that time, being quite a noob (still am!), I posted this SO question: JayData oData request with custom headers
Today I am working on a new project with Jaydata Odata server and client library and this:
application.context.prepareRequest = function (r) {
r[0].headers['apikey'] = '123456';
};
was working fine till I had to do a MERGE request. I found out that somehow MERGE request was overriding my headers so I investigated further.
It appears at first that in the oDataProvider.js (~line 617) in the _saveRest method the headers are not inherited:
request = {
requestUri: this.providerConfiguration.oDataServiceHost + '/',
headers: {
MaxDataServiceVersion: this.providerConfiguration.maxDataServiceVersion
}
};
but a few lines later we get:
this.context.prepareRequest.call(this, requestData);
which "should" call my own prepareRequest, but doesnt... Instead it still points to:
//Line 11302 jaydata.js
prepareRequest: function () { },
which of course does... nothing! Funnilly enough, when you execute a simple GET the same code supposedly on the same context instance works and points to my prepareRequest override.
I can assert with enough confidence that somehow the context between GET/MERGE is not the same instance. I cant see, however, any place where the context instance is reassigned.
Has anyone got a clue?
PS: this is NOT a CORS issue. My OPTIONS is passing fine and manually feeding the headers in oDataProvider works.
More
I followed the lead on different context instances and found something interesting. calling EntitySet.save() ends up calling the EntityContext constructor. see trace:
$data.Class.define.constructor (jaydata.js:10015)
EntityContext (VM110762:7)
Service (VM110840:8)
storeToken.factory (jaydata.js:14166)
$data.Class.define._getContextPromise (jaydata.js:13725)
$data.Class.define._getStoreContext (jaydata.js:13700)
$data.Class.define._getStoreEntitySet (jaydata.js:13756)
$data.Class.define.EntityInstanceSave (jaydata.js:13837)
$data.Entity.$data.Class.define.save (jaydata.js:9774)
(anonymous function) (app.js:162) // My save()
That explains why I get two different instances...
Hack
Replacing the prepareRequest function direcly in the class definition works, but its ugly!
for now I can cope with this:
$data.EntityContext.prototype.prepareRequest = function (r) {
r[0].headers['apikey'] = '12345';
};
This works fine as long as you only need to talk to a single endpoint.
Final word based on my experience
As much as I like JayData, it is obvious that they created a monster and its getting out of their hands (poor forum, no community, half-documented,...).
I chose JD because I was lazy and wanted to keep working with my old WCF DataService. Switching to Web API seemed wrong or too much work for me.
Also as a .net dev I liked strong typing of my entities and the ability to work with a concrete model generated from the JD tools. However, in the end, I was adding confusion. Every time my server side model changed I had to fetch the new metadata and scaffold a new entityModel.
I ended up by switching to Web Api and migrated my data service layer to Breeze. And seriously! its a breeze to work with it!
The documentation is absolutely brilliant and here on S.O you can always count on Ward or Jay Tarband to reply with a very high amount of professionalism.
In the end I realize this should probably be more a wiki than a Question.....