Files
lazarus-ccr/bindings/android-sdk/android_sdk_bindings_gen.pas

728 lines
25 KiB
ObjectPascal
Raw Normal View History

unit android_sdk_bindings_gen;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils;
type
{ TAndroidSDKBindingsGen }
TAndroidSDKBindingsGen = class
private
FSourceFile: TStringList;
FPasOutputTypes, FPasOutputClassesForward, FPasOutputClasses,
FPasOutputConsts, FPasOutputIDs, FPasOutputImpl, FPasOutputMessages: TStringList;
FJavaOutputIDs, FJavaOutputMethods: TStringList;
FClassName, FClassNamePas: string; // Class name of the class currently being parsed
FClassNum, FMethodNum: Integer;
procedure ProcessModelFile(ASourceFile, APasOutputFile, AJavaOutputFile: string);
procedure ProcessModelLine(ASourceLine: string);
procedure ProcessModelClass(ASourceLine: string);
procedure ProcessModelMethod(ASourceLine: string; AIsField: Boolean);
procedure ProcessModelConstructor(ASourceLine: string);
procedure ProcessModelConst(ASourceLine: string);
procedure ProcessModelCallbackSetterCaller(ASourceLine: string);
function GetNextWord(ALine: string; var AStartPos: Integer): string;
function GetPascalTypeName(ABaseName: string): string;
function PassByReference(ABaseName: string): Boolean;
function GetJavaResultFunction(AReturnType: string): string;
function GetJavaTypeReader(AType: string): string;
function GetIDString(AMethodName: string): string;
procedure AddOutputIDs(AIDString: string);
public
constructor Create;
destructor Destroy; override;
procedure GenerateAllBindings(AInputDir, APasOutputDir, AJavaOutputDir: string);
end;
var
AndroidSDKBindingsGen: TAndroidSDKBindingsGen;
implementation
{ TAndroidSDKBindingsGen }
procedure TAndroidSDKBindingsGen.ProcessModelFile(ASourceFile, APasOutputFile,
AJavaOutputFile: string);
var
i: Integer;
lPasOutputFile: TStringList;
lJavaOutputFile: TStringList;
begin
lPasOutputFile := TStringList.Create;
lJavaOutputFile := TStringList.Create;
try
FSourceFile.LoadFromFile(ASourceFile);
// Preparations
FClassName := '';
for i := 0 to FSourceFile.Count - 1 do
begin
ProcessModelLine(FSourceFile.Strings[i]);
end;
// Now save the Pascal file
lPasOutputFile.Add(Format('unit %s;', [ChangeFileExt(ExtractFileName(ASourceFile), '')]));
lPasOutputFile.Add('');
lPasOutputFile.Add('interface');
lPasOutputFile.Add('');
lPasOutputFile.Add('uses javalang, androidpipescomm;');
lPasOutputFile.Add('');
lPasOutputFile.Add('type');
lPasOutputFile.Add('');
lPasOutputFile.Add(' { Forward declaration of classes }');
lPasOutputFile.Add('');
lPasOutputFile.AddStrings(FPasOutputClassesForward);
lPasOutputFile.Add('');
lPasOutputFile.Add(' { Types }');
lPasOutputFile.Add('');
lPasOutputFile.AddStrings(FPasOutputTypes);
lPasOutputFile.Add('');
lPasOutputFile.Add(' { Classes }');
lPasOutputFile.Add('');
lPasOutputFile.AddStrings(FPasOutputClasses);
lPasOutputFile.Add(' end;');
lPasOutputFile.Add('');
lPasOutputFile.Add('function HandleMessage(AFirstInt: Integer): Boolean;');
lPasOutputFile.Add('');
lPasOutputFile.Add('implementation');
lPasOutputFile.Add('');
lPasOutputFile.Add('const');
lPasOutputFile.Add(' { Constants }');
lPasOutputFile.Add('');
lPasOutputFile.AddStrings(FPasOutputConsts);
lPasOutputFile.Add('');
lPasOutputFile.Add(' { IDs }');
lPasOutputFile.Add('');
lPasOutputFile.AddStrings(FPasOutputIDs);
lPasOutputFile.Add('');
lPasOutputFile.Add('{ Implementation of Classes }');
lPasOutputFile.Add('');
lPasOutputFile.AddStrings(FPasOutputImpl);
lPasOutputFile.Add('');
lPasOutputFile.Add('{ Message Handling }');
lPasOutputFile.Add('');
lPasOutputFile.Add('function HandleMessage(AFirstInt: Integer): Boolean;');
lPasOutputFile.Add('var');
lPasOutputFile.Add(' lInt: Integer;');
lPasOutputFile.Add(' lPascalPointer: PtrInt = -1;');
lPasOutputFile.Add('begin');
lPasOutputFile.Add(' case AFirstInt of');
lPasOutputFile.AddStrings(FPasOutputMessages);
lPasOutputFile.Add(' end;');
lPasOutputFile.Add('end;');
lPasOutputFile.Add('');
lPasOutputFile.Add('end.');
lPasOutputFile.SaveToFile(APasOutputFile);
lJavaOutputFile.Add('package com.pascal.androidlcl;');
lJavaOutputFile.Add('');
lJavaOutputFile.Add('import android.app.*;');
lJavaOutputFile.Add('import android.view.*;');
lJavaOutputFile.Add('import android.os.*;');
lJavaOutputFile.Add('import android.util.*;');
lJavaOutputFile.Add('import android.content.*;');
lJavaOutputFile.Add('import android.view.*;');
lJavaOutputFile.Add('import android.widget.*;');
lJavaOutputFile.Add('import java.util.*;');
lJavaOutputFile.Add('import java.lang.*;');
lJavaOutputFile.Add('');
lJavaOutputFile.Add('public class AndroidAll');
lJavaOutputFile.Add('{');
lJavaOutputFile.Add(' // info from other classes');
lJavaOutputFile.Add(' Activity activity;');
lJavaOutputFile.Add(' AndroidPipesComm MyAndroidPipesComm;');
lJavaOutputFile.Add(' JavaLang MyJavaLang;');
lJavaOutputFile.Add(' // lists of variables');
lJavaOutputFile.Add(' ArrayList ViewElements;');
lJavaOutputFile.Add('');
lJavaOutputFile.Add(' public AndroidAll(AndroidPipesComm AAndroidPipesComm, Activity AActivity, JavaLang AJavaLang)');
lJavaOutputFile.Add(' {');
lJavaOutputFile.Add(' activity = AActivity;');
lJavaOutputFile.Add(' MyAndroidPipesComm = AAndroidPipesComm;');
lJavaOutputFile.Add(' MyJavaLang = AJavaLang;');
lJavaOutputFile.Add(' ViewElements = new ArrayList();');
lJavaOutputFile.Add(' }');
lJavaOutputFile.Add('');
lJavaOutputFile.Add(' public void DebugOut(String Str)');
lJavaOutputFile.Add(' {');
lJavaOutputFile.Add(' MyAndroidPipesComm.DebugOut(Str);');
lJavaOutputFile.Add(' }');
lJavaOutputFile.Add('');
lJavaOutputFile.AddStrings(FJavaOutputIDs);
lJavaOutputFile.Add('');
lJavaOutputFile.Add(' public boolean ProcessCommand(int Buffer)');
lJavaOutputFile.Add(' {');
lJavaOutputFile.Add(' //DebugOut("AndroidUI.ProcessCommand Command=" + java.lang.Integer.toHexString(Buffer));');
lJavaOutputFile.Add(' // basic types');
lJavaOutputFile.Add(' int lInt, lIndex, lPascalPointer;');
lJavaOutputFile.Add(' // Self params');
lJavaOutputFile.Add(' View param_self_View;');
lJavaOutputFile.Add(' ViewGroup param_self_ViewGroup;');
lJavaOutputFile.Add(' TextView param_self_TextView;');
lJavaOutputFile.Add(' Button param_self_Button;');
lJavaOutputFile.Add(' EditText param_self_EditText;');
lJavaOutputFile.Add(' LinearLayout param_self_LinearLayout;');
lJavaOutputFile.Add(' TimePicker param_self_TimePicker;');
lJavaOutputFile.Add(' Display param_self_Display;');
lJavaOutputFile.Add(' DisplayMetrics param_self_DisplayMetrics;');
lJavaOutputFile.Add(' CompoundButton param_self_CompoundButton;');
lJavaOutputFile.Add(' WindowManager param_self_WindowManager;');
lJavaOutputFile.Add(' // Params');
lJavaOutputFile.Add(' ViewGroup.LayoutParams lLayoutParams_1;');
lJavaOutputFile.Add(' DisplayMetrics lDisplayMetrics_1;');
lJavaOutputFile.Add(' CharSequence lCharSequence_1;');
lJavaOutputFile.Add(' int lint_1, lint_2, lint_3, lint_4;');
lJavaOutputFile.Add(' float lfloat_1, lfloat_2;');
lJavaOutputFile.Add(' boolean lboolean_1;');
lJavaOutputFile.Add(' // Results');
lJavaOutputFile.Add(' float lResult_float;');
lJavaOutputFile.Add(' int lResult_int;');
lJavaOutputFile.Add(' boolean lResult_boolean;');
lJavaOutputFile.Add(' Display lResult_Display;');
lJavaOutputFile.Add('');
lJavaOutputFile.Add(' switch (Buffer)');
lJavaOutputFile.Add(' {');
lJavaOutputFile.Add('');
lJavaOutputFile.AddStrings(FJavaOutputMethods);
lJavaOutputFile.Add('');
lJavaOutputFile.Add(' default:');
lJavaOutputFile.Add(' return false;');
lJavaOutputFile.Add(' }');
lJavaOutputFile.Add(' return true;');
lJavaOutputFile.Add(' }');
lJavaOutputFile.Add('}');
lJavaOutputFile.SaveToFile(AJavaOutputFile);
finally
lJavaOutputFile.Free;
lPasOutputFile.Free;
end;
end;
procedure TAndroidSDKBindingsGen.ProcessModelLine(ASourceLine: string);
var
lReaderPos: Integer = 1;
lCurWord: string;
begin
if ASourceLine = '' then Exit;
lCurWord := GetNextWord(ASourceLine, lReaderPos);
// Comments
if ASourceLine[1] = '#' then Exit;
// Starting a new class
if ASourceLine[1] = '[' then
begin
ProcessModelClass(ASourceLine);
Exit;
end;
// Adding methods to a class
if lCurWord = 'method' then
begin
ProcessModelMethod(ASourceLine, False);
Exit;
end;
if lCurWord = 'constructor' then
begin
ProcessModelConstructor(ASourceLine);
Exit;
end;
// Constants
if lCurWord = 'const' then
begin
ProcessModelConst(ASourceLine);
Exit;
end;
// Callbacks
if lCurWord = 'callbacksettercaller' then
begin
ProcessModelCallbackSetterCaller(ASourceLine);
Exit;
end;
// Fields
if lCurWord = 'field' then
begin
ProcessModelMethod(ASourceLine, True);
Exit;
end;
end;
procedure TAndroidSDKBindingsGen.ProcessModelClass(ASourceLine: string);
var
lReaderPos: Integer = 1;
lCurWord, lParentClassName: string;
begin
if ASourceLine = '' then Exit;
lCurWord := GetNextWord(ASourceLine, lReaderPos);
if FClassName <> '' then
begin
FPasOutputClasses.Add(' end;');
FPasOutputClasses.Add('');
end;
FClassNamePas := GetPascalTypeName(lCurWord);
FClassName := lCurWord;
lParentClassName := GetNextWord(ASourceLine, lReaderPos);
lParentClassName := GetPascalTypeName(lParentClassName);
FPasOutputClasses.Add(Format(' %s = class(%s)', [FClassNamePas, lParentClassName]));
FPasOutputClasses.Add(' public');
lCurWord := GetNextWord(ASourceLine, lReaderPos);
Inc(FClassNum);
FMethodNum := 0;
FPasOutputIDs.Add(' // ' + FClassNamePas);
FJavaOutputIDs.Add(' // ' + FClassName);
FPasOutputConsts.Add(' { ' + FClassNamePas + ' }');
FPasOutputClassesForward.Add(' ' + FClassNamePas + ' = class;')
end;
procedure TAndroidSDKBindingsGen.ProcessModelMethod(
ASourceLine: string; AIsField: Boolean);
var
lReaderPos: Integer = 1;
lParamNum: Integer = 1;
lCurWord, lParentClassName: string;
lMethodReturn, lMethodReturnPas, lMethodName, lParamType, lParamTypePas, lParamName, lParamPrefix: string;
DeclarationBase, TmpStr, lIDString: string;
FPasOutputImplCurLine: Integer;
lJavaParamVar, lJavaParams, lJavaParamSelf: string;
begin
if ASourceLine = '' then Exit;
lCurWord := GetNextWord(ASourceLine, lReaderPos);
// Method type and name
lMethodReturn := GetNextWord(ASourceLine, lReaderPos);
lMethodReturnPas := GetPascalTypeName(lMethodReturn);
lMethodName := GetNextWord(ASourceLine, lReaderPos);
if lMethodReturn = 'void' then DeclarationBase := 'procedure '
else DeclarationBase := 'function ';
// Beginning of the implementation part
FPasOutputImplCurLine := FPasOutputImpl.Count;
lIDString := GetIDString(lMethodName);
FPasOutputImpl.Add('begin');
FPasOutputImpl.Add(' vAndroidPipesComm.SendByte(ShortInt(amkUICommand));');
FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(' + lIDString + ');');
FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(Index); // Self, Java Pointer');
lJavaParamSelf := 'param_self_' + FClassName;
FJavaOutputMethods.Add(' // ' + ASourceLine);
FJavaOutputMethods.Add(' case ' + lIDString + ':');
FJavaOutputMethods.Add(' DebugOut("' + lIDString + '");');
FJavaOutputMethods.Add(' // Self');
FJavaOutputMethods.Add(' lInt = MyAndroidPipesComm.GetInt();');
FJavaOutputMethods.Add(' ' + lJavaParamSelf + ' = (' + FClassName + ') ViewElements.get(lInt);');
FJavaOutputMethods.Add(' // params');
// Lists of constants for the IDs
AddOutputIDs(lIDString);
// Add all parameters
TmpStr := lMethodName + '(';
repeat
lParamType := GetNextWord(ASourceLine, lReaderPos);
// Method modifiers
if (lParamType = 'virtual') or (lParamType = 'override') then Continue;
lParamTypePas := GetPascalTypeName(lParamType);
lParamName := GetNextWord(ASourceLine, lReaderPos);
if PassByReference(lParamType) then lParamPrefix := 'var '
else lParamPrefix := '';
if lParamName = '' then Break;
TmpStr := TmpStr + lParamPrefix + lParamName + ': ' + lParamTypePas + '; ';
// Pascal parameter sending
FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(Integer(' + lParamName + '));');
// Java parameter reading
lJavaParamVar := 'l' + lParamType + '_' + IntToStr(lParamNum);
FJavaOutputMethods.Add(' ' + lJavaParamVar + ' = MyAndroidPipesComm.' + GetJavaTypeReader(lParamType) + '();');
lJavaParams := lJavaParams + lJavaParamVar + ', ';
Inc(lParamNum);
until lParamName = '';
// Remove the last ; for the parameters, if necessary
if (Length(TmpStr) > 0) and (TmpStr[Length(TmpStr)-1] = ';') then
TmpStr := System.Copy(TmpStr, 0, Length(TmpStr)-2);
// And for Java params too
lJavaParams := System.Copy(lJavaParams, 0, Length(lJavaParams)-2);
// Add the return
if lMethodReturn = 'void' then
begin
TmpStr := TmpStr + ');';
FPasOutputImpl.Add(' vAndroidPipesComm.WaitForReturn();');
end
else
begin
TmpStr := TmpStr + '): ' + lMethodReturnPas + ';';
FPasOutputImpl.Add(' Result := ' + lMethodReturnPas + '(vAndroidPipesComm.WaitForIntReturn());');
end;
FPasOutputClasses.Add(' ' + DeclarationBase + TmpStr);
FPasOutputImpl.Insert(FPasOutputImplCurLine, DeclarationBase + FClassNamePas + '.' + TmpStr);
FPasOutputImpl.Add('end;');
FPasOutputImpl.Add('');
FJavaOutputMethods.Add(' //');
if AIsField then
begin
FJavaOutputMethods.Add(' lResult_' + lMethodReturn + ' = ' + lJavaParamSelf + '.' + lMethodName + ';');
FJavaOutputMethods.Add(' MyAndroidPipesComm.' + GetJavaResultFunction(lMethodReturn) + '(lResult_' + lMethodReturn + ');');
end
else if lMethodReturn = 'void' then
begin
FJavaOutputMethods.Add(' ' + lJavaParamSelf + '.' + lMethodName + '(' + lJavaParams + ');');
FJavaOutputMethods.Add(' MyAndroidPipesComm.SendResult();');
end
else
begin
FJavaOutputMethods.Add(' lResult_' + lMethodReturn + ' = ' + lJavaParamSelf + '.' + lMethodName + '(' + lJavaParams + ');');
FJavaOutputMethods.Add(' MyAndroidPipesComm.' + GetJavaResultFunction(lMethodReturn) + '(lResult_' + lMethodReturn + ');');
end;
FJavaOutputMethods.Add(' break;');
Inc(FMethodNum);
end;
procedure TAndroidSDKBindingsGen.ProcessModelConstructor(ASourceLine: string);
var
lReaderPos: Integer = 1;
lCurWord: string;
lParamNum: Integer = 1;
lMethodName, lParamType, lParamTypePas, lParamName: string;
lConstructorPasParams, lConstructorJavaParams, lParamPrefix, lJavaParamVar: string;
DeclarationBase, lIDString: string;
FPasOutputImplCurLine: Integer;
HasActivityParam: Boolean = False;
begin
if ASourceLine = '' then Exit;
lCurWord := GetNextWord(ASourceLine, lReaderPos);
// Method type and name
lMethodName := GetNextWord(ASourceLine, lReaderPos);
lIDString := GetIDString(lMethodName);
AddOutputIDs(lIDString);
FPasOutputClasses.Add(' constructor ' + lMethodName + '();');
FPasOutputImpl.Add('constructor ' + FClassNamePas + '.' + lMethodName + '();');
FPasOutputImpl.Add('begin');
FPasOutputImpl.Add(' vAndroidPipesComm.SendByte(ShortInt(amkUICommand));');
FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(' + lIDString + ');');
FJavaOutputMethods.Add(' case ' + lIDString + ':');
FJavaOutputMethods.Add(' DebugOut("' + lIDString + '");');
// Constructor parameters
lConstructorJavaParams := '';
lConstructorPasParams := '';
repeat
lParamType := GetNextWord(ASourceLine, lReaderPos);
// Method modifiers
if (lParamType = 'virtual') or (lParamType = 'override') then Continue;
// The Activity global object doesn't appear in the Pascal side and
//comes as a single word in the txt file
if (lParamType = 'Activity') then
begin
HasActivityParam := True;
Continue;
end;
lParamTypePas := GetPascalTypeName(lParamType);
lParamName := GetNextWord(ASourceLine, lReaderPos);
if PassByReference(lParamType) then lParamPrefix := 'var '
else lParamPrefix := '';
if lParamName = '' then Break;
lConstructorPasParams := lConstructorPasParams + lParamPrefix + lParamName + ': ' + lParamTypePas + '; ';
// Pascal parameter sending
FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(Integer(' + lParamName + '));');
// Java parameter reading
lJavaParamVar := 'l' + lParamType + '_' + IntToStr(lParamNum);
FJavaOutputMethods.Add(' ' + lJavaParamVar + ' = MyAndroidPipesComm.' + GetJavaTypeReader(lParamType) + '();');
lConstructorJavaParams := lConstructorJavaParams + lJavaParamVar + ', ';
Inc(lParamNum);
until lParamName = '';
if HasActivityParam then lConstructorJavaParams := 'activity, ' + lConstructorJavaParams;
// Remove the last ; for the parameters, if necessary
if (Length(lConstructorPasParams) > 0) and (lConstructorPasParams[Length(lConstructorPasParams)-1] = ';') then
lConstructorPasParams := System.Copy(lConstructorPasParams, 0, Length(lConstructorPasParams)-2);
// And for Java params too
lConstructorJavaParams := System.Copy(lConstructorJavaParams, 0, Length(lConstructorJavaParams)-2);
// Finalization of the constructor
FPasOutputImpl.Add(' Index := vAndroidPipesComm.WaitForIntReturn();');
FPasOutputImpl.Add('end;');
FJavaOutputMethods.Add(' ViewElements.add(new ' + FClassName + '(' + lConstructorJavaParams + '));');
FJavaOutputMethods.Add(' MyAndroidPipesComm.SendIntResult(ViewElements.size() - 1);');
FJavaOutputMethods.Add(' break;');
Inc(FMethodNum);
end;
procedure TAndroidSDKBindingsGen.ProcessModelConst(ASourceLine: string);
var
lReaderPos: Integer = 1;
lCurWord: string;
lConstName, lConstValue: string;
begin
if ASourceLine = '' then Exit;
lConstName := GetNextWord(ASourceLine, lReaderPos);
lConstName := GetNextWord(ASourceLine, lReaderPos);
lConstValue := GetNextWord(ASourceLine, lReaderPos);
lConstValue := GetNextWord(ASourceLine, lReaderPos);
// Method type and name
FPasOutputConsts.Add(Format(' %s = %s;', [lConstName, lConstValue]));
end;
// callbacksettercaller setOnClickListener callOnClickListener OnClickCallback = procedure (v: TView) of object;
procedure TAndroidSDKBindingsGen.ProcessModelCallbackSetterCaller(ASourceLine: string);
var
lReaderPos: Integer = 1;
lCurWord: string;
lSetterName, lCallerName, lCallbackName, lCallbackDeclaration: string;
lIDSetter, lIDStart, lIDFinished: String;
begin
if ASourceLine = '' then Exit;
lSetterName := GetNextWord(ASourceLine, lReaderPos);
lSetterName := GetNextWord(ASourceLine, lReaderPos);
lCallerName := GetNextWord(ASourceLine, lReaderPos);
lCallbackDeclaration := Copy(ASourceLine, lReaderPos, Length(ASourceLine));
lCallbackDeclaration := Trim(lCallbackDeclaration);
lCallbackName := GetNextWord(ASourceLine, lReaderPos);
lIDSetter := GetIDString(lSetterName);
AddOutputIDs(lIDSetter);
lIDStart := GetIDString(lCallbackName + '_Start');
AddOutputIDs(lIDStart);
lIDFinished := GetIDString(lCallbackName + '_Finished');
AddOutputIDs(lIDFinished);
FPasOutputTypes.Add(' T' + lCallbackDeclaration);
FPasOutputClasses.Add(' public');
FPasOutputClasses.Add(' ' + lCallbackName + ': T' + lCallbackName + ';');
FPasOutputClasses.Add(' procedure ' + lSetterName + '(ACallback: T' + lCallbackName + ');');
FPasOutputClasses.Add(' procedure ' + lCallerName + '();');
FPasOutputClasses.Add(' public');
FPasOutputImpl.Add('procedure ' + FClassNamePas + '.' + lSetterName + '(ACallback: T' + lCallbackName + ');');
FPasOutputImpl.Add('begin');
FPasOutputImpl.Add(' OnClickListener := ACallback;');
FPasOutputImpl.Add(' vAndroidPipesComm.SendByte(ShortInt(amkUICommand));');
FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(' + lIDSetter + ');');
FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(Index); // Self, Java Index');
FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(PtrInt(Self)); // Self, Pascal pointer');
FPasOutputImpl.Add(' vAndroidPipesComm.WaitForReturn();');
FPasOutputImpl.Add('end;');
FPasOutputImpl.Add('');
FPasOutputImpl.Add('procedure ' + FClassNamePas + '.' + lCallerName + '();');
FPasOutputImpl.Add('begin');
FPasOutputImpl.Add(' if Assigned(OnClickListener) then OnClickListener(Self);');
FPasOutputImpl.Add('end;');
// Method type and name
FPasOutputMessages.Add(' ' + lIDStart + ':');
FPasOutputMessages.Add(' begin');
FPasOutputMessages.Add(' lPascalPointer := vAndroidPipesComm.ReadInt();');
FPasOutputMessages.Add(' TTextView(lPascalPointer).callOnClickListener();');
FPasOutputMessages.Add(' vAndroidPipesComm.SendMessage(amkUICommand, ' + lIDFinished + ');');
FPasOutputMessages.Add(' end;');
{ amkUI_MenuItem_setOnMenuItemClickListener_Start:
begin
lInt := ReadInt();
lMenuItem := TMenuItem(FindItemIdInList(MenuItems, lInt));
if lMenuItem <> nil then
lInt := lMenuItem.callOnMenuItemClickListener();
vAndroidPipesComm.SendMessage(amkUICommand, amkUI_MenuItem_setOnMenuItemClickListener_Finished);
vAndroidPipesComm.SendInt(lInt);
end;
end;}
end;
{ Reads one word in a string, starting at AStartPos (1-based index)
and going up to a space or comma or ( or ) or another separator }
function TAndroidSDKBindingsGen.GetNextWord(ALine: string;
var AStartPos: Integer): string;
const
WordSeparators = [' ','(',')','[',']',',',';',':',#9{TAB}];
var
lState: Integer = 0;
begin
Result := '';
while AStartPos <= Length(ALine) do
begin
// Searching the word start
if lState = 0 then
begin
if ALine[AStartPos] in WordSeparators then Inc(AStartPos)
else
begin
Result := ALine[AStartPos];
Inc(AStartPos);
lState := 1;
end;
end
// Reading until the word finishes
else
begin
if ALine[AStartPos] in WordSeparators then Exit
else
begin
Result := Result + ALine[AStartPos];
Inc(AStartPos);
end;
end;
end;
end;
function TAndroidSDKBindingsGen.GetPascalTypeName(ABaseName: string): string;
begin
if ABaseName = '' then Exit('');
if ABaseName = 'int' then Result := 'Integer'
else if ABaseName = 'boolean' then Result := 'Boolean'
else if ABaseName = 'float' then Result := 'Single'
else if ABaseName = 'void' then Result := ABaseName
else if ABaseName = 'CharSequence' then Result := 'string'
else if ABaseName = 'TJavaObject' then Result := ABaseName
else
begin
Result := 'T' + ABaseName;
Result := StringReplace(Result, '.', '_', [rfReplaceAll]);
end;
end;
function TAndroidSDKBindingsGen.PassByReference(ABaseName: string): Boolean;
begin
if ABaseName = '' then Exit(False);
if ABaseName = 'int' then Result := False
else if ABaseName = 'boolean' then Result := False
else if ABaseName = 'float' then Result := False
else Result := True;
end;
function TAndroidSDKBindingsGen.GetJavaResultFunction(AReturnType: string
): string;
begin
if AReturnType = 'boolean' then Result := 'SendBoolResult'
else if AReturnType = 'float' then Result := 'SendFloatResult'
else Result := 'SendIntResult';
end;
function TAndroidSDKBindingsGen.GetJavaTypeReader(AType: string): string;
begin
if AType = 'boolean' then Exit('GetBool')
else Exit('GetInt');
end;
function TAndroidSDKBindingsGen.GetIDString(AMethodName: string): string;
begin
Result := 'amkUI_' + FClassNamePas + '_' + AMethodName;;
Result := StringReplace(Result, '.', '_', [rfReplaceAll]);
end;
procedure TAndroidSDKBindingsGen.AddOutputIDs(AIDString: string);
begin
FPasOutputIDs.Add(' ' + AIDString + ' = $' + IntToHex(FClassNum*$1000+FMethodNum, 8) + ';');
FJavaOutputIDs.Add(' static final int ' + AIDString + ' = 0x' + IntToHex(FClassNum*$1000+FMethodNum, 8) + ';');
end;
constructor TAndroidSDKBindingsGen.Create;
begin
FSourceFile := TStringList.Create;
FPasOutputTypes := TStringList.Create;
FPasOutputClassesForward := TStringList.Create;
FPasOutputClasses := TStringList.Create;
FPasOutputImpl := TStringList.Create;
FPasOutputIDs := TStringList.Create;
FPasOutputConsts := TStringList.Create;
FPasOutputMessages := TStringList.Create;
FJavaOutputIDs := TStringList.Create;
FJavaOutputMethods := TStringList.Create;
FClassNum := $100;
end;
destructor TAndroidSDKBindingsGen.Destroy;
begin
FSourceFile.Free;
FPasOutputTypes.Free;
FPasOutputClassesForward.Free;
FPasOutputClasses.Free;
FPasOutputImpl.Free;
FPasOutputIDs.Free;
FPasOutputConsts.Free;
FPasOutputMessages.Free;
FJavaOutputIDs.Free;
FJavaOutputMethods.Free;
inherited Destroy;
end;
procedure TAndroidSDKBindingsGen.GenerateAllBindings(AInputDir, APasOutputDir,
AJavaOutputDir: string);
begin
ProcessModelFile(IncludeTrailingPathDelimiter(AInputDir) + 'android_all.txt',
IncludeTrailingPathDelimiter(APasOutputDir) + 'android_all.pas',
IncludeTrailingPathDelimiter(AJavaOutputDir) + 'AndroidAll.java');
end;
initialization
AndroidSDKBindingsGen := TAndroidSDKBindingsGen.Create;
finalization
AndroidSDKBindingsGen.Free;
end.