Tag: pattern

Structuring libraries, basic design tips.

Posted by on August 28, 2009

One of the most important things a programmer has to know and learn is proper code design, structuring of the code, etc. This may not be imperative for you if you’re just starting out, but sooner or later you’ll be able to spot the patterns and realize that your current way of doing things is not optimal but rather cumbersome. This is when you start to separate things into modules and you begin to design your code with more meaning and purpose.

By breaking your code into modules or “classes” you can have a finer granularity of the code itself, you can encapsulate the base code and work on top of it, you can also reuse the code in other projects if you have a good design. An example would be a log library (for logging useful debugging information onto text files) with proper design and care you’ll be able to use the same library in almost all of your projects with little to no modification at all.
More…

Macro Templates, by example.

Posted by on July 13, 2009

Heres an example of what I call “macro templates” in PureBasic. A template encapsulates certain functionality, allowing you to dynamically generate the code in a flexible manner.

This example implements a bare-bones n-vector library using a structure and a static array:

Macro Vector_Register( _n, _type )
	
	Structure VECTOR#_n#_type
		vector._type[_n]
	EndStructure
	
	Procedure._type Vector#_n#_type#_Add( *r.VECTOR#_n#_type, *a.VECTOR#_n#_type, *b.VECTOR#_n#_type )
		Define.i i
		For i=0 To _n - 1
			*r\vector[i] = *a\vector[i] + *b\vector[i]
		Next
	EndProcedure
	
	Procedure._type Vector#_n#_type#_Subtract( *r.VECTOR#_n#_type, *a.VECTOR#_n#_type, *b.VECTOR#_n#_type )
		Define.i i
		For i=0 To _n - 1
			*r\vector[i] = *a\vector[i] - *b\vector[i]
		Next
	EndProcedure
	
	Procedure._type Vector#_n#_type#_Divide( *r.VECTOR#_n#_type, *a.VECTOR#_n#_type, *b.VECTOR#_n#_type )
		Define.i i
		For i=0 To _n - 1
			If *b\vector[i] <> 0.0 And *a\vector[i] <> 0.0
				*r\vector[i] = *a\vector[i] / *b\vector[i]
			EndIf
		Next
	EndProcedure
	
	Procedure._type Vector#_n#_type#_Multiply( *r.VECTOR#_n#_type, *a.VECTOR#_n#_type, *b.VECTOR#_n#_type )
		Define.i i
		For i=0 To _n - 1
			*r\vector[i] = *a\vector[i] * *b\vector[i]
		Next
	EndProcedure
	
	Procedure._type Vector#_n#_type#_DotProduct( *a.VECTOR#_n#_type, *b.VECTOR#_n#_type )
		Define.i i
		Define._type result
		For i=0 To _n - 1
			result + ( *a\vector[i] * *b\vector[i] )
		Next
		ProcedureReturn result
	EndProcedure
	
	Procedure._type Vector#_n#_type#_Length( *v.VECTOR#_n#_type )
		ProcedureReturn Sqr( Vector#_n#_type#_DotProduct( *v, *v ) )
	EndProcedure
	
	Procedure._type Vector#_n#_type#_Distance( *a.VECTOR#_n#_type, *b.VECTOR#_n#_type )
		Define.VECTOR#_n#_type temp
		Vector#_n#_type#_Subtract( temp, *a, *b )
		ProcedureReturn Vector#_n#_type#_Length( temp )
	EndProcedure
	
	Procedure.s Vector#_n#_type#_Debug( *v.VECTOR#_n#_type, Decimals.i=#PB_Default )
		Define.i i
		Define.s tmp = "["
		For i=0 To _n-1
			tmp + StrF( *v\vector[i], Decimals.i )
			If i <> _n-1
				tmp + ", "
			EndIf
		Next
		tmp + "]"
		Debug tmp
		ProcedureReturn tmp
	EndProcedure
	
EndMacro

It might look strange/complicated at first, but once you read it you’ll realize it’s fairly simple.

Let’s see the usage of this particular template:

Vector_Register(3, f )	; Register a float "vec3".
Define.VECTOR3f a,b,c	; Define a few vectors with the new structure.

a\vector[0] = 10.0
a\vector[1] = 20.0
a\vector[2] = 30.0

b\vector[0] = 100.0
b\vector[1] = 200.0
b\vector[2] = 300.0

Vector3f_Add(c, a, b)	; c = a + b
Vector3f_Debug(c)	; show each element using the debug output.

Debug Vector3f_DotProduct( a, b )
Debug Vector3f_Length( a )
Debug Vector3f_Distance( a, b )

Cool, huh?. And you can define any amount of elements with any basic type.

Of course we sacrificed speed for flexibility. In those cases where we have to define n-vectors, this would be an ideal solution. For everything else, I suggest a specific library, such as my vec3 macro lib.

Using this principle you can abstract almost anything, within reason. One good example is my object factory template.  Ideally one would have arrays, lists, etc. Implemented in this very same way, in such case the possibilities would be endless and you’d be able to define dynamic lists/arrays inside structures, etc.

I strongly advice you to implement at least one of those templates, even if it’s just for an exercise.

Having the extra tools can’t hurt!

Cheers.

An efficient and simple object factory for PureBasic

Posted by on May 3, 2009

Whenever you deal with structures and what have you it’s obvious that there has to be a better way of doing it. Think about it, you encapsulate your structure-related code in such a way that it becomes clean, nice and tidy — in other words it makes it easy to understand what it does.

However in essence, you end up writing pretty much the same allocate / deallocate, list, etc. code every time you incorporate a new “class” into your project. Why should we?, let’s avoid it all together and focus our efforts in the task at hand rather than in the mundane stuff.

If you open your eyes you’ll see that this is an obvious pattern but what isn’t so obvious is how do you implement a template that deals with it in an efficient and clean way within the current constraints of the language.

Well… Have no fear, EasyObject is here!
First, download it. Secondly, embrace it.

Third, you’re free to post any comments regarding on how to enhance it if you dear to!.

More…