Jump to content

New here and wondernig about C# specifics


 Share

Recommended Posts

Hey folks,

 

New here and wondering if C# is "officially" supported and up to date feature-wise? In particular:

 

- Is there any part of the engine that is not exposed via C# "headers" that are exposed to other languages such as C++?

 

- When new versions are released, are up to date C# "headers" available immediately as part of the main download?

 

What I'm trying to avoid is some form of "community supported" layer. Been there. Done that. Wasn't fun. ;-)

 

Obviously there will be a perf hit with C#, but that's irrelevant for this project.

 

Thanks in advance for any info / advice.

 

- Rhino

Link to comment
Share on other sites

All .NET for LE is community supported. Every member who has supported this has come and gone and come again. The .NET environment in LE is not the most stable. That being said I personally use what is referred to as LE.NET which is basically a 1 for 1 match to the LE library which means all methods are static (basically). There is however Leadwerks.NET which is more of a community layer that is OO in nature. Both seem to be pretty stable and open source.

Link to comment
Share on other sites

Thanks for the reply folks.

 

Rick, can you elaborate on what exactly you mean by this:

 

The .NET environment in LE is not the most stable.

 

Edit: just read that Leadwerks.Net is built on top of LE.Net bindings. so rest of post was irrelevant and has been deleted.

 

Thanks,

Rhino

Link to comment
Share on other sites

Since it's community driven the people who have developed the .NET versions of LE come and go. First it was Tyler and everything looked great. Then he left the community to do other things and it pretty much died. Then I think it was Lazlo who came and took it over and made some modifications I believe. He left the community also at one point so that died. Then Roland came along and wanted to make a 3 layered version. He made LE.NET which was meant to be as close to the C headers for LE as possible. (this is the what I use and I love it because it's very very close to LE in C++). Roland then started on his version of the higher level (more object oriented) version that was to be built on top of LE.NET, but then Lazlo came back and they both started working together but eventually Roland moved on as well. At this point there still is LE.NET but it's not being updated (not sure it needs to though as it seems complete to me, but new LE versions won't get updated by anyone). Lazlo pushes Leadwerks.NET at this point as it's kind of his baby but it's more an object oriented version. I have seen Lazlo around all that much these days but I'm sure he'll try to answer any questions but he could disappear like he did before at the drop of a hat.

 

So that is what I mean by "The .NET environment in LE is not the most stable." :)

 

I'm sure there are some inaccurate pieces above but that's the main idea. People come and go that create their versions of what .NET for Leadwerks would be. Leadwerks isn't object oriented currently so there is an interpretation that needs to happen to move it to .NET and everyone has their own idea about how to do that.

Link to comment
Share on other sites

Leadwerks isn't object oriented currently so there is an interpretation that needs to happen to move it to .NET and everyone has their own idea about how to do that.

 

Thanks again for the prompt reply. That is very helpful.

 

Now that is interesting. I wasn't aware that was the current LE architecture...if I am reading between the lines correctly.

 

So LE internally is written in C (or C++), and the engine interface / API are simply DLL entrypoints? Such that LE.Net is essentially a PInvoke wrapper?

 

If so, are there any plans (public or otherwise) to drop such an architecture for Leadwerks in the near or mid-term future and move to C++ classes at the core and essentially kill LE.Net / pinvoke solution? Such an architecture would essentially kill LE.Net going forward from that point, right?

 

I can easily maintain my own very tight wrapper which are simply PInvoke declarations, which is what it sounds like LET.Net is. That's not a problem; I did that years ago with PowerRender back when it was implemented in 'C'. But when it was re-implemented in C++, I was hosed. I don't want to have the same thing happen twice if possible. ;-)

 

Thanks,

Rhino

Link to comment
Share on other sites

Actually LE is Object Oriented, but only the DLL is procedural, because BlitzMax can not export OOP DLLs. So you can go and reproduce the original internal OOP structure in Leadwerks.NET like it was done in LEO also.

LE3 will have much more library forms, including native C++ .lib format and possibly also the OOP DLL. The procedural DLL form is still needed for languages which don't support OOP.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

Thanks again for the prompt reply. That is very helpful.

 

Now that is interesting. I wasn't aware that was the current LE architecture...if I am reading between the lines correctly.

 

So LE internally is written in C (or C++), and the engine interface / API are simply DLL entrypoints? Such that LE.Net is essentially a PInvoke wrapper?

 

If so, are there any plans (public or otherwise) to drop such an architecture for Leadwerks in the near or mid-term future and move to C++ classes at the core and essentially kill LE.Net / pinvoke solution? Such an architecture would essentially kill LE.Net going forward from that point, right?

 

I can easily maintain my own very tight wrapper which are simply PInvoke declarations, which is what it sounds like LET.Net is. That's not a problem; I did that years ago with PowerRender back when it was implemented in 'C'. But when it was re-implemented in C++, I was hosed. I don't want to have the same thing happen twice if possible. ;-)

 

Thanks,

Rhino

Leadwerks Engine 2 is written in BlitzMax, and happens to use an object-oriented design internally, not that it makes any difference. The DLL uses a procedural C interface because even different C++ compilers don't make compatible OO libs, much less OO libs for other languages. (The LE2 DLL is actually built with GCC, by the way.)

 

Leadwerks Engine 3 is being written in C++ and will include a static lib with access to the engine classes, for use with C++. However, the compiled DLL will still use a procedural interface, for the same reasons LE2 does; there's no such thing as cross-language OO classes.

 

In LE3, the only way to access the original object-oriented classes of a C++ library will be to import the static library into a C++ program. This is true of any library. There are other things you can do, like create a class wrapper in whatever language and make them call the procedural commands, but C++ is the only way to directly access them. If a wrapper is done right, it will make no difference to the programmer, and they can just happily call object-oriented classes without caring about the underlying design.

 

I have not decided yet if a class wrapper will be provided for C#, but we do get requests for supporting that language more than any other.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Like Lumooja said LE is actually written in BMax not C++. LE 3 will be C++ so yeah you will be faced with the same thing you had before if you make your own wrapper now. LEO, is again, a community supported C++ object oriented wrapper to the C LE interface. I've never used it because some of it's designs I'm not a fan of. Honestly, I don't know many people who use it. There aren't to many posts about it so it's hard to judge who is using it.

Link to comment
Share on other sites

Well, but .lib is C++ only also, so there could be as well a OOP DLL for C++ only, since compiling a .lib can take very long, and compiling with a DLL is instant as it's used only in runtime. You have to remember the majorities of developers also, I think nearly 5 billion people use C++, and the other languages have only few percent share total. Here are some statistics, which of course don't tell the whole truth as each site measures them differently, but clearly C/C++ are always on the top. No idea what that Java is doing there, probably because the insane amount of LC indian developers:

http://langpop.com/

I personally prefer the Freshmeat and Google Code statistics, as they are reliable and meaningful sources. Lambda is also interesting, although I find Haskell quite horrible, but it's a new experiment whatsoever so it gets some attention before it wipes out. Haskell is very similar to Fortran though, and Fortran is faster than C++. Sad but true :)

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

Leadwerks Engine 3 is being written in C++ and will include a static lib with access to the engine classes, for use with C++. However, the compiled DLL will still use a procedural interface, for the same reasons LE2 does; there's no such thing as cross-language OO classes.

 

Thanks for the overview, that makes perfect sense, and I've seen (and built) similar constructs before.

 

Now that you are deep in LE3 impl, how compatible is the LE3 DLL procededural interface going to be to the LE2 interface? Surely there will be additions, but do you foresee large changes in the API set given the new engine architecture? Or if it a design goal to ensure / maximize compatibility?

 

I assume that today the LE2 procedure interface exposes close to if not 100% of the LE BlitzMax implementation. Will this be true as well with the DLL procedural interface for LE3?

 

Thanks,

Rhino

Link to comment
Share on other sites

It's hard to quantify the answer to that. It's a new engine and a new start, but a lot of the design is the same. One important difference is I am using a strict naming scheme instead of making commands that individually sound nice. So instead of PositionEntity() you have SetEntityPosition().

 

Here's the current header file for the procedural command set:

		//Bank
	DLLExport int GetBankSize(le3::Bank* bank);
	DLLExport int PeekBankByte(le3::Bank* bank, int position);
	DLLExport char* GetBankBuffer(le3::Bank* bank);

	//Graphics driver
	DLLExport le3::OpenGL1GraphicsDriver* CreateOpenGL1GraphicsDriver();
	DLLExport le3::OpenGL3GraphicsDriver* CreateOpenGL3GraphicsDriver();
	DLLExport void SetGraphicsDriver(le3::GraphicsDriver* graphicsdriver);
	DLLExport le3::GraphicsDriver* GetGraphicsDriver();
	DLLExport int GetGraphicsDriverName(le3::GraphicsDriver* graphicsdriver, char* s, int length);
	DLLExport int GetGraphicsDriverVendor(le3::GraphicsDriver* graphicsdriver);
	DLLExport int GraphicsDriverSupported(le3::GraphicsDriver* graphicsdriver);
	DLLExport int BuffersSupported();

	//Timing
	DLLExport float UPS();
	DLLExport int Millisecs();
	DLLExport void UpdateTime();

	//Network
	DLLExport le3::Server* CreateServer(int port);
	DLLExport le3::Message* UpdateServer(le3::Server* server, int timeout);
	DLLExport void DisconnectServer(le3::Server* server, le3::Peer* client, int force);
	DLLExport int SendServer(le3::Server* server, le3::Peer* client, int messageid, char* data, int size, int channel, int flags);

	//File system
	DLLExport void SetDir(const char* path);

	//Light
	DLLExport le3::DirectionalLight* CreateDirectionalLight(le3::Entity* parent);

	//Font
	DLLExport le3::Font* LoadFont(const char* path,int size,int style,int family);
	DLLExport void DrawFontText(le3::Font* font, char* text,int x,int y, float kerning);
	DLLExport int GetFontTextWidth(le3::Font* font,char* text);
	DLLExport int GetFontHeight(le3::Font* font);
	DLLExport void FreeFont(le3::Font* font);

	//Drawing
	DLLExport void SetViewport(int x, int y, int width, int height);
	DLLExport void SetColor(float r, float g, float b, float a);
	DLLExport void SetClearColor(float r, float g, float b, float a);
	DLLExport void SetBlendMode(int blendmode);
	DLLExport void DrawLine(int x0, int y0, int x1, int y1);
	DLLExport void DrawRect(int x, int y, int width, int height, int style);
	DLLExport void DrawImage(le3::Texture* image, int x, int y, int width, int height);
	DLLExport void TileImage(le3::Texture* image);
	DLLExport void SetRotation(float rotation);
	DLLExport void SetTranslation(float x, float y);
	DLLExport void SetScale(float x, float y);		

	//Window
	DLLExport le3::Window* CreateWindow(const char* title,int width,int height,int style);
	DLLExport le3::Window* CreateCustomWindow(HWND hwnd);
	DLLExport int GetWindowWidth(le3::Window* window);
	DLLExport int GetWindowHeight(le3::Window* window);
	DLLExport void SetWindowShape(le3::Window* window, int x, int y, int width, int height);
	DLLExport void FreeWindow(le3::Window* window);

	//Context
	DLLExport le3::Context* CreateContext(le3::Window* window,int multisamplemode);
	DLLExport void SwapContext(le3::Context* context, int sync);

	//AssetReference
	DLLExport le3::MediaReference* FindAssetReference(char* s);
	DLLExport int ReloadAssetReference(le3::MediaReference* assetreference, int flags);
	DLLExport void SetAssetReferenceName(le3::MediaReference* assetreference, char* name);
	//DLLExport int CountAssetReferences();
	//DLLExport le3::MediaReference* GetAssetReference(int n);
	//DLLExport int GetAssetReferenceName(le3::MediaReference* assetreference);
	//DLLExport int CountAssetReferenceInstances(le3::MediaReference* assetreference);

	//Asset
	DLLExport int GetAssetName(le3::Media* asset, char* s, int length);
	DLLExport le3::MediaReference* GetAssetAssetReference(le3::Media* asset);
	DLLExport int ReloadAsset(le3::Media* asset, int flags);

	//Shader
	DLLExport le3::Shader* CreateShader();
	DLLExport le3::Shader* LoadShader(char* path, int flags);
	DLLExport void SetShader(le3::Shader* shader);
	//DLLExport int ReloadShader(le3::Shader* shader, int flags);
	DLLExport int SetShaderFloat(le3::Shader* shader, char* name, float f);
	DLLExport int SetShaderVec2(le3::Shader* shader, char* name, float x, float y);
	DLLExport int SetShaderVec3(le3::Shader* shader, char* name, float x, float y, float z);
	DLLExport int SetShaderVec4(le3::Shader* shader, char* name, float x, float y, float z, float w);
	DLLExport int SetShaderMat4(le3::Shader* shader, char* name, le3::Mat4* mat);
	DLLExport void FreeShader(le3::Shader* shader);
	DLLExport int GetShaderSource(le3::Shader* shader, int shaderid, char* s, int length);
	DLLExport int GetShaderError(le3::Shader* shader, char* s, int length);
	DLLExport void SetShaderSource(le3::Shader* shader,  char* source, int shaderid);
	DLLExport int CompileShader(le3::Shader* shader, int shaderid);
	DLLExport int LinkShader(le3::Shader* shader);

	//Texture
	DLLExport int GetTextureTarget(le3::Texture* texture);
	DLLExport le3::Texture* LoadTexture(char* path, int flags);
	DLLExport le3::Texture* CreateTexture(int width, int height, int format, int flags, int frames);
	//DLLExport void LockTexture(le3::Texture* texture, int miplevel, int framenumber);
	//DLLExport void UnlockTexture(le3::Texture* texture, int miplevel, int framenumber);
	//DLLExport void WriteTexturePixel(le3::Texture* texture, int x, int y, int r, int g, int b, int a, int miplevel, int framenumber);
	//DLLExport int ReadTexturePixel(le3::Texture* texture, int x, int y, int miplevel, int framenumber);
	DLLExport void GetTexturePixels(le3::Texture* texture, char* buf, int miplevel, int framenumber, int cubeface);
	DLLExport void SetTexturePixels(le3::Texture* texture, char* buf, int miplevel, int framenumber, int cubeface);
	DLLExport int GetTextureWidth(le3::Texture* texture, int miplevel);
	DLLExport int GetTextureHeight(le3::Texture* texture, int miplevel);
	DLLExport void FreeTexture(le3::Texture* texture);
	DLLExport void SetTextureFilter(le3::Texture* texture, int filter);
	//DLLExport int TextureLocked(le3::Texture* texture, int miplevel, int framenumber);
	//DLLExport int ReloadTexture(le3::Texture* texture, int flags);
	DLLExport void BindTexture(le3::Texture* texture, int index);
	DLLExport char* GetTextureData(le3::Texture* texture, int miplevel, int framenumber);
	DLLExport int CountTextureMipmaps(le3::Texture* texture);
	DLLExport int GetTextureFormat(le3::Texture* texture);
	DLLExport int GetTextureMipmapSize(le3::Texture* texture, int mipmap);
	DLLExport void SetTextureClampMode(le3::Texture* texture, int x, int y, int z);
	DLLExport int GetTextureClampMode(le3::Texture* texture, int axis);
	DLLExport float GetTextureAnisotropy(le3::Texture* texture);
	DLLExport void SetTextureAnisotropy(le3::Texture* texture, float anisotropy);

	//Material
	DLLExport int MaterialContainsValue(le3::Material* material, const char* name);
	DLLExport void SetMaterialShader(le3::Material* material, le3::Shader* shader);
	DLLExport le3::Material* LoadMaterial(const char* path, int flags);
	DLLExport le3::Texture* GetMaterialTexture(le3::Material* material, int index);
	DLLExport void SetMaterialTexture(le3::Material* material, le3::Texture* texture, int index);
	//DLLExport int ReloadMaterial(le3::Material* material, int flags);
	DLLExport le3::Shader* GetMaterialShader(le3::Material* material);
	DLLExport void FreeMaterial(le3::Material* material);
	DLLExport void SetMaterialBlendMode(le3::Material* material, int mode);
	DLLExport int GetMaterialBlendMode(le3::Material* material);
	DLLExport void SetMaterialBackFaceCullMode(le3::Material* material, int mode);
	DLLExport int GetMaterialBackFaceCullMode(le3::Material* material);
	DLLExport void SetMaterialShadowMode(le3::Material* material, int mode);
	DLLExport int GetMaterialShadowMode(le3::Material* material);
	DLLExport void SetMaterialDepthTestMode(le3::Material* material, int mode);
	DLLExport int GetMaterialDepthTestMode(le3::Material* material);
	DLLExport void SetMaterialZSortMode(le3::Material* material, int mode);
	DLLExport int GetMaterialZSortMode(le3::Material* material);
	DLLExport void SetMaterialFloat(le3::Material* material, char* name, float x);
	DLLExport void SetMaterialVec2(le3::Material* material, char* name, float x, float y);
	DLLExport void SetMaterialVec3(le3::Material* material, char* name, float x, float y, float z);
	DLLExport void SetMaterialVec4(le3::Material* material, char* name, float x, float y, float z, float w);
	DLLExport float GetMaterialFloat(le3::Material* material, char* name);
	DLLExport void GetMaterialVec4(le3::Material* material, char* name, le3::Vec4* v);

	//Buffer
	DLLExport void GetBufferPixels(le3::Buffer* buffer, char* buf, int component);
	DLLExport void SetBuffer(le3::Buffer* buffer);
	DLLExport le3::Buffer* GetBuffer();
	DLLExport int GetBufferWidth(le3::Buffer* buffer);
	DLLExport int GetBufferHeight(le3::Buffer* buffer);
	DLLExport le3::Buffer* CreateBuffer(int width, int height, int colortextures, int depthtexture, int multisamplemode);
	DLLExport le3::Texture* GetBufferColorTexture(le3::Buffer*, int index);
	DLLExport le3::Texture* GetBufferDepthTexture(le3::Buffer*);
	DLLExport void ClearBuffer(le3::Buffer* buffer, int mode);
	DLLExport void FreeBuffer(le3::Buffer* buffer);

	//World
	DLLExport le3::World* CreateWorld();
	DLLExport void RenderWorld();
	DLLExport void SetWorld(le3::World* world);
	DLLExport le3::World* GetWorld();
	DLLExport void FreeWorld(le3::World* world);
	DLLExport void SetWorldAmbientLight(le3::World* world, float r, float g, float b, float a);

	//Entity
	DLLExport void SetEntityPosition(le3::Entity* entity,float x, float y, float z, int global);
	DLLExport void SetEntityRotation(le3::Entity* entity,float x, float y, float z, int global);
	DLLExport void GetEntityPosition(le3::Entity* entity, le3::Vec3* position, int global);
	DLLExport void GetEntityRotation(le3::Entity* entity, le3::Vec3* rotation, int global);
	DLLExport void GetEntityMatrix(le3::Entity* entity, le3::Mat4* mat);
	DLLExport void MoveEntity(le3::Entity* entity,float x, float y, float z, int global);
	DLLExport void TurnEntity(le3::Entity* entity,float x, float y, float z, int global);
	DLLExport void SetEntityMaterial(le3::Entity* entity, le3::Material* material);
	DLLExport le3::Material* GetEntityMaterial(le3::Entity* entity);
	DLLExport void GetEntityAABB(le3::Entity* entity, le3::AABB* aabb, int mode);
	DLLExport void FreeEntity(le3::Entity* entity);
	DLLExport void HideEntity(le3::Entity* entity);
	DLLExport void ShowEntity(le3::Entity* entity);
	DLLExport int CountEntityChildren(le3::Entity* entity);
	DLLExport le3::Entity* GetEntityChild(le3::Entity* entity, int n);
	DLLExport void SetEntityParent(le3::Entity* entity, le3::Entity* parent, int global);
	DLLExport void AlignEntityToVector(le3::Entity* entity, float x, float y, float z, int axis, float rate, float roll);

	//Pivot
	DLLExport le3::Pivot* CreatePivot(le3::Entity* parent);

	//Model
	DLLExport le3::Model* LoadModel(const char* path, int flags);
	DLLExport le3::Model* CreateModelSphere(int segments);
	DLLExport le3::Model* CreateCube(le3::Entity* parent);
	DLLExport void FlipModelNormals(le3::Model* model);

	//Camera
	DLLExport le3::Camera* CreateCamera(le3::Entity* parent);
	DLLExport void SetCameraRange(le3::Camera* camera, float nearrange, float farrange);
	DLLExport void GetCameraRange(le3::Camera* camera, le3::Vec2* range);
	DLLExport void SetCameraProjectionMode(le3::Camera* camera, int projectionmode);
	DLLExport int GetCameraProjectionMode(le3::Camera* camera);
	DLLExport void SetCameraClearColor(le3::Camera* camera, float r, float g, float b, float a);
	DLLExport void GetCameraClearColor(le3::Camera* camera, le3::Vec4* color);
	DLLExport void SetCameraZoom(le3::Camera* camera, float zoom);
	DLLExport float GetCameraZoom(le3::Camera* camera);
	DLLExport void SetCameraDrawMode(le3::Camera* camera, int drawmode);
	DLLExport void SetCameraFOV(le3::Camera* camera, float fov);
	DLLExport float GetCameraFOV(le3::Camera* camera);
	DLLExport void SetCameraMotionBlurMode(le3::Camera* camera, int mode);
	DLLExport void SetCameraViewport(le3::Camera* camera, float x, float y, float width, float height);
	DLLExport void GetCameraViewport(le3::Camera* camera, le3::Vec4* viewport);

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

LEO, is again, a community supported C++ object oriented wrapper to the C LE interface.

While the C headers are officially supported, LEO is kinda in a hybrid situation. It is officially supported, as in being part of the SDK, but for problems with it (there has been none since it's perfect) you'd have to ask in the Forums. Roland wrote LEO originally and I continue updating them when new engine features come out. The lack for official LEO support was partly also the lack of knowledge of C++ of the officials, but with the LE3 development the officials have gained huge C++ knowledge, indeed even to a state that they love it :) So LEO should be theoretically now 80% officially supported.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

One important difference is I am using a strict naming scheme instead of making commands that individually sound nice. So instead of PositionEntity() you have SetEntityPosition().

 

Of course, surely when making other big changes you might as well get the conventions set. Consistency in naming trumps nice sounding names.

 

If for the most part we are talking essentially the same parameter sets but different function names, then that's no biggie as search/replace can take care of that easily enough. What I'm more concerned about is if how things work fundamentally changes from LE2 to LE3 and thus require significant logic changes in order to port.

 

Thanks for providing the latest LE3 listing. I'll compare it against the LE2 listing and get an idea for myself (assuming it's in the eval kit).

 

Does anybody have any downloadable LE C# example games or walkthroughs or demo's? Just something to get an idea on performance. Would love to see if anybody has written something that loads the same datasets from both C# and C++ so you can get a idea of the perf hit taken. I have to think somebody has doen research into this...

 

And finally, I know better than to ask for a release date for LE3, but is it expected that it will be a 2011 release? 2012?

 

Thanks,

Rhino

Link to comment
Share on other sites

Josh, please contact me if ever we are to set up an official C# header for LE3; including OOP wrapping, which will mimic the exact same structure as the C++ one.

 

As to the askers' question, LE .NET is no longer supported by Roland; it was, however, pretty stable.

Leadwerks .NET is not based on LE .NET. However, it is a ver C# .NET approach to Leadwerks, much more intuitive than the procedural commands.

With the massive rollbacks of the forum, Leadwerks .NET got deleted. I could repost it, but I'm in my finals at the moment, and I have no motivation to invest time in this, especially considering even the C# community is not very hot on the idea.

 

Hopefully Josh will take the C# demands into consideration for LE3.

Link to comment
Share on other sites

Josh, please contact me if ever we are to set up an official C# header for LE3; including OOP wrapping, which will mimic the exact same structure as the C++ one.

 

Yes, that would be ideal. There is a lot of synergy which comes out of that, not the least of which is applicability of examples, documentation, and so forth. However, that may be problematic unless Josh designs for it up front. Things like multiple inheritance and certain template features are hard to implement in C#.

 

Besides, if a primary design goal was official C# support that matched the internal OO model, then I think there is a bettery way to go about it: C++ Interop (more on that below).

 

Leadwerks .NET is not based on LE .NET.

 

OK so that's interesting (and is opposite of what was said earlier). So essentialy it had it's own PInvoke declarations (even if they were a direct source-copy) and didn't usethe other DLL. Good.

 

With the massive rollbacks of the forum, Leadwerks .NET got deleted. I could repost it, but I'm in my finals at the moment, and I have no motivation to invest time in this, especially considering even the C# community is not very hot on the idea.

 

I'm hot on the idea. ;-) I'm sure it would save me some time, especially if the wrapper is already very .Net-ish, as that's how I roll. The .Net runtime is wonderful in it's consistency of implementation, and if what you've come up with has a similar look and feel then I'm sure it would save me a lot of effort.

 

Hopefully Josh will take the C# demands into consideration for LE3.

 

Part of the issue I see with C# and LE3 going forward is it's going to become a layercake situation if you assume the solution should be architected the way it is today. If I'm understanding LE2 architecure correctly, today the procedural layer essentially is the engine. But with LE3+ it's going to be a layer built on top of the engine. Then PInvoke acts as an interop / marshalling layer on top fo that. Then there's an OO C# layer on top of that. Sure, the change in LE3 architecture will affect all languages that use the procedural layer, but PInvoke is like adding insult to injury. ;-)

 

It's clearly more work for Josh (or the community), but perhaps a better way to support C# would be through Managed C++ (C++ Interop) classes that extend the new C++ engine classes for LE3. That not only provides a level of type-safety that doesn't otherwise exist, but it is also faster (in some cases a LOT faster) at marshalling data since it does a simple bit-copy with no data wrangling needed. It would be a lot faster. More info...

 

http://msdn.microsoft.com/en-us/library/ky8kkddw(v=vs.80).aspx

 

Of course, no Mono support...but since we're talking Windows only that's really not a huge deal, is it? And if you really wanted to use Mono, then just use the procedural layer and PInvoke.

 

In summary, if the goal was to have a C# OO class hierarchy that matches the C++ hierarchy, then going through the future procedural layer via PInvoke really isn't the best way to do it. Furthermore, if tne new LE3 classes are designed with the knowledge that they will have a C++ Interop layer wrapped around them (pretty please Josh), then adding and mainting such a layer will essentially become a fairly trivial bookkeeping exercise (I've written code generators that do this for me). In theory wouldn't be too much extra effort to support, because the same set of documentation and examples apply to both.

.

- Rhino

Link to comment
Share on other sites

So if we were able to get a Mono version of C# working you would support it? Mono is not Windows only.

 

I'm hot on the idea.

 

You are this week :lol: Seriously anything .NET related to LE has people coming and going all the time. No offense to you since we don't know you, but when you see it over and over again, it's hard to think otherwise. Without the proper support from Josh it's always going to be this community effort that just doesn't get much traction.

Link to comment
Share on other sites

So if we were able to get a Mono version of C# working you would support it? Mono is not Windows only.

 

 

 

I would make Mono compatible headers for LE 3. It's not that hard either.

You are this week :lol: Seriously anything .NET related to LE has people coming and going all the time. No offense to you since we don't know you, but when you see it over and over again, it's hard to think otherwise. Without the proper support from Josh it's always going to be this community effort that just doesn't get much traction.

Rick, please stop turning down the C# .NET community spirit or Leadwerks .NET for that matter, especially considering that you don't even intend to use it and stick with LE.NET. The community effort loses its momentum with comments like these.

Link to comment
Share on other sites

So if we were able to get a Mono version of C# working you would support it? Mono is not Windows only.

I have provided the existing LE3 header, and am somewhat interested in C# support. I can't same more than that yet, because I don't know enough about C# to make a judgement. One problem is the getters and setters in C#, which are a nice language feature, but also lead to everyone making their own versions of commands they think is best, and it can deviate quite a lot from the original API. I would be much more comfortable with a class wrapper that duplicates the C++ classes exactly, and then let the C# people add whatever enhancement they like in a community add-on.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

I have provided the existing LE3 header, and am somewhat interested in C# support. I can't same more than that yet, because I don't know enough about C# to make a judgement. One problem is the getters and setters in C#, which are a nice language feature, but also lead to everyone making their own versions of commands they think is best, and it can deviate quite a lot from the original API. I would be much more comfortable with a class wrapper that duplicates the C++ classes exactly, and then let the C# people add whatever enhancement they like in a community add-on.

Well, it's the difference between "Foo.GetBar()" and "Foo.Bar", and "Foo.SetBar(Xin)" and "Foo.Bar = Xin". Honestly, since the variation is always similar, it can only be seen as a language limitation. I wouldn't spend time implementing Get and Set methods in C#, everyone any familiar with C# would spit on them.

Link to comment
Share on other sites

Yeah, but then it gets into stuff like "model.surface[1].vertex[4].position.x = 3" which looks nice, but completely branches from the original API. When I see commands, and I'm not sure what they do, that means it's getting beyond my control.

 

There's also a problem that many of the C++ get/set functions use multiple or optional arguments, like Entity::SetPosition(x,y,z,true). So we either have a break in the design, where some things use getters/setters and some things use methods, or you have to make up your own terminology. In this case we could say:

entity.position = 4

-or-

entity.globalposition = 4

 

But it's not always that clear. Or should it be entity.localposition? That would be more consistent, but look less nice. I'm not even sure.

 

They really should have designed getters and setters to take multiple arguments:

entity.position = 4, true

 

Without that, they're only good for some things, and it creates an awful lot of inconsistency because you still have to use a method for anything more complex.

 

So I am still interested in C#, but I am not going to put my name behind something unless I have thoroughly examined it and decided what the API should look like, and I just don't have time right now to devote to the syntax of one language.

 

I think the uncertainty people express over C# has less to do with me not making it official, and more to do with the issues I described here, the implication being that I would devise some kind of consistent rule to clear all that up if I were to make it official.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Well, it's the difference between "Foo.GetBar()" and "Foo.Bar", and "Foo.SetBar(Xin)" and "Foo.Bar = Xin". Honestly, since the variation is always similar, it can only be seen as a language limitation. I wouldn't spend time implementing Get and Set methods in C#, everyone any familiar with C# would spit on them.

 

Lazlo, I think you are getting to caught up in .NET politics. Nobody but syntactical .NET snobs are going to care about having get/set functions over properties. Anyone who deals with non .NET libraries knows that whatever you get goes if that library wasn't design specifically in .NET. Josh is telling you that if you make C# look exactly like LE 3, he might sign off on it and you are basically saying no, you won't budge on some design options? Take what you can get so you get something functional. Are you trying to create the perfect library or are you trying to let the .NET community use LE? Pick your battles.

 

I think the uncertainty people express over C# has less to do with me not making it official, and more to do with the issues I described here, the implication being that I would devise some kind of consistent rule to clear all that up if I were to make it official.

 

You would define a rule. You would define the rule of how you want the C# to look. You could say "we use get/set, deal with it". And people would have to deal with it or make their own wrapper. I promise you the majority will deal with it. They might ask why, but they will deal with it because at the end of the day they are using .NET because it offers so much more that they can now integrate with LE. Do you know why I use .NET? It's not because I give a **** about properties over get/set it's because of it's reflection which helps me create easy and scalable scene loaders. It's because it's threading is so simple that I can do non LE stuff like pathfinding with it. It's because of how easy it is to use databases with it which I will use in my game. It's not about what LE looks like in .NET, it's about just getting it to work the same way as it does in C++ and now I have more/easy options to complement my game.

Link to comment
Share on other sites

Enough, I'm just done with Werkspace. Hire a guy who will make sloppy code that has nothing to do with C#, just a PInvoke file of your lib, and pay him hundreds of dollars. Rick, enjoy your vision of C#, that is, destroying the OOP it was meant for and using procedural commands. Actually, I won't even argue with anything. I'll do my C# headers for LE 3 and use them for myself. The rumour is pretty much right: Werkspace is an elitist community, and I'm done fighting that, I'll rather slip into the "snobs" (sic) who keep their code to themselves.

 

And to all potential buyers who view this reply (you probably won't, Josh will move it to the obscure C# forum), know that while Leadwerks is the best engine, Werkspace is the worst community.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...