Author Topic: Programming Megathread  (Read 143660 times)

Just try to make sure you don't spend too much time on your build system more than you do actually making a thing.
well, I've already spent quite a lot of time making it, but now I'm at the point where the client scripts are getting too convoluted for me to reasonably keep it all in one file, which is why I need a solution
thanks for showing me that webpack thing, I'll see how it goes~

No problem! Also, if anyone tells you that browserify is better, their opinion is wrong.

Like, actually wrong.

Browserify is a bloated mess that I'm so glad I've stepped away from. But I guess it still depends on your goal.

I didn't really like the way webpack worked (specifically that I had to concatenate everything before I could test it)
and I figured out that requirejs lets you do it in a way that looks a little more commonjs-y
but NOW I'm having trouble with circular dependencies. I have a UI module that deals with DOM elements, and an out module that deals with sending data to the server, and they rely on each other. the out module has a function that calls a UI function to get some stuff from a text box, but the UI section binds that function to an event listener so that clicking a button will call it
I could VERY EASILY solve this problem by just moving the get-from-text-box bit into the out module's function, but then I'll have stupid DOM code in the out module and if I do THAT then what's the frickin point in splitting it into modules

by the way "Circular dependencies are rare, and usually a sign that you might want to rethink the design."
frick you

I like working with the server side a lot more
maybe I'll just go back to a single file. I wouldn't be having ANY OF THESE PROBLEMS
« Last Edit: March 03, 2016, 04:56:24 PM by Foxscotch »

I didn't really like the way webpack worked (specifically that I had to concatenate everything before I could test it)
webpack works by progressively transforming your data with loaders. it also follows all reference be they js files or actual data resources like images. basically think of your data moving through a pipeline.
here's a webpack config that i made a while ago for something quick. i tend to copy my configs around and modify them. it can be pretty weird at first but webpack can be nice in production environments. it depends if you want to use the grunt/gulp way of doing things or just letting loaders figure it out and adding it to a particular extension's pipeline

ive annotated it a bit so that you hopefully get a feel for some of the things it can do. youre going to have to delve into the docs if you really want to be able to use it on your own but i figure you might be interested is a pseudo-production config
Code: [Select]
let webpack = require('webpack'),
     path    = require('path');

let base_dir = __dirname + '/node_modules/';

let definePlugin = new webpack.DefinePlugin({
  __DEV__:              JSON.stringify(JSON.parse(process.env.BUILD_DEV || 'true')),
  __PRERELEASE__: JSON.stringify(JSON.parse(process.env.BUILD_PRERELEASE || 'false'))
});

// resolve library names in config to js files
function addVendor(name, path) {
  if(!config.resolve.alias)
    config.resolve.alias = {};
  config.resolve.alias[name] = path;
}

let config = {
  // where to start the build and what libraries to use
  // build a separate vendors bundle so that users can cache your libraries and when your
  // code updates they only have to download bundle.js
  entry: {
    app: ['./src/app/main.js'],
    vendors: ['mithril', 'bootstrap', 'jquery', 'bootstrap.css']
  },
  resolve: {
    alias: {
      jquery: 'jquery/dist/jquery'
    },
    root: [path.join(__dirname, 'public/lib')]
  },
  plugins: [
          // names to resolve in the files
new webpack.ProvidePlugin({
        $: 'jquery',
   jQuery: 'jquery',
        m: 'mithril'
    }),
    // in this config we're not minifying pre-minified js... you could minify and dedupe the non-minified production versions
    // of these libraries and potentially get a smaller bundle.js size but builds take longer
    new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js')
    // new webpack.optimize.UglifyJsPlugin(),
    // new webpack.optimize.DedupePlugin()
  ],
  // where to output the build bundle.js
  output: {
    path: './public',
    filename: 'bundle.js'
  },
  module: {
    noParse: [],
    // loaders to transform files with certain file extensions read from right to left. data pipelines steps are separated with !
    loaders: [
      {
        test: /\.js$/,
        exclude: [/node_modules/, /public/],
        loader: 'babel',
        query: {
          presets: ['es2015']
        }
      },

      // use msx-loader to transform mithril jsx-like files you can see options being passed to this particular loader
      { test: /\.msx$/, loader: "msx-loader?harmony=true&precompile=true"},

       // sass-loader -> css-loader -> style-loader
      { test: /\.scss$/, loader: "style-loader!css-loader!sass-loader"},
      { test: /\.css$/,  loader: "style-loader!css-loader" },

      { test: /\.png$/,    loader: "file-loader" },

      { test: /\.(woff|woff2)$/,  loader: "url-loader?limit=10000&mimetype=application/font-woff" },
      { test: /\.ttf$/,    loader: "file-loader" },
      { test: /\.eot$/,    loader: "file-loader" },
      { test: /\.svg$/,    loader: "file-loader" }
    ]
  },
  // require('name') without extensions will automatically get files with name.[ext] where [ext] is one of the named extensions
  resolve: {
    extensions: ['', '.js', '.json', '.msx']
  }
};

// add vendor files and provide names.
addVendor('jquery',           base_dir + 'jquery/dist/jquery.min.js');
addVendor('mithril',           base_dir + 'mithril/mithril.min.js');
addVendor('bootstrap',       base_dir + 'bootstrap/dist/js/bootstrap.min.js');
addVendor('bootstrap.css', base_dir + 'bootstrap/dist/css/bootstrap.min.css');

module.exports = config;

you can do way more with it but its really good for large scale projects. this is kind of a messy way to handle css but it works for this config i guess. in the end theres no good build system for real web applications but you need them to handle the complexity of large applications.

oh yeah webpack_dev_server is really cool you should check that out. its kinda like nodemon

No problem! Also, if anyone tells you that browserify is better, their opinion is wrong.

Like, actually wrong.

Browserify is a bloated mess that I'm so glad I've stepped away from. But I guess it still depends on your goal.
it depends on what you want to do. right tool for the right job. i think browserify is alright actually

maybe I'll just go back to a single file. I wouldn't be having ANY OF THESE PROBLEMS
if that works for you, thats great. it depends on how big your application is
« Last Edit: March 04, 2016, 02:41:12 PM by Ono-Sendai »

oh and if you want sourcemaps to debug you can do that. its a really important part that i left out because they are definitely needed for serious development. chrome's inspector works quite nicely with them

i made my previous post because webpack doesnt need to do what you specified. its extremely flexible albeit confusing at first. i think it definitely is the most workable build solution but it depends on how much mental energy you want to sink into it
« Last Edit: March 04, 2016, 02:39:20 PM by Ono-Sendai »

urrrrrrrrrrrrrrrgh.

Last night, while doing programming exercises in C++, I discovered "Array Decay". Because arrays are just a fancy version of a pointer, when you pass them in as an argument to a function/method, they lose their array properties and are just treated like standard pointers. Normally this works fine; pointer notation allows you to use [] on it anyway. The issue is using Range-Based For loops for iteration over an array.

The Range-Based For loop looks like this:

for (tempType tempVariable : arrayName) {}

It's the equivalent of the foreach loop in C#. Each iteration of the loop, the tempVariable is equal to the current element of the array, and at the end of the iteration tempVariable is saved back to the element in arrayName. When your array and the range-based for loop are in the same scope, this works perfectly, however...

Because an array parameter is treated like a standard pointer, it loses certain necessary properties (such as array::begin) that the Range-Based For loop requires to work. Because there's no workaround for this and arrays don't have "length" property like in C#, you end up having to either manually keep track of the length of the array or hardcode a maximum number in and then break from the loop once it reaches some kind of terminator character.

Thoroughly frustrating.

EDIT: Should also mention; sizeof() correctly returns the length of your whole array in bytes when used in the same scope as the array. sizeof() only returns the length of the first element in an array in bytes when it is used on an array parameter. I was hoping to use simple maths (sizeof(arrayName) / sizeof(int)) to get the size of the array for this programming exercise, but that didn't work for the reasons I've said up above.
« Last Edit: March 04, 2016, 04:33:26 PM by McJob »

So I made a program that takes an input file (test.d) stores it in a 2D vector for easy modification, and then puts the result inside an output file (test.dlvl) as a way of making a "tileset"

http://pastebin.com/XnE4bUz3

I wanna know how I can make it a bit more efficient, because as you can tell from the pastebin it isn't very concise.

edit: commented the code, and tweaked a few things.
« Last Edit: March 05, 2016, 01:17:03 PM by Glass Joe »

urrrrrrrrrrrrrrrgh.

Last night, while doing programming exercises in C++, I discovered "Array Decay". Because arrays are just a fancy version of a pointer, when you pass them in as an argument to a function/method, they lose their array properties and are just treated like standard pointers. Normally this works fine; pointer notation allows you to use [] on it anyway. The issue is using Range-Based For loops for iteration over an array.

The Range-Based For loop looks like this:

for (tempType tempVariable : arrayName) {}

It's the equivalent of the foreach loop in C#. Each iteration of the loop, the tempVariable is equal to the current element of the array, and at the end of the iteration tempVariable is saved back to the element in arrayName. When your array and the range-based for loop are in the same scope, this works perfectly, however...

Because an array parameter is treated like a standard pointer, it loses certain necessary properties (such as array::begin) that the Range-Based For loop requires to work. Because there's no workaround for this and arrays don't have "length" property like in C#, you end up having to either manually keep track of the length of the array or hardcode a maximum number in and then break from the loop once it reaches some kind of terminator character.

Thoroughly frustrating.

EDIT: Should also mention; sizeof() correctly returns the length of your whole array in bytes when used in the same scope as the array. sizeof() only returns the length of the first element in an array in bytes when it is used on an array parameter. I was hoping to use simple maths (sizeof(arrayName) / sizeof(int)) to get the size of the array for this programming exercise, but that didn't work for the reasons I've said up above.
If you don't want to keep track of the array properties yourself, try using something like a vector or deque.

x
thanks for all the advice and stuff. I'll probably take another stab at it eventually, but currently I think I'm still way too frustrated to try again right now lol

So I made a program that takes an input file (test.d) stores it in a 2D vector for easy modification, and then puts the result inside an output file (test.dlvl) as a way of making a "tileset"

http://pastebin.com/XnE4bUz3

I wanna know how I can make it a bit more efficient, because as you can tell from the pastebin it isn't very concise.

edit: commented the code, and tweaked a few things.
For one, putting braces after a case statement is useless.

Anyways, http://pastebin.com/6EkTmsiJ
Basically you can have just an array of your tileset symbols, and access those directly instead of having a switch
As long as the inf.get() works correctly, the assignment statement is now one line
You can use the post increment operator (var++) to do the increment after the assignment, saving a line
You could figure out a better way to do the while(true) loop, because while(true)s are ugly
Also removed some #includes you had because they weren't used in this code.

For one, putting braces after a case statement is useless.

Anyways, http://pastebin.com/6EkTmsiJ
Basically you can have just an array of your tileset symbols, and access those directly instead of having a switch
As long as the inf.get() works correctly, the assignment statement is now one line
You can use the post increment operator (var++) to do the increment after the assignment, saving a line
You could figure out a better way to do the while(true) loop, because while(true)s are ugly
Also removed some #includes you had because they weren't used in this code.
Thanks, that tremendously slimmed down the code, but the inf.get() you mentioned doesn't quite seem to work.

(i added this section to it for testing purposes, it'll display the inputs)


Everything else though worked perfectly, though, so thanks!
« Last Edit: March 05, 2016, 03:10:47 PM by Glass Joe »

Thanks, that tremendously slimmed down the code, but the inf.get() you mentioned doesn't quite seem to work.

(i added this section to it for testing purposes, it'll display the inputs)


Everything else though worked perfectly, though, so thanks!
Yeah, I'm usually not good at getting the input reading correct on the first go.

Thanks, that tremendously slimmed down the code, but the inf.get() you mentioned doesn't quite seem to work.

(i added this section to it for testing purposes, it'll display the inputs)


Everything else though worked perfectly, though, so thanks!
is that a wii mouse cursor

If you don't want to keep track of the array properties yourself, try using something like a vector or deque.
"deque" is something new to me. I only just learned about vectors when I did that tutorial last night. I was going through the RIT course notes.



So uhh, I don't know what to do. I'd like to get better at games programming and I'm decent at intermediate C/C++/C# but I don't know where to go to get better or what to do.

is that a wii mouse cursor
ding ding ding

so after buttloads of testing, I finally got rid of the while loops in my tileset program and replaced them with lovey 2D for loops, which greatly cleans up the code

http://pastebin.com/sRkSCMqZ
« Last Edit: March 05, 2016, 06:12:06 PM by Glass Joe »