Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 705 706 [707] 708 709 ... 796

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 890040 times)

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #10590 on: June 20, 2017, 05:11:47 pm »

MySQL is the only class I ever failed in college, for more reasons than just the language itself but yeah. That happened.

What am I doing? Writing a audio metadata server, part of the backend for my planned media player. I got tired of not having a cross platform media player with the features I want, so I am writing my own. The result will probably be 2-3 separate applications, several lightweight backend servers running on my NAS or my raspberry pi, and a client that runs on everything else.
Where do you even begin with this kind of project? What kind of background do you have that allows you to even contemplate this?
Logged

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10591 on: June 20, 2017, 05:55:46 pm »

It's simple really. A basic DB populated with information ripped from audio files with TagLib, served to a simple UI that let's you brows the data and assemble a playlist, which feeds an app that plays the playlist inorder, taking commands from hotkeys (the multimedia keys to be precise).

The hard part will be the UI, the metadata server and player will be the easy parts... I'll probably have a system I can control from the command line long before I get a nice GUI done.

As for background, I taught myself. AFAIK I'm nothing special as programmers go, but since I'm the only programmer I know it's hard to tell...

EDIT:
Tip for the day: Long compile times? Type "&& echo alt+07" at the end of your compile command. This cases a sound to play when the command finishes. (alt+07 produces an ASCII "bel" character, you need to use the number pad to type the numbers while holding alt).
« Last Edit: June 20, 2017, 10:15:48 pm by milo christiansen »
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

Mephisto

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10592 on: June 20, 2017, 10:25:34 pm »

I've considered writing an ebook management system and remote viewer for my gaming books that would end up being sort of like that. I'm notoriously lazy, however, so it's not likely to happen.
Logged

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10593 on: June 20, 2017, 11:18:58 pm »

For ebooks there exists Caliber, if there was something like that for music I wouldn't be bothering with this project... Unless Caliber doesn't fit your needs?

I finally got Go and SQLite to work together well enough that I can write to the DB (I misread some of the documentation, so I wasted a bunch of time trying to figure out what I was doing wrong binding values to queries). Now I need to get TagLib working.

I am a little worried, because TagLib is C++, and Go doesn't work well with that. Hopefully the C bindings work as advertised. Once I have TagLib working I can start writing code to walk my music library and populate the DB. Luckily I have lots of experience with tasks like this from working on Rubble, so it should be easy.

After that I just need to write the server interface, once again nothing I haven't done before.

Once all that is finished I still need to write the player (trivial) and the viewer/playlist editor (non-trivial!). I may even write a second server to store player settings, playlists, etc so all my stuff will be identical across computers...

All this sounds a lot harder than it is, I expect to be mostly done with the metadata server by the end of the week, and the player should only take a few days. The playlist editor will be the hard part, but I plan to cheat and use a ugly HTML/JS piece of crap at first.

Honestly the main reason I'm doing this is that I am massively bored.
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

lethosor

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10594 on: June 21, 2017, 08:21:54 am »

Tip for the day: Long compile times? Type "&& echo alt+07" at the end of your compile command. This cases a sound to play when the command finishes. (alt+07 produces an ASCII "bel" character, you need to use the number pad to type the numbers while holding alt).

If your terminal/OS setup doesn't support Alt+07, Ctrl-V-G should work too.
Logged
DFHack - Dwarf Manipulator (Lua) - DF Wiki talk

There was a typo in the siegers' campfire code. When the fires went out, so did the game.

Strife26

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10595 on: June 22, 2017, 12:06:00 pm »

I'm having a lot of trouble getting Write or Die to run on my laptop, which is pretty annoying to my workflow. I had the conclusion that there's no reason why I couldn't program my own version of it. I mean, it's essentially just a purpose built word processor with few features other than a timer and active word-per-minute monitor. As long as I'm willing to just count every time space-character is written as a new word, there's no reason why I should have any trouble hacking together my own version.

At this point, I began drawing up a rough overflow for how exactly I'd make it work, but I then realized that I'm on my semi-functional laptop, instead of the nice desktop. This means that I lack access to both my Java and C++ options.

Long story short, MATLAB does not seem to be a language well suited to building a word processor. : |
Logged
Even the avatars expire eventually.

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10596 on: June 22, 2017, 12:11:37 pm »

Write it in html5 / Javascript, let the browser handle the fonts and shit.

Telgin

  • Bay Watcher
  • Professional Programmer
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10597 on: June 22, 2017, 12:43:31 pm »

Agreed completely with that, if you need any kind of rich text support or flow control.  You probably don't for that particular project, but if you did...

I once spent about 5 days trying to get a Python TrueType Font renderer to work for a text game.  I got most of the way there, then realized that I could save myself an amazing amount of work by just using one of the bundled Chromium + Node packages and build the program (can't remember the name now).  I'd recreated the entire Python mess I made in about 1 hour with HTML + JavaScript.
Logged
Through pain, I find wisdom.

Spehss _

  • Bay Watcher
  • full of stars
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10598 on: June 22, 2017, 08:01:32 pm »

I'm fiddling around with writing a roguelike, and I'm finding that as the project gets more complex the harder it is for me to keep track of how everything is working together.

Anyone have some links for learning about complex software design? I've seen a little strategies (flow charts and diagrams and stuff) shown in theory in college classes but I have no experience trying it in practice and I'm not sure how to start. Or even what it is I'm looking for.
Logged
Steam ID: Spehss Cat
Turns out you can seriously not notice how deep into this shit you went until you get out.

DeKaFu

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10599 on: June 24, 2017, 09:46:26 am »

So, back again, still working on My First Shitty C++/SDL2 Game Engine.

Plenty of progress. I have my renderer chugging away slapping pretty things all over the screen, a system for creating/caching text textures from ttfs, and a handful of gui objects reading mouse input and talking back and forth with data-only objects. Wow!

So... I've gotten this far without actually having ever used inheritance. Just now dipping my toe in with my GUI classes, but I suspect the way I'm doing things can definitely be improved on.

What I have right now is a base class "GUI_object" that has nothing in it but three pure virtual methods representing the three things a GUI object will ever need to do: "draw()", "handleinput()", and "update()". Everything so far just defines their own implementation of those, and then all the GUI objects are added (via unique_ptr) to a vector which the game loop goes through and calls each function on at the appropriate time.

This has a pretty obvious flaw: Every derived GUI_object uses one-or-more of those functions, but not necessarily all of them. You could have images that need to be draw()n and update() their appearance from a data-only object but couldn't care less about input, or invisible objects which are never draw()n but DO need to handeinput()... etc.

Right now I'm just leaving those functions empty when not needed, which is obviously not ideal since they're still being called regardless. The other thing I wanted to consider was the ability to turn the three features on and off separately for each thing, which would involve tracking whether they can be drawn as well as whether they should currently be drawn. Haven't got that far yet but it seems like a good idea?

So... The idea I've been mulling over for improving things goes something like:
Instead of having one GUI_object base class, I have three: GUI_drawable, GUI_interactive, GUI_updatable, each of which contain nothing but a pure virtual method (e.g. draw()) and a boolean showing whether it should currently be used (e.g. currently_visible=true), plus ways to change/check said boolean. Then, the derived objects inherit from each of the three they actually need and implement their own versions of the methods.

Then, when initializing all the GUI stuff, instead of having one vector of unique_ptr GUI_objects, I have three vectors of shared_ptrs to my three base types. An object with more than one base class would end up in multiple vectors. Then the rendering step is just calling draw() on all the GUI_drawable-derived objects, and the input handling step just calls handleinput() on all the GUI_interactive-derived objects, etc.

So... Can anyone tell me if this is stupid? :P
My reading so far has definitely given me the impression that multiple inheritance is a Bad Thing That Will Cause You Future Sadness, but it seems like this case would be pretty safe... right?

...Also, my earliest idea for initializing was to keep the GUI_object base class and have the other three bases derive from it, so I could still have one master GUI_object vector with unique_ptrs, and then just somehow go through it and use it to automatically populate the three derived vectors with raw (non-owning) pointers. But I have no idea how to do that or if the only-real-benefit of keeping all my GUI_object ownership centralized in one place is actually worth the trouble. I also can't think of any methods/variables that would actually belong in the base GUI_object class in that case, and leaving it empty seems... weird.

(I understand I am reinventing the wheel and it's probably coming out a little bit square, but I'm trying to learn.)
Logged

MagmaMcFry

  • Bay Watcher
  • [EXISTS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10600 on: June 24, 2017, 10:39:32 am »

Premature optimization is the root of all evil. Empty calls are such a ridiculously minor issue that I can't even imagine a better-performing alternative, let alone one who doesn't also fuck up the codebase to the point of being much less flexible.

As for turning drawing on and off, you should let every GUI object decide for itself if it needs to redraw itself and if so which of its children it needs to recursively draw. On the topic of recursion, it's a good idea to make all draw/handleinput/update calls recursive, so container GUI elements can pass these calls to their children on their own terms, and the main loop will only have to pass the events to your root GUI object.

tl;dr yes it's stupid
Logged

lethosor

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10601 on: June 24, 2017, 02:47:23 pm »

I'd agree with MagmaMcFry's advice. DF actually uses something a lot like your draw()/handleinput()/update() calls (here - it calls them render(), feed(), and logic()). It seems to work well, at least better than the previous system which combined all of those into a single function.

Regarding multiple inheritance: while I don't think it's necessary in this case, the type of multiple inheritance you're using isn't necessarily bad. Classes designed to be inherited with only pure virtual methods are much like "interfaces" in other languages, and I've seen that pattern in C++ as well, so I wouldn't say it's bad as long as at most one parent class is a "non-interface" class. Also, it sounds like your GUI_* classes don't have parents themselves, which makes things less likely to break. (Generally, you want to avoid inheriting from multiple classes that share a parent, which can cause all sorts of problems with accessing parent members.)
Logged
DFHack - Dwarf Manipulator (Lua) - DF Wiki talk

There was a typo in the siegers' campfire code. When the fires went out, so did the game.

DeKaFu

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10602 on: June 24, 2017, 03:47:20 pm »

tl;dr yes it's stupid
oh.

:P Well, that's why I asked before implementing it.
I'm all for avoiding over-complicating things. I was just under the impression that calling functions that do nothing would be "wasteful" performance-wise, but if it's actually no big deal I'll happily leave it as is.

Re: Recursiveness, I think that's similar to how I was hoping to eventually use it... Multiple menu buttons could be members of a "Menu" GUI_object-derived class, and calling draw on the menu would call draw on each button and maybe a background/border in an appropriate order... and then multiple menus could belong to a particular screen layout, etc. Would make it easy to switch between different screens with different layouts/functions. Haven't gotten far enough to actually try it out, though.

Good to know I was on roughly the right track with how to use the multiple inheritance safely, anyway, even if it isn't actually necessary here.

Thanks for the feedback!
Logged

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10603 on: June 24, 2017, 05:06:26 pm »

Remember anything can be done without multiple inheritance using composition. Which is more portable. Also more flexible and lets you change behavior at runtime.

e.g. instead of your gui components inheriting directly from a "draw class", give them a pointer to a base "draw class". Then if the pointer is null, they can't be drawn, and if it's not-null then the draw method of whatever it points at is called, but passing the "this" pointer of the gui object in. This effectively allows you to mix-and-match different components at runtime rather than having to hard-code all the inherited gui types. In fact, all your components can inherit directly from a single type:

e.g.

Code: [Select]
class gui_element
{
    gui_component *draw;
    gui_component *input;
    gui_component *update;

    void draw()
    {
        if(draw) draw->process(this);
    }
    // etc
}

This sort of thing is a lot more flexible than using multiple inheritance and has the benefit that all the gui_elements are of a single concrete type, so you can use them more simply. Plus ... the pointers can be "mix and matched" when creating the gui_elements as desired, or you can attach new behaviors to objects as needed. The things the pointer points to could be either unique objects or shared objects, so you probably want shared pointers here, and an object factory that assembles the gui_elements based on a spec.
« Last Edit: June 24, 2017, 05:18:57 pm by Reelya »
Logged

lethosor

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10604 on: June 24, 2017, 08:56:09 pm »

Remember anything can be done without multiple inheritance using composition. Which is more portable. Also more flexible and lets you change behavior at runtime.
This seems more complicated, and I'm not sure how it's more portable or more flexible, at least for what DeKaFu is doing.
Logged
DFHack - Dwarf Manipulator (Lua) - DF Wiki talk

There was a typo in the siegers' campfire code. When the fires went out, so did the game.
Pages: 1 ... 705 706 [707] 708 709 ... 796