Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
So I've been working on a simple text RPG to help me learn C#, and I'm just wondering if this code looks okay. So far everything in the menus works (the options to fight a monster only appear once a character has been created save for the boss fight which I haven't fully implemented yet). My main issue is being confused as to whether or not I'm doing OOP right.

Is it a good idea to have the player class be static like I have? My rationale is that there's only one player (although I imagine this could change if you wanted to create a new character). Moreover, I'm a bit confused about inheritance. I imagine that the boss class should inherit the enemy class (bosses are enemies and have both HP and a name), but then the boss class should override the enemy HP variable and be set to a different (higher) value.

Finally, is the general logic right? I'm wondering if I should be having more functions return a result rather than things like Console.Writeline (to decouple methods from formatting)m, but if thats the case, where would the methods be returning to?

Adbot
ADBOT LOVES YOU

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

NiceAaron posted:

"There's only one of it" is a pretty bad reason to make a class static, and not just because you might change your mind later (though that's a pretty good reason on its own). If you implement Player as a static class then it's hard to reason about its behavior and how its state will change, because potentially any other piece of code in your program could be touching it and changing its state. If Player is a non-static class, then you know that the Player won't be affected by anything that doesn't have a reference to the Player instance, so it's easier to reason about. (Don't just make a public static field/property for your Player instance or it's no better than the static class!)

(Contrast with, for example, the System.Math class, which doesn't have any mutable state and therefore being static doesn't cause any problems.)

Avoid unnecessary levels of inheritance. If the only difference between a boss and a regular enemy is the name and HP, then just use the one Enemy class and pass different names and HP values to the constructor. You would only need inheritance if you wanted to override the code for one of the enemy class's methods. If you design your classes to be flexible then you can get different behavior out of them without inheritance. Another example: Currently your Combat class creates an instance of Enemy. If instead you pass in Enemy as a constructor parameter, then the same Combat class will be able to handle both regular enemies and boss enemies.

Another random piece of advice: Try to keep your nuts-and-bolts "mechanism" code separate from your higher-level "game logic" code. For example, in MainMenu.cs I see two places where you prompt the player to make a choice, and if they make an invalid choice you repeat the prompt in a loop until they make a valid one. (And you've tied the loop conditions to the Player, which makes it harder to reason about since you have to think about how each choice affects the Player object.) I could easily imagine similar logic being needed again and again as your program grows. If you created a method like:

code:
public static int PromptForChoice(params string[] choices)
{
	...loop until the user enters a valid choice...
}
then you could use it like:

code:
int menuChoice = PromptForChoice("Create a character", "Quit");
// At this point menuChoice is guaranteed to be a valid choice
switch (menuChoice)
{
	...
}
And now it's easier to see what's going on because the loop isn't in the way. If you separate your "mechanism" code from your "game logic" code like this, then your "game logic" will be more direct and to the point, and therefore easier to reason about and get right.

Thanks a lot for this post! I've added in a menu choice validation function, although I did it like so:
code:
 public static string PromptForChoice(params string[] choices) // Method to ask the user to input a choice, then verifies if the input 
        {                                                               // matches one of the possible choices & returns their input. 
            while (true)
            {
                Console.WriteLine("Enter your choice now: ");
                string input = Console.ReadLine();
                if (choices.Contains(input))
                {
                    return input;
                }
                else
                {
                    Console.WriteLine("Invalid selection, please try again.");
                }
            }
        }
I also created the player class as a non static object and I instantiate the class in a variable inside the game logic code, although I feel like there may be a better way to do this.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
So as a learning project, I've been building a TUI music player using Terminal.Gui and NAudio. Terminal.Gui has been easy to use thanks to the API reference, but NAudio has no class references, only some examples here and there.

In addition to a rudimentary GUI, I've created a WinPlayer class which implements an IPlayer interface I wrote to play an audio file, and I'm using constructor injection to inject the WinPlayer (the idea is eventually I would have a MacPlayer as well). So far the audio plays inside a thread (to prevent GUI blocking), and I'm using a mutex to limit the number of audio threads to one. My issue however, is how do I stop the current audio thread from playing? Technically, it would be outputDevice.Stop(), but since the audioFile and outputDevice are local variables, I can't stop them from outside the play method.

code:
    public class WinPlayer : IPlayer
    {
        private static Mutex mut = new Mutex();

        /// <summary>
        /// Method that implements audio playback from a file.
        /// </summary>
        public void PlayAudioFile()
        {
            // Play the audio inside a new thread to prevent our GUI from blocking.
            Task.Run(() =>
            {
                // Block this section of the thread so only one audio file plays at once.
                mut.WaitOne();

                var file = @"C:\MusicSharp\example.mp3";

                try
                {
                    // Load the audio file and select an output device.
                    using var audioFile = new AudioFileReader(file);
                    using var outputDevice = new WaveOutEvent();
                    {
                        outputDevice.Init(audioFile);
                        outputDevice.Play();

                        // Sleep until playback is finished.
                        while (outputDevice.PlaybackState == PlaybackState.Playing)
                        {
                            Thread.Sleep(1000);
                        }
                    }
                }
                catch (System.IO.FileNotFoundException e)
                {
                    System.Console.WriteLine("Error", e);
                }

                // Release the thread.
                mut.ReleaseMutex();
            });
        }
    }
Is there a better way to do this?

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

Jen heir rick posted:

I don’t think you need to create a new thread. I looked at the Naudio example for winforms, and they aren’t creating a new thread with Task.Run, they just call Play and subscribe to the playback stopped event to dispose of the outputDevice. You should do something like that.

Thanks! My solution was to move
code:
using var outputDevice = new WaveOutEvent();
outside of the Play method, that way Stop and other methods can access it. This is working now.

quote:

The easiest way to accomplish this is to implement what's called a cancellation token. You would wire up your while loop to see if the cancellation token was called. Then you can abort it. Depending on how you want to do this, the easiest thing to do is setup a additional method on your IPlayer interface called Cancel() that just invokes the cancellation token and call that from whatever needs to cancel the audio file.

Just a note here too, you really don't want to be using mutexes inside tasks. I'd delegate that behavior to whatever is calling PlayAudioFile(). On your IPlayer expose a Playing, Stopped Enumeration - just a simple Property - and make whatever is calling IPlayer check the state before invoke PlayAudioFile(). To set the Playing/Stopped Enum you can use a conventional locking mechanism inside your PlayAudioFile()

I'm going to look into this tomorrow night. I had been using a task because my TUI was being blocked during audio playback. I put my play code inside Task.Run() and this stopped the blocking, but also caused the issue of letting me open and play multiple audio files at once.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

necrotic posted:

https://github.com/naudio/NAudio/blob/master/Docs/PlayAudioFileWinForms.md

This approach should also work in a TUI, and seems to have all the niceties you want built in.

Thanks for this! I've worked the ideas into my code and this approach is working great. No more Task.Run() or Mutex.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

adaz posted:

The easiest way to accomplish this is to implement what's called a cancellation token. You would wire up your while loop to see if the cancellation token was called. Then you can abort it. Depending on how you want to do this, the easiest thing to do is setup a additional method on your IPlayer interface called Cancel() that just invokes the cancellation token and call that from whatever needs to cancel the audio file.

Just a note here too, you really don't want to be using mutexes inside tasks. I'd delegate that behavior to whatever is calling PlayAudioFile(). On your IPlayer expose a Playing, Stopped Enumeration - just a simple Property - and make whatever is calling IPlayer check the state before invoke PlayAudioFile(). To set the Playing/Stopped Enum you can use a conventional locking mechanism inside your PlayAudioFile()

On a sidenote, do you by any chance have recommendations for books or guides that deal with tasks and threading? I just want to make sure I don't run into any pitfalls (like Mutexes inside of Task.run) again going forward.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
I'm currently working on a project which involves converting a log file (with approximately 1.5 million lines) from one format to another. In the process, the file must be split into smaller files, each representing a specific period grouped by a numeric identifier. The file looks something like this:

code:
$P¦1¦A¦0¦107¦0¦19:06:47.841¦L¦85.528¦10692¦2¦103¦0¦0.04¦0¦0¦0
$P¦5¦A¦0¦128¦0¦19:06:48.042¦L¦77.208¦10128¦2¦101¦0¦0.08¦0¦0¦0
$P¦10¦P¦0¦99¦0¦19:06:48.136¦L¦91.100¦11070¦2¦71.5¦2¦0.02¦0¦0¦0
$C¦U¦18001E¦R.I¦9¦12¦18¦1E¦1210737¦9935D¦T¦98647¦13¦0¦1¦0¦1¦9¦98647¦Active¦G¦0¦0¦1¦4
$C¦U¦23001E¦R.I¦A¦22¦23¦1E¦1227B88¦99B6B¦T¦98BA1¦14¦0¦1¦17451¦0¦A¦98BA1¦Active¦G¦0¦0¦C¦0
$S¦U¦250020¦R.I¦20¦25¦S5B¦206DEE86¦10AB4¦1E
$S¦U¦250004¦R.I¦20¦25¦S5¦206DEE86¦19E61¦1E
$S¦U¦25000A¦R.I¦20¦25¦T5¦206DEE86¦14AC¦1E
$H¦N¦3F18D¦R.I¦G¦5F959488¦12C0153¦45¦0
$P¦12¦A¦0¦122¦0¦19:06:48.042¦L¦45.424¦6009¦1¦102.5¦0¦0.00¦0¦0¦0
$P¦15¦P¦0¦114¦0¦19:06:44.455¦L¦144.545¦11139¦5¦100.5¦7¦0.00¦0¦0¦0
$P¦20¦P¦0¦75¦0¦19:06:47.911¦L¦153.272¦9997¦6¦0¦74¦0.00¦0¦0¦0
$P¦21¦P¦0¦89¦0¦19:06:47.823¦L¦73.178¦8595¦1¦0¦24¦-0.19¦0¦0¦0
What's the best way to parse something like this? Should I load the entire file into memory, parse it, and then write each segment out to the new format, or is there a better way? In the past, I've only ever done some light CSV parsing with the CSVHelper library, but the only parsing library I can use here is ANTLR.

Some of the lines are extra information which are not needed and can likely be skipped over, but I'll need to figure out where to separate the files based on the spec sheet I have.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

Hammerite posted:

Can you treat each line separately, or do you have to be aware of other lines that came before or might come after? If you can treat each line separately, then you should probably open the file as a text stream and read it line by line. That way you're not trying to fit the whole thing in memory at once. It probably won't matter if the files all have about 1.5 million lines, but if one day you get one with 150 million lines, it could matter then.

As to parsing individual lines themselves, it's basically CSV data but with | as the separator character, or so it appears. It's not hard to write your own CSV parser but you need to figure out the answers to a few questions:
  • Do the field values ever contain the | character? If so, how is it distinguished from a | character that separates two fields? By escaping? quoting? If by quoting, what quote characters are used, and how are literal quotes escaped?
  • do the field values ever contain newlines? If so, how are they represented?
Parsing of a line should be done with a finite-state machine.

I don't know anything about ANTLR so I can't comment on that.

According to the spec sheet, "every record starts with a header and ends with a CR/LF. Inside the record, the fields are separated by the “broken bar” symbol 0xA6 (not to be confused with the pipe symbol 0x7C)."

I don't believe that the actual pipe symbol is ever used.

Eldred posted:

How is the data going to be split? Are you just reading the file until you get to a separator or end of file then saving the previous chunk to a file, or do you need to do more analysis than that? Wondering if you can spare yourself from loading the full file into memory at once.

I'm still familiarizing myself with the spec sheet, but I believe that the data will be split when you get to a ¦P¦ inside a record of $C (at position 11), and the number in position 6 matches the first number inside a $P record. All $P records preceding that would be grouped together, for example:

$P¦3¦A¦0¦142¦0¦18:43:07.693¦L¦45.293¦6004¦1¦101¦0¦0.01¦0¦0¦0
$P¦3¦A¦0¦142¦0¦18:43:07.795¦L¦45.424¦5980¦1¦101.5¦0¦0.01¦0¦0¦0
$C¦U¦2C0008¦R.I¦18¦3¦2C¦8¦534AF9¦CBC12¦P¦9A69B¦5¦63249¦0¦3346F¦0¦18¦9A69B¦Active¦G¦1¦8¦15¦0

In this case, 3 is the grouping number, and so the 2 $P values would be considered a group (3s after the $C would be considered a new group). Inside the files, there are multiple $P (and other) records with different numbers mixed in between (this example cuts them out, but there are different $P values inside the file in between these two), all of which would need to be grouped together and split once a matching $C containing both that number and ¦P¦ is reached.

Lastly, I'm not sure if it makes a difference, but the final conversion is performed with a class that conforms to an interface (would this mean I need to feed the data directly to the class properties as opposed to writing directly to split files?).

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

Hammerite posted:

OK so I misidentified the character because I thought it was just the font rendering | weirdly. you can reread my post but mentally substitute ¦ for |, the same points apply no matter the particular character used as a delimiter.


I haven't bothered to understand what you're saying in depth, but it sounds like you care about the current line and some state from previous lines. That state might just be a list of previous lines that are waiting to be addressed by a later line, or it might be some more complicated data structure. Regardless, you want to read the file line by line and act on each line in turn - you probably don't want the whole file in memory at the same time.


I have no idea. Are you not in charge of the interface? Surely you have freedom to decide the implementation of your parser.


Doubtless this is true. However, implementing a finite-state machine parser for a line from a CSV file is not difficult. Providing you know what the rules are for quoting/escaping (but of course, you would also need to know those rules in order to properly configure your CSV library).

Essentially, all lines starting with $P should be grouped together by an identifier number found inside the record. Once a $C line is reached that contains the same identifier number, plus a P in it, all those $Ps should be written out to a file. Given this, I think its safe to assume I can read the file line by line.

The spec sheet doesn't mention anything about quoting or escape characters however. I'm not sure there are any as the data is recorded from a serial feed pulling data from microcontrollers.

quote:

Just to add - It looks like you have a whole lot of sample data, so I would say that you have a great opportunity here to add tests of whatever implementation you decide on. Alongside your code, add a unit test that consumes one of the sample files, and assert precisely what results it should spit out. Have this test run as part of your build process.

This is a great idea, thanks!

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
I'm working on writing a wrapper library for an undocumented public facing API, but am confused about the use of nullable. I have DTO classes to map the JSON deserialization, and I transfer these into models which are then sent to the user. While working on an endpoint, I received a null reference error for one of the endpoint properties, but only on a certain date.

Using <Nullable>enable</Nullable> in my .csproj makes tons of warnings appear in my DTOs and elsewhere. I'm just wondering, since I don't know exactly what might be null and what isn't in the API, do I just treat everything as nullable? I had been doing this but I'm not sure if this is the correct route. It also adds a ton of ? all over my code.

The alternative I had recommended to me was to make everything non-nullable, and only use nullable types for values which can be null (I'll need to do a lot of trial and error through this route).

Supersonic fucked around with this message at 01:27 on May 23, 2021

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

EssOEss posted:

The purpose of nullable reference types is to help you more easily write code that does not throw NullReferenceException.

Yes, if you work with data models coming from an external source, you can either treat everything as nullable. This will mean many ? in many places. But that is correct - every place you have to add a ? and check for nullness in logic is a place that could otherwise throw NullReferenceException.

Alternatively, you can skip marking the fields nullable. However, nullable reference type annotations are a feature for you - the code author - and even if you mark a reference field as non-nullable, this does not mean it is not null on the write.

If you want to avoid NullReferenceExceptions then you could, for example, validate all the deserialized DTOs to ensure that non-nullable fields do not actually contain null values.

Alternatively, you could just accept NullReferenceExceptions if some data is unusual.

Alternatively, you can add ? operators and/or null checks everywhere that the potentially nullable data is used.

Personally, I would just validate the DTOs after deserialization and throw when some mystery null values appear, only marking as nullable the "I expect this to sometimes be null" fields.

Thanks! For now I'm going to treat everything as nullable so I don't need to refactor all the DTOs right now, but I'm going to look into DTO validation in the longer term.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
I'm looking to upload a file to Amazon S3 in multiple parts using C# and either WebClient or HttpClient. The upload process is a 4-step operation:

1. Initiate a multipart upload
2. Create pre-signed URLs for each part
3. Upload the object’s parts
4. Complete multipart upload

I've written methods for step 1, 2, and 4, but I'm not clear as to how to actually upload a file in parts. The parts need to be 5mb in size (or less for the final part), and I've created a method which calculates how many parts the chosen file should be split into.

Here is a working example of uploading a file in a single part with a presigned URL:

C# code:
public void UploadSingleFilePresignedUrl(string filePath, string fileName)
{
    string preSignedUrl = _server.GeneratePreSignedURL(fileName);

    HttpWebRequest httpRequest = WebRequest.Create(preSignedUrl) as HttpWebRequest;
    httpRequest.Method = "PUT";
    using (Stream dataStream = httpRequest.GetRequestStream())
    {
        byte[] buffer = new byte[8000];
        using FileStream fileStream = new(filePath, FileMode.Open, FileAccess.Read);
        int bytesRead = 0;
        while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
        {
            dataStream.Write(buffer, 0, bytesRead);
        }
    }
        HttpWebResponse response = httpRequest.GetResponse() as HttpWebResponse;
}
In step 2, I've created a list of presigned URLs for each part. I plan to iterate over the list and pass the presigned URL and part number to the method for each part. Do I make a stream and send segments to a method that uploads it?

In addition, whenever you upload a part, Amazon S3 returns an ETag header in its response. For each part upload, I need to record the part number and the ETag value.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

raminasi posted:

Is there a reason you're not just using the utility class AWS provides for this?

The software has a client and server component, and we don't want to put the AWS keys on the client (like the class requires). With a pre-signed URL supplied by the server, the client can initiate an upload without needing to have access to the AWS secret keys and gives us more flexibility for our needs.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
Edit: Ended up solving this.

Supersonic fucked around with this message at 16:40 on Jun 24, 2021

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
I just had a WPF related question. I have a view which contains tabs, and within some of the tabs I have sub-views containing textboxes. Currently, these text boxes don't expand to the full width of their parent:



It seems that there are TabControl items which contain nested TabItems. Right now, the TabItem in question looks something like:

code:
        <TabItem Name="Notes">
            <TabItem.Header>
                <StackPanel Orientation="Horizontal">
                    <Image Source="{dx:SvgImageSource Uri='pack:///Resources/Icons/svg/notes.svg'}" Style="{StaticResource IconTab}" />
                    <Label Content="Notes" Style="{StaticResource TitleStyle}" />
                </StackPanel>
            </TabItem.Header>
            <StackPanel Orientation="Vertical">
                <StackPanel Orientation="Horizontal" Margin="0,0,0,0">
                    <Image Style="{StaticResource IconTitle}" Source="{dx:SvgImageSource Uri='pack:///Resources/Icons/svg/notes.svg'}"></Image>
                    <Label Content="Pre-session Notes" Style="{StaticResource TitleStyle}"/>
                </StackPanel>
                <controls:ExtendedTextBox Text="{wpfcore:CultureAwareBinding SessionCache.SessionObject.Strings.PreSessionNotes, UpdateSourceTrigger=LostFocus}" AcceptsReturn="true" Height="300" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Left" Width="600" TextWrapping="Wrap"/>
                <StackPanel Orientation="Horizontal" Margin="0,0,0,0">
                    <Image Style="{StaticResource IconTitle}" Source="{dx:SvgImageSource Uri='pack://Resources/Icons/svg/notes.svg'}"></Image>
                    <Label Content="Post-session Notes" Style="{StaticResource TitleStyle}"/>
                </StackPanel>
                <controls:ExtendedTextBox Text="{wpfcore:CultureAwareBinding SessionCache.SessionObject.Strings.PostSessionNotes, UpdateSourceTrigger=LostFocus}" AcceptsReturn="true" Height="300" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Left" Width="600" TextWrapping="Wrap"/>
            </StackPanel>
        </TabItem>
Is there a way I can get them to expand to the full-width of the parent using StackPanel, or do I need to Switch a DockPanel or a grid?

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
Thanks! These suggestions ended up working for the horizontal, now the only issue I'm having is with the vertical. Is there a way I can have that stretch as well? Right now its set to 300 on both boxes, but
if I remove the set height and add VerticalAlignment="stretch" to both they don't expand to fit the parent. Here's what it looks like when I do that.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
I'm writing an api wrapper and am currently trying to deserialize this JSON response: http://data.nba.net/json/bios/player_201935.json

I'm able to get the response correctly, but my model keeps getting null properties. Is there a step I'm missing in this code?

https://pastebin.com/5g6c32sR

I'm using this deserializer (https://json2csharp.com/json-to-csharp) which outputs a Bio class and a Root class containing a bio object to model the DTOs after.

Supersonic fucked around with this message at 15:08 on Dec 31, 2021

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
Thanks, I've made this change now!

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

New Yorp New Yorp posted:

What properties are null? Are they always null, or only null in some cases? If they're only null in some cases, have you looked at the data directly?

Also don't catch exceptions unless you're going to do something with the exception. The catch { throw; } thing is completely useless.

The response comes back with the correct JSON, but looking at my playerBioModel return, all the properties are null:


This leads me to believe that there's an issue with my playerBioRootDto line.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

HexiDave posted:

Should PlayerBioRootDto have a nested property called PlayerBioDto? The JSON looks like it's trying to map it to one called "Bio", so I'm wondering if the PlayerBioDto property isn't mapped correctly.

This solved it, thanks!

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

epswing posted:

If you’re not aware, if you have a good sample of the data, you can “Edit -> Paste Special -> XML/JSON as classes” in a .cs file and VS will generate the class/property structure for you. Sometimes not perfectly but it’s usually easy to fix up.

This is handy, thanks!

Supersonic fucked around with this message at 20:41 on Dec 31, 2021

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
On the topic of WPF, I've been working on a larger WPF project with some other people, and one issue I've been running into is understanding Databinding. For example, consider the following view:
code:
<dx:LoadingDecorator
    x:Class="QDev.DataManagement.Client.Wpf.Views.CustomizableLoadingDecorator"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
    xmlns:local="clr-namespace:QDev.DataManagement.Client.Wpf.Views"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="450"
    d:DesignWidth="800"
    SplashScreenDataContext="{Binding }">
        <dx:LoadingDecorator.SplashScreenTemplate>
            <DataTemplate>
                <dx:WaitIndicator Content="{Binding }" DeferedVisibility="True">
                    <dx:WaitIndicator.ContentTemplate>
                        <DataTemplate>
                        <TextBlock Text="{Binding SpinnerText}" />
                        </DataTemplate>
                    </dx:WaitIndicator.ContentTemplate>
                </dx:WaitIndicator>
            </DataTemplate>
        </dx:LoadingDecorator.SplashScreenTemplate>
</dx:LoadingDecorator>


The splash screen and data template both use {Binding} with nothing specified. Looking at example view files from MS documentation, they all seem to explicitly set this to something, eg:
code:
Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}">
How can I tell what is bound to what here?

Supersonic fucked around with this message at 13:42 on Jan 1, 2022

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
I'm planning on developing an IoT device using the Wilderness Labs F7 and would like to connect it to the cloud to collect data from the sensors I will be using. Right now I'm trying to think of an optimal architecture.

I'm thinking of temporarily storing the sensor data on the device using SQLite, and then every so often (maybe once an hour?) transfer the data to a server-side DB via WiFi.

Should I setup an Azure serverless function with an endpoint that ingests the data and then writes it to a server-side DB? I've seen libraries to sync databases, but I'm looking to have one way data flow here as the device DB should get deleted after it gets sent since it has limited memory. There's also Azure IoT but I'm thinking that it might be overkill for my use case?

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

Calidus posted:

Write the data into a durable queue then process off that into whatever you want.

So I would use something like RabbitMQ for this? I haven't used durable queues before so I'm just trying to mentally conceptualize the model:

IoT device --> Send data in a continuous stream to RabbitMQ? --> Process the data from the queue.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
So I have an idea for a side project which involves placing photos on a map and associating data with them. While logged in, users would be able to create pins (or the pin is placed automatically if GPS data is present in the image EXIF), and other users in the same account would be able to view the data, edit it, and generate reports. The photos would appear as pins like in Google maps which would then open a view to see and edit the associated data. If there's a lot of pins in one area then they would be grouped together and you can click on them to expand like this:



I'm just wondering, does anyone have any recommendations in terms of stack for this (I have C# experience and am familiar with the basics of ASP.NET and EF)? Would ASP .NET, EF Core, and Postgres work for the backend, or should I go for something more like Supabase? In addition, am I okay using something like openstreetmap or are there benefits to using the Google Maps API?

In terms of frontends, I've used Astro, plain html/css/js, and a bit of React. Would React be a good frontend choice, or does Vue or Svelte have better developer velocity assuming I'm the only one working on it? Aside from working on desktop, it would be nice if there was a phone app to take the pictures and add them to the system as well (I'm assuming I could just use the SPA for this?).

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
I'm developing an ASP .NET Core Web API for a side project, and was just wondering, what kind of permissions system do I need so users are members of different organizations? I'd like to use Azure B2C.

For example, Org 1 has users A, B, C, and Org 2 has D, E, F. When user A accesses the /products endpoint, they would only see products added by their organization.

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan
Thanks everyone! I believe for my use case, separate DBs are the way to go. I'll most likely use Azure's managed Postgres service for each DB and factor the costs into my pricing.

Also, this might be for another thread, but currently I have an MS Business basic subscription which I use for email hosting & Onedrive (domain1.com). I have an Azure account tied to this subscription which I use to host my portfolio website and a few Static Web Apps.

If I'm planning on creating a SaaS app, do I want to purchase a separate Business subscription for the email addresses and create a new Azure account under that (to keep the SaaS stuff completely separate from my other things), or am I better off using my existing Azure account and just setup a new subscription inside that one?

I also use Simplelogin and have the option of forwarding domain2.com's emails to my main domain. I can also send emails on behalf of domain2 this way as well. Just curious as ideally I don't want to have to pay for two separate MS Business accounts if I don't need to.

Adbot
ADBOT LOVES YOU

Supersonic
Mar 28, 2008

You have used 43 of 300 characters allowed.
Tortured By Flan

ChocolatePancake posted:

If you inject your ITenantProvider with your OnConfiguring method for entity framework, you can use a scoped database service no problem. I have used this approach several times, and it works well. I can probably get you some sample code tomorrow if you like.

This would be appreciated! I've also been looking at Finbuckle Multitenant tonight which seems to be a potential solution as well.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply