How to proper organize 28K lines of code?

Just starting out? Need help? Post your questions and find answers here.
T4r4ntul4
Enthusiast
Enthusiast
Posts: 119
Joined: Tue Mar 04, 2014 4:15 pm
Location: Netherlands

How to proper organize 28K lines of code?

Post by T4r4ntul4 »

Hey all,

So i made administration software with PB with at least 28.000 code lines. I did make new features/bugfixes to it the last 3 years, but its getting harder everytime when i maintenance the code.
Now my plan is to make a version 2.0. To fix all my mistakes i did with version 1.

i already have a list with things i want to fix with the rewrite, but theres something i cant get my head around it, in pseudo code i did the following::

GUI layout is a panelgadget with 8 tabs, every tab has its own include file, separated in macro's for: global vars, procedures, GUI and last macro for menu case's
Every panelgadget tab include file has this layout:

Code: Select all

macro GloablVarsTab1
; all the global vars of Tab 1
endmacro

macro ProceduresTab1
; all the Procedures of tab 1
endmacro

macro GuiTab1
; all the GUI of tab 1
endmacro

macro casesTab1
; all the cases of tab 1
endmacro

then in main.pb i have:
; startup:
constants, globals, includes, etc (not included in a macro)
- then macro's for all the global vars from all the includes
- after that i have all the macro's for procedures
then i have the 'If openwindow' code lines
- after that i have alle the GUI macro's in their tabs in the panelgadget code
- after that there is the 'repeat until' code with all the macro's from the cases for the GUI

Why did i do it this way? Well, i have relative small code in my main.pb and the rest of the code is separated in their own included file.

Now my questions are:
- Was above a good plan after all?
- Can i do the same as above but without all the macro's?
- What is the best practice to organize long code as this?
- How do you do your code in big projects?

Any insight will help!
User avatar
skywalk
Addict
Addict
Posts: 4220
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: How to proper organize 28K lines of code?

Post by skywalk »

What is harder to maintain?
Are you using a version control system like Fossil or git?
As any code grows, it inevitably becomes more complex to make changes.
Using a VCS and diff tools is a must.
Always try to reduce your globals and house them in a structure.
Macros are great for speed, but do not expand while debugging.
I use Macros to inline repetitive steps for speed and to initialize gui settings.
And to insulate data types for common functions like add(x,y) or DoSomeMath(x,y).
I do not use the module approach since I want amalgamated code for simplicity and speed.
It is much easier to remember and maintain mylib_DoThis() instead of UseMyLib, mylib::DoThis(), EndMyLib.
This makes for simpler diff tool and code automation.
For my apps, I keep all gui elements within myapp.pb and then include math.pbi, network.pbi, etc.
Each pb or pbi has their own structured globals.
Each pb or pbi can compile on its own with a few includes.
This allows me to test each file independently.
Can you compile each include by itself?
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Joubarbe
Enthusiast
Enthusiast
Posts: 713
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: How to proper organize 28K lines of code?

Post by Joubarbe »

Your macro approach seems wrong to me. Don't abuse them, they have a use sometimes, but they are here to support and "emulate" things that in other languages are done in a more complex way (allowing easy debugging, which macros don't have, as skywalk said).

To offer a different point of view from skywalk's, I personally strongly rely on modules (one file = one module) and a semi-object approach. I don't believe in OOP anymore, but I do believe that your code should be split as much as you can, to make maintenance and development more easy. What I call "semi-object" is this:

Code: Select all

DeclareModule Car
  UseModule Common : EnableExplicit

  ;{ OBJECT DEFINITION
  Structure _car Extends Vehicle::_vehicle
    id.i
    doors.i
  EndStructure
  Global NewList cars._car()
;}

  Declare.i New(brand.s, doors.i)
EndDeclareModule

Module Car
  UseModule Common : EnableExplicit

  ;- PRIVATE
  ;- PUBLIC
  Procedure.i New(brand.s, doors.i)
    Static id.i

    AppendElement(cars())
    cars()\id = id : id + 1
    cars()\brand = brand
    cars()\doors = doors
    Vehicle::Register(@cars())
    
    ProcedureReturn @cars()
  EndProcedure
  
  Procedure CallParkingModule(*vehicle.Vehicle::_vehicle, *parking.Parking::_parking)
    If Parking::IsParked(*vehicle, *parking)
      Debug "Vehicle " + *vehicle\brand + " is parked"
    EndIf
  EndProcedure
EndModule
In that approach, you still have functions and not methods, giving you another way of thinking from OOP. Your "car" is not an object, but a reference that must be specified in any functions you call. I had very satisfied results in the past few months with that approach (I have a tool that "inject" the redundant code wherever I need it).

Anyway, I'm pro module :) You don't need a very sophisticated approach to realize that your code will be well maintained that way. A "common" module is the perfect way to store globals (even though globals are also something you should limit). The fact that PB is a one-pass compiler is actually a good thing, it forces you to properly arrange your code and see your mistakes.

After 3 or 4 years of development, I started to change my way of thinking when I had to read and improve the code of other people. At that time, you realize that PB can do a lot of things, and that the readability of a code should be top priority.

In your project, you probably have redundant code if you have one file per tab. Your tabs probably share some identical functions?
Post Reply